generated from your-land/yl_template
466 lines
17 KiB
Lua
466 lines
17 KiB
Lua
-- Logging
|
|
local function log(text)
|
|
local logmessage = yl_survey_fs.t("log_prefix", yl_survey_fs.modname, text)
|
|
if yl_survey_fs.settings.debug then minetest.log("action", logmessage) end
|
|
return logmessage
|
|
end
|
|
|
|
function yl_survey_fs.log(text) return log(text) end
|
|
|
|
-- Helper
|
|
|
|
local function get_next_q_id_and_sort(questions, current_sort)
|
|
if current_sort == nil then current_sort = 0 end
|
|
|
|
local ret_id, ret_sort
|
|
local ret_maxsort = 0
|
|
local temp = math.huge
|
|
for _, q in pairs(questions) do
|
|
if ((q.sort > current_sort) and (q.sort < temp) and (q.enabled == true)) then
|
|
temp = q.sort
|
|
ret_id = q.id
|
|
ret_sort = q.sort
|
|
end
|
|
if ((q.sort >= ret_maxsort) and (q.enabled == true)) then
|
|
ret_maxsort = q.sort
|
|
end
|
|
end
|
|
return ret_id, ret_sort, ret_maxsort
|
|
end
|
|
|
|
function yl_survey_fs.get_next_q_id_and_sort(questions, current_sort)
|
|
return get_next_q_id_and_sort(questions, current_sort)
|
|
end
|
|
|
|
local function get_previous_q_id_and_sort(questions, current_sort)
|
|
if current_sort == nil then current_sort = 0 end
|
|
|
|
local ret_id, ret_sort
|
|
local ret_minsort = math.huge
|
|
local temp = 0
|
|
for _, q in pairs(questions) do
|
|
if ((q.sort < current_sort) and (q.sort > temp) and (q.enabled == true)) then
|
|
temp = q.sort
|
|
ret_id = q.id
|
|
ret_sort = q.sort
|
|
end
|
|
if ((q.sort <= ret_minsort) and (q.enabled == true)) then
|
|
ret_minsort = q.sort
|
|
end
|
|
end
|
|
return ret_id, ret_sort, ret_minsort
|
|
end
|
|
|
|
function yl_survey_fs.get_previous_q_id_and_sort(questions, current_sort)
|
|
return get_previous_q_id_and_sort(questions, current_sort)
|
|
end
|
|
|
|
local function get_cache(survey_id, question_id, playername)
|
|
|
|
local _, responses = yl_survey.get_response(survey_id, question_id,
|
|
playername, true, true)
|
|
|
|
-- q obj
|
|
local q_success = yl_survey.get_question(survey_id, question_id, true,
|
|
playername)
|
|
if (q_success == false) then return responses end
|
|
|
|
local cache = {}
|
|
for k, v in pairs(responses) do
|
|
local n_key = tonumber(k)
|
|
if (n_key > 0) then cache[k] = true end
|
|
end
|
|
|
|
return cache
|
|
end
|
|
|
|
-- Validation
|
|
|
|
local function validate(value, expect_type, allow_nil)
|
|
if ((allow_nil == true) and (value == nil)) then return true end
|
|
if ((allow_nil == false) and (value == nil)) then return false end
|
|
if (type(value) == expect_type) then return true end
|
|
return false
|
|
end
|
|
|
|
function yl_survey_fs.validate(value, expect_type, allow_nil)
|
|
return validate(value, expect_type, allow_nil)
|
|
end
|
|
|
|
-- Formspecs
|
|
|
|
-- construct_frame_formspec
|
|
--
|
|
|
|
yl_survey_fs.frame_formspec = table.concat({
|
|
"formspec_version[6]", "size[16.18,10]",
|
|
"button_exit[15.03,0.15;1,1;btn_quit;X]",
|
|
"button[6.68,8.5;3,1;btn_start;Start]", "label[0.5,0.75;%s]",
|
|
"textarea[0.5,1.5;15.03,6.5;;;%s]"
|
|
}, "")
|
|
|
|
local string_replacements = {
|
|
["@allow_anonymous@"] = "allow_anonymous",
|
|
["@allow_changes@"] = "allow_changes",
|
|
["@allow_names@"] = "allow_names",
|
|
["@creation_date@"] = "creation_date",
|
|
["@id@"] = "id",
|
|
["@modification_date@"] = "modification_date",
|
|
["@owner@"] = "owner",
|
|
["@title@"] = "title"
|
|
}
|
|
|
|
local function construct_frame_formspec(playername, survey_id)
|
|
|
|
local record = yl_survey.get_record(survey_id)
|
|
-- local owner = record["metadata"].owner
|
|
local title = record["metadata"].title or ""
|
|
local description = record["metadata"].description or ""
|
|
|
|
for replaceme, replacemewith in pairs(string_replacements) do
|
|
local r = record["metadata"][replacemewith] or "N/A"
|
|
description = string.gsub(description, replaceme, tostring(r))
|
|
end
|
|
|
|
-- local fs_owner = minetest.formspec_escape(owner)
|
|
local fs_title = minetest.formspec_escape(title)
|
|
local fs_description = minetest.formspec_escape(description)
|
|
|
|
return
|
|
string.format(yl_survey_fs.frame_formspec, fs_title, fs_description) or
|
|
""
|
|
end
|
|
|
|
function yl_survey_fs.construct_frame_formspec(playername, survey_id)
|
|
return construct_frame_formspec(playername, survey_id)
|
|
end
|
|
|
|
-- construct_answer_formspec
|
|
--
|
|
|
|
yl_survey_fs.single_answer_formspec = table.concat({
|
|
"checkbox[0,%s;checkbox_%s;;%s]", -- answer ID
|
|
"textarea[0.5,%s;14,1;;;%s]" -- answer text
|
|
}, "")
|
|
|
|
yl_survey_fs.single_freetext_formspec =
|
|
"textarea[0.5,2.5;15.03,1;input_freetext;;%s]" -- Freetext
|
|
|
|
yl_survey_fs.answers_formspec = table.concat({
|
|
"formspec_version[6]", "size[16.18,10]", -- buttons
|
|
"button_exit[15.03,0.15;1,1;btn_quit;X]",
|
|
"button[6.68,8.5;3,1;btn_save;Save]",
|
|
"button[12.68,8.5;3,1;btn_skip;Skip >]",
|
|
"button[0.68,8.5;3,1;btn_back;< Back]", -- Content
|
|
"label[0.5,0.75;%s]", -- Title
|
|
"textarea[0.5,1.5;15.03,1;;;%s]", -- Question
|
|
"%s", -- "textarea[0.5,2.5;15.03,1;input_freetext;;%s]", -- Freetext
|
|
"scrollbaroptions[arrows=show]",
|
|
"scrollbar[15.35,3.75;0.5,4.5;vertical;scroll_options;]",
|
|
"scroll_container[0.5,3.75;14.53,4.5;scroll_options;vertical;]", "%s", -- Answers
|
|
"scroll_container_end[]"
|
|
}, "")
|
|
|
|
local function construct_answer_formspec(playername, survey_id, question_id)
|
|
|
|
local record = yl_survey.get_record(survey_id)
|
|
if (record == nil) then return end
|
|
local title = record["metadata"].title or ""
|
|
|
|
local fs_title = minetest.formspec_escape(title)
|
|
|
|
local q_success, q = yl_survey.get_question(survey_id, question_id, true,
|
|
playername)
|
|
if (q_success == false) then return end
|
|
|
|
if (q["enabled"] ~= true) then return end
|
|
local fs_question = minetest.formspec_escape(q.question or "N/A")
|
|
-- error:
|
|
if (yl_survey.table_contains(q.allowed_types, "singlechoice") == true) and
|
|
(yl_survey.table_contains(q.allowed_types, "multiplechoice") == true) then
|
|
return
|
|
end
|
|
-- singlechoice
|
|
if (yl_survey.table_contains(q.allowed_types, "singlechoice") == true) then
|
|
fs_question = "singlechoice : " .. fs_question
|
|
end
|
|
-- multiplechoice
|
|
if (yl_survey.table_contains(q.allowed_types, "multiplechoice") == true) then
|
|
fs_question = "multiplechoice : " .. fs_question
|
|
end
|
|
|
|
local r_success, responses = yl_survey.get_response(survey_id, question_id,
|
|
playername, false, true)
|
|
if (r_success == false) then return end
|
|
local answers = q.answers or {}
|
|
local freetext_default = yl_survey_fs.t("freetext_default")
|
|
local fs_freetext = minetest.formspec_escape(responses["0"] or
|
|
freetext_default)
|
|
|
|
local insert_freetext = ""
|
|
if (yl_survey.table_contains(q.allowed_types, "freetext") == true) then
|
|
insert_freetext = string.format(yl_survey_fs.single_freetext_formspec,
|
|
fs_freetext)
|
|
end
|
|
|
|
local t_answers = {}
|
|
local spacer = 0
|
|
local checkbox_spacer = 0.3
|
|
local textarea_spacer = 0
|
|
for key, answer in pairs(answers) do
|
|
local fs_answer = minetest.formspec_escape(answer)
|
|
local checkbox_y = checkbox_spacer + spacer
|
|
local textarea_y = textarea_spacer + spacer
|
|
local checked = responses[tostring(key)] and true or false
|
|
local s_new = string.format(yl_survey_fs.single_answer_formspec,
|
|
tostring(checkbox_y), tostring(key),
|
|
tostring(checked), tostring(textarea_y),
|
|
fs_answer)
|
|
spacer = spacer + 1
|
|
table.insert(t_answers, s_new)
|
|
end
|
|
|
|
local s_answers = table.concat(t_answers, "")
|
|
return string.format(yl_survey_fs.answers_formspec, fs_title, fs_question,
|
|
insert_freetext, s_answers) or ""
|
|
end
|
|
|
|
function yl_survey_fs.construct_answer_formspec(playername, survey_id,
|
|
question_id)
|
|
return construct_answer_formspec(playername, survey_id, question_id)
|
|
end
|
|
|
|
-- Cache
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
local playername = player:get_player_name()
|
|
yl_survey_fs.data[playername] = nil
|
|
end)
|
|
|
|
--[[
|
|
|
|
yl_survey_fs.data =
|
|
{
|
|
AliasAlreadyTaken = {
|
|
survey_id = "somecrazy UUID",
|
|
q_id = 4,
|
|
response = {}
|
|
}
|
|
}
|
|
|
|
]] --
|
|
|
|
-- on_player_receive_fields
|
|
--
|
|
|
|
minetest.register_on_player_receive_fields(
|
|
function(player, formname, fields)
|
|
|
|
local playername = player:get_player_name()
|
|
local survey_id = yl_survey_fs and yl_survey_fs.data and
|
|
yl_survey_fs.data[playername] and
|
|
yl_survey_fs.data[playername].survey_id or ""
|
|
|
|
--[[ if (string.sub(formname,1,12) ~= "yl_survey_fs") then
|
|
return
|
|
end ]] --
|
|
|
|
if (formname ~= "yl_survey_fs:" .. survey_id) then return end
|
|
|
|
if fields == nil then
|
|
yl_survey_fs.data[playername] = nil
|
|
return
|
|
end
|
|
|
|
if fields.quit then
|
|
yl_survey_fs.data[playername] = nil
|
|
return
|
|
end
|
|
|
|
if fields.btn_start then
|
|
|
|
local q_success, questions =
|
|
yl_survey.list_questions(survey_id, false)
|
|
if (q_success == false) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot find questions"))
|
|
return
|
|
end
|
|
-- local current_q_id = 0
|
|
local current_sort = 0
|
|
local next_q_id, next_sort =
|
|
yl_survey_fs.get_next_q_id_and_sort(questions, current_sort)
|
|
if (next_q_id == nil) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot find next q_id"))
|
|
return
|
|
end
|
|
if (next_sort == nil) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot find next sort"))
|
|
return
|
|
end
|
|
local formspec = yl_survey_fs.construct_answer_formspec(playername,
|
|
survey_id,
|
|
next_q_id)
|
|
|
|
if (formspec == nil) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot create formspec"))
|
|
return
|
|
end
|
|
|
|
-- The survey ID won't change. We know it already and if it's different, THEN there's a problem
|
|
-- yl_survey_fs.data[playername].survey_id = survey_id
|
|
yl_survey_fs.data[playername].q_id = next_q_id
|
|
yl_survey_fs.data[playername].sort = next_sort
|
|
yl_survey_fs.data[playername].response =
|
|
get_cache(survey_id, next_q_id, playername)
|
|
minetest.show_formspec(playername, formname, formspec)
|
|
elseif fields.btn_back then
|
|
|
|
local q_success, questions =
|
|
yl_survey.list_questions(survey_id, false)
|
|
if (q_success == false) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot find questions"))
|
|
return
|
|
end
|
|
-- local current_q_id = yl_survey_fs.data[playername].q_id
|
|
local current_sort = yl_survey_fs.data[playername].sort
|
|
local previous_q_id, previous_sort, min_sort =
|
|
yl_survey_fs.get_previous_q_id_and_sort(questions, current_sort)
|
|
|
|
local formspec
|
|
if (current_sort == min_sort) then
|
|
-- Back button on first question
|
|
yl_survey_fs.data[playername].q_id = 0
|
|
yl_survey_fs.data[playername].sort = 0
|
|
yl_survey_fs.data[playername].response = {}
|
|
formspec = yl_survey_fs.construct_frame_formspec(playername,
|
|
survey_id)
|
|
else
|
|
if (previous_q_id == nil) then
|
|
minetest.log("warning",
|
|
yl_survey_fs.t("cannot find previous q_id"))
|
|
return
|
|
end
|
|
if (previous_sort == nil) then
|
|
minetest.log("warning",
|
|
yl_survey_fs.t("cannot find previous sort"))
|
|
return
|
|
end
|
|
formspec = yl_survey_fs.construct_answer_formspec(playername,
|
|
survey_id,
|
|
previous_q_id)
|
|
yl_survey_fs.data[playername].q_id = previous_q_id
|
|
yl_survey_fs.data[playername].sort = previous_sort
|
|
yl_survey_fs.data[playername].response =
|
|
get_cache(survey_id, previous_q_id, playername)
|
|
end
|
|
|
|
if (formspec == nil) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot create formspec"))
|
|
return
|
|
end
|
|
|
|
minetest.show_formspec(playername, formname, formspec)
|
|
elseif fields.btn_skip then
|
|
|
|
local q_success, questions =
|
|
yl_survey.list_questions(survey_id, false)
|
|
if (q_success == false) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot find questions"))
|
|
return
|
|
end
|
|
-- local current_q_id = yl_survey_fs.data[playername].q_id
|
|
local current_sort = yl_survey_fs.data[playername].sort
|
|
local next_q_id, next_sort, max_sort =
|
|
yl_survey_fs.get_next_q_id_and_sort(questions, current_sort)
|
|
|
|
local formspec
|
|
if (current_sort == max_sort) then
|
|
-- Skip button on last question
|
|
yl_survey_fs.data[playername].q_id = 0
|
|
yl_survey_fs.data[playername].sort = 0
|
|
yl_survey_fs.data[playername].response = {}
|
|
formspec = yl_survey_fs.construct_frame_formspec(playername,
|
|
survey_id)
|
|
else
|
|
if (next_q_id == nil) then
|
|
minetest.log("warning",
|
|
yl_survey_fs.t("cannot find next q_id"))
|
|
return
|
|
end
|
|
if (next_sort == nil) then
|
|
minetest.log("warning",
|
|
yl_survey_fs.t("cannot find next sort"))
|
|
return
|
|
end
|
|
formspec = yl_survey_fs.construct_answer_formspec(playername,
|
|
survey_id,
|
|
next_q_id)
|
|
yl_survey_fs.data[playername].q_id = next_q_id
|
|
yl_survey_fs.data[playername].sort = next_sort
|
|
yl_survey_fs.data[playername].response =
|
|
get_cache(survey_id, next_q_id, playername)
|
|
end
|
|
|
|
if (formspec == nil) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot create formspec"))
|
|
return
|
|
end
|
|
|
|
minetest.show_formspec(playername, formname, formspec)
|
|
elseif fields.btn_save then
|
|
-- storeme
|
|
|
|
-- Cache
|
|
if (yl_survey_fs.data[playername] == nil) then
|
|
yl_survey_fs.data[playername] = {}
|
|
end
|
|
|
|
-- Stored previously
|
|
local question_id = yl_survey_fs.data[playername].q_id
|
|
-- local cache = get_cache(survey_id, question_id, playername)
|
|
|
|
local q_success, q = yl_survey.get_question(survey_id, question_id,
|
|
true, playername)
|
|
if (q_success == false) then return end
|
|
|
|
local response = {}
|
|
for k, v in pairs(yl_survey_fs.data[playername].response) do
|
|
local n_key = tonumber(k)
|
|
if ((n_key > 0) and (v == true)) then
|
|
response[k] = q.answers[n_key]
|
|
end
|
|
end
|
|
|
|
-- Add freetext if applicable
|
|
if ((fields.input_freetext) and
|
|
(yl_survey.table_contains(q.allowed_types, "freetext") == true)) then
|
|
response["0"] = fields.input_freetext
|
|
end
|
|
|
|
-- store it!
|
|
local a_success =
|
|
yl_survey.answer_question(survey_id, question_id, playername,
|
|
response, true)
|
|
if (a_success == false) then
|
|
minetest.log("warning", yl_survey_fs.t("cannot store responses"))
|
|
return
|
|
end
|
|
|
|
else
|
|
for k, v in pairs(fields) do
|
|
local checkbox_id = string.sub(k, 9 + 1)
|
|
if ((string.sub(k, 1, 9) == "checkbox_") and
|
|
(tonumber(checkbox_id) ~= nil)) then
|
|
if v == "true" then
|
|
yl_survey_fs.data[playername].response[checkbox_id] =
|
|
true
|
|
else
|
|
yl_survey_fs.data[playername].response[checkbox_id] =
|
|
false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
end)
|