Index: openacs-4/packages/contacts/contacts.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/contacts.info,v diff -u -r1.77 -r1.78 --- openacs-4/packages/contacts/contacts.info 5 Jun 2006 08:13:27 -0000 1.77 +++ openacs-4/packages/contacts/contacts.info 26 Jun 2006 06:36:50 -0000 1.78 @@ -7,14 +7,14 @@ f f - + Matthew Geddert This application lets you collaboratively view, edit and categorize contacts. - 2006-06-05 + 2006-06-25 Contacts is an application for managing all those people and or organization you need to keep track of. It has a complete UI for storing and categorizing contacts. Each contact can have an arbitrary number of custom attributes associated with it, including other contacts (i.e. a certain contact "belongs" to a certain organization). It also functions as a service contract provider for attributes related to users in your system 0 - + Index: openacs-4/packages/contacts/catalog/contacts.en_US.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/catalog/contacts.en_US.ISO-8859-1.xml,v diff -u -r1.85 -r1.86 --- openacs-4/packages/contacts/catalog/contacts.en_US.ISO-8859-1.xml 6 Jun 2006 19:47:04 -0000 1.85 +++ openacs-4/packages/contacts/catalog/contacts.en_US.ISO-8859-1.xml 26 Jun 2006 06:36:51 -0000 1.86 @@ -1,5 +1,5 @@ - + -- select a group -- -- add column -- @@ -24,10 +24,13 @@ Add Email Message Add Group Add Letter Message + Add List Add Message Add New Add new %object_type% selected groups + Add new owner Add Organization + Add Owner Add Person Add Relationship Amount of relationships to be deleted @@ -41,6 +44,8 @@ Add to Group Add to group Add to Groups + Add to List + Add to Lists Add User Address Admin @@ -63,7 +68,9 @@ Archive Archive the checked contacts Archived + Are you sure? Are you sure you want to delete this contact? + Are you sure you want to delete this list? area code is -> area code is not -> Type of Relationship @@ -85,6 +92,8 @@ Cancel and return CC Send copy to multiple addresses separated by ";" + Change + Change Sharing Changed Date: Changes Check/Uncheck @@ -138,6 +147,7 @@ Create role Create User Creating Club + Creator CSV Current Customer: @@ -216,6 +226,7 @@ Searches in the search include name and mailing address for use with windowed envelopes + Insufficient permission to edit sharing Invalid Invalid Object Type irrelevant @@ -241,6 +252,10 @@ Letter Letterhead Limit Contacts to + List + A list already exists with this name + Lists + lists -- Groups -------------------------- -- My Searches --------------------- -- no not include a signature -- @@ -254,6 +269,7 @@ Add relationship to these people Add relationship type Add to Selected Group(s) + Add to Selected Lists Advanced searches are very powerful but in return they require very specific input... Aggregated reports require at least one added column All searches are case insensitive, capitalization does not matter. If more than one contact match the search a list of results is returned. If only one contact meets the search criteria you are redirected to that contact. @@ -276,6 +292,7 @@ %attribute_pretty% is set %attribute_pretty% is: <strong>%option_pretty%</strong> %attribute_pretty% is: <strong>%value%</strong> + %attribute_pretty% less than %interval% ago %attribute_pretty% is less than <strong>%interval%</strong> ago %attribute_pretty% state/province is: <strong>%value%</strong> %attribute_pretty% state/province is not: <strong>%value%</strong> @@ -365,7 +382,9 @@ Person or Organization %pretty_plural_list_name% found in search, please try again or add a new contact remember that you can use mail merge substitutions. The most common wildcards are {name} {first_names}, {last_name}, {salutation}, {mailing_address}, {directphone} and {date} + Remove from List Remove from Selected Group(s) + Remove from selected lists Remove from this Group Remove all other relationships of this type for these contacts Remove all other relationships of this type for the related contact @@ -382,8 +401,10 @@ state/province is not -> The object type %contact_link% was added the action supplied is not valid + Contact in the list <strong>%title%</strong> The contact is in the group: <strong>%group_pretty%</strong> The contact is NOT in the group: <strong>%group_pretty%</strong> + Contact is NOT in the list <strong>%title%</strong> The contact specified does not exist The contact specified is not one of the contacts in this relationship The contacts were merged and the other one was deleted. @@ -457,6 +478,8 @@ Make Public Make the checked contacts current Manage Group Categories + Members + Merge Contacts Merge with Message Message is required @@ -473,6 +496,7 @@ Name is required New Next + No Lists (none) Normal Searches Not Configured @@ -501,6 +525,8 @@ Other Options Output Owner + Owners + Owners Only Paid: Paper Type Parent Group @@ -528,6 +554,7 @@ Print Print Letter Privacy Settings + Private Processes PROJECT Project: @@ -555,13 +582,16 @@ relationships Remove Default Remove extended options set as default for search_id #%search_id% - Remove From Group + Remove from Group Remove from Group + Remove from List + Remove from Lists Remove from Group Required Results Return to history Return to %title% + Return to where you were Role Role for these contacts Role Name @@ -597,7 +627,9 @@ Set Default Set default Settings + Shared Shared Searches + Sharing Show Showing Signature @@ -628,6 +660,7 @@ The search "%title%" was made public The selected relationship requires that the related contact be an organization The selected relationship requires that the related contact be a person + There must be at least one owner This contact doesn't have an email, you are going to use it's employer email (%emp_addr%) This organization has closed down This person is deceased @@ -665,6 +698,8 @@ Working Project Tasks years You can extend this search by: + You cannot remove the list creator unless you are an administrator + You do not own any lists. You must first create a list to use this feature. Your message was sent to: <strong>%recipients%</strong> your signatures Yourself Index: openacs-4/packages/contacts/lib/contacts.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/contacts.tcl,v diff -u -r1.67 -r1.68 --- openacs-4/packages/contacts/lib/contacts.tcl 12 Jun 2006 07:53:26 -0000 1.67 +++ openacs-4/packages/contacts/lib/contacts.tcl 26 Jun 2006 06:36:51 -0000 1.68 @@ -139,6 +139,8 @@ template::multirow create bulk_acts pretty link detailed template::multirow append bulk_acts "[_ contacts.Add_to_Group]" "${base_url}group-parties-add" "[_ contacts.Add_to_group]" template::multirow append bulk_acts "[_ contacts.Remove_From_Group]" "${base_url}group-parties-remove" "[_ contacts.lt_Remove_from_this_Grou]" +template::multirow append bulk_acts "[_ contacts.Add_to_List]" "${base_url}list-parties-add" "[_ contacts.Add_to_List]" +template::multirow append bulk_acts "[_ contacts.Remove_from_List]" "${base_url}list-parties-remove" "[_ contacts.Remove_from_List]" template::multirow append bulk_acts "[_ contacts.Add_Relationship]" "${base_url}relationship-bulk-add" "[_ contacts.lt_Add_relationship_to_sel]" template::multirow append bulk_acts "[_ contacts.Mail_Merge]" "${base_url}message" "[_ contacts.lt_E-mail_or_Mail_the_se]" if { [permission::permission_p -object_id $package_id -privilege "admin"] } { Index: openacs-4/packages/contacts/lib/list-parties-add.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/list-parties-add.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/list-parties-add.adp 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,5 @@ + +@title@ + + + Index: openacs-4/packages/contacts/lib/list-parties-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/list-parties-add.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/list-parties-add.tcl 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,97 @@ +ad_page_contract { + List and manage contacts. + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-07-28 + @cvs-id $Id: list-parties-add.tcl,v 1.1 2006/06/26 06:36:51 matthewg Exp $ +} { + {party_id:integer,multiple,optional} + {party_ids:optional} + {return_url "./"} + {list_id:integer ""} +} -validate { + valid_party_submission { + if { ![exists_and_not_null party_id] && ![exists_and_not_null party_ids] } { + ad_complain "[_ contacts.lt_Your_need_to_provide_]" + } + } + valid_list_id -requires {list_id} { + if { ![contact::owner_p -object_id $list_id -owner_id [ad_conn user_id]] } { + ad_complain "[_ contacts.You_do_not_own_this_list]" + } + } +} + +if { [exists_and_not_null party_id] } { + set party_ids [list] + foreach party_id $party_id { + lappend party_ids $party_id + } +} +foreach id $party_ids { + contact::require_visiblity -party_id $id +} + +if { [llength $party_ids] eq 1 && $list_id ne "" } { + # this is a request to add one party to one + # list + contact::list::member_add -list_id $list_id -party_id [lindex $party_ids 0] + contact::search::flush_results_counts + ad_returnredirect $return_url + ad_script_abort +} + + +set title "[_ contacts.Add_to_List]" +set user_id [ad_conn user_id] +set peeraddr [ad_conn peeraddr] +set context [list $title] +set package_id [ad_conn package_id] +set recipients [list] +foreach party_id $party_ids { + lappend recipients "[contact::name -party_id $party_id]" +} +set recipients [join $recipients ", "] + +set form_elements { + party_ids:text(hidden) + return_url:text(hidden) + {recipients:text(inform),optional {label "[_ contacts.Contacts]"}} +} + +set list_options [db_list_of_lists get_lists { select ao.title, cl.list_id from contact_lists cl, acs_objects ao where cl.list_id = ao.object_id and cl.list_id in ( select object_id from contact_owners where owner_id in ( :user_id, :package_id )) }] + +if { [llength $list_options] == "0" } { + ad_return_error "[_ contacts.No_Lists]" "[_ contacts.You_do_not_own_any_lists]" +} + +append form_elements { + {list_ids:text(checkbox),multiple {label "[_ contacts.Add_to_Lists]"} {options $list_options}} +} +set edit_buttons [list [list "[_ contacts.lt_Add_to_Selected_Lists]" create]] + + + + +ad_form -name add_to_list \ + -cancel_label "[_ contacts.Cancel]" \ + -cancel_url $return_url \ + -edit_buttons $edit_buttons \ + -form $form_elements \ + -on_request { + } -on_submit { + db_transaction { + foreach list_id $list_ids { + foreach party_id $party_ids { + contact::list::member_add -list_id $list_id -party_id $party_id + } + } + } + } -after_submit { + contact::search::flush_results_counts + ad_returnredirect $return_url + ad_script_abort + } + + + Index: openacs-4/packages/contacts/lib/list-parties-remove.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/list-parties-remove.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/list-parties-remove.adp 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,5 @@ + +@title@ + + + Index: openacs-4/packages/contacts/lib/list-parties-remove.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/list-parties-remove.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/list-parties-remove.tcl 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,97 @@ +ad_page_contract { + List and manage contacts. + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-07-28 + @cvs-id $Id: list-parties-remove.tcl,v 1.1 2006/06/26 06:36:51 matthewg Exp $ +} { + {party_id:integer,multiple,optional} + {party_ids:optional} + {return_url "./"} + {list_id:integer ""} +} -validate { + valid_party_submission { + if { ![exists_and_not_null party_id] && ![exists_and_not_null party_ids] } { + ad_complain "[_ contacts.lt_Your_need_to_provide_]" + } + } + valid_list_id -requires {list_id} { + if { ![contact::owner_p -object_id $list_id -owner_id [ad_conn user_id]] } { + ad_complain "[_ contacts.You_do_not_own_this_list]" + } + } +} + +if { [exists_and_not_null party_id] } { + set party_ids [list] + foreach party_id $party_id { + lappend party_ids $party_id + } +} +foreach id $party_ids { + contact::require_visiblity -party_id $id +} + +if { [llength $party_ids] eq 1 && $list_id ne "" } { + # this is a request to add one party to one + # list + contact::list::member_delete -list_id $list_id -party_id [lindex $party_ids 0] + contact::search::flush_results_counts + ad_returnredirect $return_url + ad_script_abort +} + + +set title "[_ contacts.Remove_from_List]" +set user_id [ad_conn user_id] +set peeraddr [ad_conn peeraddr] +set context [list $title] +set package_id [ad_conn package_id] +set recipients [list] +foreach party_id $party_ids { + lappend recipients "[contact::name -party_id $party_id]" +} +set recipients [join $recipients ", "] + +set form_elements { + party_ids:text(hidden) + return_url:text(hidden) + {recipients:text(inform),optional {label "[_ contacts.Contacts]"}} +} + +set list_options [db_list_of_lists get_lists { select ao.title, cl.list_id from contact_lists cl, acs_objects ao where cl.list_id = ao.object_id and cl.list_id in ( select object_id from contact_owners where owner_id in ( :user_id, :package_id )) }] + +if { [llength $list_options] == "0" } { + ad_return_error "[_ contacts.No_Lists]" "[_ contacts.You_do_not_own_any_lists]" +} + +append form_elements { + {list_ids:text(checkbox),multiple {label "[_ contacts.Remove_from_Lists]"} {options $list_options}} +} +set edit_buttons [list [list "[_ contacts.lt_Remove_from_selected_Lists]" create]] + + + + +ad_form -name remove_from_list \ + -cancel_label "[_ contacts.Cancel]" \ + -cancel_url $return_url \ + -edit_buttons $edit_buttons \ + -form $form_elements \ + -on_request { + } -on_submit { + db_transaction { + foreach list_id $list_ids { + foreach party_id $party_ids { + contact::list::member_delete -list_id $list_id -party_id $party_id + } + } + } + } -after_submit { + contact::search::flush_results_counts + ad_returnredirect $return_url + ad_script_abort + } + + + Index: openacs-4/packages/contacts/lib/lists-include.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/lists-include.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/lists-include.adp 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,16 @@ + + +

