Index: openacs-4/packages/contacts/lib/contacts.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/contacts.adp,v diff -u -r1.7 -r1.8 --- openacs-4/packages/contacts/lib/contacts.adp 1 Feb 2006 20:16:44 -0000 1.7 +++ openacs-4/packages/contacts/lib/contacts.adp 1 Apr 2006 07:07:16 -0000 1.8 @@ -13,3 +13,16 @@ <br> <listtemplate name="contacts"></listtemplate> + +<if @add_columns@ not nil or @remove_columns@ not nil> +<table cellpadding="0" cellspacing="0" border="0"> + <tr> + <if @add_columns@ not nil> + <td><formtemplate id="add_column_form" style="../../../contacts/resources/forms/inline"></formtemplate></td> + </if> + <if @remove_columns@ not nil> + <td><formtemplate id="remove_column_form" style="../../../contacts/resources/forms/inline"></formtemplate></td> + </if> + </tr> +</table> +</if> Index: openacs-4/packages/contacts/lib/contacts.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/contacts.tcl,v diff -u -r1.49 -r1.50 --- openacs-4/packages/contacts/lib/contacts.tcl 24 Mar 2006 13:18:04 -0000 1.49 +++ openacs-4/packages/contacts/lib/contacts.tcl 1 Apr 2006 07:07:16 -0000 1.50 @@ -7,7 +7,6 @@ set _orderby "first_names,asc" set _format "normal" set _page_size "25" -set _tasks_interval "7" set admin_p 0 if { [string is false [exists_and_not_null package_id]] } { @@ -34,6 +33,24 @@ } } +# see if the person is attemping to add +# or remove a column +set extended_columns [ns_queryget extended_columns] +set add_column [ns_queryget add_column] +set remove_column [ns_queryget remove_column] +if { $extended_columns ne "" && $remove_column ne "" } { + set lindex_id [lsearch -exact $extended_columns $remove_column] + if { $lindex_id >= 0 } { + set extended_columns [lreplace $extended_columns $lindex_id $lindex_id] + } +} +if { $add_column ne "" } { + lappend extended_columns $add_column +} + +set add_column "" +set remove_column "" + # This is for showing the employee_id and employeer relationship set type_list [db_list get_condition_type { }] @@ -70,9 +87,6 @@ {extend_values:text(hidden) {value "$extend_values"} } - {attr_val_name:text(hidden) - {value "$attr_val_name"} - } } -on_submit { # We clear the list when no value is submited, otherwise # we acumulate the extend values. @@ -81,7 +95,7 @@ } else { lappend extend_values [list $extend_option] } - ad_returnredirect [export_vars -base "?" {search_id extend_values attr_val_name}] + ad_returnredirect [export_vars -base "?" {search_id extend_values extended_columns}] } } @@ -102,29 +116,36 @@ set last_modified_join "" set last_modified_clause "" + +set first_names_url [export_vars -base $base_url -url {format search_id query page page_size extended_columns {orderby {first_names,asc}}}] +set last_name_url [export_vars -base $base_url -url {format search_id query page page_size extended_columns {orderby {last_name,asc}}}] +set organization_url [export_vars -base $base_url -url {format search_id query page page_size extended_columns {orderby {organization,asc}}}] +set last_modified_url [export_vars -base $base_url -url {format search_id query page page_size extended_columns {orderby {last_modified,desc}}}] switch $orderby { "first_names,asc" { - set name_label "[_ contacts.Sort_by]: [_ contacts.First_Names] | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size attr_val_name {orderby {last_name,asc}}}]\">[_ contacts.Last_Name]</a> | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size attr_val_name {orderby {organization,asc}}}]\">[_ contacts.Organization]</a> | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size attr_val_name {orderby {last_modified,desc}}}]\">[_ contacts.Last_Modified]</a>" + set name_label "[_ contacts.Sort_by] [_ contacts.First_Names] | <a href=\"${last_name_url}\">[_ contacts.Last_Name]</a> | <a href=\"${organization_url}\">[_ contacts.Organization]</a> | <a href=\"${last_modified_url}\">[_ contacts.Last_Modified]</a>" set left_join "left join persons on (p.party_id = persons.person_id)" set sort_item "lower(first_names), lower(last_name)" } "last_name,asc" { - set name_label "[_ contacts.Sort_by] <a href=\"[export_vars -base $base_url -url {format search_id query page page_size attr_val_name {orderby {first_names,asc}}}]\">[_ contacts.First_Names]</a> | [_ contacts.Last_Name] | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size {orderby {organization,asc}}}]\">[_ contacts.Organization]</a> | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size {orderby {last_modified,desc}}}]\">[_ contacts.Last_Modified]</a>" + set name_label "[_ contacts.Sort_by] <a href=\"${first_names_url}\">[_ contacts.First_Names]</a> | [_ contacts.Last_Name] | <a href=\"${organization_url}\">[_ contacts.Organization]</a> | <a href=\"${last_modified_url}\">[_ contacts.Last_Modified]</a>" set left_join "left join persons on (p.party_id = persons.person_id)" set sort_item "lower(last_name), lower(first_names)" } "organization,asc" { - set name_label "[_ contacts.Sort_by] <a href=\"[export_vars -base $base_url -url {format search_id query page page_size attr_val_name {orderby {first_names,asc}}}]\">[_ contacts.First_Names]</a> | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size {orderby {last_name,asc}}}]\">[_ contacts.Last_Name]</a> | [_ contacts.Organization] | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size {orderby {last_modified,desc}}}]\">[_ contacts.Last_Modified]</a>" + set name_label "[_ contacts.Sort_by] <a href=\"${first_names_url}\">[_ contacts.First_Names]</a> | <a href=\"${last_name_url}\">[_ contacts.Last_Name]</a> | [_ contacts.Organization] | <a href=\"${last_modified_url}\">[_ contacts.Last_Modified]</a>" set left_join "left join organizations on (p.party_id = organizations.organization_id)" set sort_item "lower(organizations.name)" } "last_modified,desc" { - set name_label "[_ contacts.Sort_by] <a href=\"[export_vars -base $base_url -url {format search_id query page page_size attr_val_name {orderby {first_names,asc}}}]\">[_ contacts.First_Names]</a> | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size {orderby {last_name,asc}}}]\">[_ contacts.Last_Name]</a> | <a href=\"[export_vars -base $base_url -url {format search_id query page page_size {orderby {organization,asc}}}]\">[_ contacts.Organization]</a> | [_ contacts.Last_Modified]" + set name_label "[_ contacts.Sort_by] <a href=\"${first_names_url}\">[_ contacts.First_Names]</a> | <a href=\"${last_name_url}\">[_ contacts.Last_Name]</a> | <a href=\"${organization_url}\">[_ contacts.Organization]</a> | [_ contacts.Last_Modified]" set left_join "" set sort_item "cr.publish_date" } } + + append name_label " [_ contacts.Show]: " @@ -136,15 +157,15 @@ if { $page_size == $page_s } { lappend page_size_list $page_s } else { - lappend page_size_list "<a href=\"[export_vars -base $base_url -url {format search_id query page orderby attr_val_name {page_size $page_s}}]\">$page_s</a>" + lappend page_size_list "<a href=\"[export_vars -base $base_url -url {format search_id query page orderby extended_columns {page_size $page_s}}]\">$page_s</a>" } } append name_label [join $page_size_list " | "] if { [string is true [parameter::get -parameter "DisableCSV" -default "0"]] } { set format normal } else { - append name_label " [_ contacts.Get]: <a href=\"[export_vars -base $base_url -url {{format csv} search_id query page orderby attr_val_name page_size}]\">[_ contacts.CSV]</a>" + append name_label " [_ contacts.Get]: <a href=\"[export_vars -base $base_url -url {{format csv} search_id query page orderby page_size extended_columns}]\">[_ contacts.CSV]</a>" } template::multirow create bulk_acts pretty link detailed @@ -234,65 +255,88 @@ } -# We are going to extend the list also by the attributes specified in the -# parameters, if there is any. Only when attr_val_name is empty and exists a -# search_id, otherwise we would have duplicates since when attr_val_name is -# present then the default attributes specified on the parameter already come -# in this list. +if { [exists_and_not_null search_id] } { -if { ![exists_and_not_null attr_val_name] && [exists_and_not_null search_id] } { - - set object_type [db_string get_object_type { }] + set object_type [db_string get_object_type {}] switch $object_type { person { set page_query_name "person_pagination" if {[string eq $orderby "organization,asc"]} { set orderby "first_names,asc" } - set default_attr_extend [parameter::get -parameter "DefaultPersonAttributeExtension"] +# set default_attr_extend [parameter::get -parameter "DefaultPersonAttributeExtension"] } organization { set page_query_name "organization_pagination" if {[string eq $orderby "first_names,asc"] || [string eq $orderby "last_name,asc"]} { set orderby "organization,asc" } - set default_attr_extend [parameter::get -parameter "DefaultOrganizationAttributeExtension"] +# set default_attr_extend [parameter::get -parameter "DefaultOrganizationAttributeExtension"] } party { set page_query_name "contacts_pagination" - set default_attr_extend [parameter::get -parameter "DefaultPersonOrganAttributeExtension"] +# set default_attr_extend [parameter::get -parameter "DefaultPersonOrganAttributeExtension"] } } - - # We are going to take all the blank spaces and split the list by ";" - regsub -all " " $default_attr_extend "" default_attr_extend - set default_attr_extend [split $default_attr_extend ";"] +} - foreach attr $default_attr_extend { - set attr_id [attribute::id -object_type "person" -attribute_name "$attr"] - if { [empty_string_p $attr_id] } { - # Is not a person attribute is an organization attribute - set attr_id [attribute::id -object_type "organization" -attribute_name "$attr"] - } - lappend attr_val_name [list $attr_id $attr] - } +set actions [list] +if { $admin_p && [exists_and_not_null search_id] } { + set actions [list "[_ contacts.Set_default_extend]" "admin/ext-search-options?search_id=$search_id" "[_ contacts.Set_default_extend]" ] } -# This is for the attributes -set extend_attr [list] -foreach attribute $attr_val_name { - set attr_id [lindex $attribute 0] - lappend row_list $attr_id [list] - lappend elements $attr_id [list label [attribute::pretty_name -attribute_id $attr_id] display_template "@contacts.${attr_id};noquote@"] - lappend extend_attr $attr_id + +template::multirow create ext impl type type_pretty key key_pretty + +# permissions for what attributes/extensions are visible to this +# user are to be handled by this callback proc. The callback +# MUST only return keys that are visible to this user + +callback contacts::extensions \ + -user_id [ad_conn user_id] \ + -multirow ext \ + -package_id [ad_conn package_id] + + +set add_columns [list] +set remove_columns [list] +set db_extend_columns [list] +if { $search_id ne "" } { + # now we get the extensions for this specific search + set db_extend_columns [contact::search::get_extensions -search_id $search_id] } +set extended_columns [concat $db_extend_columns $extended_columns] -set actions [list] -if { $admin_p && [exists_and_not_null search_id] } { - set actions [list "[_ contacts.Set_default_extend]" "admin/ext-search-options?search_id=$search_id" "[_ contacts.Set_default_extend]" ] +# we run through the multirow here to determine wether or not the columns are allowed +template::multirow foreach ext { + set selected_p 0 + set immutable_p 0 + if { [lsearch $extended_columns "${type}__${key}"] >= 0 } { + # we want to use this column in our table + set selected_p 1 + if { [lsearch $db_extend_columns "${type}__${key}"] >= 0 } { + set immutable_p 1 + } + # we add the column to the template::list + lappend elements "${type}__${key}" [list label $key_pretty display_col "${type}__${key}" display_template "@contacts.${type}__${key};noquote@"] + lappend row_list "${type}__${key}" [list] + } + if { [string is true $selected_p] && [string is false $immutable_p] } { + lappend remove_columns [list $key_pretty "${type}__${key}" $type_pretty] + } elseif { [string is false $selected_p] } { + lappend add_columns [list $key_pretty "${type}__${key}" $type_pretty] + } + } + + + + + + + template::list::create \ -html {width 100%} \ -name "contacts" \ @@ -310,13 +354,12 @@ -bulk_action_export_vars { search_id return_url } \ -elements $elements \ -filters { - attr_val_name {} search_id {} page_size {} extend_values {} attribute_values {} - tasks_interval {} query {} + extended_columns {} } -orderby { first_names { label "[_ contacts.First_Name]" @@ -338,8 +381,7 @@ orderby_asc "cr.publish_date" orderby_desc "cr.publish_date" } - - default_value first_names,asc + default_value first_names,asc } -formats { normal { label "[_ contacts.Table]" @@ -358,7 +400,8 @@ } } -set extend_list "$extend_attr contact_url message_url name orga_info" +#set extend_list "$extend_attr contact_url message_url name orga_info" +set extend_list "contact_url message_url name orga_info" if { ![string equal [lsearch -exact $type_list "employees"] "-1"] } { # We use this multirow since is going to retrive the attribute values @@ -368,24 +411,6 @@ set contact_url [contact::url -party_id $party_id] set message_url [export_vars -base "$contact_url/message" {{message_type "email"}}] set name "[contact::name -party_id $party_id]" - - foreach attribute $attr_val_name { - set attr_id [lindex $attribute 0] - set attr_name [lindex $attribute 1] - set contact_party_revision [contact::live_revision -party_id $party_id] - set $attr_id [ams::value \ - -object_id $contact_party_revision \ - -attribute_id $attr_id \ - -attribute_name "$attr_name"] - - if { ![exists_and_not_null $attr_id] } { - set contact_party_revision [contact::live_revision -party_id $employee_id] - set $attr_id [ams::value \ - -object_id $contact_party_revision \ - -attribute_id $attr_id \ - -attribute_name "$attr_name"] - } - } set display_employers_p [parameter::get \ -parameter DisplayEmployersP \ @@ -418,15 +443,6 @@ set contact_url [contact::url -party_id $party_id] set message_url [export_vars -base "$contact_url/message" {{message_type "email"}}] set name "[contact::name -party_id $party_id]" - foreach attribute $attr_val_name { - set attr_id [lindex $attribute 0] - set attr_name [lindex $attribute 1] - set contact_party_revision [contact::live_revision -party_id $party_id] - set $attr_id [ams::value \ - -object_id $contact_party_revision \ - -attribute_id $attr_id \ - -attribute_name "$attr_name"] - } set display_employers_p [parameter::get \ -parameter DisplayEmployersP \ @@ -462,5 +478,73 @@ } -list::write_output -name contacts +set limit_clause "" +if { $format != "csv" } { + if { $page_size ne "" } { + if { $page eq "" } { set page 1 } + set limit_clause "limit $page_size offset [expr [expr $page - 1 ] * $page_size]" + } +} +set select_query "select party_id from ( [db_map $page_query_name] $limit_clause) party_query" +# extend the multirow +contacts::multirow \ + -extend $extended_columns \ + -multirow contacts \ + -select_query $select_query + + +# create forms to add/remove columns from the multirow +if { [llength $add_columns] > 0 } { + set add_columns [concat [list [list "[_ contacts.--add_column--]" "" ""]] $add_columns] +} +if { [llength $remove_columns] > 0 } { + set remove_columns [concat [list [list "[_ contacts.--remove_column--]" "" ""]] $remove_columns] +} + +set extended_columns_preserved $extended_columns + +ad_form \ + -name "add_column_form" \ + -method "GET" \ + -export {format search_id query page page_size orderby} \ + -has_submit "1" \ + -has_edit "1" \ + -form { + {extended_columns:text(hidden),optional} + {add_column:text(select_with_optgroup) + {label ""} + {html {onChange "document.add_column_form.submit();"}} + {options $add_columns} + } + } \ + -on_request {} \ + -on_submit {} + +ad_form \ + -name "remove_column_form" \ + -method "GET" \ + -export {format search_id query page page_size orderby} \ + -has_submit "1" \ + -has_edit "1" \ + -form { + {extended_columns:text(hidden),optional} + {remove_column:text(select_with_optgroup) + {label ""} + {html {onChange "document.remove_column_form.submit();"}} + {options $remove_columns} + } + } \ + -on_request {} \ + -on_submit {} + + +set extended_columns $extended_columns_preserved +template::element::set_value add_column_form extended_columns $extended_columns +template::element::set_value remove_column_form extended_columns $extended_columns + + + + + +list::write_output -name contacts Index: openacs-4/packages/contacts/lib/contacts.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/contacts.xql,v diff -u -r1.22 -r1.23 --- openacs-4/packages/contacts/lib/contacts.xql 13 Mar 2006 07:21:59 -0000 1.22 +++ openacs-4/packages/contacts/lib/contacts.xql 1 Apr 2006 07:07:16 -0000 1.23 @@ -21,7 +21,7 @@ <fullquery name="organization_pagination"> <querytext> select - organizations.organization_id + organizations.organization_id as party_id from organizations, cr_items ci, cr_revisions cr, group_distinct_member_map where @@ -36,7 +36,7 @@ <fullquery name="person_pagination"> <querytext> select - persons.person_id + persons.person_id as party_id from persons, cr_items ci, cr_revisions cr, group_distinct_member_map where Index: openacs-4/packages/contacts/sql/postgresql/contacts-search-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/sql/postgresql/contacts-search-create.sql,v diff -u -r1.11 -r1.12 --- openacs-4/packages/contacts/sql/postgresql/contacts-search-create.sql 15 Feb 2006 10:06:36 -0000 1.11 +++ openacs-4/packages/contacts/sql/postgresql/contacts-search-create.sql 1 Apr 2006 07:07:16 -0000 1.12 @@ -177,8 +177,5 @@ constraint contact_search_extend_map_extend_id_fk references contact_extend_options (extend_id) on delete cascade, - attribute_id integer - constraint contact_search_extend_map_attribute_id_fk - references acs_attributes (attribute_id) - on delete cascade + extend_column varchar(255) ); Index: openacs-4/packages/contacts/tcl/attribute-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/attribute-procs.tcl,v diff -u -r1.11 -r1.12 --- openacs-4/packages/contacts/tcl/attribute-procs.tcl 26 Dec 2005 20:33:46 -0000 1.11 +++ openacs-4/packages/contacts/tcl/attribute-procs.tcl 1 Apr 2006 07:07:16 -0000 1.12 @@ -1,6 +1,6 @@ ad_library { - Support procs for attributes in the contacts package + Support procs for attributes in the contacts package @author Matthew Geddert openacs@geddert.com @creation-date 2004-07-28 @@ -144,67 +144,12 @@ } else { set mailing_address_list [ams::widget \ -widget postal_address \ - -request "value_list" \ + -request "value_list_text" \ -value $value \ ] - # This sets the address, muncipality,region, postal_code, country_code - template::util::list_of_lists_to_array $mailing_address_list row - - # Now define the locale. This should not be set (usually), as you should always rely on the - # locale of the session, (as the country name should be in the language of the user), - # but who knows. - if {$locale eq ""} { - if { [ad_conn isconnected] } { - # We are in an HTTP connection (request) so use that locale - set locale [ad_conn locale] - } else { - # There is no HTTP connection - resort to system locale - set locale [lang::system::locale] - } - } - - # Set the country right. - set key "ams.country_$row(country_code)" - - if { [string is true [lang::message::message_exists_p $locale $key]] } { - set country [lang::message::lookup $locale $key] - } else { - # cache the country codes - template::util::address::country_options_not_cached -locale $locale - - if { [string is true [lang::message::message_exists_p $locale $key]] } { - set country [lang::message::lookup $locale $key] - } else { - # we get the default en_US key which was created with the - # template::util::address::country_options_not_cached proc - set country [lang::message::lookup "en_US" $key] - } - } - set row(country) $country - - # Set the townline - # Different formats depending on the country - switch $row(country_code) { - "US" { - set row(town_line) "$row(municipality), $row(region) $row(postal_code)" - } - "DE" { - set row(town_line) "$row(postal_code) $row(municipality)" - } - "UK" { - set row(town_line) "$row(municipality), $row(region) $row(postal_code)" - } - "CH" { - set row(town_line) "$row(postal_code) $row(municipality)" - } - default { - if { [parameter::get_from_package_key -package_key "ams" -parameter "DefaultAdressLayoutP" -default 1] } { - set row(town_line) "$row(municipality) $row(region) $row(postal_code)" - } else { - set row(town_line) "$row(postal_code) $row(municipality) $row(region)" - } - } - } + # This sets the address, muncipality, region, postal_code, country_code, country + array set row $mailing_address_list + set row(town_line) [template::util::address::town_line -municipality $row(municipality) -region $row(region) -postal_code $row(postal_code) -country_code $row(country_code)] return 1 } } Index: openacs-4/packages/contacts/tcl/contact-extend-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/contact-extend-procs.tcl,v diff -u -r1.4 -r1.5 --- openacs-4/packages/contacts/tcl/contact-extend-procs.tcl 15 Nov 2005 15:56:46 -0000 1.4 +++ openacs-4/packages/contacts/tcl/contact-extend-procs.tcl 1 Apr 2006 07:07:16 -0000 1.5 @@ -82,4 +82,105 @@ Returns a list of the form { var_name pretty_name subquery description aggregated_p } of the extend_id } { return [db_list_of_lists get_options { }] -} \ No newline at end of file +} + + + + + + + + + + + +namespace eval template::widget {} + +ad_proc -public template::widget::select_with_optgroup { element_reference tag_attributes } { + + upvar $element_reference element + + if { [info exists element(html)] } { + array set attributes $element(html) + } + + array set attributes $tag_attributes + set options_list $element(options) + set widget_name $element(name) + set element_mode $element(mode) + + # edit... + # Create an array for easier testing of selected values + template::util::list_to_lookup $element(values) values + + if { ![string equal $element(mode) "edit"] } { + # this is the same as the menu display. + # we may want to customize it to use the optgroup + # as some sort of heading for certain options + set selected_list [list] + + foreach option $options_list { + + set label [lindex $option 0] + set value [lindex $option 1] + + if { [info exists values($value)] } { + lappend selected_list $label + append output "<input type=\"hidden\" name=\"$widget_name\" value=\"[ad_quotehtml $value]\">" + } + } + + append output [join $selected_list ", "] + } else { + + + append output "<select name=\"$widget_name\" " + foreach name [array names attributes] { + if { [string equal $attributes($name) {}] } { + append output " $name=\"$name\"" + } else { + append output " $name=\"$attributes($name)\"" + } + } + append output ">\n" + + + set optgroup {} + foreach option $options_list { + + set label [lindex $option 0] + set value [lindex $option 1] + set group [string trim [lindex $option 2]] + + + if { $group eq "" } { + if { $optgroup ne "" } { + append output "</optgroup>\n" + } + set optgroup {} + } elseif { $group ne $optgroup } { + if { $optgroup ne "" } { + append output "</optgroup>\n" + } + append output "<optgroup label=\"[ad_quotehtml $group]\">\n" + set optgroup $group + } + + + append output " <option value=\"[template::util::quote_html $value]\"" + if { [info exists values($value)] } { + append output " selected=\"selected\"" + } + append output ">$label</option>\n" + + + } + if { $optgroup ne {} } { + append output "</optgroup>\n" + } + append output "</select>" + } + + return $output +} + Index: openacs-4/packages/contacts/tcl/contact-search-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/contact-search-procs.tcl,v diff -u -r1.23 -r1.24 --- openacs-4/packages/contacts/tcl/contact-search-procs.tcl 12 Mar 2006 17:54:18 -0000 1.23 +++ openacs-4/packages/contacts/tcl/contact-search-procs.tcl 1 Apr 2006 07:07:16 -0000 1.24 @@ -60,6 +60,17 @@ db_1row select_search_info {} -column_array row } +ad_proc -public contact::search::get_extensions { + -search_id:required +} { +} { + return [db_list get_search_exensions { + select extend_column + from contact_search_extend_map + where search_id = :search_id + }] +} + ad_proc -public contact::search::update { {-search_id ""} {-title ""} Index: openacs-4/packages/contacts/tcl/contacts-callback-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/contacts-callback-procs.tcl,v diff -u -r1.30 -r1.31 --- openacs-4/packages/contacts/tcl/contacts-callback-procs.tcl 12 Mar 2006 14:43:03 -0000 1.30 +++ openacs-4/packages/contacts/tcl/contacts-callback-procs.tcl 1 Apr 2006 07:07:16 -0000 1.31 @@ -58,6 +58,21 @@ } { } +ad_proc -public -callback contacts::multirow::extend { + {-type} + {-key} + {-select_query} + {-format "html"} +} { +} - + +ad_proc -public -callback contacts::extensions { + {-multirow} + {-user_id} + {-package_id} +} { +} - + ad_proc -public -callback contact::organization_new { {-package_id:required} {-contact_id:required} @@ -556,3 +571,139 @@ } } + + +ad_proc -public -callback contacts::multirow::extend -impl attributes { + {-type} + {-key} + {-select_query} + {-format "html"} +} { +} { + if { $format ne "text" } { + set format "html" + } + + set object_type $type + + if { [lsearch [list party person organization] $object_type] >= 0 } { + set attribute_name $key + # now we check for a sub_attribute + regexp {^(.*)__(.*)$} $attribute_name match attribute_name sub_attribute_name + + set attribute_id [attribute::id -object_type $object_type -attribute_name $attribute_name] + if { [db_0or1row get_attribute_info { select aa.*, aw.value_method from ams_attributes aa, ams_widgets aw where aa.widget = aw.widget and aa.attribute_id = :attribute_id }] } { + set results [list] + + db_foreach get_ams_values " +select ci.item_id as party_id, ${value_method}(aav.value_id) as value + from ams_attribute_values aav, + cr_items ci + where aav.attribute_id = $attribute_id + and aav.object_id = ci.live_revision + and ci.item_id in ( $select_query ) + " { + + if { [info exists sub_attribute_name] } { + array set sub_attribute_values [ams::widget -widget $widget -request "value_list_${format}" -attribute_name $attribute_name -attribute_id $attribute_id -value $value] + if { [info exists sub_attribute_values($sub_attribute_name)] } { + set value $sub_attribute_values($sub_attribute_name) + lappend results $party_id $value + } else { + set results "" + } + } else { + lappend results $party_id [ams::widget -widget $widget -request "value_${format}" -attribute_name $attribute_name -attribute_id $attribute_id -value $value] + } + + } + + return $results + } + } + return [list] +} + + +ad_proc -public -callback contacts::extensions -impl attributes { + {-multirow} + {-user_id} + {-package_id} +} { +} { + + set list_ids "" + set group_ids [list] + foreach group [contact::groups_list] { + lappend group_ids [lindex $group 0] + } + # since contact::groups_list doesn't get the default_groups + # we have to add them here + set group_ids [concat $group_ids [contacts::default_groups]] + + foreach group_id $group_ids { + if { ![permission::permission_p -object_id $group_id -party_id $user_id -privilege read] } { + continue + } + set list_id [ams::list::get_list_id \ + -package_key "contacts" \ + -object_type "person" \ + -list_name "${package_id}__${group_id}"] + if { $list_id ne "" } { + lappend list_ids $list_id + } + set list_id [ams::list::get_list_id \ + -package_key "contacts" \ + -object_type "organization" \ + -list_name "${package_id}__${group_id}"] + if { $list_id ne "" } { + lappend list_ids $list_id + } + } + + if { [llength $list_ids] == 0 } { + return {} + } + + set attr_list [db_list_of_lists get_all_attributes " +select pretty_name, object_type, attribute_name, widget + from ams_attributes + where attribute_id in ( select attribute_id + from ams_list_attribute_map + where list_id in ([template::util::tcl_to_sql_list $list_ids]) + ) + and not deprecated_p + "] + + set attr_list [ams::util::localize_and_sort_list_of_lists -list $attr_list -position 0] + # now that its sorted by attribute_name, we sort it + # by object_type, lsort leaves the same order + # as the previous sort if the new sort is tied + # so this keeps the attributes ordered alphabetically + # by type + set attr_list [lsort -dictionary -index 1 $attr_list] + + # now we want to first get the sort by + foreach attr $attr_list { + util_unlist $attr pretty_name object_type attribute_name widget + switch $object_type { + party { set type_pretty [_ contacts.Contact] } + person { set type_pretty [_ contacts.Person] } + organization { set type_pretty [_ contacts.Organization] } + } + append type_pretty " [_ contacts.Attributes]" + + set sub_attributes_list [ams::widget -widget $widget -request value_list_headings] + + if { [llength $sub_attributes_list] > 0 } { + foreach {sub_attribute_name sub_pretty_name} $sub_attributes_list { + template::multirow append $multirow attribute $object_type $type_pretty "${attribute_name}__${sub_attribute_name}" "${pretty_name}: ${sub_pretty_name}" + } + } else { + template::multirow append $multirow attribute $object_type $type_pretty $attribute_name $pretty_name + } + + } + +} + Index: openacs-4/packages/contacts/tcl/contacts-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/contacts-procs.tcl,v diff -u -r1.74 -r1.75 --- openacs-4/packages/contacts/tcl/contacts-procs.tcl 15 Mar 2006 23:04:53 -0000 1.74 +++ openacs-4/packages/contacts/tcl/contacts-procs.tcl 1 Apr 2006 07:07:16 -0000 1.75 @@ -106,6 +106,40 @@ } } +ad_proc -public contacts::multirow { + {-extend ""} + {-multirow} + {-select_query} + {-party_id_column "party_id"} +} { + This procedure extends a contacts multirow by the type.key pairs specified as + a list as the extend param. The supplied select query will return a list of + party_ids to the callback proc... this proc is then to use the subselct + in their retrieval of the values requested. A list of lists, i.e. + {{party_id1 value1} {party_id2 value2}} + this procedure then takes that list of lists and matches values with parties + and extends the multirow provided with those values +} { + foreach id $extend { + set ${id}__list "" + regexp {^(.*?)__(.*)$} $id match type key + set results [callback contacts::multirow::extend -type $type -key $key -select_query $select_query] + foreach result $results { + if { $result ne "" } { + array set "${id}__array" $result + } + } + template::multirow extend $multirow $id + } + template::multirow foreach $multirow { + foreach id $extend { + if { [info exists ${id}__array(${party_id})] } { + set $id [set ${id}__array(${party_id})] + } + } + } +} + ad_proc -private contact::util::generate_filename { {-title:required} {-extension:required} Index: openacs-4/packages/contacts/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/index.adp,v diff -u -r1.19 -r1.20 --- openacs-4/packages/contacts/www/index.adp 20 Feb 2006 22:01:03 -0000 1.19 +++ openacs-4/packages/contacts/www/index.adp 1 Apr 2006 07:07:16 -0000 1.20 @@ -14,6 +14,6 @@ base_url="@package_url@" extend_p="@extend_p@" extend_values="@extend_values@" - attr_val_name="@attr_val_name@" + search_id="@search_id@" > -</else> \ No newline at end of file +</else> Index: openacs-4/packages/contacts/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/index.tcl,v diff -u -r1.20 -r1.21 --- openacs-4/packages/contacts/www/index.tcl 20 Feb 2006 22:01:03 -0000 1.20 +++ openacs-4/packages/contacts/www/index.tcl 1 Apr 2006 07:07:16 -0000 1.21 @@ -16,7 +16,7 @@ {aggregate_attribute_id ""} {aggregate_extend_id:multiple ""} {extend_values:optional ""} - {attr_val_name:optional ""} + {extended_columns:optional ""} } if { [exists_and_not_null add_person] } { @@ -27,6 +27,20 @@ ad_script_abort } +set extended_columns [ns_queryget extended_columns] +set add_column [ns_queryget add_column] +set remove_column [ns_queryget remove_column] +if { $extended_columns ne "" && $remove_column ne "" } { + set lindex_id [lsearch -exact $extended_columns $remove_column] + if { $lindex_id >= 0 } { + set extended_columns [lreplace $extended_columns $lindex_id $lindex_id] + } +} +if { $add_column ne "" } { + lappend extended_columns $add_column +} + + set aggregated_p 0 if {[exists_and_not_null aggregate_attribute_id] } { set aggregated_p 1 @@ -83,7 +97,7 @@ } } -ad_form -name "search" -method "GET" -export {orderby page_size format} -form $form_elements \ +ad_form -name "search" -method "GET" -export {orderby page_size format extended_columns} -form $form_elements \ -on_request { } -edit_request { } -on_refresh { Index: openacs-4/packages/contacts/www/search.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/search.adp,v diff -u -r1.11 -r1.12 --- openacs-4/packages/contacts/www/search.adp 20 Feb 2006 22:01:03 -0000 1.11 +++ openacs-4/packages/contacts/www/search.adp 1 Apr 2006 07:07:16 -0000 1.12 @@ -2,35 +2,21 @@ <formtemplate id="advanced_search" style="../../../contacts/resources/forms/inline"></formtemplate> +<if @search_exists_p@> <br /> <br /> -<if @search_exists_p@> - <table> - <tr> - <td> - <formtemplate id="extend_attributes" style="../../../contacts/resources/forms/inline"></formtemplate> - </td> - <if @attribute_values@ not nil> - <td> - <small> - <b>@show_default_names;noquote@</b> @show_names;noquote@ - ( <a href="search?search_id=@search_id@">#contacts.Clear#</a> ) - <table><tr><td> - <form action="@package_url@"> - <input type="hidden" name="attr_val_name" value="@attr_val_name@"> - <input type="hidden" name="search_id" value="@search_id@"> - <input type="submit" value="#contacts.Go#" style="font-size: 8px;"> - </form></td><td> - <form action="save-attribute"> - <input type="hidden" name="attr_val_name" value="@attr_val_name@"> - <input type="hidden" name="search_id" value="@search_id@"> - <input type="submit" value="#contacts.Save#" style="font-size: 8px;"> - </form></td></tr></table> - </small> - </td> - </if> - </tr> - </table> +<if @add_columns@ not nil or @remove_columns@ not nil> +<table cellpadding="0" cellspacing="0" border="0"> + <tr> + <if @add_columns@ not nil> + <td><formtemplate id="add_column_form" style="../../../contacts/resources/forms/inline"></formtemplate></td> + </if> + <if @remove_columns@ not nil> + <td><formtemplate id="remove_column_form" style="../../../contacts/resources/forms/inline"></formtemplate></td> + </if> + </tr> +</table> </if> +</if> Index: openacs-4/packages/contacts/www/search.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/search.tcl,v diff -u -r1.25 -r1.26 --- openacs-4/packages/contacts/www/search.tcl 20 Feb 2006 22:01:03 -0000 1.25 +++ openacs-4/packages/contacts/www/search.tcl 1 Apr 2006 07:07:16 -0000 1.26 @@ -22,20 +22,16 @@ {attribute_values ""} {attribute_option ""} {attribute_names ""} - {attr_val_name ""} + {add_column ""} + {remove_column ""} } -validate { valid_object_type -requires {object_type} { if { [lsearch [list party person organization] $object_type] < 0 } { ad_complain "[_ contacts.You_have_specified_an_invalid_object_type]" } } valid_search_id -requires {search_id} { - db_0or1row condition_exists_p { - select owner_id - from contact_searches - where search_id = :search_id - } - if { [exists_and_not_null owner_id] } { + if { [db_0or1row condition_exists_p {}] } { set valid_owner_ids [list] lappend valid_owner_ids [ad_conn user_id] if { [permission::permission_p -object_id [ad_conn package_id] -privilege "admin"] } { @@ -78,167 +74,99 @@ # set query_pretty [list] if { [exists_and_not_null search_id] } { if { [contact::search::exists_p -search_id $search_id] } { - db_1row get_em { } + db_1row get_search_info { } set search_exists_p 1 } } if { $search_exists_p } { - # Figure out if the search was over a person, organization or both - set search_for [db_string get_search_for { } -default ""] + + template::multirow create ext impl type type_pretty key key_pretty - set search_for_clause "" + # permissions for what attributes/extensions are visible to this + # user are to be handled by this callback proc. The callback + # MUST only return keys that are visible to this user - # Get the var list of the search if type equals group - # so we can retrieve the default attributes of the group - # also. - set var_list [db_string get_var_list { } -default ""] + callback contacts::extensions \ + -user_id [ad_conn user_id] \ + -multirow ext \ + -package_id [ad_conn package_id] - # We get the default attributes of persons, organizations or both and of the group - # if there is a condition for the gorup in the search (when var_list not null) - switch $search_for { - person { - - if { ![empty_string_p $var_list] } { - # Default attributes for the group and persons - set group_id [lindex [split $var_list " "] 1] - set search_for_clause "and (l.list_name like '%__-2' or l.list_name like '%__$group_id') " - } else { - # Default attributes for person only - set search_for_clause "and l.list_name like '%__-2' " - } - append search_for_clause "and object_type = 'person'" - - # We are going to take the default attributes from the parameter - set default_extend_attributes [parameter::get -parameter "DefaultPersonAttributeExtension"] - - } - organization { - - if { ![empty_string_p $var_list] } { - # Default attributes for the group and organizations - set group_id [lindex [split $var_list " "] 1] - set search_for_clause "and (l.list_name like '%__-2' or l.list_name like '%__$group_id') " - } else { - # Default attributes for organization - set search_for_clause "and l.list_name like '%__-2' " - } - append search_for_clause "and object_type = 'organization'" - - # We are going to take the default attributes from the parameter - set default_extend_attributes [parameter::get -parameter "DefaultOrganizationAttributeExtension"] - } - party { - if { ![empty_string_p $var_list] } { - # Default attributes for the group, persons and organizations - set group_id [lindex [split $var_list " "] 1] - set search_for_clause "and (l.list_name like '%__-2' or l.list_name like '%__$group_id') " - } - - # We are going to take the default attributes from the parameter - set default_extend_attributes [parameter::get -parameter "DefaultPersonOrganAttributeExtension"] - } + set add_columns [list] + set remove_columns [list] + set extended_columns [contact::search::get_extensions -search_id $search_id] + if { [lsearch $extended_columns $remove_column] >= 0 && $remove_column ne "" } { + # remove this extension + db_dml delete_column {} + set extended_columns [contact::search::get_extensions -search_id $search_id] } - - set show_default_names "" - set show_names "" - # We add the default attributes, first we take out all spaces - # and then split by ";" - regsub -all " " $default_extend_attributes "" default_extend_attributes - set default_extend_attributes [split $default_extend_attributes ";"] - - # Now we are going to add the mapped attributes in the contact_search_extend_map - set ema_list [db_list get_extend_mapped_attributes { }] - - foreach extend_attribute_id $ema_list { - # We check that the attribute is nor already in the default list - # to avoid duplicates - ams::attribute::get -attribute_id $extend_attribute_id -array ea_info - set attribute_name $ea_info(attribute_name) - - if { [string equal [lsearch $default_extend_attributes $attribute_name] "-1"] } { - lappend default_extend_attributes $attribute_name - } + if { [lsearch $extended_columns $add_column] <= 0 && $add_column ne "" } { + db_dml insert_column {} + lappend extended_columns $add_column } - foreach attr $default_extend_attributes { - # Now we get the attribute_id - set attr_id [attribute::id -object_type "person" -attribute_name "$attr"] - if { [empty_string_p $attr_id] } { - set attr_id [attribute::id -object_type "organization" -attribute_name "$attr"] + # we run through the multirow here to determine wether or not the columns are allowed + template::multirow foreach ext { + set selected_p 0 + if { [lsearch $extended_columns "${type}__${key}"] >= 0 } { + # we want to use this column in our table + lappend remove_columns [list $key_pretty "${type}__${key}" $type_pretty] + } else { + lappend add_columns [list $key_pretty "${type}__${key}" $type_pretty] } - - # We need to check if the attribute is not already present - # in the list, otherwise we could have duplicated. - if { ![empty_string_p $attr_id] } { - lappend attribute_values $attr_id - lappend default_names [attribute::pretty_name -attribute_id $attr_id] - } - - if { [string equal [lsearch -exact $attr_val_name "[list $attr_id $attr]"] "-1"] } { - lappend attr_val_name [list $attr_id $attr] - } + } - # To extend the result list using default attributes - if { [exists_and_not_null default_names] } { - set show_default_names "[join $default_names ", "], " + # create forms to add/remove columns from the multirow + if { [llength $add_columns] > 0 } { + set add_columns [concat [list [list "[_ contacts.--add_column--]" "" ""]] $add_columns] } - - # To extend the reult list using the selected attributes - if { [exists_and_not_null attribute_names] } { - set show_names [join $attribute_names ", "] + if { [llength $remove_columns] > 0 } { + set remove_columns [concat [list [list "[_ contacts.--remove_column--]" "" ""]] $remove_columns] } - - # Now we are going to create the select options - set attribute_values_query "" - if { [exists_and_not_null attribute_values] } { - set attribute_values_query "and lam.attribute_id not in ([template::util::tcl_to_sql_list $attribute_values])" - } - set attribute_options [db_list_of_lists get_ams_options " "] - set ams_options [list [list "- - - - - - - - - -" ""]] - foreach attribute $attribute_options { - set attribute_name [lang::util::localize [db_string get_ams_pretty_name { }]] - lappend ams_options [list $attribute_name $attribute] - } - ad_form -name extend_attributes -has_submit 1 -form { - {attribute_option:text(select),optional - {label "[_ contacts.Extend_result_list_by]:"} - {options { $ams_options }} - {html { onChange "document.extend_attributes.submit();" }} - } - {search_id:text(hidden) - {value "$search_id"} - } - {attribute_values:text(hidden) - {value "$attribute_values"} - } - {attribute_names:text(hidden) - {value "$attribute_names"} - } - {attr_val_name:text(hidden) - {value "$attr_val_name"} - } - } -on_submit { - # We clear the list when no value is submited, otherwise - # we acumulate the extend values. - if { [empty_string_p $attribute_option] } { - set attribute_values [list] - set attribute_names [list] - set attr_val_name [list] - } else { - set attribute $attribute_option - ams::attribute::get -attribute_id $attribute -array attr_info - set name $attr_info(attribute_name) - lappend attribute_names [attribute::pretty_name -attribute_id $attribute] + set extended_columns_preserved $extended_columns + + ad_form \ + -name "add_column_form" \ + -method "GET" \ + -export {format search_id query page page_size orderby} \ + -has_submit "1" \ + -has_edit "1" \ + -form { + {extended_columns:text(hidden),optional} + {add_column:text(select_with_optgroup) + {label ""} + {html {onChange "document.add_column_form.submit();"}} + {options $add_columns} + } + } \ + -on_request {} \ + -on_submit {} + + ad_form \ + -name "remove_column_form" \ + -method "GET" \ + -export {format search_id query page page_size orderby} \ + -has_submit "1" \ + -has_edit "1" \ + -form { + {extended_columns:text(hidden),optional} + {remove_column:text(select_with_optgroup) + {label ""} + {html {onChange "document.remove_column_form.submit();"}} + {options $remove_columns} + } + } \ + -on_request {} \ + -on_submit {} + - lappend attribute_values $attribute - lappend attr_val_name [list $attribute $name] - } - ad_returnredirect [export_vars -base "search" {search_id attribute_values attribute_names attr_val_name}] - } + set extended_columns $extended_columns_preserved + template::element::set_value add_column_form extended_columns $extended_columns + template::element::set_value remove_column_form extended_columns $extended_columns + } @@ -277,9 +205,7 @@ if { $search_exists_p } { set conditions [list] - db_foreach selectqueries { - select condition_id, type as query_type, var_list as query_var_list from contact_search_conditions where search_id = :search_id - } { + db_foreach selectqueries {} { set condition_name [contacts::search::condition_type -type $query_type -request pretty -var_list $query_var_list] if { [empty_string_p $condition_name] } { set condition_name "[_ contacts.Employees]" Index: openacs-4/packages/contacts/www/search.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/search.xql,v diff -u -r1.5 -r1.6 --- openacs-4/packages/contacts/www/search.xql 23 Nov 2005 17:29:47 -0000 1.5 +++ openacs-4/packages/contacts/www/search.xql 1 Apr 2006 07:07:16 -0000 1.6 @@ -1,6 +1,31 @@ <?xml version="1.0"?> <queryset> +<fullquery name="condition_exists_p"> + <querytext> + select owner_id + from contact_searches + where search_id = :search_id + </querytext> +</fullquery> + +<fullquery name="delete_column"> + <querytext> + delete from contact_search_extend_map + where search_id = :search_id + and extend_column = :remove_column + </querytext> +</fullquery> + +<fullquery name="insert_column"> + <querytext> + insert into contact_search_extend_map + ( search_id, extend_column ) + values + ( :search_id , :add_column ) + </querytext> +</fullquery> + <fullquery name="contacts_pagination"> <querytext> select gmm.member_id as party_id @@ -147,7 +172,7 @@ </querytext> </fullquery> -<fullquery name="get_em"> +<fullquery name="get_search_info"> <querytext> select title, @@ -161,5 +186,13 @@ </querytext> </fullquery> +<fullquery name="selectqueries"> + <querytext> + select condition_id, type as query_type, var_list as query_var_list + from contact_search_conditions + where search_id = :search_id + </querytext> +</fullquery> + </queryset>