diff --git a/README.md b/README.md index f517fcb..d2842da 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ yl_survey.evaluate(s_id) ??? How do we evaluate that stuff ??? ``` -yl_survey.create_question(s_id, question, category, sort, {allowed_types}, {answers}, enabled) +yl_survey.create_question(s_id, question, category, sort, {options}, {answers}, enabled) ``` Returns `true, q_id` if successful, `false, "errormessage"` if not. @@ -115,12 +115,12 @@ Adds a question to the survey identified by `s_id`. * question: string, required. This is the question text the survey asks its respondents. * category: string, optional, default empty. Use it for additonal explanation, category, help. Is displayed near the question. May be nil or empty. * sort: integer, optional, defaults to the next free number. Use this to order your questions. -* {allowed_types}: table of enum("singlechoice","multiplechoice","freetext"), required. `singlechoice` and `multiplechoice` are mutually exclusive, while freetxt can be combined with either. +* {options}: table of options with defaults `{"has_freetext" : true, "min_responses" : 0, "max_responses" : 0}`, optional. `max_responses : 0` means there is no limit on the maximum number of answers. Example: "singlechoice question without freetext": `{"has_freetext" : false, "min_responses" : 0, "max_responses" : 1}` * {answers}: table of strings, optional. Holds the answers to a singlechoice or multiplechoice question. * enabled: boolean, optional, defaults to true. If true, the question is delivered to a participant. If false, the question is hidden. ``` -yl_survey.edit_question(s_id, q_id, question, sort, category, {allowed_types}, {answers}, enabled, delete_responses) +yl_survey.edit_question(s_id, q_id, question, sort, category, {options}, {answers}, enabled, delete_responses) ``` Returns `true, q_id` if successful, `false, "errormessage"` if not. diff --git a/api.lua b/api.lua index 912d7ee..4b40433 100644 --- a/api.lua +++ b/api.lua @@ -44,37 +44,30 @@ local function validate(value, expect_type, allow_nil) return false end -local function validate_questiontype(allowed_types) - local valid_types = { - singlechoice = true, - multiplechoice = true, - freetext = true - } +local function validate_options(options) - local sm_count = 0 - local ft_count = 0 + if (validate(options, "table", false) == false) then return false end + if (validate(options.has_freetext, "boolean", true) == false) then return false end + if (validate(options.min_responses, "number", true) == false) then return false end + if (validate(options.max_responses, "number", true) == false) then return false end - for _, t in ipairs(allowed_types) do + if (options and options.min_responses and (options.min_responses < 0)) then return false end + if (options and options.max_responses and (options.max_responses < 0)) then return false end - -- Invalid question type - if (valid_types[t] == nil) then return false end + if (options and options.min_responses and options.max_responses and + (options.min_responses > options.max_responses)) then return false end - -- Either singlechoice OR multiplechoice - if ((t == "singlechoice") or (t == "multiplechoice")) then - sm_count = sm_count + 1 - end + return true +end - if sm_count > 1 then return false end - - -- Only one freetext allowed - if (t == "freetext") then ft_count = ft_count + 1 end - - if ft_count > 1 then return false end +local function validate_answers(answers, options) + if (((answers == nil) or (next(answers) == nil)) and + ((options and options.min_responses and (options.min_responses > 0)) or + (options and options.min_responses and (options.max_responses > 0)))) then + return false end - if ((ft_count + sm_count) == 0) then return false end - return true end @@ -322,7 +315,7 @@ function yl_survey.remove_record(id) return remove_record(id) end -- create_question -- -local function create_question(id, question, category, sort, allowed_types, +local function create_question(id, question, category, sort, options, answers, enabled) -- Defense if (validate(id, "string", false) == false) then @@ -338,8 +331,9 @@ local function create_question(id, question, category, sort, allowed_types, if (validate_nil_or_positive(sort) == false) then return false, yl_survey.t("sort must be positive number") end - if (validate(allowed_types, "table", false) == false) then - return false, yl_survey.t("allowed_types must be table") + if (options == nil) then options = {} end + if (validate(options, "table", false) == false) then + return false, yl_survey.t("options must be table") end if (validate(answers, "table", true) == false) then return false, yl_survey.t("answers must be table") @@ -349,19 +343,22 @@ local function create_question(id, question, category, sort, allowed_types, return false, yl_survey.t("enabled must be boolean") end - -- Specialcase : allowed_types must be a combination of - -- "singlechoice" or "multiplechoice" or "freetext" - if (validate_questiontype(allowed_types) == false) then - return false, yl_survey.t("wrong allowed_types") + if (validate_options(options) == false) then + return false, yl_survey.t("wrong options") end - -- Specialcase : answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice + if (validate_answers(answers, options) == false) then + return false, yl_survey.t("wrong answers") + end + + --[[ if (((answers == nil) or (next(answers) == nil)) and - ((yl_survey.table_contains(allowed_types, "multiplechoice") == true) or - (yl_survey.table_contains(allowed_types, "singlechoice") == true))) then + ((yl_survey.table_contains(options, "multiplechoice") == true) or + (yl_survey.table_contains(options, "singlechoice") == true))) then return false, yl_survey.t( "answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice") end + ]]-- local record = yl_survey.get_record(id) @@ -392,7 +389,9 @@ local function create_question(id, question, category, sort, allowed_types, sort = next_sort, question = question, enabled = enabled, - allowed_types = allowed_types, + has_freetext = options.has_freetext or true, + min_responses = options.min_responses or 0, + max_responses = options.max_responses or 0, answers = answers, responses = {} } @@ -409,16 +408,16 @@ local function create_question(id, question, category, sort, allowed_types, end end -function yl_survey.create_question(id, question, category, sort, allowed_types, +function yl_survey.create_question(id, question, category, sort, options, answers, enabled) - return create_question(id, question, category, sort, allowed_types, answers, + return create_question(id, question, category, sort, options, answers, enabled) end -- edit_question -- -local function edit_question(id, q_id, question, sort, category, allowed_types, +local function edit_question(id, q_id, question, sort, category, options, answers, enabled, delete_responses) -- Defense if (validate(id, "string", false) == false) then @@ -438,8 +437,9 @@ local function edit_question(id, q_id, question, sort, category, allowed_types, if (validate_nil_or_positive(sort) == false) then return false, yl_survey.t("sort must be positive number") end - if (validate(allowed_types, "table", true) == false) then - return false, yl_survey.t("allowed_types must be table") + if (options == nil) then options = {} end + if (validate(options, "table", false) == false) then + return false, yl_survey.t("options must be table") end if (validate(answers, "table", true) == false) then return false, yl_survey.t("answers must be table") @@ -451,19 +451,12 @@ local function edit_question(id, q_id, question, sort, category, allowed_types, return false, yl_survey.t("delete_responses must be boolean") end - -- Specialcase : allowed_types must be a combination of - -- "singlechoice" or "multiplechoice" or "freetext" - if ((allowed_types ~= nil) and - (validate_questiontype(allowed_types) == false)) then - return false, yl_survey.t("wrong allowed_types") + if (validate_options(options) == false) then + return false, yl_survey.t("wrong options") end - -- Specialcase : answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice - if ((answers ~= nil) and (next(answers) ~= nil) and - ((yl_survey.table_contains(allowed_types, "multiplechoice") == true) or - (yl_survey.table_contains(allowed_types, "singlechoice") == true))) then - return false, yl_survey.t( - "answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice") + if (validate_answers(answers, options) == false) then + return false, yl_survey.t("wrong answers") end local record = yl_survey.get_record(id) @@ -504,7 +497,9 @@ local function edit_question(id, q_id, question, sort, category, allowed_types, sort = sort or t_question["sort"], question = question or t_question["question"], enabled = enabled or t_question["enabled"], - allowed_types = allowed_types or t_question["allowed_types"], + has_freetext = options.has_freetext or t_question["has_freetext"] or true, + min_responses = options.min_responses or t_question["min_responses"] or 0, + max_responses = options.max_responses or t_question["max_responses"] or 0, answers = answers or t_question["answers"], responses = n_responses } @@ -523,9 +518,9 @@ local function edit_question(id, q_id, question, sort, category, allowed_types, end function yl_survey.edit_question(s_id, q_id, question, sort, category, - allowed_types, answers, enabled, + options, answers, enabled, delete_responses) - return edit_question(s_id, q_id, question, sort, category, allowed_types, + return edit_question(s_id, q_id, question, sort, category, options, answers, enabled, delete_responses) end diff --git a/dev/whatdowedo.txt b/dev/whatdowedo.txt index bd2363e..7dc4e5c 100644 --- a/dev/whatdowedo.txt +++ b/dev/whatdowedo.txt @@ -20,8 +20,8 @@ remove_survey(s_id) list_surveys() evaluate(s_id) -create_question(s_id, question, category, sort, {allowed_types}, {answers}) return q_id -edit_question(s_id, q_id, question, sort, category, {allowed_types}, {answers}, delete_responses) +create_question(s_id, question, category, sort, {options}, {answers}) return q_id +edit_question(s_id, q_id, question, sort, category, {options}, {answers}, delete_responses) remove_question(q_id) list_questions() @@ -51,11 +51,9 @@ This is the planned data structure: "sort": 99, "question": "How did you find out about Minetest in general?", "enabled" : true, - "allowed_types": [ - "singlechoice", - "multiplechoice", - "freetext" - ], + "has_freetext" : true, + "min_responses" : 1, + "max_responses" : 5, "answers": { "1": "Friend dragged me over", "2": "I came here of my own free will" @@ -81,11 +79,9 @@ This is the planned data structure: "sort": 2, "question": "What do you think about the current state of the server?", "enabled" : true, - "allowed_types": [ - "singlechoice", - "multiplechoice", - "freetext" - ], + "has_freetext" : true, + "min_responses" : 1, + "max_responses" : 0 "answers": { "0": "Write your answer here", "1": "Terrible",