#contacts.Lists#

+ + +
+ + + Index: openacs-4/packages/contacts/lib/lists-include.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/lists-include.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/lists-include.tcl 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,70 @@ +# @author Matthew Geddert openacs@geddert.com +# @creation-date 2005-07-09 +# @cvs-id $Id: lists-include.tcl,v 1.1 2006/06/26 06:36:51 matthewg Exp $ + +if { [string is false [contact::exists_p -party_id $party_id]] } { + error "[_ contacts.lt_The_party_id_specifie]" +} + +set user_id [ad_conn user_id] +set package_id [ad_conn package_id] +set package_url [ad_conn package_url] + +set return_url "[ad_conn url]?[ad_conn query]" + +set list_add_options [db_list_of_lists getem { + select ao.title, cl.list_id + from contact_lists cl, + acs_objects ao + where cl.list_id = ao.object_id + and cl.list_id not in ( select list_id from contact_list_members where party_id = :party_id ) + and cl.list_id in ( select object_id from contact_owners where owner_id = :user_id ) + order by upper(ao.title), cl.list_id +}] + + + +if { [llength $list_add_options] > 0 } { + set form_p 1 + set list_add_options [concat [list [list "--[_ contacts.Add_to_List]--" ""]] $list_add_options] + ad_form \ + -action ${package_url}list-parties-add \ + -name "add_list_member" \ + -method "GET" \ + -has_submit "1" \ + -export {return_url party_id} \ + -form { + {list_id:integer(select) {label ""} {options $list_add_options} {html {onChange "submit()"}}} + } -validate { + } -on_submit { + #set title [string trim $title] + #set list_id [contact::list::new -title $title] + #contact::owner_add -object_id $list_id -owner_id [ad_conn user_id] + } -after_submit { + #ad_returnredirect [ad_conn url] + #ad_script_abort + } + + +} else { + set form_p 0 +} + + +db_multirow -extend {owner_p list_url delete_url} lists get_contact_lists { + select ao.title, + cl.list_id + from contact_lists cl, + acs_objects ao, + contact_list_members clm + where cl.list_id = ao.object_id + and cl.list_id = clm.list_id + and clm.party_id = :party_id + and cl.list_id in ( select object_id from contact_owners where owner_id in ( :user_id, :package_id )) + order by upper(ao.title), cl.list_id + +} { + set owner_p [contact::owner_p -object_id $list_id -owner_id $user_id] + set list_url [export_vars -base $package_url -url {{search_id $list_id}}] + set delete_url [export_vars -base ${package_url}list-parties-remove {list_id return_url party_id}] +} Index: openacs-4/packages/contacts/lib/lists.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/lists.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/lists.adp 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,15 @@ + + + + + +

