Index: openacs-4/packages/acs-subsite/tcl/attribute-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-subsite/tcl/attribute-procs.tcl,v diff -u -N -r1.19 -r1.20 --- openacs-4/packages/acs-subsite/tcl/attribute-procs.tcl 17 Sep 2018 13:38:51 -0000 1.19 +++ openacs-4/packages/acs-subsite/tcl/attribute-procs.tcl 17 Sep 2018 13:47:05 -0000 1.20 @@ -1,9 +1,8 @@ # /packages/mbryzek-subsite/tcl/attribute-procs.tcl ad_library { - + Procs to help with attributes for object types - @author mbryzek@arsdigita.com @creation-date Thu Dec 7 10:30:57 2000 @@ -19,7 +18,7 @@ } { set dynamic_p [db_string attribute_for_dynamic_object_p { - select exists (select 1 from acs_attributes a, acs_object_types t + select exists (select 1 from acs_attributes a, acs_object_types t where t.dynamic_p = 't' and a.object_type = t.object_type and a.attribute_id = :value) @@ -32,545 +31,541 @@ } -namespace eval attribute { +namespace eval attribute { + ad_proc -public exists_p { + { -convert_p "t" } + object_type + orig_attribute + } { + Returns 1 if the object type already has an attribute of the given name. -ad_proc -public exists_p { - { -convert_p "t" } - object_type - orig_attribute -} { - Returns 1 if the object type already has an attribute of the given name. - - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 12/2000 + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 12/2000 - @param convert_p If t, we convert the attribute using - plsql_utility::generate_oracle_name + @param convert_p If t, we convert the attribute using + plsql_utility::generate_oracle_name - @param orig_attribute The attribute in which we are - interested. Note that if convert_p is set to - t, we will internally look for the converted attribute - name + @param orig_attribute The attribute in which we are + interested. Note that if convert_p is set to + t, we will internally look for the converted attribute + name - @return 1 if the object type already has an attribute of the - specified name. 0 otherwise - -} { - if { $convert_p == "t" } { - set attribute [plsql_utility::generate_oracle_name $orig_attribute] - } else { - set attribute $orig_attribute + @return 1 if the object type already has an attribute of the + specified name. 0 otherwise + + } { + if { $convert_p == "t" } { + set attribute [plsql_utility::generate_oracle_name $orig_attribute] + } else { + set attribute $orig_attribute + } + + set attr_exists_p [db_string attr_exists_p { + select 1 from acs_attributes a + where (a.attribute_name = :attribute or a.column_name = :attribute) + and a.object_type = :object_type + } -default 0] + + if { $attr_exists_p || $convert_p == "f" } { + return $attr_exists_p + } + return [exists_p -convert_p f $object_type $orig_attribute] } - - set attr_exists_p [db_string attr_exists_p { - select 1 from acs_attributes a - where (a.attribute_name = :attribute or a.column_name = :attribute) - and a.object_type = :object_type - } -default 0] - - if { $attr_exists_p || $convert_p == "f" } { - # If the attribute exists, o - return $attr_exists_p - } - return [exists_p -convert_p f $object_type $orig_attribute] -} -ad_proc -public add { - { -default "" } - { -min_n_values "" } - { -max_n_values "" } - object_type - datatype - pretty_name - pretty_plural -} { - wrapper for the acs_attribute.create_attribute - call. Note that this procedure assumes type-specific storage. + ad_proc -public add { + { -default "" } + { -min_n_values "" } + { -max_n_values "" } + object_type + datatype + pretty_name + pretty_plural + } { + wrapper for the acs_attribute.create_attribute + call. Note that this procedure assumes type-specific storage. - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 12/2000 + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 12/2000 - @return The attribute_id of the newly created - attribute - -} { - - set default_value $default + @return The attribute_id of the newly created + attribute - # We always use type-specific storage. Grab the tablename from the - # object_type - if { ![db_0or1row select_table { - select t.table_name - from acs_object_types t - where t.object_type = :object_type - }] } { - error "Specified object type \"$object_type\" does not exist" - } - - # In OpenACS, where we care that SQL must be separate from code, we don't - # use these annoying formatting procs on our SQL. We write out the queries in full. (ben) + } { - # Attribute name returned from this function will be oracle - # friendly and is thus used as the column name - set attribute_name [plsql_utility::generate_oracle_name $pretty_name] - -# set attr_list [list] -# lappend attr_list [list "object_type" '$object_type'] -# lappend attr_list [list "attribute_name" '$attribute_name'] -# lappend attr_list [list "min_n_values" '$min_n_values'] -# lappend attr_list [list "max_n_values" '$max_n_values'] -# lappend attr_list [list "default_value" '$default'] -# lappend attr_list [list "datatype" '$datatype'] -# lappend attr_list [list "pretty_name" '$pretty_name'] -# lappend attr_list [list "pretty_plural" '$pretty_plural'] - - # A note (by ben, OpenACS) - # the queries are empty because they are pulled out later in db_exec_plsql - - set plsql [list] - lappend plsql_drop [list db_exec_plsql "drop_attribute" "FOO"] - lappend plsql [list db_exec_plsql "create_attribute" "FOO"] + set default_value $default - set sql_type [datatype_to_sql_type -default $default_value $table_name $attribute_name $datatype] - - lappend plsql_drop [list db_dml "drop_attr_column" "FOO"] - lappend plsql [list db_dml "add_column" "FOO"] - - for { set i 0 } { $i < [llength $plsql] } { incr i } { - set cmd [lindex $plsql $i] - if { [catch $cmd err_msg] } { - # Rollback what we've done so far. The loop contitionals are: - # start at the end of the plsql_drop list (Drop things in reverse order of creation) - # execute drop statements until we reach position $i+1 - # This position represents the operation on which we failed, and thus - # is not executed - for { set inner [expr {[llength $plsql_drop] - 1}] } { $inner > $i + 1 } { incr inner -1 } { - set drop_cmd [lindex $plsql_drop $inner] - if { [catch $drop_cmd err_msg_2] } { - append err_msg "\nAdditional error while trying to roll back: $err_msg_2" - return -code error $err_msg + # We always use type-specific storage. Grab the tablename from the + # object_type + if { ![db_0or1row select_table { + select t.table_name + from acs_object_types t + where t.object_type = :object_type + }] } { + error "Specified object type \"$object_type\" does not exist" + } + + # In OpenACS, where we care that SQL must be separate from code, we don't + # use these annoying formatting procs on our SQL. We write out the queries in full. (ben) + + # Attribute name returned from this function will be oracle + # friendly and is thus used as the column name + set attribute_name [plsql_utility::generate_oracle_name $pretty_name] + + # set attr_list [list] + # lappend attr_list [list "object_type" '$object_type'] + # lappend attr_list [list "attribute_name" '$attribute_name'] + # lappend attr_list [list "min_n_values" '$min_n_values'] + # lappend attr_list [list "max_n_values" '$max_n_values'] + # lappend attr_list [list "default_value" '$default'] + # lappend attr_list [list "datatype" '$datatype'] + # lappend attr_list [list "pretty_name" '$pretty_name'] + # lappend attr_list [list "pretty_plural" '$pretty_plural'] + + # A note (by ben, OpenACS) + # the queries are empty because they are pulled out later in db_exec_plsql + + set plsql [list] + lappend plsql_drop [list db_exec_plsql "drop_attribute" "FOO"] + lappend plsql [list db_exec_plsql "create_attribute" "FOO"] + + set sql_type [datatype_to_sql_type -default $default_value $table_name $attribute_name $datatype] + + lappend plsql_drop [list db_dml "drop_attr_column" "FOO"] + lappend plsql [list db_dml "add_column" "FOO"] + + for { set i 0 } { $i < [llength $plsql] } { incr i } { + set cmd [lindex $plsql $i] + if { [catch $cmd err_msg] } { + # Rollback what we've done so far. The loop contitionals are: + # start at the end of the plsql_drop list (Drop things in reverse order of creation) + # execute drop statements until we reach position $i+1 + # This position represents the operation on which we failed, and thus + # is not executed + for { set inner [expr {[llength $plsql_drop] - 1}] } { $inner > $i + 1 } { incr inner -1 } { + set drop_cmd [lindex $plsql_drop $inner] + if { [catch $drop_cmd err_msg_2] } { + append err_msg "\nAdditional error while trying to roll back: $err_msg_2" + return -code error $err_msg + } } + return -code error $err_msg } - return -code error $err_msg } + + return [db_string select_attribute_id { + select a.attribute_id + from acs_attributes a + where a.object_type = :object_type + and a.attribute_name = :attribute_name + }] + } - - return [db_string select_attribute_id { - select a.attribute_id - from acs_attributes a - where a.object_type = :object_type - and a.attribute_name = :attribute_name - }] -} + ad_proc -private datatype_to_sql_type { + { -default "" } + table + column + datatype + } { + Returns the appropriate sql type for a table definition + based on the table, column, datatype, and default value. Note that for + default values, this proc automatically generates appropriate + constraint names as well. -ad_proc -private datatype_to_sql_type { - { -default "" } - table - column - datatype -} { - Returns the appropriate sql type for a table definition - based on the table, column, datatype, and default value. Note that for - default values, this proc automatically generates appropriate - constraint names as well. - - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 12/2000 + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 12/2000 - @param default If specified, we add a default clause to the sql statement + @param default If specified, we add a default clause to the sql statement -} { - set type "" - set constraint "" - - switch -- $datatype { - "string" { set type "varchar(1000)" } - "boolean" { set type "char(1)" - set constraint "[plsql_utility::generate_constraint_name $table $column "ck"] check ($column in ('t','f'))" } - "number" { set type "number" } - "money" { set type "number (12,2)" } - "date" { set type "date" } - "text" { set type "varchar(4000)" } - "integer" { set type "integer" } - "enumeration" { set type "varchar(100)" } - "keyword" { set type "varchar(1000)" } - default {error "Unsupported datatype. Datatype $datatype is not implemented at this time"} - } + } { + set type "" + set constraint "" - set sql "$type" - - if { $default ne "" } { - # This is also pretty nasty - we have to make sure we - # treat db literals appropriately - null is much different - # than 'null' - mbryzek - set vars [list null sysdate] - if {[string tolower $default] ni $vars} { - set default "'$default'" + switch -- $datatype { + "string" { set type "varchar(1000)" } + "boolean" { set type "char(1)" + set constraint "[plsql_utility::generate_constraint_name $table $column "ck"] check ($column in ('t','f'))" } + "number" { set type "number" } + "money" { set type "number (12,2)" } + "date" { set type "date" } + "text" { set type "varchar(4000)" } + "integer" { set type "integer" } + "enumeration" { set type "varchar(100)" } + "keyword" { set type "varchar(1000)" } + default {error "Unsupported datatype. Datatype $datatype is not implemented at this time"} } - append sql " default $default" + + set sql "$type" + + if { $default ne "" } { + # This is also pretty nasty - we have to make sure we + # treat db literals appropriately - null is much different + # than 'null' - mbryzek + set vars [list null sysdate] + if {[string tolower $default] ni $vars} { + set default "'$default'" + } + append sql " default $default" + } + if { $constraint ne "" } { + append sql " constraint $constraint" + } + return $sql } - if { $constraint ne "" } { - append sql " constraint $constraint" - } - return $sql -} -ad_proc -public delete { attribute_id } { - Delete the specified attribute id and all its values. This is - irreversible. Returns 1 if the attribute was actually deleted. 0 - otherwise. + ad_proc -public delete { attribute_id } { + Delete the specified attribute id and all its values. This is + irreversible. Returns 1 if the attribute was actually deleted. 0 + otherwise. - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 12/2000 + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 12/2000 -} { - - # 1. Drop the attribute with its column - # 2. Return - - if { ![db_0or1row select_attr_info { - select a.object_type, a.attribute_name, - case when a.storage = 'type_specific' then t.table_name else a.table_name end as table_name, - coalesce(a.column_name, a.attribute_name) as column_name - from acs_attributes a, acs_object_types t - where a.attribute_id = :attribute_id - and t.object_type = a.object_type - }] } { - # Attribute doesn't exist - return 0 - } - - if { $table_name eq "" || $column_name eq "" } { - # We have to have both a non-empty table name and column name - error "We do not have enough information to automatically remove this attribute. Namely, we are missing either the table name or the column name" - } + } { - set drop_table_column_p [expr {[db_column_exists $table_name $column_name] ? "t" : "f"}] + # 1. Drop the attribute with its column + # 2. Return - db_exec_plsql drop_attribute {} - - return 1 -} + if { ![db_0or1row select_attr_info { + select a.object_type, a.attribute_name, + case when a.storage = 'type_specific' then t.table_name else a.table_name end as table_name, + coalesce(a.column_name, a.attribute_name) as column_name + from acs_attributes a, acs_object_types t + where a.attribute_id = :attribute_id + and t.object_type = a.object_type + }] } { + # Attribute doesn't exist + return 0 + } -ad_proc -public value_add {attribute_id enum_value sort_order} { - adds the specified enumeration value to the attribute. + if { $table_name eq "" || $column_name eq "" } { + # We have to have both a non-empty table name and column name + error "We do not have enough information to automatically remove this attribute. Namely, we are missing either the table name or the column name" + } - @author Ben Adida (ben@openforce.net) - @creation-date 08/2001 + set drop_table_column_p [expr {[db_column_exists $table_name $column_name] ? "t" : "f"}] - @param attribute_id The attribute to which we are adding - @param enum_value The value which we are adding to the enum -} { - # Just insert it if we can - db_dml insert_enum_value { - insert into acs_enum_values - (attribute_id, sort_order, enum_value, pretty_name) - select :attribute_id, :sort_order, :enum_value, :enum_value - from dual - where not exists (select 1 - from acs_enum_values v2 - where v2.pretty_name = :enum_value - and v2.attribute_id = :attribute_id) + db_exec_plsql drop_attribute {} + + return 1 } -} -ad_proc -public value_delete { attribute_id enum_value } { - deletes the specified enumeration value from the attribute. The - net effect is that this attribute will have one fewer options for - acceptable values. + ad_proc -public value_add {attribute_id enum_value sort_order} { + adds the specified enumeration value to the attribute. - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 12/2000 + @author Ben Adida (ben@openforce.net) + @creation-date 08/2001 - @param attribute_id The attribute from which we are deleting - @param enum_value The value of we are deleting - -} { - # This function should remove all occurrences of the - # attribute, but we don't do that now. - - if { ![db_0or1row select_last_sort_order { - select v.sort_order as old_sort_order - from acs_enum_values v - where v.attribute_id = :attribute_id - and v.enum_value = :enum_value - }] } { - # nothing to delete - return + @param attribute_id The attribute to which we are adding + @param enum_value The value which we are adding to the enum + } { + # Just insert it if we can + db_dml insert_enum_value { + insert into acs_enum_values + (attribute_id, sort_order, enum_value, pretty_name) + select :attribute_id, :sort_order, :enum_value, :enum_value + from dual + where not exists (select 1 + from acs_enum_values v2 + where v2.pretty_name = :enum_value + and v2.attribute_id = :attribute_id) + } } - - db_dml delete_enum_value { - delete from acs_enum_values v - where v.attribute_id = :attribute_id - and v.enum_value = :enum_value - } - if { [db_resultrows] > 0 } { - # update the sort order - db_dml update_sort_order { - update acs_enum_values v - set v.sort_order = v.sort_order - 1 + + ad_proc -public value_delete { attribute_id enum_value } { + deletes the specified enumeration value from the attribute. The + net effect is that this attribute will have one fewer options for + acceptable values. + + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 12/2000 + + @param attribute_id The attribute from which we are deleting + @param enum_value The value of we are deleting + + } { + # This function should remove all occurrences of the + # attribute, but we don't do that now. + + if { ![db_0or1row select_last_sort_order { + select v.sort_order as old_sort_order + from acs_enum_values v where v.attribute_id = :attribute_id - and v.sort_order > :old_sort_order + and v.enum_value = :enum_value + }] } { + # nothing to delete + return } - } - return - -} + db_dml delete_enum_value { + delete from acs_enum_values v + where v.attribute_id = :attribute_id + and v.enum_value = :enum_value + } + if { [db_resultrows] > 0 } { + # update the sort order + db_dml update_sort_order { + update acs_enum_values v + set v.sort_order = v.sort_order - 1 + where v.attribute_id = :attribute_id + and v.sort_order > :old_sort_order + } + } + return -ad_proc -public translate_datatype { - datatype -} { - translates the datatype into one that can be - validated. Default datatype is text (when no validator is found) + } - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 12/2000 -} { - if { [datatype_validator_exists_p $datatype] } { - return $datatype + ad_proc -public translate_datatype { + datatype + } { + translates the datatype into one that can be + validated. Default datatype is text (when no validator is found) + + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 12/2000 + + } { + if { [datatype_validator_exists_p $datatype] } { + return $datatype + } + switch -- $datatype { + boolean { set datatype "text" } + keyword { set datatype "text" } + money { set datatype "integer" } + number { set datatype "integer" } + string { set datatype "text" } + } + if { [datatype_validator_exists_p $datatype] } { + return $datatype + } + # No validator exists... return text as default + return "text" } - switch -- $datatype { - boolean { set datatype "text" } - keyword { set datatype "text" } - money { set datatype "integer" } - number { set datatype "integer" } - string { set datatype "text" } - } - if { [datatype_validator_exists_p $datatype] } { - return $datatype - } - # No validator exists... return text as default - return "text" -} -ad_proc -public datatype_validator_exists_p { - datatype -} { + ad_proc -public datatype_validator_exists_p { + datatype + } { - Returns 1 if we have a validator for this datatype. 0 - otherwise. We currently do not support the "date" datatype and - hardcoded support for enumeration. This - is hardcoded in this procedure. Also, this procedure assumes that - validators are procedures named - ::template::data::validate::$datatype + Returns 1 if we have a validator for this datatype. 0 + otherwise. We currently do not support the "date" datatype and + hardcoded support for enumeration. This + is hardcoded in this procedure. Also, this procedure assumes that + validators are procedures named + ::template::data::validate::$datatype - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 12/2000 + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 12/2000 -} { - if {$datatype eq "date"} { - return 0 + } { + if {$datatype eq "date"} { + return 0 + } + if {$datatype eq "enumeration"} { + return 1 + } + if { [info commands "::template::data::validate::$datatype"] eq "" } { + return 0 + } + return 1 } - if {$datatype eq "enumeration"} { - return 1 - } - if { [info commands "::template::data::validate::$datatype"] eq "" } { - return 0 - } - return 1 -} -ad_proc -public array_for_type { - { -start_with "acs_object" } - { -include_storage_types {type_specific} } - array_name - enum_array_name - object_type -} { + ad_proc -public array_for_type { + { -start_with "acs_object" } + { -include_storage_types {type_specific} } + array_name + enum_array_name + object_type + } { - Fills in 2 arrays used for displaying attributes + Fills in 2 arrays used for displaying attributes - @author Michael Bryzek (mbryzek@arsdigita.com) - @creation-date 1/8/2001 + @author Michael Bryzek (mbryzek@arsdigita.com) + @creation-date 1/8/2001 - @param array_name The name of the array to hold the basic - attribute information. The attributes defined are: - - * array_name(pretty_name:$name) The pretty_name of the attribute - * array_name(id:$name) The attribute_id of the attribute - * array_name(datatype:$name) The datatype of the attribute - + @param array_name The name of the array to hold the basic + attribute information. The attributes defined are: + + * array_name(pretty_name:$name) The pretty_name of the attribute + * array_name(id:$name) The attribute_id of the attribute + * array_name(datatype:$name) The datatype of the attribute + - @param enum_array_name The name of the array to hold the pretty - name of the values of an enumeration. This is only used when the - datatype of the attribute_name is enumeration. This array is a - mapping from "$attribute_name:enum_value" to value_pretty_name. + @param enum_array_name The name of the array to hold the pretty + name of the values of an enumeration. This is only used when the + datatype of the attribute_name is enumeration. This array is a + mapping from "$attribute_name:enum_value" to value_pretty_name. - @param object_type The object for which we are looking up - attributes + @param object_type The object for which we are looking up + attributes - @return A list of all the names of attributes we looked up. This - list can be used to iterated through the arrays: -
-        set attr_list [attribute::array_for_type attr_props enum_values "group"]
-	foreach key $attr_list {
-	    set attribute_id $attr_props(id:$attribute_name)
-	    ...
-        }    
-    
+ @return A list of all the names of attributes we looked up. This + list can be used to iterated through the arrays: +
+            set attr_list [attribute::array_for_type attr_props enum_values "group"]
+            foreach key $attr_list {
+                set attribute_id $attr_props(id:$attribute_name)
+                ...
+            }
+        
-} { - upvar $array_name attr_props - upvar $enum_array_name enum_values - set attr_list [list] + } { + upvar $array_name attr_props + upvar $enum_array_name enum_values + set attr_list [list] - set storage_clause "" + set storage_clause "" - if {$include_storage_types ne ""} { - set storage_clause " - and a.storage in ('[join $include_storage_types "', '"]')" - } + if {$include_storage_types ne ""} { + set storage_clause " + and a.storage in ('[join $include_storage_types "', '"]')" + } - db_foreach select_attributes {} { - # Enumeration values show up more than once... - if {$name ni $attr_list} { - lappend attr_list $name - set attr_props(pretty_name:$name) $pretty_name - set attr_props(datatype:$name) $datatype - set attr_props(id:$name) $attribute_id - } - if {$datatype eq "enumeration"} { - set enum_values($name:$enum_value) $value_pretty_name - } + db_foreach select_attributes {} { + # Enumeration values show up more than once... + if {$name ni $attr_list} { + lappend attr_list $name + set attr_props(pretty_name:$name) $pretty_name + set attr_props(datatype:$name) $datatype + set attr_props(id:$name) $attribute_id + } + if {$datatype eq "enumeration"} { + set enum_values($name:$enum_value) $value_pretty_name + } + } + return $attr_list } - return $attr_list -} -ad_proc -public multirow { - { -start_with "acs_object" } - { -include_storage_types {type_specific} } - { -datasource_name "attributes" } - { -object_type "" } - { -return_url "" } - object_id -} { - Sets up a multirow datasource containing the attribute values of object_id. - We only support specific storage attributes. - We include all attributes of the object's type, or any of its supertypes, - up to $start_with. -} { + ad_proc -public multirow { + { -start_with "acs_object" } + { -include_storage_types {type_specific} } + { -datasource_name "attributes" } + { -object_type "" } + { -return_url "" } + object_id + } { + Sets up a multirow datasource containing the attribute values of object_id. + We only support specific storage attributes. + We include all attributes of the object's type, or any of its supertypes, + up to $start_with. + } { - upvar $datasource_name attributes + upvar $datasource_name attributes - if {$object_type eq ""} { - set object_type [db_string object_type_query { - select object_type from acs_objects where object_id = :object_id - }] - } + if {$object_type eq ""} { + set object_type [db_string object_type_query { + select object_type from acs_objects where object_id = :object_id + }] + } - if {$return_url eq ""} { - set return_url "[ad_conn url]?[ad_conn query]" - } + if {$return_url eq ""} { + set return_url "[ad_conn url]?[ad_conn query]" + } - # Build up the list of attributes for the type specific lookup - set attr_list [attribute::array_for_type \ - -start_with $start_with \ - -include_storage_types $include_storage_types \ - attr_props enum_values $object_type] + # Build up the list of attributes for the type specific lookup + set attr_list [attribute::array_for_type \ + -start_with $start_with \ + -include_storage_types $include_storage_types \ + attr_props enum_values $object_type] - # Build up a multirow datasource to present these attributes to the user - template::multirow create $datasource_name pretty_name value export_vars + # Build up a multirow datasource to present these attributes to the user + template::multirow create $datasource_name pretty_name value export_vars - set package_object_view [package_object_view \ - -start_with "acs_object" \ - $object_type] + set package_object_view [package_object_view \ + -start_with "acs_object" \ + $object_type] - if { [array size attr_props] > 0 } { - db_foreach attribute_select " - select * - from ($package_object_view) - where object_id = :object_id - " { - foreach key $attr_list { - set col_value [set $key] - set attribute_id $attr_props(id:$key) - if { $attr_props(datatype:$key) eq "enumeration" && [info exists enum_values($key:$col_value)] } { - # Replace the value stored in the column with the - # pretty name for that attribute - set col_value $enum_values($key:$col_value) - } - template::multirow append $datasource_name $attr_props(pretty_name:$key) $col_value "id_column=$object_id&[export_vars {attribute_id return_url}]" - } - } + if { [array size attr_props] > 0 } { + db_foreach attribute_select " + select * + from ($package_object_view) + where object_id = :object_id + " { + foreach key $attr_list { + set col_value [set $key] + set attribute_id $attr_props(id:$key) + if { $attr_props(datatype:$key) eq "enumeration" && [info exists enum_values($key:$col_value)] } { + # Replace the value stored in the column with the + # pretty name for that attribute + set col_value $enum_values($key:$col_value) + } + template::multirow append $datasource_name $attr_props(pretty_name:$key) $col_value "id_column=$object_id&[export_vars {attribute_id return_url}]" + } + } + } } -} -ad_proc -public add_form_elements { - { -form_id "" } - { -start_with "acs_object" } - { -object_type "acs_object" } - { -variable_prefix "" } -} { - Adds form elements to the specified form_id. Each form element - corresponds to an attribute belonging to the given object_type. + ad_proc -public add_form_elements { + { -form_id "" } + { -start_with "acs_object" } + { -object_type "acs_object" } + { -variable_prefix "" } + } { + Adds form elements to the specified form_id. Each form element + corresponds to an attribute belonging to the given object_type. - @param form_id ID of a form to add form elements to. - @param start_with Object type to start with. Defaults to acs_object. - @param object_type Object type to extract attributes for. - Defaults to acs_object. - @param variable_prefix Variable prefix. -} { + @param form_id ID of a form to add form elements to. + @param start_with Object type to start with. Defaults to acs_object. + @param object_type Object type to extract attributes for. + Defaults to acs_object. + @param variable_prefix Variable prefix. + } { - if {$form_id eq ""} { - error "attribute::add_form_elements - form_id not specified" - } + if {$form_id eq ""} { + error "attribute::add_form_elements - form_id not specified" + } - if {$object_type eq ""} { - error "attribute::add_form_elements - object type not specified" - } + if {$object_type eq ""} { + error "attribute::add_form_elements - object type not specified" + } - if {$variable_prefix ne ""} { - append variable_prefix "." - } + if {$variable_prefix ne ""} { + append variable_prefix "." + } - # pull out all the attributes up the hierarchy from this object_type - # to the $start_with object type - set attr_list_of_lists [package_object_attribute_list -start_with $start_with $object_type] + # pull out all the attributes up the hierarchy from this object_type + # to the $start_with object type + set attr_list_of_lists [package_object_attribute_list -start_with $start_with $object_type] - foreach row $attr_list_of_lists { - lassign $row attribute_id . attribute_name pretty_name datatype required_p default - # Might translate the datatype into one for which we have a - # validator (e.g. a string datatype would change into text). - set datatype [translate_datatype $datatype] + foreach row $attr_list_of_lists { + lassign $row attribute_id . attribute_name pretty_name datatype required_p default + # Might translate the datatype into one for which we have a + # validator (e.g. a string datatype would change into text). + set datatype [translate_datatype $datatype] - if {$datatype eq "enumeration"} { - # For enumerations, we generate a select box of all the possible values - set option_list [db_list_of_lists select_enum_values { - select enum.pretty_name, enum.enum_value - from acs_enum_values enum - where enum.attribute_id = :attribute_id - order by enum.sort_order - }] - if {$required_p == "f"} { - # This is not a required option list... offer a default - lappend option_list [list " (no value) " ""] - } - template::element create $form_id "$variable_prefix$attribute_name" \ - -datatype "text" [ad_decode $required_p "f" "-optional" ""] \ - -widget select \ - -options $option_list \ - -label "$pretty_name" \ - -value $default - } else { - template::element create $form_id "$variable_prefix$attribute_name" \ - -datatype $datatype [ad_decode $required_p "f" "-optional" ""] \ - -widget text \ - -label $pretty_name \ - -value $default - } + if {$datatype eq "enumeration"} { + # For enumerations, we generate a select box of all the possible values + set option_list [db_list_of_lists select_enum_values { + select enum.pretty_name, enum.enum_value + from acs_enum_values enum + where enum.attribute_id = :attribute_id + order by enum.sort_order + }] + if {$required_p == "f"} { + # This is not a required option list... offer a default + lappend option_list [list " (no value) " ""] + } + template::element create $form_id "$variable_prefix$attribute_name" \ + -datatype "text" [ad_decode $required_p "f" "-optional" ""] \ + -widget select \ + -options $option_list \ + -label "$pretty_name" \ + -value $default + } else { + template::element create $form_id "$variable_prefix$attribute_name" \ + -datatype $datatype [ad_decode $required_p "f" "-optional" ""] \ + -widget text \ + -label $pretty_name \ + -value $default + } + } } } -} - - # Local variables: # mode: tcl # tcl-indent-level: 4