Index: openacs-4/packages/contacts/contacts.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/contacts.info,v diff -u -r1.91 -r1.92 --- openacs-4/packages/contacts/contacts.info 26 Jun 2007 02:53:12 -0000 1.91 +++ openacs-4/packages/contacts/contacts.info 27 Jun 2007 23:55:35 -0000 1.92 @@ -7,14 +7,14 @@ <initial-install-p>f</initial-install-p> <singleton-p>f</singleton-p> - <version name="1.2b30" url="http://openacs.org/repository/download/apm/contacts-1.2b30.apm"> + <version name="1.2b31" url="http://openacs.org/repository/download/apm/contacts-1.2b31.apm"> <owner url="mailto:openacs@geddert.com">Matthew Geddert</owner> <summary>This application lets you collaboratively view, edit and categorize contacts.</summary> <release-date>2006-06-25</release-date> <description format="text/plain">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</description> <maturity>0</maturity> - <provides url="contacts" version="1.2b30"/> + <provides url="contacts" version="1.2b31"/> <requires url="acs-datetime" version="4.1"/> <requires url="acs-events" version="0.5d3"/> <requires url="acs-tcl" version="5.3.0d2"/> @@ -24,6 +24,7 @@ <requires url="categories" version="1.0d6"/> <requires url="general-comments" version="4.1"/> <requires url="mail-tracking" version="0.6.4"/> + <requires url="notifications" version="5.4.0d3"/> <requires url="organizations" version="0.6d1"/> <requires url="ajaxhelper" version="0.82d"/> 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.98 -r1.99 --- openacs-4/packages/contacts/catalog/contacts.en_US.ISO-8859-1.xml 27 Jun 2007 02:53:30 -0000 1.98 +++ openacs-4/packages/contacts/catalog/contacts.en_US.ISO-8859-1.xml 27 Jun 2007 23:55:36 -0000 1.99 @@ -513,9 +513,10 @@ <msg key="lt_zippostal_does_not_st">zip/postal does not start with -></msg> <msg key="lt_zippostal_starts_with">zip/postal starts with -></msg> <msg key="Mail">Mail</msg> - <msg key="Mail_recipient">Message to %recipient%</msg> + <msg key="Mail_group">Mail %recipient%</msg> <msg key="Mail_Merge">Mail Merge</msg> <msg key="Mail_Merge_Results">Mail Merge Results</msg> + <msg key="Mail_recipient">Mail %recipient%</msg> <msg key="Mail_through_p">Mail Through</msg> <msg key="Mail_to_contact">Mail to contact</msg> <msg key="mailing_allowed">mailing allowed</msg> @@ -551,6 +552,8 @@ <msg key="Normal_Searches">Normal Searches</msg> <msg key="Not_Configured">Not Configured</msg> <msg key="not_in_the_search">not in the search</msg> + <msg key="Notify">Notify</msg> + <msg key="Notify_recipient">Notify %recipient%</msg> <msg key="Number_of_Rows">Number of Rows</msg> <msg key="Object">Object:</msg> <msg key="Object_id">Object_id</msg> @@ -626,6 +629,7 @@ <msg key="Query">Query</msg> <msg key="READ_THESE">READ THESE</msg> <msg key="Recipients">Recipients</msg> + <msg key="Recipients_requesting_notification">%recipients% requesting notification</msg> <msg key="Refund">Refund</msg> <msg key="rel_bulk_add_confirm">Confirm deleting relationships</msg> <msg key="Related_contact">Related contact</msg> Index: openacs-4/packages/contacts/lib/email-search.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/lib/email-search.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/contacts/lib/email-search.tcl 25 Jun 2007 16:25:39 -0000 1.1 +++ openacs-4/packages/contacts/lib/email-search.tcl 27 Jun 2007 23:55:36 -0000 1.2 @@ -25,6 +25,18 @@ set no_callback_p f } +if { [contact::group::notifications_p -group_id $search_id] } { + set recipients_label [_ contacts.Notify] + # we cannot do interpolation with notifications since + # only one notification is generated for all recipients + set content_body_help_text "" +} else { + set recipients_label [_ contacts.Recipients] + # since each message is dealt with individually we can + # do interpolation + set content_body_help_text [_ contacts.lt_remember_that_you_can] +} + # The element check_uncheck only calls a javascript function # to check or uncheck all recipients set form_elements { @@ -34,21 +46,36 @@ title:text(hidden),optional search_id:text(hidden) {message_type:text(hidden) {value "email"}} - {-section "sec1" {legendtext "[_ contacts.Recipients]"}} + {-section "sec1" {legendtext "$recipients_label"}} {recipients:text(inform) - {label "[_ contacts.Recipients]"} + {label "$recipients_label"} {value "$recipients"} } - {cc:text(text),optional - {label "[_ contacts.CC]:"} - {html {size 60}} - {help_text "[_ contacts.cc_help]"} +} + +if { [contact::group::notifications_p -group_id $search_id] } { + + # CC and BCC are not avalable for notifications + append form_elements { + {cc:text(hidden),optional} + {bcc:text(hidden),optional} } - {bcc:text(text),optional - {label "[_ acs-mail-lite.BCC]:"} - {html {size 60}} - {help_text "[_ contacts.cc_help]"} + +} else { + + append form_elements { + {cc:text(text),optional + {label "[_ contacts.CC]:"} + {html {size 60}} + {help_text "[_ contacts.cc_help]"} + } + {bcc:text(text),optional + {label "[_ acs-mail-lite.BCC]:"} + {html {size 60}} + {help_text "[_ contacts.cc_help]"} + } } + } # Set single_email_p in the form @@ -135,7 +162,7 @@ {content_body:richtext(richtext),optional {label "[_ contacts.Message]"} {html {cols 80 rows 18}} - {help_text "[_ contacts.lt_remember_that_you_can]"} + {help_text "$content_body_help_text"} {value $content_list} } {upload_file:file(file),optional @@ -199,84 +226,7 @@ } -on_submit { set package_id [ad_conn package_id] - - # Make sure we get the correct users and can send an e-mail to them - if {[contact::group::mapped_p -group_id $search_id]} { - - # Make sure the user has write permission on the group - permission::require_permission -object_id $search_id -privilege "write" - - # Get the party_ids from the group members - if { [contact::group::mapped_p -group_id $search_id] } { - set valid_party_ids [group::get_members -group_id $search_id] - } - } else { - set valid_party_ids [contact::search::results -search_id $search_id -package_id $package_id] - } - - foreach party_id $valid_party_ids { - if { [party::email -party_id $party_id] eq "" } { - # We are going to check if there is an employee relationship - # if there is we are going to check if the employer has an - # email adrres, if it does we are going to use that address - set employer_id [lindex [contact::util::get_employee_organization -employee_id $party_id] 0] - - if { ![empty_string_p $employer_id] } { - set emp_addr [contact::email -party_id $employer_id] - if { ![empty_string_p $emp_addr] } { - lappend party_ids $employer_id - } else { - lappend invalid_party_ids $party_id - } - } else { - lappend invalid_party_ids $party_id - } - } else { - lappend party_ids $party_id - } - } - # Deal with the invalid recipients - foreach party_id $invalid_party_ids { - set contact_name [contact::name -party_id $party_id] - set contact_url [contact::url -party_id $party_id] - lappend invalid_recipients "<a href=\"${contact_url}\">${contact_name}</a>" - } - - set invalid_recipients [join $invalid_recipients ", "] - if { [llength $invalid_recipients] > 0 } { - switch $message_type { - letter { - set error_message [_ contacts.lt_You_cannot_send_a_letter_to_invalid_recipients] - } - email { - set error_message [_ contacts.lt_You_cannot_send_an_email_to_invalid_recipients] - } - default { - set error_message [_ contacts.lt_You_cannot_send_a_message_to_invalid_recipients] - } - } - if { $party_ids != "" } { - util_user_message -html -message $error_message - } - } - - # We get the attribute_id of the salutation attribute - set attribute_id [attribute::id -object_type "person" -attribute_name "salutation"] - - # List to store know wich emails recieved the message - set recipients_addr [list] - - set from [ad_conn user_id] - set from_addr [contact::email -party_id $from] - - # Remove all spaces in cc and bcc - regsub -all " " $cc "" cc - regsub -all " " $bcc "" bcc - - set cc_list [split $cc ";"] - set bcc_list [split $bcc ";"] - set mime_type [template::util::richtext::get_property format $content_body] set content_body [template::util::richtext::get_property contents $content_body] @@ -297,100 +247,198 @@ lappend file_ids $file_id } } + + + - - # Send the mail to all parties. - set member_size [llength $party_ids] - set counter 1 - foreach party_id $party_ids { - # Differentiate between person and organization - if {[person::person_p -party_id $party_id]} { - set salutation [contact::salutation -party_id $party_id] - db_1row names "select first_names, last_name from persons where person_id = :party_id" - set name "$first_names $last_name" + if { [contact::group::notifications_p -group_id $search_id] } { + + permission::require_permission -object_id $search_id -privilege "write" + + notification::new \ + -type_id [notification::type::get_type_id -short_name contacts_group_notif] \ + -object_id $search_id \ + -notif_subject $subject \ + -notif_text [ad_html_text_convert -from $mime_type -to text/plain -- $content_body] \ + -notif_html [ad_html_text_convert -from $mime_type -to text/html -- $content_body] \ + -file_ids $file_ids + + } else { + + + # Make sure we get the correct users and can send an e-mail to them + if {[contact::group::mapped_p -group_id $search_id]} { + + # Make sure the user has write permission on the group + permission::require_permission -object_id $search_id -privilege "write" + set valid_party_ids [group::get_members -group_id $search_id] } else { - set name [contact::name -party_id $party_id] - set salutation "Dear ladies and gentlemen" - # the following is a hot fix (nfl 2006/10/20) - set first_names "" - set last_name "" + set valid_party_ids [contact::search::results -search_id $search_id -package_id $package_id] } - - set date [lc_time_fmt [dt_sysdate] "%q"] + set party_ids [list] + set invalid_party_ids [list] + set invalid_recipients [list] + foreach party_id $valid_party_ids { + if { [party::email -party_id $party_id] eq "" } { + # We are going to check if there is an employee relationship + # if there is we are going to check if the employer has an + # email adrres, if it does we are going to use that address + set employer_id [lindex [contact::util::get_employee_organization -employee_id $party_id] 0] + + if { ![empty_string_p $employer_id] } { + set emp_addr [contact::email -party_id $employer_id] + if { ![empty_string_p $emp_addr] } { + lappend party_ids $employer_id + } else { + lappend invalid_party_ids $party_id + } + } else { + lappend invalid_party_ids $party_id + } + } else { + lappend party_ids $party_id + } + } - set values [list] - foreach element [list first_names last_name salutation name date] { - lappend values [list "{$element}" [set $element]] + # Deal with the invalid recipients + foreach party_id $invalid_party_ids { + set contact_name [contact::name -party_id $party_id] + set contact_url [contact::url -party_id $party_id] + lappend invalid_recipients "<a href=\"${contact_url}\">${contact_name}</a>" } - set interpol_subject [contact::message::interpolate -text $subject -values $values] - - set interpol_content_body [contact::message::interpolate -text $content_body -values $values] - - # If we are doing mail through for tracking purposes - # Set the reply_to_addr accordingly - if {$mail_through_p} { - regsub -all {@} $from_addr {#} reply_to - set reply_to_addr "${reply_to}@[acs_mail_lite::address_domain]" - } else { - set reply_to_addr $from_addr + set invalid_recipients [join $invalid_recipients ", "] + if { [llength $invalid_recipients] > 0 } { + switch $message_type { + letter { + set error_message [_ contacts.lt_You_cannot_send_a_letter_to_invalid_recipients] + } + email { + set error_message [_ contacts.lt_You_cannot_send_an_email_to_invalid_recipients] + } + default { + set error_message [_ contacts.lt_You_cannot_send_a_message_to_invalid_recipients] + } + } + if { $party_ids != "" } { + util_user_message -html -message $error_message + } } - - ns_log Notice "Recipient: $name $party_id ( $counter / $member_size )" - incr counter - - acs_mail_lite::complex_send \ - -to_party_ids $party_id \ - -cc_addr $cc_list \ - -bcc_addr $bcc_list \ - -from_addr "$from_addr" \ - -reply_to "$reply_to_addr" \ - -subject "$interpol_subject" \ - -body "$interpol_content_body" \ - -package_id $package_id \ - -file_ids $file_ids \ - -mime_type $mime_type \ - -object_id $context_id \ - -no_callback_p $no_callback_p \ - -single_email - # Link the files to all parties - if {[exists_and_not_null revision_id]} { - application_data_link::new -this_object_id $revision_id -target_object_id $party_id + # We get the attribute_id of the salutation attribute + set attribute_id [attribute::id -object_type "person" -attribute_name "salutation"] + + # List to store know wich emails recieved the message + set recipients_addr [list] + + set from [ad_conn user_id] + set from_addr [contact::email -party_id $from] + + # Remove all spaces in cc and bcc + regsub -all " " $cc "" cc + regsub -all " " $bcc "" bcc + + set cc_list [split $cc ";"] + set bcc_list [split $bcc ";"] + + # Send the mail to all parties. + set member_size [llength $party_ids] + set counter 1 + + foreach party_id $party_ids { + + # Differentiate between person and organization + if {[person::person_p -party_id $party_id]} { + set salutation [contact::salutation -party_id $party_id] + db_1row names "select first_names, last_name from persons where person_id = :party_id" + set name "$first_names $last_name" + } else { + set name [contact::name -party_id $party_id] + set salutation "Dear ladies and gentlemen" + # the following is a hot fix (nfl 2006/10/20) + set first_names "" + set last_name "" + } + + + set date [lc_time_fmt [dt_sysdate] "%q"] + + set values [list] + foreach element [list first_names last_name salutation name date] { + lappend values [list "{$element}" [set $element]] + } + + set interpol_subject [contact::message::interpolate -text $subject -values $values] + + set interpol_content_body [contact::message::interpolate -text $content_body -values $values] + + # If we are doing mail through for tracking purposes + # Set the reply_to_addr accordingly + if { [string is true $mail_through_p] } { + regsub -all {@} $from_addr {#} reply_to + set reply_to_addr "${reply_to}@[acs_mail_lite::address_domain]" + } else { + set reply_to_addr $from_addr + } + + ns_log Notice "Recipient: $name $party_id ( $counter / $member_size )" + incr counter + + acs_mail_lite::complex_send \ + -to_party_ids $party_id \ + -cc_addr $cc_list \ + -bcc_addr $bcc_list \ + -from_addr "$from_addr" \ + -reply_to "$reply_to_addr" \ + -subject "$interpol_subject" \ + -body "$interpol_content_body" \ + -package_id $package_id \ + -file_ids $file_ids \ + -mime_type $mime_type \ + -object_id $context_id \ + -no_callback_p $no_callback_p \ + -single_email + + # Link the files to all parties + if {[exists_and_not_null revision_id]} { + application_data_link::new -this_object_id $revision_id -target_object_id $party_id + } + + # Log the sending of the mail in contacts history + if { ![empty_string_p $item_id]} { + + contact::message::log \ + -message_type "email" \ + -sender_id $from \ + -recipient_id $party_id \ + -title $title \ + -description $subject \ + -content $content_body \ + -content_format "text/plain" \ + -item_id "$item_id" + + } } - # Log the sending of the mail in contacts history - if { ![empty_string_p $item_id]} { - contact::message::log \ - -message_type "email" \ - -sender_id $from \ - -recipient_id $party_id \ - -title $title \ - -description $subject \ - -content $content_body \ - -content_format "text/plain" \ - -item_id "$item_id" - } - } - - ad_returnredirect $return_url - # Prepare the user message - foreach cc_addr [concat $cc_list $bcc_list] { - set cc_id [party::get_by_email -email $cc_addr] - if {$cc_id eq ""} { - lappend recipients $cc_addr - } else { - lappend recipients "<a href=\"[contact::url -party_id $cc_id]\">[contact::name -party_id $cc_id]</a>" + # Prepare the user message + foreach cc_addr [concat $cc_list $bcc_list] { + set cc_id [party::get_by_email -email $cc_addr] + if {$cc_id eq ""} { + lappend recipients $cc_addr + } else { + lappend recipients "<a href=\"[contact::url -party_id $cc_id]\">[contact::name -party_id $cc_id]</a>" + } } - } - util_user_message -html -message "[_ contacts.Your_message_was_sent_to_-recipients-]" + util_user_message -html -message "[_ contacts.Your_message_was_sent_to_-recipients-]" + } } -after_submit { + ad_returnredirect $return_url ad_script_abort } 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.18 -r1.19 --- openacs-4/packages/contacts/sql/postgresql/contacts-create.sql 10 Jan 2007 07:16:25 -0000 1.18 +++ openacs-4/packages/contacts/sql/postgresql/contacts-create.sql 27 Jun 2007 23:55:36 -0000 1.19 @@ -65,6 +65,8 @@ constraint contact_groups_default_p_nn not null, user_change_p boolean default 'f' constraint contact_groups_user_change_p_nn not null, + notifications_p boolean default 'f' + constraint contact_groups_notifications_p_nn not null, package_id integer constraint contact_groups_package_id_fk references apm_packages(package_id) constraint contact_groups_package_id_nn not null, @@ -233,3 +235,4 @@ \i contacts-search-create.sql \i contacts-messages-create.sql \i contacts-list-create.sql +\i groups-notifications-init.sql Index: openacs-4/packages/contacts/sql/postgresql/groups-notifications-init.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/sql/postgresql/groups-notifications-init.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/sql/postgresql/groups-notifications-init.sql 27 Jun 2007 23:55:36 -0000 1.1 @@ -0,0 +1,69 @@ +-- Contact Group Notifications +-- +-- @author Matthew Geddert (openacs@geddert.com) +-- @creation-date 2007-06-25 +-- @cvs-id $Id: groups-notifications-init.sql,v 1.1 2007/06/27 23:55:36 matthewg Exp $ +-- + +create function inline_0() returns integer as ' +declare + impl_id integer; + v_foo integer; +begin + -- the notification type impl + impl_id := acs_sc_impl__new ( + ''NotificationType'', + ''contacts_group_notif_type'', + ''contacts'' + ); + + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''contacts_group_notif_type'', + ''GetURL'', + ''contacts::group::notification::get_url'', + ''TCL'' + ); + + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''contacts_group_notif_type'', + ''ProcessReply'', + ''contacts::group::notification::process_reply'', + ''TCL'' + ); + + PERFORM acs_sc_binding__new ( + ''NotificationType'', + ''contacts_group_notif_type'' + ); + + v_foo:= notification_type__new ( + NULL, + impl_id, + ''contacts_group_notif'', + ''Group Notification'', + ''Notifications for Groups'', + now(), + NULL, + NULL, + NULL + ); + + -- enable the various intervals and delivery methods + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in (''instant'',''hourly'',''daily''); + + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in (''email''); + + return (0); +end; +' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); Index: openacs-4/packages/contacts/sql/postgresql/upgrade/upgrade-1.2b30-1.2b31.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/sql/postgresql/upgrade/upgrade-1.2b30-1.2b31.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/contacts/sql/postgresql/upgrade/upgrade-1.2b30-1.2b31.sql 27 Jun 2007 23:55:36 -0000 1.1 @@ -0,0 +1,76 @@ +-- +-- packages/contacts/sql/postgresql/upgrade/upgrade-1.2b30-1.2b31.sql +-- +-- @author Matthew Geddert (openacs@geddert.com) +-- @creation-date 2007-06-25 +-- @arch-tag: +-- @cvs-id $Id: upgrade-1.2b30-1.2b31.sql,v 1.1 2007/06/27 23:55:36 matthewg Exp $ +-- + +alter table contact_groups add column notifications_p boolean; +alter table contact_groups alter column notifications_p set default 'f'; +update contact_groups set notifications_p = 'f'; +alter table contact_groups alter column notifications_p set not null; + +create function inline_0() returns integer as ' +declare + impl_id integer; + v_foo integer; +begin + -- the notification type impl + impl_id := acs_sc_impl__new ( + ''NotificationType'', + ''contacts_group_notif_type'', + ''contacts'' + ); + + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''contacts_group_notif_type'', + ''GetURL'', + ''contacts::group::notification::get_url'', + ''TCL'' + ); + + v_foo := acs_sc_impl_alias__new ( + ''NotificationType'', + ''contacts_group_notif_type'', + ''ProcessReply'', + ''contacts::group::notification::process_reply'', + ''TCL'' + ); + + PERFORM acs_sc_binding__new ( + ''NotificationType'', + ''contacts_group_notif_type'' + ); + + v_foo:= notification_type__new ( + NULL, + impl_id, + ''contacts_group_notif'', + ''Group Notification'', + ''Notifications for Groups'', + now(), + NULL, + NULL, + NULL + ); + + -- enable the various intervals and delivery methods + insert into notification_types_intervals + (type_id, interval_id) + select v_foo, interval_id + from notification_intervals where name in (''instant'',''hourly'',''daily''); + + insert into notification_types_del_methods + (type_id, delivery_method_id) + select v_foo, delivery_method_id + from notification_delivery_methods where short_name in (''email''); + + return (0); +end; +' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); Index: openacs-4/packages/contacts/tcl/contacts-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/tcl/contacts-procs-postgresql.xql,v diff -u -r1.28 -r1.29 --- openacs-4/packages/contacts/tcl/contacts-procs-postgresql.xql 24 Jun 2007 08:50:16 -0000 1.28 +++ openacs-4/packages/contacts/tcl/contacts-procs-postgresql.xql 27 Jun 2007 23:55:36 -0000 1.29 @@ -197,14 +197,16 @@ CASE WHEN contact_groups.package_id is not null THEN '1' ELSE '0' END as mapped_p, CASE WHEN default_p THEN '1' ELSE '0' END as default_p, CASE WHEN user_change_p THEN '1' ELSE '0' END as user_change_p, - $dotlrn_community_p as dotlrn_community_p - from (select g.* from groups g left join application_groups ag on (ag.group_id = g.group_id) - where (package_id is null or g.group_id = 1231) and group_name not like 'forumgroup_%') groups2 - left join ( select * from contact_groups where package_id = :package_id ) as contact_groups on ( groups2.group_id = contact_groups.group_id ), - acs_objects + $dotlrn_community_p as dotlrn_community_p, + CASE WHEN contact_groups.notifications_p THEN '1' ELSE '0' END as notifications_p + from ( select g.* + from groups g left join application_groups ag on (ag.group_id = g.group_id) + where package_id is null ) groups2 + left join ( select * from contact_groups where package_id = :package_id ) as contact_groups on ( groups2.group_id = contact_groups.group_id ), + acs_objects $additional_from where groups2.group_id not in ('-1','[contacts::default_group -package_id $package_id]') - and groups2.group_id = acs_objects.object_id + and groups2.group_id = acs_objects.object_id and groups2.group_id not in ( select gcm.component_id from group_component_map gcm where gcm.group_id != -1 ) $additional_where order by mapped_p desc, CASE WHEN contact_groups.default_p THEN '000000000' ELSE upper( $name_field ) END @@ -254,9 +256,9 @@ <fullquery name="contact::group::map.map_group"> <querytext> insert into contact_groups - (group_id,default_p,package_id) + (group_id,default_p,notification_p,package_id) values - (:group_id,:default_p,:package_id) + (:group_id,:default_p,:notification_p,:package_id) </querytext> </fullquery> @@ -268,6 +270,15 @@ </querytext> </fullquery> +<fullquery name="contact::group::notifications_p.select_notifications_p"> + <querytext> + select 1 from contact_groups + where group_id = :group_id + and notifications_p + limit 1 + </querytext> +</fullquery> + <fullquery name="contact::revision::new.insert_item"> <querytext> insert into cr_items 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.114 -r1.115 --- openacs-4/packages/contacts/tcl/contacts-procs.tcl 26 Jun 2007 03:52:13 -0000 1.114 +++ openacs-4/packages/contacts/tcl/contacts-procs.tcl 27 Jun 2007 23:55:36 -0000 1.115 @@ -15,7 +15,24 @@ namespace eval contact::rels:: {} namespace eval contacts::person:: {} namespace eval contact::special_attributes {} +namespace eval contacts::group::notification {} +ad_proc -public contacts::group::notification::get_url { + object_id +} { + # there is not good page to send users regarding a group + # so we don't bring them anywhere + return "/notifications/manage" +} + +ad_proc -public contacts::group::notification::process_reply { + reply_id +} { + +} + + + ad_proc -public contacts::default_group { {-package_id ""} } { @@ -926,6 +943,7 @@ -group_id:required {-package_id ""} {-default_p "f"} + {-notifications_p "f"} } { this creates a new group for use with contacts (and the permissions system) } { @@ -947,6 +965,14 @@ return [db_0or1row select_mapped_p {}] } +ad_proc -public contact::group::notifications_p { + -group_id:required +} { + Does this group use notifications (if one contacts instance does then all do, since the group is not bound to the contacts instance) +} { + return [db_0or1row select_notifications_p {}] +} + ad_proc -public contact::group::name { -group_id:required } { @@ -1053,6 +1079,31 @@ } group::flush_members_cache -group_id $group_id + if { [contact::group::notifications_p -group_id $group_id] && [contact::type -party_id $user_id] ne "organization" } { + if { [contact::type -party_id $user_id] ne "user" } { + util_user_message -message "Only users can be notified. The person ($user_id) was added to the group." + } + # notifications only allows users to receive notifications. + # this actually makes sense, since the recipient needs + # a way to remove themselves from the notifications + # they are getting. + # + # We could potentially automatically upgrade a person + # to a user user if a notification request is made. + # to do this uncomment the following + # contact::person_upgrade_to_user -person_id $user_id -no_perm_check "t" + + + + notification::request::new \ + -type_id [notification::type::get_type_id -short_name contacts_group_notif] \ + -user_id $user_id \ + -object_id $group_id \ + -interval_id [notification::get_interval_id -name instant] \ + -delivery_method_id [notification::get_delivery_method_id -name email] \ + -format "html" + } + } @@ -1124,7 +1175,7 @@ set user_id [ad_conn user_id] set group_list [list] foreach one_group [contact::groups_list -package_id $package_id -include_dotlrn_p $include_dotlrn_p] { - util_unlist $one_group group_id group_name member_count component_count mapped_p default_p user_change_p dotlrn_community_p + util_unlist $one_group group_id group_name member_count component_count mapped_p default_p user_change_p dotlrn_community_p notifications_p if {$user_change_p eq ""} { set user_change_p 0 } @@ -1143,11 +1194,11 @@ } if { $mapped_p || $all_p} { # we localize twice because for some reason some localized keys references another localized key - lappend group_list [list [lang::util::localize [lang::util::localize $group_name]] $group_id $member_count "1" $mapped_p $default_p $user_change_p $dotlrn_community_p] + lappend group_list [list [lang::util::localize [lang::util::localize $group_name]] $group_id $member_count "1" $mapped_p $default_p $user_change_p $dotlrn_community_p $notifications_p] if { $component_count > 0 && ( $expand == "all" || $expand == $group_id ) } { db_foreach get_components {} { if { $mapped_p || $all_p} { - lappend group_list [list "$indent_with[lang::util::localize [lang::util::localize $group_name]]" $group_id $member_count "2" $mapped_p $default_p $user_change_p $dotlrn_community_p] + lappend group_list [list "$indent_with[lang::util::localize [lang::util::localize $group_name]]" $group_id $member_count "2" $mapped_p $default_p $user_change_p $dotlrn_community_p $notifications_p] } } } Index: openacs-4/packages/contacts/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/index.tcl,v diff -u -r1.31 -r1.32 --- openacs-4/packages/contacts/www/index.tcl 27 Jun 2007 02:51:40 -0000 1.31 +++ openacs-4/packages/contacts/www/index.tcl 27 Jun 2007 23:55:36 -0000 1.32 @@ -119,11 +119,17 @@ if { $search_id ne "" && $contacts_total_count > 0 } { if {[contact::group::mapped_p -group_id $search_id]} { set recipient [contact::group::name -group_id $search_id] + set notifications_p [contact::group::notifications_p -group_id $search_id] } else { set recipient [contact::search::title -search_id $search_id] + set notifications_p 0 } - set label "[_ contacts.Mail_recipient]" + if { $notifications_p } { + set label [_ contacts.Notify_recipient] + } else { + set label [_ contacts.Mail_recipient] + } append form_elements { {mail_merge_group:text(submit) {label $label} {value "1"}} } Index: openacs-4/packages/contacts/www/message.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/message.tcl,v diff -u -r1.40 -r1.41 --- openacs-4/packages/contacts/www/message.tcl 27 Jun 2007 02:52:33 -0000 1.40 +++ openacs-4/packages/contacts/www/message.tcl 27 Jun 2007 23:55:36 -0000 1.41 @@ -48,13 +48,17 @@ set package_id [ad_conn package_id] set recipients [list] +set recipients_label [_ contacts.Recipients] if { $search_id ne "" } { set return_url [export_vars -base [apm_package_url_from_id $package_id] -url {search_id}] if {[contact::group::mapped_p -group_id $search_id]} { # Make sure the user has write permission on the group permission::require_permission -object_id $search_id -privilege "write" lappend recipients "<a href=\"$return_url\">[contact::group::name -group_id $search_id]</a>" + if { [contact::group::notifications_p -group_id $search_id] } { + set recipients_label [_ contacts.Notify] + } } else { lappend recipients "<a href=\"$return_url\">[contact::search::title -search_id $search_id]</a>" } @@ -215,7 +219,7 @@ folder_id:text(hidden) object_id:text(hidden) context_id:text(hidden) - {to_name:text(inform),optional {label "[_ contacts.Recipients]"} {value $recipients}} + {to_name:text(inform),optional {label "$recipients_label"} {value $recipients}} } if { ![exists_and_not_null message_type] } { Index: openacs-4/packages/contacts/www/admin/group-map.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/admin/group-map.tcl,v diff -u -r1.5 -r1.6 --- openacs-4/packages/contacts/www/admin/group-map.tcl 21 Jun 2007 20:06:42 -0000 1.5 +++ openacs-4/packages/contacts/www/admin/group-map.tcl 27 Jun 2007 23:55:37 -0000 1.6 @@ -11,7 +11,7 @@ {return_url "./"} } -validate { action_valid -requires {action} { - if { [lsearch [list map unmap makedefault] $action] < 0 } { + if { [lsearch [list map unmap makedefault notificationson notificationsoff] $action] < 0 } { ad_complain "[_ contacts.lt_the_action_supplied_i]" } } @@ -82,6 +82,16 @@ update contact_groups set default_p = 't' where package_id = :package_id and group_id = :group_id } } + notificationson { + db_dml notificationson { + update contact_groups set notifications_p = 't' where package_id = :package_id and group_id = :group_id + } + } + notificationsoff { + db_dml notificationsoff { + update contact_groups set notifications_p = 'f' where package_id = :package_id and group_id = :group_id + } + } } Index: openacs-4/packages/contacts/www/admin/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/contacts/www/admin/index.tcl,v diff -u -r1.16 -r1.17 --- openacs-4/packages/contacts/www/admin/index.tcl 25 Jun 2007 16:25:39 -0000 1.16 +++ openacs-4/packages/contacts/www/admin/index.tcl 27 Jun 2007 23:55:37 -0000 1.17 @@ -64,6 +64,19 @@ </if> } } + notifications { + label {Notifications} + display_template { + <if @groups.dotlrn_community_p@ false and @groups.mapped_p@ and @groups.level@ eq 1> + <if @groups.notifications_p@> + <a href="group-map?action=notificationsoff&group_id=@groups.group_id@"><img src="/resources/acs-subsite/checkboxchecked.gif" border="0" height="13" width="13" alt="[_ contacts.True]"></a> + </if> + <else> + <a href="group-map?action=notificationson&group_id=@groups.group_id@"><img src="/resources/acs-subsite/checkbox.gif" border="0" height="13" width="13" alt="[_ contacts.False]"></a> + </else> + </if> + } + } user_change { label {User Change} display_template { @@ -113,18 +126,12 @@ } -multirow create groups group_id group_name group_url ams_person_url ams_org_url member_count level mapped_p default_p categories_url edit_url user_change_p dotlrn_community_p +multirow create groups group_id group_name group_url ams_person_url ams_org_url member_count level mapped_p default_p categories_url edit_url user_change_p dotlrn_community_p notifications_p set return_url [ad_conn url] foreach group [contact::groups -indent_with "..." -expand "all" -output "all" -privilege_required "admin" -all -include_dotlrn_p "1"] { - set group_id [lindex $group 1] - set group_name [lindex $group 0] - set member_count [lindex $group 2] - set level [lindex $group 3] - set mapped_p [lindex $group 4] - set default_p [lindex $group 5] - set user_change_p [lindex $group 6] - set dotlrn_community_p [lindex $group 7] + util_unlist $group group_name group_id member_count level mapped_p default_p user_change_p dotlrn_community_p notifications_p + set ams_person_url [ams::list::url \ -package_key "contacts" \ -object_type "person" \ @@ -144,7 +151,7 @@ set edit_url [export_vars -base "/acs-lang/admin/edit-localized-message" {{package_key acs-translations} {locale "[ad_conn locale]"} {message_key "group_title_${group_id}"} {return_url [ad_return_url]}}] set categories_url [export_vars -base "/categories/cadmin/object-map" -url {{object_id $group_id}}] - multirow append groups [lindex $group 1] [lindex $group 0] "../?group_id=${group_id}" $ams_person_url $ams_org_url $member_count $level $mapped_p $default_p $categories_url $edit_url $user_change_p $dotlrn_community_p + multirow append groups [lindex $group 1] [lindex $group 0] "../?group_id=${group_id}" $ams_person_url $ams_org_url $member_count $level $mapped_p $default_p $categories_url $edit_url $user_change_p $dotlrn_community_p $notifications_p }