Index: openacs-4/packages/q-forms/README.md
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/q-forms/README.md,v
diff -u -r1.1 -r1.2
--- openacs-4/packages/q-forms/README.md 14 Nov 2014 18:27:52 -0000 1.1
+++ openacs-4/packages/q-forms/README.md 2 Jan 2017 10:30:48 -0000 1.2
@@ -28,7 +28,7 @@
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
+ the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -57,6 +57,8 @@
Optional automatic hash generation helps secure form transactions
and ignores multiple posts caused from mouse double-clicks and browsing page history.
+This extra secure feature also prevents tampering of hidden form values.
+
Multiple values of same key can be combined as a list (instead of producing
a form post error).
Index: openacs-4/packages/q-forms/q-forms.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/q-forms/q-forms.info,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/q-forms/q-forms.info 3 May 2015 08:49:12 -0000 1.3
+++ openacs-4/packages/q-forms/q-forms.info 2 Jan 2017 10:30:48 -0000 1.4
@@ -1,4 +1,4 @@
-
+`^
@@ -9,14 +9,16 @@
ff
-
+ Benjamin BrinkOpenACS CommunityProvides code for building forms dynamically in tcl
- Provides qf_* form bulding and interpreting procedures, especially designed for building forms dynamically.
+ Provides qf_* form bulding and interpreting procedures, especially designed for building forms dynamically in tcl.1
+ GNU Gpl 2.0 or higher
+ GPL2
-
+
Index: openacs-4/packages/q-forms/tcl/form-helper-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/q-forms/tcl/form-helper-procs.tcl,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/q-forms/tcl/form-helper-procs.tcl 3 May 2015 08:49:12 -0000 1.3
+++ openacs-4/packages/q-forms/tcl/form-helper-procs.tcl 2 Jan 2017 10:30:48 -0000 1.4
@@ -2,7 +2,11 @@
procedures for helping render form data or presentation for form data
@creation-date 15 May 2012
- @cs-id $Id:
+ @Copyright (c) 2012-5 Benjamin Brink
+ @license GNU General Public License 2, see project home or http://www.gnu.org/licenses/gpl.html
+ @project home: http://github.com/tekbasse/q-forms
+ @address: po box 20, Marylhurst, OR 97036-0020 usa
+ @email: tekbasse@yahoo.com
to vertically align textarea label, add to css:
@@ -13,8 +17,137 @@
}
+ad_proc -public qf_lists_to_vars {
+ values_list
+ keys_list
+ {only_these_keys_list ""}
+} {
+ Returns variables assigned to the values in values_list, paired by index.
+ For example the fourth index of keys_list is assigned the value of the
+ fourth index of values_list.
+ If values_list is shorter, the orphaned keys are assigned an empty string.
+ If keys_list is shorter, excess values are returned as a list.
+ If only_these_keys_list is not empty, only these keys will be converted.
+ Anything in only_these_keys_list that is not in keys_list is ignored.
+} {
+ set remainder_list [list ]
+ set values_list_len [llength $values_list]
+ set keys_list_len [llength $keys_list]
+ if { $values_list_len > $keys_list_len } {
+ set remainder_list [lrange $values_list $keys_list_len end]
+ set values_list [lrange $values_list 0 ${keys_list_len}-1]
+ }
+ if { $only_these_keys_list eq "" } {
+ set i 0
+ foreach key $keys_list {
+ upvar 1 $key val_${key}
+ set val_${key} [lindex $values_list $i]
+ incr i
+ }
+ } else {
+ # fkey = filtered key
+ set otk_list [split $only_these_keys_list]
+ foreach fkey $otk_list {
+ set i [lsearch -exact $keys_list $fkey]
+ if { $i > -1 } {
+ upvar 1 $fkey val_${fkey}
+ set val_${fkey} [lindex $values_list $i]
+ }
+ }
+ }
+ return $remainder_list
+}
+
+ad_proc -public qf_lists_to_array {
+ array_name
+ values_list
+ keys_list
+} {
+ Returns an array with elements in key_list assigned to the values in values_list, paired by list index.
+ For example the fourth index of keys_list is an element assigned the value of the
+ fourth index of values_list.
+ If values_list is shorter, the orphaned keys are assigned an empty string.
+ If keys_list is shorter, excess values are returned as a list.
+} {
+ upvar 1 $array_name name_arr
+ set remainder_list [list ]
+ set values_list_len [llength $values_list]
+ set keys_list_len [llength $keys_list]
+ if { $values_list_len > $keys_list_len } {
+ set remainder_list [lrange $values_list $keys_list_len end]
+ set values_list [lrange $values_list 0 ${keys_list_len}-1]
+ }
+ set i 0
+ foreach key $keys_list {
+ set name_arr(${key}) [lindex $values_list $i]
+ incr i
+ }
+ return $remainder_list
+}
+
+
+ad_proc -public qf_array_to_vars {
+ array_name
+ keys_list
+} {
+ Returns variables assigned to the values in array(variable) for variables named in keys_list.
+ This returns a selection of array values, not all elements as done by template::util::array_to_vars
+ If a key doesn't exist, the variable is created and assigned the empty string.
+} {
+ upvar 1 $array_name an_arr
+ foreach key $keys_list {
+ if { [info exists an_arr(${key}) ] } {
+ uplevel [list set $key $an_arr(${key}) ]
+ } else {
+ uplevel [list set $key ""]
+ }
+ }
+ return 1
+}
+
+
+ad_proc -public qss_table_cols_filter {
+ table_lists
+ col_names
+ {blank_missing_cols_p "0"}
+} {
+ Excludes all columns not referenced by name.
+ Columns are ordered in order of names.
+ If column not found in table and blank_missing_cols_p is 1,
+ an empty column is included in returned table.
+ Otherwise, column is not included in table.
+} {
+ set col_names_list [split $col_names]
+
+ # create an index list of column titles
+ set titles_list [lindex $table_lists 0]
+ set cols_idx_list [list ]
+ foreach name $col_names_list {
+ set col_name [string trim $name]
+ set col_idx [lsearch -exact $col_name $titles_list]
+ if { $col_idx > -1 || $blank_missing_cols_p } {
+ lappend cols_idx_list $col_idx
+ }
+ }
+ # build new table with column titles index
+ set new_table_lists [list ]
+ foreach row_list $table_lists {
+ set new_row_list [list ]
+ foreach col_idx $cols_idx_list {
+ if { $col_idx > -1 } {
+ set col_value [lindex $row_list $col_idx]
+ } else {
+ set col_value ""
+ }
+ lappend new_row_list $col_value
+ }
+ lappend new_table_lists $new_row_list
+ }
+ return $new_table_lists
+}
+
ad_proc -public qss_txt_to_tcl_list_of_lists {
textarea
linebreak
@@ -254,6 +387,7 @@
set rows_count 1
set bguess 1
}
+ ns_log Notice "qss_txt_table_stats linebreak '${linebreak_char}' delim '${delimiter}' rows '${rows_count}' columns '${bguess}'"
set return_list [list $linebreak_char $delimiter $rows_count $bguess]
# ns_log Notice "qss_txt_table_stats: return_list $return_list"
return $return_list
@@ -286,7 +420,7 @@
#setup repeat pattern for formatting rows, if last formatting row is not blank
set repeat_last_row_p 0
if { [llength [lindex $td_attribute_lists end] ] > 0 } {
- # this feature only comes into play if td_attrubte_lists is not as long as table_list_of_lists
+ # this feature only comes into play if td_attribute_lists is not as long as table_list_of_lists
set repeat_last_row_p 1
set repeat_row [expr { [llength $td_attribute_lists] - 1 } ]
}
@@ -426,6 +560,16 @@
return $is_natural
}
+ad_proc -public qf_is_integer {
+ value
+} {
+ answers question: is value an integer?
+ returns 0 or 1
+} {
+ set is_integer [regexp {^(0*)(([\-]?[1-9][0-9]*|0))$} $value match zeros value]
+ return $is_integer
+}
+
ad_proc -public qf_remove_from_list {
value value_list
} {
@@ -910,10 +1054,48 @@
ad_proc -public qf_unquote {
value
} {
- unquotes html similar to ad_unquotehtml except language keys, so that they are not rendered. Useful when creating forms with existing input values.
+ unquotes html similar to ad_unquotehtml except language keys,
+ so that they are not rendered.
+ Useful when creating forms with existing input values.
+ Does not unqoute square brackets.
} {
- set value_quoted [ad_unquotehtml $value]
- regsub -all -- {\#} $value_quoted {\#} value_quoted
- return $value_quoted
+ # following from ad_unquotehtml
+ set value_unquoted [string map {& & > > < < " \" " \" ' '} $value]
+ regsub -all -- {\#} $value_unquoted {\#} value_unquoted
+ return $value_unquoted
}
+# tcl now has:
+# string is true -strict $value
+# string is false -strict $value
+# in openacs api: template::util::is_true, but that looks like an wip since description does not fit actual.
+
+ad_proc -public qf_is_true {
+ value
+ {default "0"}
+} {
+ Intreprets value as a boolean. If value is ambiguous, defaults to the value of default, usually 0.
+} {
+ set test1 [string is true -strict $value]
+ set test2 [string is false -strict $value]
+ if { $test1 == $test2 } {
+ set interp_p $default
+ } else {
+ set interp_p $test1
+ }
+ return $interp_p
+}
+
+ad_proc -public qf_is_even {
+ number
+} {
+ Returns 1 if number is even, otherwise returns 0. Works for base 1 to 16 (hexidecimal).
+} {
+ set even_p 0
+ set last_digit [string range $number end end]
+ set even_digits_list [list 0 2 4 6 8 a c e A C E]
+ if { $last_digit in $even_digits_list } {
+ set even_p 1
+ }
+ return $even_p
+}
Index: openacs-4/packages/q-forms/tcl/form-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/q-forms/tcl/form-procs.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/q-forms/tcl/form-procs.tcl 8 Apr 2015 08:34:36 -0000 1.2
+++ openacs-4/packages/q-forms/tcl/form-procs.tcl 2 Jan 2017 10:30:48 -0000 1.3
@@ -2,9 +2,17 @@
routines for creating, managing input via html forms
@creation-date 21 Nov 2010
- @cs-id $Id:
+ @Copyright (c) 2010-5 Benjamin Brink
+ @license GNU General Public License 2, see project home or http://www.gnu.org/licenses/gpl.html
+ @project home: http://github.com/tekbasse/q-forms
+ @address: po box 20, Marylhurst, OR 97036-0020 usa
+ @email: tekbasse@yahoo.com
}
+#agenda:
+##code a proc called qf_bypass that does like qf_input hidden with sec_hash
+## but emits no html tag to the form.
+
# use _ to clear a new default
# use upvar to grab previous defaults and re-use (with qf_input only)
# main namespace vars:
@@ -14,6 +22,7 @@
# __form_ids_fieldset_open_list = list that contains form ids where a fieldset tag is open
# __form_arr contains an array of forms. Each form built as a string by appending tags, indexed by form_id, for example __form_arr($id)
# __qf_arr contains last attribute values of a tag (for all forms), indexed by {tag}_attribute, __form_last_id is in __qf_arr(form_id)
+# __qf_hc_arr contains sh_key_id for each form_id
# a blank id passed in anything other than qf_form assumes the current (most recent used form_id)
# to fix: id for nonform tag should not be same as form_id. use an attribute "form_id" for assigning tags to specific forms.
@@ -33,6 +42,9 @@
} {
creates the form key for a more secure form transaction. Returns the security hash. See also qf_submit_key_accepted_p
} {
+ upvar 1 __qf_hc_arr __qf_hc_arr
+ upvar 1 attributes_arr attributes_arr
+
# This proc is inspired from sec_random_token
if { $instance_id eq "" } {
# set instance_id package_id
@@ -68,9 +80,11 @@
}
append sec_hash_string $start_clicks $session_id $secure_p $client_ip $action_url $time_sec $key_id
set sec_hash [ns_sha1 $sec_hash_string]
+ set sh_key_id [db_nextval qf_id_seq]
db_dml qf_form_key_create {insert into qf_key_map
- (instance_id,rendered_timestamp,sec_hash,key_id,session_id,action_url,secure_conn_p,client_ip)
- values (:instance_id,:time_sec,:sec_hash,:key_id,:session_id,:action_url,:secure_p,:client_ip) }
+ (instance_id,sh_key_id,rendered_timestamp,sec_hash,key_id,session_id,action_url,secure_conn_p,client_ip)
+ values (:instance_id,:sh_key_id,:time_sec,:sec_hash,:key_id,:session_id,:action_url,:secure_p,:client_ip) }
+ set __qf_hc_arr($attributes_arr(form_id)) $sh_key_id
return $sec_hash
}
@@ -80,6 +94,8 @@
} {
Checks the form key against existing ones. Returns 1 if matches and unexpired, otherwise returns 0.
} {
+ # sh_key_id is passed to qf_get_inputs_as_array to collect hidden name value pairs.
+ upvar 1 sh_key_id sh_key_id
# This proc is inspired from sec_random_token
if { $instance_id eq "" } {
# set instance_id package_id
@@ -104,19 +120,24 @@
}
# the key_id is used to help generate unpredictable hashes, but isn't used at this level of input validation
set accepted_p [db_0or1row qf_form_key_check_hash {
- select session_id as session_id_i, action_url as action_url_i, secure_conn_p as secure_conn_p_i, client_ip as client_ip_i from qf_key_map
- where instance_id =:instance_id and sec_hash =:sec_hash and submit_timestamp is null } ]
+ select session_id as session_id_i, action_url as action_url_i, secure_conn_p as secure_conn_p_i, client_ip as client_ip_i, sh_key_id
+ from qf_key_map
+ where instance_id=:instance_id
+ and sec_hash=:sec_hash
+ and submit_timestamp is null } ]
if { !$accepted_p } {
# there is nothing to compare. log current values:
- ns_log Warning "qf_submit_key_accepted_p: is false. action_url '$action_url' sec_hash '$sec_hash'"
+ ns_log Warning "qf_submit_key_accepted_p.115: is false. action_url '${action_url}' sec_hash '${sec_hash}'"
if { $connected_p } {
- ns_log Warning "qf_submit_key_accepted_p: session_id '$session_id' secure_p '$secure_p' client_ip '$client_ip'"
+ ns_log Warning "qf_submit_key_accepted_p.117: session_id '${session_id}' secure_p '${secure_p}' client_ip '${client_ip}'"
}
} else {
# Mark the key expired
set submit_timestamp [ns_time]
- db_dml qf_form_key_expire { update qf_key_map
- set submit_timestamp = :submit_timestamp where instance_id =:instance_id and sec_hash =:sec_hash and submit_timestamp is null }
+ db_dml qf_form_key_expire { update qf_key_map set submit_timestamp=:submit_timestamp
+ where instance_id =:instance_id
+ and sec_hash=:sec_hash
+ and submit_timestamp is null }
}
return $accepted_p
}
@@ -143,7 +164,8 @@
set arg_arr(multiple_key_as_list) 0
set arg_arr(hash_check) 0
set arg_full_list [list duplicate_key_check multiple_key_as_list hash_check]
- #set arg_list [list $arg1 $arg2 $arg3 $arg4 $arg5 $arg6 ]
+ #set arg_list \[list $arg1 $arg2 $arg3 $arg4 $arg5 $arg6 \]
+ set instance_id [ad_conn package_id]
# collect args
if { [llength $arg1] > 1 && $value1 eq "" } {
set arg_list $arg1
@@ -160,10 +182,10 @@
foreach {name value} $arg_list {
set attribute_index [lsearch -exact $arg_full_list $name]
if { $attribute_index > -1 } {
- set arg_arr($name) $value
+ set arg_arr(${name}) $value
} else {
if { $name ne "" } {
- ns_log Error "qf_get_inputs_as_array: '${name}' is not a valid name for use with args."
+ ns_log Error "qf_get_inputs_as_array.170: '${name}' is not a valid name for use with args."
}
}
}
@@ -176,21 +198,21 @@
} else {
set __form_size [ns_set size $__form]
}
- #ns_log Notice "qf_get_inputs_as_array: formsize $__form_size"
+ #ns_log Notice "qf_get_inputs_as_array.183: formsize $__form_size"
for { set __form_counter_i 0 } { $__form_counter_i < $__form_size } { incr __form_counter_i } {
regexp -nocase -- {^[a-z][a-z0-9_\.\:\(\)]*} [ns_set key $__form $__form_counter_i] __form_key
# Why doesn't work for regexp -nocase -- {^[a-z][a-z0-9_\.\:\(\)]*$ } ?
set __form_key_exists [info exists __form_key]
- # ns_log Notice "qf_get_inputs_as_array: __form_key_exists = ${__form_key_exists}"
+ # ns_log Notice "qf_get_inputs_as_array.189: __form_key_exists = ${__form_key_exists}"
# no inserting tcl commands etc!
if { $__form_key_exists == 0 || ( $__form_key_exists == 1 && [string length $__form_key] == 0 ) } {
# let's make this an error for now, so we log any attempts
- # ns_log Notice "qf_get_inputs_as_array: __form_key_exists ${__form_key_exists} length __form_key [string length ${__form_key}]"
- # ns_log Notice "qf_get_inputs_as_array(ref156: attempt to insert unallowed characters to user input '{__form_key}' as '[ns_set key $__form $__form_counter_i]' for counter ${__form_counter_i}."
+ # ns_log Notice "qf_get_inputs_as_array.194: __form_key_exists ${__form_key_exists} length __form_key \[string length ${__form_key}\]"
+ # ns_log Notice "qf_get_inputs_as_array.196: attempt to insert unallowed characters to user input '{__form_key}' as '\[ns_set key $__form $__form_counter_i\]' for counter ${__form_counter_i}."
if { $__form_counter_i > 0 } {
- ns_log Notice "qf_get_inputs_as_array: attempt to insert unallowed characters to user input '{__form_key}'."
+ ns_log Notice "qf_get_inputs_as_array.197: attempt to insert unallowed characters to user input '{__form_key}'."
}
} else {
set __form_key [ad_quotehtml $__form_key]
@@ -202,52 +224,109 @@
set __form_input_exists 1
# check for duplicate key?
- if { $arg_arr(duplicate_key_check) && [info exists __form_buffer_arr($__form_key) ] } {
- if { $__form_input ne $__form_buffer_arr($__form_key) } {
+ if { $arg_arr(duplicate_key_check) && [info exists __form_buffer_arr(${__form_key}) ] } {
+ if { $__form_input ne $__form_buffer_arr(${__form_key}) } {
# which one is correct? log error
- ns_log Error "qf_get_form_input: form input error. duplcate key provided for ${__form_key}"
+ ns_log Error "qf_get_form_input.212: form input error. duplcate key provided for '${__form_key}'"
ad_script_abort
# set __form_input_exists to -1 instead of ad_script_abort?
} else {
- ns_log Warning "qf_get_form_input: notice, form has a duplicate key with multiple values containing same info.."
+ ns_log Warning "qf_get_form_input.216: notice, form has a duplicate key with multiple values containing same info.."
}
} elseif { $arg_arr(multiple_key_as_list) } {
- ns_log Notice "qf_get_inputs_as_array: A key has been posted with multible values. Values assigned to the key as a list."
- if { [llength $__form_buffer_arr($__form_key)] > 1 } {
+ ns_log Notice "qf_get_inputs_as_array.219: A key has been posted with multible values. Values assigned to the key as a list."
+ if { [llength $__form_buffer_arr(${__form_key})] > 1 } {
# value is a list, lappend
- lappend __form_buffer_arr($__form_key) $__form_input
+ lappend __form_buffer_arr(${__form_key}) $__form_input
} else {
# convert the key value to a list
- set __value_one $__form_buffer_arr($__form_key)
- unset __form_buffer_arr($__form_key)
- set __form_buffer_arr($__form_key) [list $__value_one $__form_input]
+ set __value_one $__form_buffer_arr(${__form_key})
+ unset __form_buffer_arr(${__form_key})
+ set __form_buffer_arr(${__form_key}) [list $__value_one $__form_input]
}
} else {
- set __form_buffer_arr($__form_key) $__form_input
- # ns_log Debug "qf_get_inputs_as_array: set ${form_array_name}($__form_key) '${__form_input}'."
+ set __form_buffer_arr(${__form_key}) $__form_input
+ # ns_log Debug "qf_get_inputs_as_array.231: set ${form_array_name}($__form_key) '${__form_input}'."
}
# next key-value pair
}
+
}
- if { $arg_arr(hash_check) } {
- if { [info exists __form_buffer_arr(qf_security_hash) ] } {
- set accepted_p [qf_submit_key_accepted_p $__form_buffer_arr(qf_security_hash) ]
- if { $accepted_p } {
- unset __form_buffer_arr(qf_security_hash)
- array set __form_input_arr [array get __form_buffer_arr]
- return $__form_input_exists
+ if { $__form_input_exists } {
+ if { $arg_arr(hash_check) } {
+ if { [info exists __form_buffer_arr(qf_security_hash) ] } {
+ set accepted_p [qf_submit_key_accepted_p $__form_buffer_arr(qf_security_hash) ]
+ if { $accepted_p } {
+
+ # Are there any hidden name pairs to grab from db?
+ set name_value_lists [db_list_of_lists qf_name_value_pairs_r {select arg_name,arg_value
+ from qf_name_value_pairs
+ where instance_id=:instance_id
+ and sh_key_id=:sh_key_id} ]
+ # clear any external input and warn if it is different
+ foreach pair_list $name_value_lists {
+ set __form_key [lindex $pair_list 0]
+ set __form_input [lindex $pair_list 1]
+ if { [info exists __form_buffer_arr(${__form_key}) ] } {
+ set test [ad_unquotehtml $__form_buffer_arr(${__form_key})]
+ if { $test ne $__form_input } {
+ ns_log Warning "qf_get_inputs_as_array.12000: input of type 'hidden' from form does not match for name '${__form_key}'. Internal used. internal '${__form_input}' from form '${test}'"
+ array unset __form_buffer_arr $__form_key
+ }
+ }
+ }
+ foreach pair_list $name_value_lists {
+ set __form_key [lindex $pair_list 0]
+ set __form_input [lindex $pair_list 1]
+ # For consistency, this is a repeat of external form logic checks above.
+
+ # check for duplicate key?
+ if { $arg_arr(duplicate_key_check) && [info exists __form_buffer_arr(${__form_key}) ] } {
+ if { $__form_input ne $__form_buffer_arr(${__form_key}) } {
+ # which one is correct? log error
+ ns_log Error "qf_get_form_input.312: form input error. duplcate key provided for '${__form_key}'"
+ ad_script_abort
+ # set __form_input_exists to -1 instead of ad_script_abort?
+ } else {
+ ns_log Warning "qf_get_form_input.316: notice, form has a duplicate key with multiple values containing same info.."
+ }
+ } elseif { $arg_arr(multiple_key_as_list) } {
+ ns_log Notice "qf_get_inputs_as_array.319: A key has been posted with multible values. Values assigned to the key as a list."
+ if { [llength $__form_buffer_arr(${__form_key})] > 1 } {
+ # value is a list, lappend
+ lappend __form_buffer_arr(${__form_key}) $__form_input
+ } else {
+ # convert the key value to a list
+ set __value_one $__form_buffer_arr(${__form_key})
+ unset __form_buffer_arr(${__form_key})
+ set __form_buffer_arr(${__form_key}) [list $__value_one $__form_input]
+ }
+ } else {
+ set __form_buffer_arr(${__form_key}) $__form_input
+ # ns_log Debug "qf_get_inputs_as_array.231: set ${form_array_name}($__form_key) '${__form_input}'."
+ }
+
+ # next key-value pair
+ }
+
+ unset __form_buffer_arr(qf_security_hash)
+ array set __form_input_arr [array get __form_buffer_arr]
+ return $__form_input_exists
+ } else {
+ ns_log Notice "qf_get_inputs_as_array.346: hash_check with form input of '$__form_buffer_arr(qf_security_hash)' did not match."
+ return 0
+ }
} else {
- ns_log Notice "qf_get_inputs_as_array: hash_check with form input of '$__form_buffer_arr(qf_security_hash)' did not match."
+ set accepted_p 0
+ ns_log Notice "qf_get_inputs_as_array.351: hash_check requires qf_security_hash, but was not included with form input."
return 0
}
} else {
- set accepted_p 0
- ns_log Notice "qf_get_inputs_as_array: hash_check requires qf_security_hash, but was not included with form input."
- return 0
+ array set __form_input_arr [array get __form_buffer_arr]
+ return $__form_input_exists
}
} else {
- array set __form_input_arr [array get __form_buffer_arr]
return $__form_input_exists
}
}
@@ -270,16 +349,37 @@
{value1 ""}
args
} {
- Initiates a form with form tag and supplied attributes. Returns an id. A clumsy url based id is provided if not passed (not recommended).
+ Initiates a form with form tag and supplied attributes.
+ Returns an id.
+ A clumsy url-based id is provided if not passed (not recommended).
If hash_check passed, creates a hash to be checked on submit for server-client transaction continuity.
+
+ To create a form that uploads a file, set attribute enctype to "multipart/form-data", set method to "post".
+ Also, create an input tag with type attribute set to "file" to choose a file to upload,
+ and set name attribute to name of file as it will be received at the server along with
+ other input from the form.
+
+ In the following example, name is set to "clientfile".
+
+ After the form has been submitted, data can be retreived via ns_queryget (or qf_get_inputs_as_array ):
+
+ set uploaded_filename \[ns_queryget clientfile \]
+
+ set file_pathname_on_server \[ns_queryget clientfile.tmpfile \]
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
+ the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,