# /tcl/ad-utilities.tcl.preload
#
# This file provides a variety of utilities (originally written by
# philg@mit.edu a long time ago) as well as some compatibility
# functions to handle differences between AOLserver 2.x and
# AOLserver 3.x.
#
# Author: ron@arsdigita.com, February 2000
#
# ad-utilities.tcl.preload,v 3.13.2.3 2000/03/18 02:31:02 ron Exp
# Let's define the nsv arrays out here, so we can call nsv_exists
# on their keys without checking to see if it already exists.
# we create the array by setting a bogus key.
nsv_set proc_source_file . ""
proc proc_doc {name args doc_string body} {
# let's define the procedure first
proc $name $args $body
nsv_set proc_doc $name $doc_string
# generate a log message for multiply defined scripts
if {[nsv_exists proc_source_file $name]
&& [string compare [nsv_get proc_source_file $name] [info script]] != 0} {
ns_log Notice "Multiple definition of $name in [nsv_get proc_source_file $name] and [info script]"
}
nsv_set proc_source_file $name [info script]
}
proc proc_source_file_full_path {proc_name} {
if ![nsv_exists proc_source_file $proc_name] {
return ""
} else {
set tentative_path [nsv_get proc_source_file $proc_name]
regsub -all {/\./} $tentative_path {/} result
return $result
}
}
proc_doc util_report_library_entry {{extra_message ""}} "Should be called at beginning of private Tcl library files so that it is easy to see in the error log whether or not private Tcl library files contain errors." {
set tentative_path [info script]
regsub -all {/\./} $tentative_path {/} scrubbed_path
if { [string compare $extra_message ""] == 0 } {
set message "Loading $scrubbed_path"
} else {
set message "Loading $scrubbed_path; $extra_message"
}
ns_log Notice $message
}
util_report_library_entry
# stuff to process the data that comes
# back from the users
# if the form looked like
# and
# then after you run this function you'll have Tcl vars
# $foo and $bar set to whatever the user typed in the form
# this uses the initially nauseating but ultimately delicious
# Tcl system function "uplevel" that lets a subroutine bash
# the environment and local vars of its caller. It ain't Common Lisp...
## Security fix
## (patch code from aD)
##
# This is an ad-hoc check to make sure users aren't trying to pass in
# "naughty" form variables in an effort to hack the database by passing
# in SQL. It is called in all instances where a Tcl variable
# is set from a form variable.
proc check_for_form_variable_naughtiness { name value } {
if { [string compare $name user_id] == 0 } {
if { [string length $value] > 0 && ![regexp {^[0-9]+$} $value] } {
# user_id not null, and not an integer
error "The user_id value must be an integer!"
}
}
# This plugs a potentially huge security hole -- michael@cleverly.com
if { [string match $name QQ*] } {
error "Form variables should never begin with QQ!"
}
# another bug discovered by Michael Cleverly.
if { [string compare $name form_counter_i] == 0} {
error "DOS attack attempting to override the form counter"
}
# extension of Michael Cleverly's above bug, fixed by ben@openforce
if { [string compare $name form_size] == 0} {
error "DOS attack attempting to override the form size"
}
}
proc set_form_variables {{error_if_not_found_p 1}} {
if { $error_if_not_found_p == 1} {
uplevel {
if { [ns_getform] == "" } {
ns_returnerror 500 "Missing form data"
return
}
}
} else {
uplevel {
if { [ns_getform] == "" } {
# we're not supposed to barf at the user but we want to return
# from this subroutine anyway because otherwise we'd get an error
return
}
}
}
# at this point we know that the form is legal
uplevel {
set form [ns_getform]
set form_size [ns_set size $form]
set form_counter_i 0
while {$form_counter_i<$form_size} {
set name [ns_set key $form $form_counter_i]
set value [ns_set value $form $form_counter_i]
check_for_form_variable_naughtiness $name $value
set $name $value
incr form_counter_i
}
}
}
proc set_form_variables_string_trim_DoubleAposQQ {} {
uplevel {
set form [ns_getform]
if {$form == ""} {
ns_returnerror 500 "Missing form data"
return;
}
set form_size [ns_set size $form]
set form_counter_i 0
while {$form_counter_i<$form_size} {
set QQ[ns_set key $form $form_counter_i] [DoubleApos [string trim [ns_set value $form $form_counter_i]]]
incr form_counter_i
}
}
}
proc set_the_usual_form_variables {{error_if_not_found_p 1}} {
if { [ns_getform] == "" } {
if $error_if_not_found_p {
uplevel {
ns_returnerror 500 "Missing form data"
return
}
} else {
return
}
}
uplevel {
set form [ns_getform]
set form_size [ns_set size $form]
set form_counter_i 0
while {$form_counter_i<$form_size} {
set name [ns_set key $form $form_counter_i]
set value [ns_set value $form $form_counter_i]
check_for_form_variable_naughtiness $name $value
set $name $value
set QQ[ns_set key $form $form_counter_i] [DoubleApos [string trim $value]]
incr form_counter_i
}
}
}
proc set_form_variables_string_trim_DoubleApos {} {
uplevel {
set form [ns_getform]
if {$form == ""} {
ns_returnerror 500 "Missing form data"
return;
}
set form_size [ns_set size $form]
set form_counter_i 0
while {$form_counter_i<$form_size} {
set name [ns_set key $form $form_counter_i]
set value [ns_set value $form $form_counter_i]
check_for_form_variable_naughtiness $name $value
set $name [DoubleApos [string trim $value]]
incr form_counter_i
}
}
}
proc set_form_variables_string_trim {} {
uplevel {
set form [ns_getform]
if {$form == ""} {
ns_returnerror 500 "Missing form data"
return;
}
set form_size [ns_set size $form]
set form_counter_i 0
while {$form_counter_i<$form_size} {
set name [ns_set key $form $form_counter_i]
set value [ns_set value $form $form_counter_i]
check_for_form_variable_naughtiness $name $value
set $name [string trim $value]
incr form_counter_i
}
}
}
proc DoubleApos {string} {
regsub -all ' "$string" '' result
return $result
}
# if the user types "O'Malley" and you try to insert that into an SQL
# database, you will lose big time because the single quote is magic
# in SQL and the insert has to look like 'O''Malley'. This function
# also trims white space off the ends of the user-typed data.
# if the form looked like
# and
# then after you run this function you'll have Tcl vars
# $QQfoo and $QQbar set to whatever the user typed in the form
# plus an extra single quote in front of the user's single quotes
# and maybe some missing white space
proc_doc ad_page_variables {variable_specs} {
Current syntax:
ad_page_variables {var_spec1 [varspec2] ... }
This proc handles translating form inputs into Tcl variables, and checking
to see that the correct set of inputs was supplied. Note that this is mostly a
check on the proper programming of a set of pages.
Here are the recognized var_specs:
variable; means it's required
{variable default-value}
Optional, with default value. If the value is supplied but is null, and the
default-value is present, that value is used.
{variable -multiple-list}
The value of the Tcl variable will be a list containing all of the
values (in order) supplied for that form variable. Particularly useful
for collecting checkboxes or select multiples.
Note that if required or optional variables are specified more than once, the
first (leftmost) value is used, and the rest are ignored.
{variable -array}
This syntax supports the idiom of supplying multiple form variables of the
same name but ending with a "_[0-9]", e.g., foo_1, foo_2.... Each value will be
stored in the array variable variable with the index being whatever follows the
underscore.
There is an optional third element in the var_spec. If it is "QQ", "qq", or
some variant, a variable named "QQvariable" will be created and given the
same value, but with single quotes escaped suitable for handing to SQL.
Other elements of the var_spec are ignored, so a documentation string
describing the variable can be supplied.
Note that the default value form will become the value form in a "set"
Note that the default values are filled in from left to right, and can depend on
values of variables to their left:
ad_page_variables {
file
{start 0}
{end {[expr $start + 20]}}
}
} {
set exception_list [list]
set form [ns_getform]
if { $form != "" } {
set form_size [ns_set size $form]
set form_counter_i 0
# first pass -- go through all the variables supplied in the form
while {$form_counter_i<$form_size} {
set variable [ns_set key $form $form_counter_i]
set value [ns_set value $form $form_counter_i]
check_for_form_variable_naughtiness $variable $value
set found "not"
# find the matching variable spec, if any
foreach variable_spec $variable_specs {
if { [llength $variable_spec] >= 2 } {
switch -- [lindex $variable_spec 1] {
-multiple-list {
if { [lindex $variable_spec 0] == $variable } {
# variable gets a list of all the values
upvar 1 $variable var
lappend var $value
set found "done"
break
}
}
-array {
set varname [lindex $variable_spec 0]
set pattern "($varname)_(.+)"
if { [regexp $pattern $variable match array index] } {
if { ![empty_string_p $array] } {
upvar 1 $array arr
set arr($index) [ns_set value $form $form_counter_i]
}
set found "done"
break
}
}
default {
if { [lindex $variable_spec 0] == $variable } {
set found "set"
break
}
}
}
} elseif { $variable_spec == $variable } {
set found "set"
break
}
}
if { $found == "set" } {
upvar 1 $variable var
if { ![info exists var] } {
# take the leftmost value, if there are multiple ones
set var [ns_set value $form $form_counter_i]
}
}
incr form_counter_i
}
}
# now make a pass over each variable spec, making sure everything required is there
# and doing defaulting for unsupplied things that aren't required
foreach variable_spec $variable_specs {
set variable [lindex $variable_spec 0]
upvar 1 $variable var
if { [llength $variable_spec] >= 2 } {
if { ![info exists var] } {
set default_value_or_flag [lindex $variable_spec 1]
switch -- $default_value_or_flag {
-array {
# don't set anything
}
-multiple-list {
set var [list]
}
default {
# Needs to be set.
uplevel [list eval set $variable "\[subst [list $default_value_or_flag]\]"]
# This used to be:
#
# uplevel [list eval [list set $variable "$default_value_or_flag"]]
#
# But it wasn't properly performing substitutions.
}
}
}
} else {
if { ![info exists var] } {
lappend exception_list "\"$variable\" required but not supplied"
}
}
# modified by rhs@mit.edu on 1/31/2000
# to QQ everything by default (but not arrays)
if {[info exists var] && ![array exists var]} {
upvar QQ$variable QQvar
set QQvar [DoubleApos $var]
}
}
set n_exceptions [llength $exception_list]
# this is an error in the HTML form
if { $n_exceptions == 1 } {
ns_returnerror 500 [lindex $exception_list 0]
return -code return
} elseif { $n_exceptions > 1 } {
ns_returnerror 500 "
[join $exception_list "\n
"]\n"
return -code return
}
}
# debugging kludges
proc NsSettoTclString {set_id} {
set result ""
for {set i 0} {$i<[ns_set size $set_id]} {incr i} {
append result "[ns_set key $set_id $i] : [ns_set value $set_id $i]\n"
}
return $result
}
proc get_referrer {} {
return [ns_set get [ns_conn headers] Referer]
}
proc post_args_to_query_string {} {
set arg_form [ns_getform]
if {$arg_form!=""} {
set form_counter_i 0
while {$form_counter_i<[ns_set size $arg_form]} {
append query_return "[ns_set key $arg_form $form_counter_i]=[ns_urlencode [ns_set value $arg_form $form_counter_i]]&"
incr form_counter_i
}
set query_return [string trim $query_return &]
}
}
proc get_referrer_and_query_string {} {
if {[ns_conn method]!="GET"} {
set query_return [post_args_to_query_string]
return "[get_referrer]?${query_return}"
} else {
return [get_referrer]
}
}
# a philg hack for getting all the values from a set of checkboxes
# returns 0 if none are checked, a Tcl list with the values otherwise
# terence change: specify default return if none checked
proc_doc util_GetCheckboxValues {form checkbox_name {default_return 0}} "For getting all the boxes from a set of checkboxes in a form. This procedure takes the complete ns_conn form and returns a list of checkbox values. It returns 0 if none are found (or some other default return value if specified)." {
set i 0
set size [ns_set size $form]
while {$i<$size} {
if { [ns_set key $form $i] == $checkbox_name} {
# LIST_TO_RETURN will be created if it doesn't exist
lappend list_to_return [ns_set value $form $i]
}
incr i
}
#if no list, you can specify a default return
#default default is 0
if { [info exists list_to_return] } { return $list_to_return } else {return $default_return}
}
# a legacy name that is deprecated
proc nmc_GetCheckboxValues {form checkbox_name {default_return 0}} {
return [util_GetCheckboxValues $form $checkbox_name $default_return]
}
##
# Database-related code
##
proc nmc_GetNewIDNumber {id_name db} {
ns_db dml $db "begin transaction;"
ns_db dml $db "update id_numbers set $id_name = $id_name + 1;"
set id_number [ns_set value\
[ns_db 1row $db "select unique $id_name from id_numbers;"] 0]
ns_db dml $db "end transaction;"
return $id_number
}
# if you do a
# set selection [ns_db 1row $db "select foo,bar from my_table where key=37"]
# set_variables_after_query
# then you will find that the Tcl vars $foo and $bar are set to whatever
# the database returned. If you don't like these var names, you can say
# set selection [ns_db 1row $db "select count(*) as n_rows from my_table"]
# set_variables_after_query
# and you will find the Tcl var $n_rows set
# You can also use this in a multi-row loop
# set selection [ns_db select $db "select *,upper(email) from mailing_list order by upper(email)"]
# while { [ns_db getrow $db $selection] } {
# set_variables_after_query
# ... your code here ...
# }
# then the appropriate vars will be set during your loop
#
# CAVEAT NERDOR: you MUST use the variable name "selection"
#
#
# we pick long names for the counter and limit vars
# because we don't want them to conflict with names of
# database columns or in parent programs
#
proc set_variables_after_query {} {
uplevel {
set set_variables_after_query_i 0
set set_variables_after_query_limit [ns_set size $selection]
while {$set_variables_after_query_i<$set_variables_after_query_limit} {
set [ns_set key $selection $set_variables_after_query_i] [ns_set value $selection $set_variables_after_query_i]
incr set_variables_after_query_i
}
}
}
# as above, but you must use sub_selection
proc set_variables_after_subquery {} {
uplevel {
set set_variables_after_query_i 0
set set_variables_after_query_limit [ns_set size $sub_selection]
while {$set_variables_after_query_i<$set_variables_after_query_limit} {
set [ns_set key $sub_selection $set_variables_after_query_i] [ns_set value $sub_selection $set_variables_after_query_i]
incr set_variables_after_query_i
}
}
}
#same as philg's but you can:
#1. specify the name of the "selection" variable
#2. append a prefix to all the named variables
proc set_variables_after_query_not_selection {selection_variable {name_prefix ""}} {
set set_variables_after_query_i 0
set set_variables_after_query_limit [ns_set size $selection_variable]
while {$set_variables_after_query_i<$set_variables_after_query_limit} {
# NB backslash squarebracket needed since mismatched {} would otherwise mess up value stmt.
uplevel "
set ${name_prefix}[ns_set key $selection_variable $set_variables_after_query_i] \[ns_set value $selection_variable $set_variables_after_query_i]
"
incr set_variables_after_query_i
}
}
# takes a query like "select unique short_name from products where product_id = 45"
# and returns the result (only works when you are after a single row/column
# intersection)
proc database_to_tcl_string {db sql { no_prep 0 }} {
if { $no_prep == 1 } {
set selection [ns_db 1row $db $sql]
} else {
set selection [ns_db 1row $db [db_sql_prep $sql]]
}
return [ns_set value $selection 0]
}
proc database_to_tcl_string_or_null {db sql {null_value ""}} {
set selection [ns_db 0or1row $db [db_sql_prep $sql]]
if { $selection != "" } {
return [ns_set value $selection 0]
} else {
# didn't get anything from the database
return $null_value
}
}
#for commands like set full_name ["select first_name, last_name..."]
proc database_cols_to_tcl_string {db sql} {
set string_to_return ""
set selection [ns_db 1row $db $sql]
set size [ns_set size $selection]
set i 0
while {$i<$size} {
append string_to_return " [ns_set value $selection $i]"
incr i
}
return [string trim $string_to_return]
}
proc_doc database_to_tcl_list {db sql} {takes a query like "select product_id from foobar" and returns all the ids as a Tcl list} {
set selection [ns_db select $db [db_sql_prep $sql]]
set list_to_return [list]
while {[ns_db getrow $db $selection]} {
lappend list_to_return [ns_set value $selection 0]
}
return $list_to_return
}
proc_doc database_to_tcl_list_list {db sql} "Returns a list of Tcl lists, with each sublist containing the columns returned by the database; if no rows are returned by the database, returns the empty list (empty string in Tcl 7.x and 8.x)" {
set selection [ns_db select $db [db_sql_prep $sql]]
set list_to_return [list]
while {[ns_db getrow $db $selection]} {
set row_list ""
set size [ns_set size $selection]
set i 0
while {$i<$size} {
lappend row_list [ns_set value $selection $i]
incr i
}
lappend list_to_return $row_list
}
return $list_to_return
}
proc_doc database_1row_to_tcl_list {db sql} "Returns the column values from one row in the database as a Tcl list. If there isn't exactly one row from this query, throws an error." {
set selection [ns_db 1row $db $sql]
set list_to_return [list]
set size [ns_set size $selection]
set counter 0
while {$counter<$size} {
lappend list_to_return [ns_set value $selection $counter]
incr counter
}
return $list_to_return
}
proc_doc ad_dbclick_check_dml { db table_name id_column_name generated_id return_url insert_sql } "
this proc is used for pages using double click protection. table_name is table_name for which we are checking whether the double click occured. id_column_name is the name of the id table column. generated_id is the generated id, which is supposed to have been generated on the previous page. return_url is url to which this procedure will return redirect in the case of successful insertion in the database. insert_sql is the sql insert statement. if data is ok this procedure will insert data into the database in a double click safe manner and will returnredirect to the page specified by return_url. if database insert fails, this procedure will return a sensible error message to the user." {
if [catch {
ns_db dml $db $insert_sql
} errmsg] {
# Oracle choked on the insert
# detect double click
set selection [ns_db 0or1row $db "
select 1
from $table_name
where $id_column_name='[DoubleApos $generated_id]'"]
if { ![empty_string_p $selection] } {
# it's a double click, so just redirect the user to the index page
ns_returnredirect $return_url
return
}
ns_log Error "[info script] choked. Oracle returned error: $errmsg"
ad_return_error "Error in insert" "
We were unable to do your insert in the database.
Here is the error that was returned:
$errmsg
"
return
}
ns_returnredirect $return_url
return
}
proc nmc_IllustraDatetoPrettyDate {sql_date} {
regexp {(.*)-(.*)-(.*)$} $sql_date match year month day
set allthemonths {January February March April May June July August September October November December}
# we have to trim the leading zero because Tcl has such a
# brain damaged model of numbers and decided that "09-1"
# was "8.0"
set trimmed_month [string trimleft $month 0]
set pretty_month [lindex $allthemonths [expr $trimmed_month - 1]]
return "$pretty_month $day, $year"
}
proc util_IllustraDatetoPrettyDate {sql_date} {
regexp {(.*)-(.*)-(.*)$} $sql_date match year month day
set allthemonths {January February March April May June July August September October November December}
# we have to trim the leading zero because Tcl has such a
# brain damaged model of numbers and decided that "09-1"
# was "8.0"
set trimmed_month [string trimleft $month 0]
set pretty_month [lindex $allthemonths [expr $trimmed_month - 1]]
return "$pretty_month $day, $year"
}
# this is the preferred one to use
proc_doc util_AnsiDatetoPrettyDate {sql_date} "Converts 1998-09-05 to September 5, 1998" {
set sql_date [string range $sql_date 0 9]
if ![regexp {(.*)-(.*)-(.*)$} $sql_date match year month day] {
return ""
} else {
set allthemonths {January February March April May June July August September October November December}
# we have to trim the leading zero because Tcl has such a
# brain damaged model of numbers and decided that "09-1"
# was "8.0"
set trimmed_month [string trimleft $month 0]
set pretty_month [lindex $allthemonths [expr $trimmed_month - 1]]
set trimmed_day [string trimleft $day 0]
return "$pretty_month $trimmed_day, $year"
}
}
proc_doc util_AnsiTimestamptoPrettyTimestamp {sql_timestamp} "Converts 1998-09-05 10:00:00 to September 5, 1998 10:00" {
## Add a hack for Postgres dates that include the timestamp
# DRB: the right number really is 9 "YYYY-MM-DD"
set pretty_date [util_AnsiDatetoPrettyDate [string range $sql_timestamp 0 9]]
return "$pretty_date [string range $sql_timestamp 10 end]"
}
# from the new-utilities.tcl file
proc remove_nulls_from_ns_set {old_set_id} {
set new_set_id [ns_set new "no_nulls$old_set_id"]
for {set i 0} {$i<[ns_set size $old_set_id]} {incr i} {
if { [ns_set value $old_set_id $i] != "" } {
ns_set put $new_set_id [ns_set key $old_set_id $i] [ns_set value $old_set_id $i]
}
}
return $new_set_id
}
proc merge_form_with_ns_set {form set_id} {
for {set i 0} {$i<[ns_set size $set_id]} {incr i} {
set form [ns_formvalueput $form [ns_set key $set_id $i] [ns_set value $set_id $i]]
}
return $form
}
proc merge_form_with_query {form db query} {
set set_id [ns_db 0or1row $db $query]
if { $set_id != "" } {
for {set i 0} {$i<[ns_set size $set_id]} {incr i} {
set form [ns_formvalueput $form [ns_set key $set_id $i] [ns_set value $set_id $i]]
}
}
return $form
}
proc bt_mergepiece {htmlpiece values} {
# HTMLPIECE is a form usually; VALUES is an ns_set
# NEW VERSION DONE BY BEN ADIDA (ben@mit.edu)
# Last modification (ben@mit.edu) on Jan ?? 1998
# added support for dates in the date_entry_widget.
#
# modification (ben@mit.edu) on Jan 12th, 1998
# when the val of an option tag is "", things screwed up
# FIXED.
#
# This used to count the number of vars already introduced
# in the form (see remaining num_vars statements), so as
# to end early. However, for some unknown reason, this cut off a number
# of forms. So now, this processes every tag in the HTML form.
set newhtml ""
set html_piece_ben $htmlpiece
set num_vars 0
for {set i 0} {$i<[ns_set size $values]} {incr i} {
if {[ns_set key $values $i] != ""} {
set database_values([ns_set key $values $i]) [philg_quote_double_quotes [ns_set value $values $i]]
incr num_vars
}
}
set vv {[Vv][Aa][Ll][Uu][Ee]} ; # Sorta obvious
set nn {[Nn][Aa][Mm][Ee]} ; # This is too
set qq {"([^"]*)"} ; # Matches what's in quotes
set pp {([^ ]*)} ; # Matches a word (mind yer pp and qq)
set slist {}
set count 0
while {1} {
incr count
set start_point [string first < $html_piece_ben]
if {$start_point==-1} {
append newhtml $html_piece_ben
break;
}
if {$start_point>0} {
append newhtml [string range $html_piece_ben 0 [expr $start_point - 1]]
}
set end_point [string first > $html_piece_ben]
if {$end_point==-1} break
incr start_point
incr end_point -1
set tag [string range $html_piece_ben $start_point $end_point]
incr end_point 2
set html_piece_ben [string range $html_piece_ben $end_point end]
set CAPTAG [string toupper $tag]
set first_white [string first " " $CAPTAG]
set first_word [string range $CAPTAG 0 [expr $first_white - 1]]
switch -regexp $CAPTAG {
{^INPUT} {
if {[regexp {TYPE[ ]*=[ ]*("IMAGE"|"SUBMIT"|"RESET"|IMAGE|SUBMIT|RESET)} $CAPTAG]} {
###
# Ignore these
###
append newhtml <$tag>
} elseif {[regexp {TYPE[ ]*=[ ]*("CHECKBOX"|CHECKBOX)} $CAPTAG]} {
# philg and jesse added optional whitespace 8/9/97
## If it's a CHECKBOX, we cycle through
# all the possible ns_set pair to see if it should
## end up CHECKED or not.
if {[regexp "$nn=$qq" $tag m nam]} {}\
elseif {[regexp "$nn=$pp" $tag m nam]} {}\
else {set nam ""}
if {[regexp "$vv=$qq" $tag m val]} {}\
elseif {[regexp "$vv=$pp" $tag m val]} {}\
else {set val ""}
regsub -all {[Cc][Hh][Ee][Cc][Kk][Ee][Dd]} $tag {} tag
# support for multiple check boxes provided by michael cleverly
if {[info exists database_values($nam)]} {
if {[ns_set unique $values $nam]} {
if {$database_values($nam) == $val} {
append tag " checked"
incr num_vars -1
}
} else {
for {set i [ns_set find $values $nam]} {$i < [ns_set size $values]} {incr i} {
if {[ns_set key $values $i] == $nam && [philg_quote_double_quotes [ns_set value $values $i]] == $val} {
append tag " checked"
incr num_vars -1
break
}
}
}
}
append newhtml <$tag>
} elseif {[regexp {TYPE[ ]*=[ ]*("RADIO"|RADIO)} $CAPTAG]} {
## If it's a RADIO, we remove all the other
# choices beyond the first to keep from having
## more than one CHECKED
if {[regexp "$nn=$qq" $tag m nam]} {}\
elseif {[regexp "$nn=$pp" $tag m nam]} {}\
else {set nam ""}
if {[regexp "$vv=$qq" $tag m val]} {}\
elseif {[regexp "$vv=$pp" $tag m val]} {}\
else {set val ""}
#Modified by Ben Adida (ben@mit.edu) so that
# the checked tags are eliminated only if something
# is in the database.
if {[info exists database_values($nam)]} {
regsub -all {[Cc][Hh][Ee][Cc][Kk][Ee][Dd]} $tag {} tag
if {$database_values($nam)==$val} {
append tag " checked"
incr num_vars -1
}
}
append newhtml <$tag>
} else {
## If it's an INPUT TYPE that hasn't been covered
# (text, password, hidden, other (defaults to text))
## then we add/replace the VALUE tag
if {[regexp "$nn=$qq" $tag m nam]} {}\
elseif {[regexp "$nn=$pp" $tag m nam]} {}\
else {set nam ""}
set nam [ns_urldecode $nam]
if {[info exists database_values($nam)]} {
regsub -all "$vv=$qq" $tag {} tag
regsub -all "$vv=$pp" $tag {} tag
append tag " value=\"$database_values($nam)\""
incr num_vars -1
} else {
if {[regexp {ColValue.([^.]*).([^ ]*)} $tag all nam type]} {
set nam [ns_urldecode $nam]
set typ ""
if {[string match $type "day"]} {
set typ "day"
}
if {[string match $type "year"]} {
set typ "year"
}
if {$typ != ""} {
if {[info exists database_values($nam)]} {
regsub -all "$vv=$qq" $tag {} tag
regsub -all "$vv=$pp" $tag {} tag
append tag " value=\"[ns_parsesqldate $typ $database_values($nam)]\""
}
}
#append tag ">
}
}
{^TEXTAREA} {
###
# Fill in the middle of this tag
###
if {[regexp "$nn=$qq" $tag m nam]} {}\
elseif {[regexp "$nn=$pp" $tag m nam]} {}\
else {set nam ""}
if {[info exists database_values($nam)]} {
while {![regexp {^<( *)/[Tt][Ee][Xx][Tt][Aa][Rr][Ee][Aa]} $html_piece_ben]} {
regexp {^.[^<]*(.*)} $html_piece_ben m html_piece_ben
}
append newhtml <$tag>$database_values($nam)
incr num_vars -1
} else {
append newhtml <$tag>
}
}
{^SELECT} {
###
# Set the snam flag, and perhaps smul, too
###
set smul [regexp "MULTIPLE" $CAPTAG]
set sflg 1
set select_date 0
if {[regexp "$nn=$qq" $tag m snam]} {}\
elseif {[regexp "$nn=$pp" $tag m snam]} {}\
else {set snam ""}
set snam [ns_urldecode $snam]
# In case it's a date
if {[regexp {ColValue.([^.]*).month} $snam all real_snam]} {
if {[info exists database_values($real_snam)]} {
set snam $real_snam
set select_date 1
}
}
lappend slist $snam
append newhtml <$tag>
}
{^OPTION} {
###
# Find the value for this
###
if {$snam != ""} {
if {[lsearch -exact $slist $snam] != -1} {regsub -all {[Ss][Ee][Ll][Ee][Cc][Tt][Ee][Dd]} $tag {} tag}
if {[regexp "$vv *= *$qq" $tag m opt]} {}\
elseif {[regexp "$vv *= *$pp" $tag m opt]} {}\
else {
if {[info exists opt]} {
unset opt
} }
# at this point we've figured out what the default from the form was
# and put it in $opt (if the default was spec'd inside the OPTION tag
# just in case it wasn't, we're going to look for it in the
# human-readable part
regexp {^([^<]*)(.*)} $html_piece_ben m txt html_piece_ben
if {![info exists opt]} {
set val [string trim $txt]
} else {
set val $opt
}
if {[info exists database_values($snam)]} {
# If we're dealing with a date
if {$select_date == 1} {
set db_val [ns_parsesqldate month $database_values($snam)]
} else {
set db_val $database_values($snam)
}
if {
($smul || $sflg) &&
[string match $db_val $val]
} then {
append tag " selected"
incr num_vars -1
set sflg 0
}
}
}
append newhtml <$tag>$txt
}
{^/SELECT} {
###
# Do we need to add to the end?
###
set txt ""
if {$snam != ""} {
if {[info exists database_values($snam)] && $sflg} {
append txt "