Software /
code /
prosody-modules
Comparison
mod_captcha_registration/util/dataforms.lua @ 1373:985bfc6e8cad
mod_captcha_registration: initial commit
author | mrDoctorWho <mrdoctorwho@gmail.com> |
---|---|
date | Sat, 29 Mar 2014 22:56:24 +0700 |
comparison
equal
deleted
inserted
replaced
1372:a573d64968e9 | 1373:985bfc6e8cad |
---|---|
1 -- Prosody IM | |
2 -- Copyright (C) 2008-2010 Matthew Wild | |
3 -- Copyright (C) 2008-2010 Waqas Hussain | |
4 -- | |
5 -- This project is MIT/X11 licensed. Please see the | |
6 -- COPYING file in the source package for more information. | |
7 -- | |
8 | |
9 local setmetatable = setmetatable; | |
10 local pairs, ipairs = pairs, ipairs; | |
11 local tostring, type, next = tostring, type, next; | |
12 local t_concat = table.concat; | |
13 local st = require "util.stanza"; | |
14 local jid_prep = require "util.jid".prep; | |
15 | |
16 module "dataforms" | |
17 | |
18 local xmlns_forms = 'jabber:x:data'; | |
19 | |
20 local form_t = {}; | |
21 local form_mt = { __index = form_t }; | |
22 | |
23 function new(layout) | |
24 return setmetatable(layout, form_mt); | |
25 end | |
26 | |
27 function form_t.form(layout, data, formtype) | |
28 local form = st.stanza("x", { xmlns = xmlns_forms, type = formtype or "form" }); | |
29 if layout.title then | |
30 form:tag("title"):text(layout.title):up(); | |
31 end | |
32 if layout.instructions then | |
33 form:tag("instructions"):text(layout.instructions):up(); | |
34 end | |
35 for n, field in ipairs(layout) do | |
36 local field_type = field.type or "text-single"; | |
37 -- Add field tag | |
38 form:tag("field", { type = field_type, var = field.name, label = field.label }); | |
39 | |
40 local value = (data and data[field.name]) or field.value; | |
41 | |
42 if value then | |
43 -- Add value, depending on type | |
44 if field_type == "hidden" then | |
45 if type(value) == "table" then | |
46 -- Assume an XML snippet | |
47 form:tag("value") | |
48 :add_child(value) | |
49 :up(); | |
50 else | |
51 form:tag("value"):text(tostring(value)):up(); | |
52 end | |
53 elseif field_type == "boolean" then | |
54 form:tag("value"):text((value and "1") or "0"):up(); | |
55 elseif field_type == "fixed" then | |
56 form:tag("value"):text(value):up(); | |
57 elseif field_type == "jid-multi" then | |
58 for _, jid in ipairs(value) do | |
59 form:tag("value"):text(jid):up(); | |
60 end | |
61 elseif field_type == "jid-single" then | |
62 form:tag("value"):text(value):up(); | |
63 elseif field_type == "text-single" or field_type == "text-private" then | |
64 form:tag("value"):text(value):up(); | |
65 elseif field_type == "text-multi" then | |
66 -- Split into multiple <value> tags, one for each line | |
67 for line in value:gmatch("([^\r\n]+)\r?\n*") do | |
68 form:tag("value"):text(line):up(); | |
69 end | |
70 elseif field_type == "list-single" then | |
71 local has_default = false; | |
72 for _, val in ipairs(value) do | |
73 if type(val) == "table" then | |
74 form:tag("option", { label = val.label }):tag("value"):text(val.value):up():up(); | |
75 if val.default and (not has_default) then | |
76 form:tag("value"):text(val.value):up(); | |
77 has_default = true; | |
78 end | |
79 else | |
80 form:tag("option", { label= val }):tag("value"):text(tostring(val)):up():up(); | |
81 end | |
82 end | |
83 elseif field_type == "list-multi" then | |
84 for _, val in ipairs(value) do | |
85 if type(val) == "table" then | |
86 form:tag("option", { label = val.label }):tag("value"):text(val.value):up():up(); | |
87 if val.default then | |
88 form:tag("value"):text(val.value):up(); | |
89 end | |
90 else | |
91 form:tag("option", { label= val }):tag("value"):text(tostring(val)):up():up(); | |
92 end | |
93 end | |
94 elseif field_type == "media" then | |
95 form:tag("media", { xmlns = "urn:xmpp:media-element" }); | |
96 for _, val in ipairs(value) do | |
97 form:tag("uri", { type = val.type }):text(val.uri):up() | |
98 end | |
99 form:up(); | |
100 end | |
101 end | |
102 | |
103 if field.required then | |
104 form:tag("required"):up(); | |
105 end | |
106 | |
107 -- Jump back up to list of fields | |
108 form:up(); | |
109 end | |
110 return form; | |
111 end | |
112 | |
113 local field_readers = {}; | |
114 | |
115 function form_t.data(layout, stanza) | |
116 local data = {}; | |
117 local errors = {}; | |
118 | |
119 for _, field in ipairs(layout) do | |
120 local tag; | |
121 for field_tag in stanza:childtags() do | |
122 if field.name == field_tag.attr.var then | |
123 tag = field_tag; | |
124 break; | |
125 end | |
126 end | |
127 | |
128 if not tag then | |
129 if field.required then | |
130 errors[field.name] = "Required value missing"; | |
131 end | |
132 else | |
133 local reader = field_readers[field.type]; | |
134 if reader then | |
135 data[field.name], errors[field.name] = reader(tag, field.required); | |
136 end | |
137 end | |
138 end | |
139 if next(errors) then | |
140 return data, errors; | |
141 end | |
142 return data; | |
143 end | |
144 | |
145 field_readers["text-single"] = | |
146 function (field_tag, required) | |
147 local data = field_tag:get_child_text("value"); | |
148 if data and #data > 0 then | |
149 return data | |
150 elseif required then | |
151 return nil, "Required value missing"; | |
152 end | |
153 end | |
154 | |
155 field_readers["text-private"] = | |
156 field_readers["text-single"]; | |
157 | |
158 field_readers["jid-single"] = | |
159 function (field_tag, required) | |
160 local raw_data = field_tag:get_child_text("value") | |
161 local data = jid_prep(raw_data); | |
162 if data and #data > 0 then | |
163 return data | |
164 elseif raw_data then | |
165 return nil, "Invalid JID: " .. raw_data; | |
166 elseif required then | |
167 return nil, "Required value missing"; | |
168 end | |
169 end | |
170 | |
171 field_readers["jid-multi"] = | |
172 function (field_tag, required) | |
173 local result = {}; | |
174 local err = {}; | |
175 for value_tag in field_tag:childtags("value") do | |
176 local raw_value = value_tag:get_text(); | |
177 local value = jid_prep(raw_value); | |
178 result[#result+1] = value; | |
179 if raw_value and not value then | |
180 err[#err+1] = ("Invalid JID: " .. raw_value); | |
181 end | |
182 end | |
183 if #result > 0 then | |
184 return result, (#err > 0 and t_concat(err, "\n") or nil); | |
185 elseif required then | |
186 return nil, "Required value missing"; | |
187 end | |
188 end | |
189 | |
190 field_readers["list-multi"] = | |
191 function (field_tag, required) | |
192 local result = {}; | |
193 for value in field_tag:childtags("value") do | |
194 result[#result+1] = value:get_text(); | |
195 end | |
196 if #result > 0 then | |
197 return result; | |
198 elseif required then | |
199 return nil, "Required value missing"; | |
200 end | |
201 end | |
202 | |
203 field_readers["text-multi"] = | |
204 function (field_tag, required) | |
205 local data, err = field_readers["list-multi"](field_tag, required); | |
206 if data then | |
207 data = t_concat(data, "\n"); | |
208 end | |
209 return data, err; | |
210 end | |
211 | |
212 field_readers["list-single"] = | |
213 field_readers["text-single"]; | |
214 | |
215 local boolean_values = { | |
216 ["1"] = true, ["true"] = true, | |
217 ["0"] = false, ["false"] = false, | |
218 }; | |
219 | |
220 field_readers["boolean"] = | |
221 function (field_tag, required) | |
222 local raw_value = field_tag:get_child_text("value"); | |
223 local value = boolean_values[raw_value ~= nil and raw_value]; | |
224 if value ~= nil then | |
225 return value; | |
226 elseif raw_value then | |
227 return nil, "Invalid boolean representation"; | |
228 elseif required then | |
229 return nil, "Required value missing"; | |
230 end | |
231 end | |
232 | |
233 field_readers["hidden"] = | |
234 function (field_tag) | |
235 return field_tag:get_child_text("value"); | |
236 end | |
237 | |
238 field_readers["media"] = field_readers["text-single"] | |
239 | |
240 return _M; | |
241 | |
242 | |
243 --[=[ | |
244 | |
245 Layout: | |
246 { | |
247 | |
248 title = "MUC Configuration", | |
249 instructions = [[Use this form to configure options for this MUC room.]], | |
250 | |
251 { name = "FORM_TYPE", type = "hidden", required = true }; | |
252 { name = "field-name", type = "field-type", required = false }; | |
253 } | |
254 | |
255 | |
256 --]=] |