#contacts.Are_you_sure_you_want_to_delete_list#

+

#acs-kernel.common_Yes# - #acs-kernel.common_no#

+
+ + +

+
+ + +
Index: openacs-4/packages/contacts/lib/lists.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/lists.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/lists.tcl 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,110 @@ +ad_page_contract { + List and manage contacts. + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-07-28 + @cvs-id $Id: lists.tcl,v 1.1 2006/06/26 06:36:51 matthewg Exp $ +} { + {delete_list_id:integer ""} + {confirm_p:boolean "0"} +} -validate { + valid_set_public_p -requires {delete_list_id} { + if { [db_string get_creator { select creation_user from acs_objects where object_id = :delete_list_id }] ne [ad_conn user_id] || ![contact::owner_p -object_id $delete_list_id -owner_id [ad_conn user_id]] } { + if { ![permission::permission_p -object_id [ad_conn package_id] -privilege "admin"] } { + ad_complain "[_ contacts.You_can_only_delete_list_you_created_and_own]" + } + } + } +} + + + +set package_id [ad_conn package_id] +set package_url [ad_conn package_url] +set user_id [ad_conn user_id] +set admin_p [permission::permission_p -object_id $package_id -privilege "admin"] +set url [ad_conn url] + +if { $delete_list_id ne "" } { + if { [string is true $confirm_p] } { + contact::owner_delete_all -object_id $delete_list_id + contact::list::delete -list_id $delete_list_id + ad_returnredirect [ad_conn url] + ad_script_abort + } else { + set no_url [export_vars -base $url] + set yes_url [export_vars -base $url -url {delete_list_id {confirm_p 1}}] + } +} + + + + +ad_form \ + -name "add_list" \ + -method "POST" \ + -form { + {title:text(text) {label ""} {html {size 30 maxlength 255}}} + {add:text(submit) {label "[_ contacts.Add_List]"}} + } -validate { + {title + { ![expr { [string trim $title] eq "" }] } + {[_ contacts.Required]} + } + {title + { ![db_0or1row list_already_exists " select 1 from contact_lists, acs_objects, contact_owners where contact_lists.list_id = acs_objects.object_id and acs_objects.object_id = contact_owners.object_id and acs_objects.package_id = :package_id and contact_owners.owner_id in (:user_id,:package_id) and acs_objects.title = '[db_quote [string trim $title]]' limit 1 "] } + {[_ contacts.List_already_exists_with_this_name]} + } + } -on_submit { + set title [string trim $title] + set list_id [contact::list::new -title $title] + contact::owner_add -object_id $list_id -owner_id [ad_conn user_id] + } -after_submit { + ad_returnredirect [ad_conn url] + ad_script_abort + } + + + +template::list::create \ + -name "lists" \ + -row_pretty_plural "[_ contacts.lists]" \ + -elements { + title { + label {[_ contacts.List]} + link_url_eval $list_url + } + sharing { + label {[_ contacts.Sharing]} + link_url_eval $sharing_url + } + members { + label {[_ contacts.Members]} + } + action { + label "" + display_template { + + } + } + } + + + +db_multirow -extend {list_url delete_url sharing sharing_url} -unclobber lists select_lists {} { + if { $members eq "" } { set members "0" } + set list_url [export_vars -base ${package_url} -url {{search_id ${list_id}}}] + set delete_url [export_vars -base "lists" -url {{delete_list_id $list_id}}] + set sharing_url [export_vars -base "sharing" -url {{object_id $list_id} {return_url $url}}] + + if { [contact::owner_p -object_id $list_id -owner_id $package_id] } { + set sharing "[_ contacts.Public]" + } else { + set count [contact::owner_count -object_id $list_id] + if { $count > 1 } { + set sharing "[_ contacts.Shared]" + } else { + set sharing "[_ contacts.Private]" + } + } +} Index: openacs-4/packages/contacts/lib/lists.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/lists.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/lists.xql 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,16 @@ + + + + + + select contact_lists.list_id, title, members.members + from contact_lists left join ( select count(1) as members, list_id from contact_list_members group by list_id ) members on ( contact_lists.list_id = members.list_id), + acs_objects + where contact_lists.list_id = acs_objects.object_id + and acs_objects.package_id = :package_id + and contact_lists.list_id in ( select object_id from contact_owners where owner_id = :user_id or owner_id = :package_id ) + order by upper(title), contact_lists.list_id + + + + Index: openacs-4/packages/contacts/lib/sharing.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/sharing.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/sharing.adp 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,20 @@ + +@title@: #contacts.Sharing# + +

#contacts.Return_to_where_you_were#

+ + + +

#contacts.Sharing#: #contacts.Public##contacts.Owners_Only#

+ + + + +

#contacts.Owners#

+ + + +

+ Index: openacs-4/packages/contacts/lib/sharing.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/sharing.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/lib/sharing.tcl 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,130 @@ +ad_page_contract { + List and manage contacts. + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-07-28 + @cvs-id $Id: sharing.tcl,v 1.1 2006/06/26 06:36:51 matthewg Exp $ +} { + object_id:integer,notnull + return_url:notnull + {remove_owner_id ""} + {set_public_p ""} +} -validate { + valid_object_and_ownership -requires {object_id} { + # currently sharing is limited to contact_lists + # in the future somebody might want to change this + # to include things like contact_searches and other + # object_types. Those should be added here. + if { [lsearch [list contact_list] [acs_object_type $object_id]] < 0 } { + ad_complain "[_ contacts.Insufficient_permission_to_edit_sharing]" + } elseif { [db_string get_package_id { select package_id from acs_objects where object_id = :object_id } -default {}] ne [ad_conn package_id] } { + ad_complain "[_ contacts.Insufficient_permission_to_edit_sharing]" + } elseif { ![contact::owner_p -object_id $object_id -owner_id [ad_conn user_id]] } { + # the are not an explicit owner, but if this is public and they are an + # admin they are okay. + if { ![contact::owner_p -object_id $object_id -owner_id [ad_conn package_id]] || ![permission::permission_p -object_id [ad_conn package_id] -privilege "admin"] } { + ad_complain "[_ contacts.Insufficient_permission_to_edit_sharing]" + } + } + } + valid_remove_owner_id -requires {remove_owner_id} { + if { ![permission::permission_p -object_id [ad_conn package_id] -privilege "admin"] && [db_string getcreator { select creation_user from acs_objects where object_id = :object_id }] eq $remove_owner_id } { + ad_complain "[_ contacts.You_cannot_remove_creator_unless]" + } + if { [db_string getit { select count(1) from contact_owners where object_id = :object_id and owner_id in ( select party_id from parties ) }] eq "1" } { + ad_complain "[_ contacts.There_must_be_at_least_one_owner]" + } + } + valid_set_public_p -requires {set_public_p} { + if { $set_public_p ne "" && ![permission::permission_p -object_id [ad_conn package_id] -privilege "admin"] } { + ad_complain "[_ contacts.Only_admins_can_edit_public_settings]" + } + } +} + + +set package_id [ad_conn package_id] +set package_url [ad_conn package_url] +set user_id [ad_conn user_id] +set admin_p [permission::permission_p -object_id $package_id -privilege "admin"] +set url [ad_conn url] + +if { $remove_owner_id ne "" } { + contact::owner_delete -object_id $object_id -owner_id $remove_owner_id + ad_returnredirect [export_vars -base $url -url {object_id return_url}] + ad_script_abort +} + +if { $set_public_p ne "" } { + if { [string is true $set_public_p] } { + contact::owner_add -object_id $object_id -owner_id [ad_conn package_id] + } elseif { [string is false $set_public_p] } { + contact::owner_delete -object_id $object_id -owner_id [ad_conn package_id] + } + ad_returnredirect [export_vars -base $url -url {object_id return_url}] + ad_script_abort + +} + +set public_p [contact::owner_p -object_id $object_id -owner_id [ad_conn package_id]] +if { [string is true $public_p] } { + set public_url [export_vars -base $url -url {object_id return_url {set_public_p 0}}] +} else { + set public_url [export_vars -base $url -url {object_id return_url {set_public_p 1}}] +} + +db_1row get_title_and_creator { select * from acs_objects where object_id = :object_id } + + +ad_form \ + -name "add_owner" \ + -method "POST" \ + -export {object_id return_url} \ + -form { + {user_id:contact_search(contact_search) {label "[_ contacts.Add_new_owner]"} {search persons}} + } -validate { + } -on_submit { + contact::owner_add -object_id $object_id -owner_id $user_id + } -after_submit { + ad_returnredirect [export_vars -base [ad_conn url] -url {object_id return_url}] + ad_script_abort + } + +set user_id [ad_conn user_id] + +template::list::create \ + -name "owners" \ + -row_pretty_plural "[_ contacts.owners]" \ + -elements { + name { + label {} + link_url_eval $contact_url + } + email { + label {} + link_url_eval ${contact_url}message + } + action { + label "" + display_template { + + } + } + } + + + +db_multirow -extend {contact_url delete_url name} -unclobber owners select_owners { + + select contact_owners.owner_id, + parties.email + from contact_owners, persons, parties + where contact_owners.owner_id = persons.person_id + and contact_owners.owner_id = parties.party_id + and contact_owners.object_id = :object_id + order by upper(persons.first_names), upper(persons.last_name) +} { + set name [contact::name -party_id $owner_id] + set contact_url [contact::url -party_id $owner_id] + set delete_url [export_vars -base $url -url {object_id return_url {remove_owner_id $owner_id}}] +} Index: openacs-4/packages/contacts/sql/postgresql/contacts-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/sql/postgresql/contacts-create.sql,v diff -u -r1.13 -r1.14 --- openacs-4/packages/contacts/sql/postgresql/contacts-create.sql 2 Jun 2006 09:18:30 -0000 1.13 +++ openacs-4/packages/contacts/sql/postgresql/contacts-create.sql 26 Jun 2006 06:36:51 -0000 1.14 @@ -183,5 +183,6 @@ \i contacts-package-create.sql \i contacts-search-create.sql \i contacts-messages-create.sql +\i contacts-list-create.sql Index: openacs-4/packages/contacts/sql/postgresql/contacts-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/sql/postgresql/contacts-drop.sql,v diff -u -r1.9 -r1.10 --- openacs-4/packages/contacts/sql/postgresql/contacts-drop.sql 2 Jun 2006 09:18:30 -0000 1.9 +++ openacs-4/packages/contacts/sql/postgresql/contacts-drop.sql 26 Jun 2006 06:36:51 -0000 1.10 @@ -6,6 +6,11 @@ -- -- +drop view contact_owners; +drop table contact_owner_rels; +drop table contact_list_members; +drop table contact_lists; + drop table contact_privacy; drop table contact_message_log; drop table contact_message_items; @@ -18,6 +23,7 @@ select drop_package('contact_search'); select acs_object__delete(search_id) from contact_searches; select acs_object_type__drop_type('contact_search','t'); +select acs_object_type__drop_type ('contact_list','t'); drop view contact_rel_types; drop table contact_signatures; @@ -28,6 +34,7 @@ select content_type__drop_type ('contact_party_revision','t','t'); --drop table contact_party_revisions; +select acs_rel_type__drop_type('contact_owner','t'); select acs_rel_type__drop_type('organization_rel','t'); select acs_rel_type__drop_type(object_type,'t') from acs_object_types where supertype = 'contact_rel'; select acs_rel_type__drop_type('contact_rel','t'); @@ -36,5 +43,7 @@ select drop_package('contact'); select drop_package('contact_rel'); select drop_package('contact_party_revision'); +select drop_package('contact_list'); +select drop_package('contact_owner'); drop sequence contact_extend_search_seq; Index: openacs-4/packages/contacts/sql/postgresql/contacts-list-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/sql/postgresql/contacts-list-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/sql/postgresql/contacts-list-create.sql 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,176 @@ +-- contacts-lists-create.sql +-- +-- @author Matthew Geddert openacs@geddert.com +-- @creation-date 2006-06-25 +-- @cvs-id $Id: contacts-list-create.sql,v 1.1 2006/06/26 06:36:51 matthewg Exp $ +-- +-- + +create table contact_lists ( + list_id integer primary key + constraint contact_lists_list_id_fk references acs_objects(object_id) on delete cascade +); + +-- a list can have many owners to allow collaboration + +create table contact_list_members ( + list_id integer not null + constraint contact_list_members_list_id_fk references contact_lists(list_id) on delete cascade, + party_id integer not null + constraint contact_list_members_party_id_fk references parties(party_id) on delete cascade, + unique(list_id,party_id) +); + + +select acs_object_type__create_type ( + 'contact_list', -- content_type + 'Contact List', -- pretty_name + 'Contact Lists', -- pretty_plural + 'acs_object', -- supertype + 'contact_lists', -- table_name + 'list_id', -- id_column + 'contact_list', -- package_name + 'f', -- abstract_p + NULL, -- type_extension_table + NULL -- name_method +); + + + +select define_function_args('contact_list__new','list_id,title,package_id,creation_date;now(),creation_user,creation_ip,context_id'); + +create or replace function contact_list__new (integer,varchar,integer,timestamptz,integer,varchar,integer) +returns integer as ' +declare + p_list_id alias for $1; + p_title alias for $2; + p_package_id alias for $3; + p_creation_date alias for $4; + p_creation_user alias for $5; + p_creation_ip alias for $6; + p_context_id alias for $7; + v_list_id integer; +begin + + v_list_id := acs_object__new( + p_list_id, + ''contact_list'', + p_creation_date, + p_creation_user, + p_creation_ip, + coalesce(p_context_id, p_package_id), + ''t'', + p_title, + p_package_id + ); + + update acs_objects set title = p_title where object_id = v_list_id; + + insert into contact_lists + (list_id) + values + (v_list_id); + + return v_list_id; +end;' language 'plpgsql'; + +select define_function_args('contact_list__delete','list_id'); + +create or replace function contact_list__delete (integer) +returns integer as ' +declare + p_list_id alias for $1; +begin + + delete from contact_list_members where list_id = p_list_id; + delete from contact_lists where list_id = p_list_id; + perform acs_object__delete(p_list_id); + + return ''0''; +end;' language 'plpgsql'; + + + + + + +create table contact_owner_rels ( + rel_id integer primary key + constraint contact_owner_rels_rel_id_fk references acs_rels(rel_id) on delete cascade +); + +create view contact_owners as + select object_id_one as object_id, + object_id_two as owner_id + from acs_rels, + contact_owner_rels + where acs_rels.rel_id = contact_owner_rels.rel_id; + + +select acs_rel_type__create_type ( + 'contact_owner', + 'Contact Object Owner', + 'Contact Object Owner', + 'relationship', + 'contact_owner_rels', + 'rel_id', + 'contact_owner', + 'acs_object', + null, + 0, + null, + 'acs_object', + null, + 0, + null + ); + +select define_function_args('contact_owner__new','rel_id,rel_type;contact_owner,object_id_one,object_id_two,creation_user,creation_ip'); + +create function contact_owner__new(integer,varchar,integer,integer,integer,varchar) +returns integer as ' +DECLARE + p_rel_id alias for $1; + p_rel_type alias for $2; + p_object_id_one alias for $3; + p_object_id_two alias for $4; + p_creation_user alias for $5; + p_creation_ip alias for $6; + v_rel_id integer; +BEGIN + v_rel_id:= acs_rel__new( + p_rel_id, + p_rel_type, + p_object_id_one, + p_object_id_two, + null, + p_creation_user, + p_creation_ip + ); + + insert + into contact_owner_rels + (rel_id) + values + (v_rel_id); + + return v_rel_id; +END; +' language 'plpgsql'; + + +select define_function_args('contact_owner__delete','rel_id'); + +create or replace function contact_owner__delete (integer) +returns integer as ' +DECLARE + p_rel_id alias for $1; +BEGIN + + PERFORM acs_object__delete(p_rel_id); + + return 0; +END; +' language 'plpgsql'; + + 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.12 -r1.13 --- openacs-4/packages/contacts/sql/postgresql/contacts-search-create.sql 1 Apr 2006 07:07:16 -0000 1.12 +++ openacs-4/packages/contacts/sql/postgresql/contacts-search-create.sql 26 Jun 2006 06:36:51 -0000 1.13 @@ -10,7 +10,6 @@ search_id integer constraint contact_searches_id_fk references acs_objects(object_id) on delete cascade constraint contact_searches_id_pk primary key, - title varchar(255), owner_id integer constraint contact_searches_owner_id_fk references acs_objects(object_id) on delete cascade constraint contact_searches_owner_id_nn not null, Index: openacs-4/packages/contacts/sql/postgresql/upgrade/upgrade-1.2b15-1.2b16.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/sql/postgresql/upgrade/upgrade-1.2b15-1.2b16.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/sql/postgresql/upgrade/upgrade-1.2b15-1.2b16.sql 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,183 @@ +-- +-- packages/contacts/sql/postgresql/upgrade/upgrade-1.2d15-1.2d16.sql +-- +-- @author Matthew Geddert (openacs@geddert.com) +-- @creation-date 2006-06-05 +-- @arch-tag: +-- @cvs-id $Id: upgrade-1.2b15-1.2b16.sql,v 1.1 2006/06/26 06:36:51 matthewg Exp $ +-- + +-- we are now using the title column from the acs_objects table and not the title +-- column from the contact_searches table so we remove that column here to not +-- confuse future programmers + +alter table contact_searches drop column title; + +-- contacts lists are a simple and super light +-- weight list building mechanism which allows users +-- to share their lists with one another. we do not use +-- groups for this because on sites with 15000+ contacts/users +-- performance is too slow, in part because of the approval +-- process + +create table contact_lists ( + list_id integer primary key + constraint contact_lists_list_id_fk references acs_objects(object_id) on delete cascade +); + +-- a list can have many owners to allow collaboration + +create table contact_list_members ( + list_id integer not null + constraint contact_list_members_list_id_fk references contact_lists(list_id) on delete cascade, + party_id integer not null + constraint contact_list_members_party_id_fk references parties(party_id) on delete cascade, + unique(list_id,party_id) +); + + +select acs_object_type__create_type ( + 'contact_list', -- content_type + 'Contact List', -- pretty_name + 'Contact Lists', -- pretty_plural + 'acs_object', -- supertype + 'contact_lists', -- table_name + 'list_id', -- id_column + 'contact_list', -- package_name + 'f', -- abstract_p + NULL, -- type_extension_table + NULL -- name_method +); + + + +select define_function_args('contact_list__new','list_id,title,package_id,creation_date;now(),creation_user,creation_ip,context_id'); + +create or replace function contact_list__new (integer,varchar,integer,timestamptz,integer,varchar,integer) +returns integer as ' +declare + p_list_id alias for $1; + p_title alias for $2; + p_package_id alias for $3; + p_creation_date alias for $4; + p_creation_user alias for $5; + p_creation_ip alias for $6; + p_context_id alias for $7; + v_list_id integer; +begin + + v_list_id := acs_object__new( + p_list_id, + ''contact_list'', + p_creation_date, + p_creation_user, + p_creation_ip, + coalesce(p_context_id, p_package_id), + ''t'', + p_title, + p_package_id + ); + + update acs_objects set title = p_title where object_id = v_list_id; + + insert into contact_lists + (list_id) + values + (v_list_id); + + return v_list_id; +end;' language 'plpgsql'; + +select define_function_args('contact_list__delete','list_id'); + +create or replace function contact_list__delete (integer) +returns integer as ' +declare + p_list_id alias for $1; +begin + + delete from contact_list_members where list_id = p_list_id; + delete from contact_lists where list_id = p_list_id; + perform acs_object__delete(p_list_id); + + return ''0''; +end;' language 'plpgsql'; + +create table contact_owner_rels ( + rel_id integer primary key + constraint contact_owner_rels_rel_id_fk references acs_rels(rel_id) on delete cascade +); + +select acs_rel_type__create_type ( + 'contact_owner', + 'Contact Object Owner', + 'Contact Object Owner', + 'relationship', + 'contact_owner_rels', + 'rel_id', + 'contact_owner', + 'acs_object', + null, + 0, + null, + 'acs_object', + null, + 0, + null + ); + +select define_function_args('contact_owner__new','rel_id,rel_type;contact_owner,object_id_one,object_id_two,creation_user,creation_ip'); + +create function contact_owner__new(integer,varchar,integer,integer,integer,varchar) +returns integer as ' +DECLARE + p_rel_id alias for $1; + p_rel_type alias for $2; + p_object_id_one alias for $3; + p_object_id_two alias for $4; + p_creation_user alias for $5; + p_creation_ip alias for $6; + v_rel_id integer; +BEGIN + v_rel_id:= acs_rel__new( + p_rel_id, + p_rel_type, + p_object_id_one, + p_object_id_two, + null, + p_creation_user, + p_creation_ip + ); + + insert + into contact_owner_rels + (rel_id) + values + (v_rel_id); + + return v_rel_id; +END; +' language 'plpgsql'; + + +select define_function_args('contact_owner__delete','rel_id'); + +create or replace function contact_owner__delete (integer) +returns integer as ' +DECLARE + p_rel_id alias for $1; +BEGIN + + PERFORM acs_object__delete(p_rel_id); + + return 0; +END; +' language 'plpgsql'; + + +create view contact_owners as + select object_id_one as object_id, + object_id_two as owner_id + from acs_rels, + contact_owner_rels + where acs_rels.rel_id = contact_owner_rels.rel_id; Index: openacs-4/packages/contacts/tcl/contact-list-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/contact-list-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/tcl/contact-list-procs.tcl 26 Jun 2006 06:36:51 -0000 1.1 @@ -0,0 +1,180 @@ +ad_library { + + Support procs for the lists in the contacts package + + @author Matthew Geddert openacs@geddert.com + @creation-date 2006-06-23 + @cvs-id $Id: contact-list-procs.tcl,v 1.1 2006/06/26 06:36:51 matthewg Exp $ + +} + +namespace eval contact:: {} +namespace eval contact::list:: {} + + +ad_proc -public contact::list::new { + {-list_id ""} + {-title:required} + {-package_id ""} +} { + create a contact list +} { + if { ![exists_and_not_null package_id] } { + set package_id [ad_conn package_id] + } + set var_list [list \ + [list list_id $list_id] \ + [list title $title] \ + [list package_id $package_id] \ + ] + + return [package_instantiate_object -var_list $var_list contact_list] +} + +ad_proc -public contact::list::delete { + {-list_id:required} +} { +} { + return [db_string delete_list { select contact_list__delete(:list_id) } -default {}] +} + +ad_proc -public contact::list::member_add { + {-list_id:required} + {-party_id:required} +} { + Add a party to a list +} { + if { $party_id ne "" } { + if { ![contact::list::member_p -list_id $list_id -party_id $party_id] } { + db_dml insert_member { + insert into contact_list_members + ( list_id, party_id ) + values + ( :list_id, :party_id ) + } + } + } +} + +ad_proc -public contact::list::member_delete { + {-list_id:required} + {-party_id:required} +} { + Delete a party from a list +} { + db_dml insert_member { + delete from contact_list_members where list_id = :list_id and party_id = :party_id + } +} + +ad_proc -public contact::list::member_p { + {-list_id:required} + {-party_id:required} +} { + Add a party to a list +} { + if { $party_id eq "" } { + error "You must specify a party_id" + } + return [db_0or1row select_member_p { select 1 from contact_list_members where list_id = :list_id and party_id = :party_id }] +} + +ad_proc -public contact::list::exists_p { + {-list_id:required} +} { +} { + return [db_0or1row select_list_p { select 1 from contact_lists where list_id = :list_id }] +} + + +ad_proc -public contact::owner_add { + {-object_id:required} + {-owner_id:required} +} { +} { + return [relation_add contact_owner $object_id $owner_id] +} + +ad_proc -public contact::owner_delete { + {-object_id:required} + {-owner_id:required} +} { +} { + set rel_id [relation::get_id -object_id_one $object_id -object_id_two $owner_id -rel_type "contact_owner"] + if { $rel_id ne "" } { + relation_remove $rel_id + } +} + +ad_proc -public contact::owner_delete_all { + {-object_id:required} +} { +} { + foreach owner_id [db_list get_owners { select owner_id from contact_owners where object_id = :object_id }] { + contact::owner_delete -object_id $object_id -owner_id $owner_id + } +} + +ad_proc -public contact::owner_p { + {-object_id:required} + {-owner_id:required} +} { +} { + return [db_0or1row getit { select 1 from contact_owners where object_id = :object_id and owner_id = :owner_id }] +} + +ad_proc -public contact::owner_require { + {-object_id:required} + {-owner_id:required} +} { +} { + if { ![contact::owner_p -object_id $object_id -owner_id $owner_id] } { + if { !${owner_id} } { + auth::require_login + } else { + ns_log notice "contact::owner_require $owner_id (user [ad_conn user_id]) is not an owner of $object_id" + ad_return_forbidden "Permission Denied" "
You don't have sufficient permission.
" + } + ad_script_abort + } +} + +ad_proc -public contact::owner_read_p { + {-object_id:required} + {-owner_id:required} +} { +} { + if { [contact::owner_p -object_id $object_id -owner_id $owner_id] } { + return 1 + } elseif { [contact::owner_p -object_id $object_id -owner_id [ad_conn package_id]] } { + return 1 + } else { + return 0 + } + +} + +ad_proc -public contact::owner_require_read { + {-object_id:required} + {-owner_id:required} +} { +} { + if { ![contact::owner_read_p -object_id $object_id -owner_id $owner_id] } { + if { !${owner_id} } { + auth::require_login + } else { + ns_log notice "contact::owner_require $owner_id (user [ad_conn user_id]) cannot read $object_id" + ad_return_forbidden "Permission Denied" "
You don't have sufficient permission.
" + } + ad_script_abort + } +} + +ad_proc -public contact::owner_count { + {-object_id:required} +} { + How many owners own this object? +} { + return [db_string get_count { select count(1) from contact_owners where object_id = :object_id } -default {0}] +} + Index: openacs-4/packages/contacts/tcl/contact-search-condition-type-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/contact-search-condition-type-procs.tcl,v diff -u -r1.35 -r1.36 --- openacs-4/packages/contacts/tcl/contact-search-condition-type-procs.tcl 18 Jun 2006 00:58:25 -0000 1.35 +++ openacs-4/packages/contacts/tcl/contact-search-condition-type-procs.tcl 26 Jun 2006 06:36:51 -0000 1.36 @@ -915,8 +915,89 @@ } } +ad_proc -private contacts::search::condition_type::group { + -request:required + -package_id:required + {-var_list ""} + {-form_name ""} + {-party_id ""} + {-revision_id ""} + {-prefix "contact"} + {-object_type ""} +} { + Return all widget procs. Each list element is a list of the first then pretty_name then the widget + @param party_id the sql column where a party id can be found (normally something like parties.party_id, but it might be persons.person_id, or organizations.organization_id) +} { + set operand [ns_queryget "${prefix}operand"] + set list_id [ns_queryget "${prefix}list_id"] + switch $request { + ad_form_widgets { + set user_id [ad_conn user_id] + set form_elements [list] + set operand_options [list \ + [list "[_ contacts.contact_is_in_-]" "in"] \ + [list "[_ contacts.contact_is_not_in_-]" "not_in"] \ + ] + + set list_options [db_list_of_lists get_readable_lists { + select ao.title, + cl.list_id + from contact_lists cl, + acs_objects ao + where cl.list_id = ao.object_id + and cl.list_id in ( select object_id from contact_owners where owner_id in ( :user_id, :package_id )) + }] + + lappend form_elements [list ${prefix}operand:text(select) [list label {}] [list options $operand_options] [list value $operand]] + lappend form_elements [list ${prefix}list_id:integer(select) [list label {}] [list options $list_options] [list value $list_id]] + return $form_elements + } + form_var_list { + if { [exists_and_not_null operand] && [exists_and_not_null list_id] } { + if { [contact::owner_read_p -object_id $list_id -owner_id [ad_conn user_id]] } { + return [list $operand $list_id] + } + } + return {} + } + sql - pretty { + set operand [lindex $var_list 0] + set list_id [lindex $var_list 1] + set title [db_string get_title { select title from acs_objects where object_id = :list_id } -default {}] + if { $title eq "" } { + # this list has been deleted or they don't have permission to read it any more + if { $request eq "pretty" } { + return "[_ contacts.List] [_ contacts.Deleted]" + } else { + return " t = f " + } + } + switch $operand { + in { + set output_pretty "[_ contacts.lt_The_contact_in_list]" + set output_code "${party_id} in ( select clm${list_id}.party_id from contact_list_members clm${list_id} where clm${list_id}.list_id = $list_id )" + } + not_in { + set output_pretty "[_ contacts.lt_The_contact_NOT_in_li]" + set output_code "${party_id} not in ( select clm${list_id}.party_id from contact_list_members clm${list_id} where clm${list_id}.list_id = $list_id )" + } + } + if { $request == "pretty" } { + return $output_pretty + } else { + return $output_code + } + } + type_name { + return [_ contacts.List] + } + } +} + + + ad_proc -private contacts::search::condition_type::relationship { -request:required -package_id:required 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.32 -r1.33 --- openacs-4/packages/contacts/tcl/contact-search-procs.tcl 12 Jun 2006 07:58:00 -0000 1.32 +++ openacs-4/packages/contacts/tcl/contact-search-procs.tcl 26 Jun 2006 06:36:51 -0000 1.33 @@ -552,19 +552,36 @@ } { contact::search::permitted -search_id $search_id if { $and_p } { - return [util_memoize [list ::contact::search::where_clause_not_cached \ - -search_id $search_id \ - -and \ - -party_id $party_id \ - -revision_id $revision_id \ - -limit_type_p $limit_type_p]] + set resutls [util_memoize [list ::contact::search::where_clause_not_cached \ + -search_id $search_id \ + -and \ + -party_id $party_id \ + -revision_id $revision_id \ + -limit_type_p $limit_type_p]] } else { - return [util_memoize [list ::contact::search::where_clause_not_cached \ - -search_id $search_id \ - -party_id $party_id \ - -revision_id $revision_id \ - -limit_type_p $limit_type_p]] + set results [util_memoize [list ::contact::search::where_clause_not_cached \ + -search_id $search_id \ + -party_id $party_id \ + -revision_id $revision_id \ + -limit_type_p $limit_type_p]] } + + if { $results eq "" } { + # we allow for the special case that somebody supplied a + # list_id instead of a search_id, if this was the case and + # they have permission to read this list + if { [contact::list::exists_p -list_id $search_id] } { + if { [contact::owner_read_p -object_id $search_id -owner_id [ad_conn user_id]] } { + set result {} + if { $and_p } { + append results " and " + } + append results " $party_id in ( select party_id from contact_list_members where list_id = $search_id ) " + } + } + } + return $results + } ad_proc -public contact::search::where_clause_not_cached { @@ -620,15 +637,14 @@ append result [lindex $where_clauses 0] } } - - if { [exists_and_not_null result] } { - set result "( $result )" - if { $and_p } { - set result "and $result" - } + } + if { [exists_and_not_null result] } { + set result "( $result )" + if { $and_p } { + set result "and $result" } } else { - set result {} + set result {} } return $result 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.91 -r1.92 --- openacs-4/packages/contacts/tcl/contacts-procs.tcl 18 Jun 2006 01:00:04 -0000 1.91 +++ openacs-4/packages/contacts/tcl/contacts-procs.tcl 26 Jun 2006 06:36:51 -0000 1.92 @@ -632,11 +632,15 @@ } { create a contact revision } { - if {[db_0or1row revision_exists_p {select 1 from cr_items where item_id = :party_id}]} { - return [item::get_live_revision $party_id] - } else { - return "" - } + # since we run the sweeper to create cr_items for every contact + # we know that it has a cr_item, so we can simply use the item + # proc. + #if {[db_0or1row revision_exists_p {select 1 from cr_items where item_id = :party_id}]} { + # return [item::get_live_revision $party_id] + #} else { + # return "" + #} + return [item::get_live_revision $party_id] } ad_proc -public contact::subsite_user_group { Index: openacs-4/packages/contacts/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/index.tcl,v diff -u -r1.23 -r1.24 --- openacs-4/packages/contacts/www/index.tcl 1 May 2006 19:54:52 -0000 1.23 +++ openacs-4/packages/contacts/www/index.tcl 26 Jun 2006 06:36:52 -0000 1.24 @@ -70,11 +70,15 @@ } set public_searches [lang::util::localize_list_of_lists -list [db_list_of_lists public_searches {}]] set search_options [concat [list [list [_ contacts.All_Contacts] ""]] $public_searches] -set searchcount 1 -db_foreach my_recent_searches {} { - lappend search_options [list "${searchcount}) ${recent_title}" ${recent_search_id}] - incr searchcount + +db_foreach my_searches {} { + lappend search_options [list "${my_searches_title}" ${my_searches_search_id} [_ contacts.My_Searches]] } +db_foreach my_lists {} { + lappend search_options [list "${my_lists_title}" ${my_lists_list_id} [_ contacts.Lists]] +} + + if { [exists_and_not_null search_id] } { set search_in_list_p 0 foreach search_option $search_options { @@ -93,7 +97,7 @@ set package_url [ad_conn package_url] set form_elements { - {search_id:integer(select),optional {label ""} {options $search_options} {html {onChange "javascript:acs_FormRefresh('search')"}}} + {search_id:integer(select_with_optgroup),optional {label ""} {options $search_options} {html {onChange "javascript:acs_FormRefresh('search')"}}} {query:text(text),optional {label ""} {html {size 20 maxlength 255}}} {save:text(submit) {label {[_ contacts.Search]}} {value "go"}} {results_count:integer(inform),optional {label "  [_ contacts.Results] $contacts_total_count "}} Index: openacs-4/packages/contacts/www/index.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/index.vuh,v diff -u -r1.16 -r1.17 --- openacs-4/packages/contacts/www/index.vuh 28 May 2006 01:50:21 -0000 1.16 +++ openacs-4/packages/contacts/www/index.vuh 26 Jun 2006 06:36:52 -0000 1.17 @@ -91,7 +91,19 @@ rp_form_put object_type "organization" } rp_internal_redirect contact-add - } + } + lists { + rp_internal_redirect /packages/contacts/lib/lists + } + list-parties-add { + rp_internal_redirect /packages/contacts/lib/list-parties-add + } + list-parties-remove { + rp_internal_redirect /packages/contacts/lib/list-parties-remove + } + sharing { + rp_internal_redirect /packages/contacts/lib/sharing + } default { ns_returnnotfound ad_script_abort Index: openacs-4/packages/contacts/www/index.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/index.xql,v diff -u -r1.9 -r1.10 --- openacs-4/packages/contacts/www/index.xql 19 Jun 2006 08:07:32 -0000 1.9 +++ openacs-4/packages/contacts/www/index.xql 26 Jun 2006 06:36:52 -0000 1.10 @@ -15,20 +15,30 @@ - + - select ao.title as recent_title, - cs.search_id as recent_search_id - from contact_searches cs, contact_search_log csl, acs_objects ao - where csl.user_id = :user_id - and cs.search_id = csl.search_id - and cs.search_id = ao.object_id + select ao.title as my_searches_title, + cs.search_id as my_searches_search_id + from contact_searches cs, + acs_objects ao + where cs.search_id = ao.object_id and ao.title is not null - and cs.owner_id != :package_id + and cs.owner_id = :user_id and not cs.deleted_p - order by csl.last_search desc - limit 10 + order by upper(ao.title) + + + select ao.title as my_lists_title, + cl.list_id as my_lists_list_id + from contact_lists cl, + acs_objects ao + where cl.list_id = ao.object_id + and ao.object_id in ( select object_id from contact_owners where owner_id in ( :user_id , :package_id )) + order by upper(ao.title) + + +