• Publicity: Public Only All

calendar-procs.tcl

Utility functions for Calendar Applications

Location:
packages/calendar/tcl/calendar-procs.tcl
Created:
Dec 14, 2000
Authors:
Dirk Gomez <openacs@dirkgomez.de>
Gary Jin <gjin@arsdigita.com>
Ben Adida <ben@openforce.net>
CVS Identification:
$Id: calendar-procs.tcl,v 1.39.2.21 2023/06/06 14:37:01 antoniop Exp $

Procedures in this file

Detailed information

calendar::adjust_date (public, deprecated)

 calendar::adjust_date [ -date date ] [ -julian_date julian_date ]
Deprecated. Invoking this procedure generates a warning.

Switches:
-date (optional)
-julian_date (optional)
Returns:
the date if it is provided. Otherwise, the julian date in ANSI format, if provided, or the system date. DEPRECATED: this proc implements a trivial defaulting logic that can be inlined just as well.
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 ad_log_deprecated ad_log_deprecated (public) dt_julian_to_ansi dt_julian_to_ansi (public) dt_sysdate dt_sysdate (public) calendar::adjust_date calendar::adjust_date calendar::adjust_date->ad_log_deprecated calendar::adjust_date->dt_julian_to_ansi calendar::adjust_date->dt_sysdate

Testcases:
No testcase defined.

calendar::assign_permissions (public, deprecated)

 calendar::assign_permissions calendar_id party_id cal_privilege \
    [ revoke ]
Deprecated. Invoking this procedure generates a warning.

Given a calendar_id, party_id and a permission this proc will assign the permission to the party the legal permissions are: public, private, calendar_read, calendar_write, calendar_delete If the revoke is set, then the given permission will be removed for the party. DEPRECATED: this api is a trivial wrapper to the permission api

Parameters:
calendar_id (required)
party_id (required)
cal_privilege (required)
revoke (optional)
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 calendar_assign_permissions calendar_assign_permissions (public, deprecated) calendar::assign_permissions calendar::assign_permissions calendar_assign_permissions->calendar::assign_permissions acs_magic_object acs_magic_object (public) calendar::assign_permissions->acs_magic_object ad_log_deprecated ad_log_deprecated (public) calendar::assign_permissions->ad_log_deprecated permission::grant permission::grant (public) calendar::assign_permissions->permission::grant permission::revoke permission::revoke (public) calendar::assign_permissions->permission::revoke

Testcases:
No testcase defined.

calendar::attachments_enabled_p (public)

 calendar::attachments_enabled_p [ -package_id package_id ]
Switches:
-package_id (optional)
the package_id, assumed to belong to a calendar package instance. When not specified, we will determine the package from the connection. When no package can be determined, this proc will return 0.
Returns:
1 if the attachments are enabled, otherwise 0.

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_enabled attachments_enabled (test calendar) calendar::attachments_enabled_p calendar::attachments_enabled_p test_attachments_enabled->calendar::attachments_enabled_p ad_conn ad_conn (public) calendar::attachments_enabled_p->ad_conn ad_log ad_log (public) calendar::attachments_enabled_p->ad_log site_node::get_children site_node::get_children (public) calendar::attachments_enabled_p->site_node::get_children site_node::get_node_id_from_object_id site_node::get_node_id_from_object_id (public) calendar::attachments_enabled_p->site_node::get_node_id_from_object_id calendar::item::get calendar::item::get (public) calendar::item::get->calendar::attachments_enabled_p packages/calendar/www/cal-item-view.tcl packages/calendar/ www/cal-item-view.tcl packages/calendar/www/cal-item-view.tcl->calendar::attachments_enabled_p

Testcases:
attachments_enabled

calendar::calendar_list (public)

 calendar::calendar_list [ -package_id package_id ] \
    [ -user_id user_id ] [ -privilege privilege ]
Switches:
-package_id (optional)
-user_id (optional)
-privilege (optional)
Returns:
a list of calendars

Partial Call Graph (max 5 caller/called nodes):
%3 test_cal_item_add_delete cal_item_add_delete (test calendar) calendar::calendar_list calendar::calendar_list test_cal_item_add_delete->calendar::calendar_list ad_conn ad_conn (public) calendar::calendar_list->ad_conn db_list_of_lists db_list_of_lists (public) calendar::calendar_list->db_list_of_lists packages/calendar/www/cal-item-new.tcl packages/calendar/ www/cal-item-new.tcl packages/calendar/www/cal-item-new.tcl->calendar::calendar_list packages/calendar/www/cal-options.tcl packages/calendar/ www/cal-options.tcl packages/calendar/www/cal-options.tcl->calendar::calendar_list packages/calendar/www/view.tcl packages/calendar/ www/view.tcl packages/calendar/www/view.tcl->calendar::calendar_list

Testcases:
cal_item_add_delete

calendar::create (public)

 calendar::create owner_id private_p [ calendar_name ]

Create a new calendar.

Parameters:
owner_id (required)
private_p (required)
defaults to true since the default calendar is a private calendar.
calendar_name (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 test_cal_item_add_delete cal_item_add_delete (test calendar) calendar::create calendar::create test_cal_item_add_delete->calendar::create test_cal_item_edit_recurrence cal_item_edit_recurrence (test calendar) test_cal_item_edit_recurrence->calendar::create ad_conn ad_conn (public) calendar::create->ad_conn db_exec_plsql db_exec_plsql (public) calendar::create->db_exec_plsql permission::set_not_inherit permission::set_not_inherit (public) calendar::create->permission::set_not_inherit calendar_create calendar_create (public, deprecated) calendar_create->calendar::create packages/calendar/www/admin/calendar-create.tcl packages/calendar/ www/admin/calendar-create.tcl packages/calendar/www/admin/calendar-create.tcl->calendar::create

Testcases:
cal_item_edit_recurrence, cal_item_add_delete

calendar::delete (public)

 calendar::delete -calendar_id calendar_id

Delete a calendar

Switches:
-calendar_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_cal_item_add_delete cal_item_add_delete (test calendar) calendar::delete calendar::delete test_cal_item_add_delete->calendar::delete test_calendar_basic_api calendar_basic_api (test calendar) test_calendar_basic_api->calendar::delete db_exec_plsql db_exec_plsql (public) calendar::delete->db_exec_plsql calendar::apm::before_uninstantiate calendar::apm::before_uninstantiate (private) calendar::apm::before_uninstantiate->calendar::delete packages/calendar/www/admin/calendar-delete.tcl packages/calendar/ www/admin/calendar-delete.tcl packages/calendar/www/admin/calendar-delete.tcl->calendar::delete

Testcases:
cal_item_add_delete, calendar_basic_api

calendar::do_notifications (public)

 calendar::do_notifications -mode mode -cal_item_id cal_item_id

Perform the notifications

Switches:
-mode (required)
-cal_item_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_cal_item_add_delete cal_item_add_delete (test calendar) calendar::do_notifications calendar::do_notifications test_cal_item_add_delete->calendar::do_notifications _ _ (public) calendar::do_notifications->_ acs_user::get acs_user::get (public) calendar::do_notifications->acs_user::get ad_conn ad_conn (public) calendar::do_notifications->ad_conn ad_html_to_text ad_html_to_text (public) calendar::do_notifications->ad_html_to_text ad_url ad_url (public) calendar::do_notifications->ad_url calendar::item::edit calendar::item::edit (public) calendar::item::edit->calendar::do_notifications calendar::item::new calendar::item::new (public) calendar::item::new->calendar::do_notifications

Testcases:
cal_item_add_delete

calendar::from_sql_datetime (public, deprecated)

 calendar::from_sql_datetime -sql_date sql_date -format format
Deprecated. Invoking this procedure generates a warning.

Converts a date in a specified format into a templating date dict.

Switches:
-sql_date (required)
a date in one of the supported format.
-format (required)
one of the supported format, "YYYY-MM-DD", "HH12:MIam" or "HH24:MI". When unspecified or invalid, we will try to treat the date as an ansi date. DEPRECATED: this api has been superseded by api in acs-templating.
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 ad_log_deprecated ad_log_deprecated (public) template::util::date::create template::util::date::create (public) template::util::date::set_property template::util::date::set_property (public) calendar::from_sql_datetime calendar::from_sql_datetime calendar::from_sql_datetime->ad_log_deprecated calendar::from_sql_datetime->template::util::date::create calendar::from_sql_datetime->template::util::date::set_property

Testcases:
No testcase defined.

calendar::get (public)

 calendar::get -calendar_id calendar_id [ -array array ]

Get calendar info

Switches:
-calendar_id (required)
-array (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 test_calendar_basic_api calendar_basic_api (test calendar) calendar::get calendar::get test_calendar_basic_api->calendar::get db_1row db_1row (public) calendar::get->db_1row calendar::personal_p calendar::personal_p (public) calendar::personal_p->calendar::get

Testcases:
calendar_basic_api

calendar::get_item_types (public)

 calendar::get_item_types -calendar_id calendar_id

return the item types

Switches:
-calendar_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_calendar_basic_api calendar_basic_api (test calendar) calendar::get_item_types calendar::get_item_types test_calendar_basic_api->calendar::get_item_types db_list_of_lists db_list_of_lists (public) calendar::get_item_types->db_list_of_lists packages/calendar/www/cal-item-new.tcl packages/calendar/ www/cal-item-new.tcl packages/calendar/www/cal-item-new.tcl->calendar::get_item_types packages/calendar/www/calendar-item-types.tcl packages/calendar/ www/calendar-item-types.tcl packages/calendar/www/calendar-item-types.tcl->calendar::get_item_types

Testcases:
calendar_basic_api

calendar::have_private_p (public)

 calendar::have_private_p [ -return_id return_id ] \
    [ -calendar_id_list calendar_id_list ] [ -party_id party_id ]

Check to see if the user has a private calendar. When the provided -return_id is 1, then proc will return the calendar_id

Switches:
-return_id (optional, defaults to "0")
when set to 1, this proc will return the calendar_id
-calendar_id_list (optional)
If you supply the calendar_id_list, then we'll only search for a personal calendar among the calendars supplied here.
-party_id (optional, defaults to "party_id")
Returns:
boolean or the calendar_id according to 'return_id' flag.

Partial Call Graph (max 5 caller/called nodes):
%3 test_cal_item_add_delete cal_item_add_delete (test calendar) calendar::have_private_p calendar::have_private_p test_cal_item_add_delete->calendar::have_private_p db_string db_string (public) calendar::have_private_p->db_string calendar_have_private_p calendar_have_private_p (public, deprecated) calendar_have_private_p->calendar::have_private_p packages/calendar/www/cal-item-new.tcl packages/calendar/ www/cal-item-new.tcl packages/calendar/www/cal-item-new.tcl->calendar::have_private_p packages/calendar/www/index.tcl packages/calendar/ www/index.tcl packages/calendar/www/index.tcl->calendar::have_private_p

Testcases:
cal_item_add_delete

calendar::item_type_delete (public)

 calendar::item_type_delete -calendar_id calendar_id \
    -item_type_id item_type_id

Delete an item type

Switches:
-calendar_id (required)
-item_type_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_calendar_basic_api calendar_basic_api (test calendar) calendar::item_type_delete calendar::item_type_delete test_calendar_basic_api->calendar::item_type_delete db_dml db_dml (public) calendar::item_type_delete->db_dml db_transaction db_transaction (public) calendar::item_type_delete->db_transaction calendar::apm::before_uninstantiate calendar::apm::before_uninstantiate (private) calendar::apm::before_uninstantiate->calendar::item_type_delete packages/calendar/www/item-type-delete.tcl packages/calendar/ www/item-type-delete.tcl packages/calendar/www/item-type-delete.tcl->calendar::item_type_delete

Testcases:
calendar_basic_api

calendar::item_type_new (public)

 calendar::item_type_new -calendar_id calendar_id \
    [ -item_type_id item_type_id ] -type type

creates a new item type

Switches:
-calendar_id (required)
-item_type_id (optional)
-type (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_calendar_basic_api calendar_basic_api (test calendar) calendar::item_type_new calendar::item_type_new test_calendar_basic_api->calendar::item_type_new db_dml db_dml (public) calendar::item_type_new->db_dml db_nextval db_nextval (public) calendar::item_type_new->db_nextval packages/calendar/www/item-type-new.tcl packages/calendar/ www/item-type-new.tcl packages/calendar/www/item-type-new.tcl->calendar::item_type_new

Testcases:
calendar_basic_api

calendar::make_datetime (public, deprecated)

 calendar::make_datetime event_date [ event_time ]
Deprecated. Invoking this procedure generates a warning.

given a date, and a time, construct the proper date string to be imported into oracle. (yyyy-mm-dd hh24:mi format)s DEPRECATED: clock idioms and HTML5 feature make this date conversion api less useful

Parameters:
event_date (required)
event_time (optional)
See Also:
  • clock

Partial Call Graph (max 5 caller/called nodes):
%3 calendar_make_datetime calendar_make_datetime (public, deprecated) calendar::make_datetime calendar::make_datetime calendar_make_datetime->calendar::make_datetime ad_log_deprecated ad_log_deprecated (public) calendar::make_datetime->ad_log_deprecated

Testcases:
No testcase defined.

calendar::name (public)

 calendar::name calendar_id

Return a calendar's name

Parameters:
calendar_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_calendar_basic_api calendar_basic_api (test calendar) calendar::name calendar::name test_calendar_basic_api->calendar::name db_string db_string (public) calendar::name->db_string packages/calendar/www/admin/calendar-edit.tcl packages/calendar/ www/admin/calendar-edit.tcl packages/calendar/www/admin/calendar-edit.tcl->calendar::name

Testcases:
calendar_basic_api

calendar::new (public)

 calendar::new -owner_id owner_id [ -private_p private_p ] \
    -calendar_name calendar_name [ -package_id package_id ]

Create a new calendar

Switches:
-owner_id (required)
-private_p (optional, defaults to "f")
-calendar_name (required)
-package_id (optional)
Returns:
the new calendar_id

Partial Call Graph (max 5 caller/called nodes):
%3 test_calendar_basic_api calendar_basic_api (test calendar) calendar::new calendar::new test_calendar_basic_api->calendar::new ad_conn ad_conn (public) calendar::new->ad_conn package_instantiate_object package_instantiate_object (public) calendar::new->package_instantiate_object packages/calendar/www/admin/calendar-edit.tcl packages/calendar/ www/admin/calendar-edit.tcl packages/calendar/www/admin/calendar-edit.tcl->calendar::new packages/calendar/www/cal-item-new.tcl packages/calendar/ www/cal-item-new.tcl packages/calendar/www/cal-item-new.tcl->calendar::new packages/calendar/www/index.tcl packages/calendar/ www/index.tcl packages/calendar/www/index.tcl->calendar::new

Testcases:
calendar_basic_api

calendar::notification::get_url (public)

 calendar::notification::get_url object_id
Parameters:
object_id (required)
Returns:
a full URL to the object_id

Partial Call Graph (max 5 caller/called nodes):
%3 test_cal_item_add_delete cal_item_add_delete (test calendar) calendar::notification::get_url calendar::notification::get_url test_cal_item_add_delete->calendar::notification::get_url site_node::get_url_from_object_id site_node::get_url_from_object_id (public) calendar::notification::get_url->site_node::get_url_from_object_id AcsSc.notificationtype.geturl.calendar_notif_type AcsSc.notificationtype.geturl.calendar_notif_type (private) AcsSc.notificationtype.geturl.calendar_notif_type->calendar::notification::get_url

Testcases:
cal_item_add_delete

calendar::personal_p (public)

 calendar::personal_p -calendar_id calendar_id [ -user_id user_id ]
Switches:
-calendar_id (required)
-user_id (optional)
The user whose calendar you want to check
Returns:
true (1) if this is the user's personal calendar, false (0) otherwise.

Partial Call Graph (max 5 caller/called nodes):
%3 test_cal_item_add_delete cal_item_add_delete (test calendar) calendar::personal_p calendar::personal_p test_cal_item_add_delete->calendar::personal_p ad_conn ad_conn (public) calendar::personal_p->ad_conn calendar::get calendar::get (public) calendar::personal_p->calendar::get calendar::item::new calendar::item::new (public) calendar::item::new->calendar::personal_p packages/calendar/www/cal-item-new.tcl packages/calendar/ www/cal-item-new.tcl packages/calendar/www/cal-item-new.tcl->calendar::personal_p packages/calendar/www/view.tcl packages/calendar/ www/view.tcl packages/calendar/www/view.tcl->calendar::personal_p

Testcases:
cal_item_add_delete

calendar::rename (public)

 calendar::rename -calendar_id calendar_id -calendar_name calendar_name

rename a calendar

Switches:
-calendar_id (required)
-calendar_name (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_calendar_basic_api calendar_basic_api (test calendar) calendar::rename calendar::rename test_calendar_basic_api->calendar::rename db_dml db_dml (public) calendar::rename->db_dml packages/calendar/www/admin/calendar-edit.tcl packages/calendar/ www/admin/calendar-edit.tcl packages/calendar/www/admin/calendar-edit.tcl->calendar::rename

Testcases:
calendar_basic_api

calendar::to_sql_datetime (public, deprecated)

 calendar::to_sql_datetime -date date -time time [ -time_p time_p ]
Deprecated. Invoking this procedure generates a warning.

This takes two date chunks, one for date one for time, and combines them correctly. The issue here is the incoming format. date: ANSI SQL YYYY-MM-DD time: we return HH24. DEPRECATED: this api has been superseded by api in acs-templating.

Switches:
-date (required)
-time (required)
-time_p (optional, defaults to "1")
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 ad_log_deprecated ad_log_deprecated (public) template::util::date::get_property template::util::date::get_property (public) calendar::to_sql_datetime calendar::to_sql_datetime calendar::to_sql_datetime->ad_log_deprecated calendar::to_sql_datetime->template::util::date::get_property

Testcases:
No testcase defined.
[ hide source ] | [ make this the default ]

Content File Source

# /packages/calendar/tcl/calendar-procs.tcl

ad_library {

    Utility functions for Calendar Applications

    @author Dirk Gomez (openacs@dirkgomez.de)
    @author Gary Jin (gjin@arsdigita.com)
    @author Ben Adida (ben@openforce.net)
    @creation-date Dec 14, 2000
    @cvs-id $Id: calendar-procs.tcl,v 1.39.2.21 2023/06/06 14:37:01 antoniop Exp $

}

namespace eval calendar {}
namespace eval calendar::notification {}

d_proc -deprecated calendar::make_datetime {
    event_date
    {event_time ""}
} {
    given a date, and a time, construct the proper date string
    to be imported into oracle. (yyyy-mm-dd hh24:mi format)s

    DEPRECATED: clock idioms and HTML5 feature make this date
                conversion api less useful

    @see clock
} {

    # MUST CONVERT TO ARRAYS! (ben)
    array set event_date_arr $event_date
    if {$event_time ne ""} {
        array set event_time_arr $event_time
    }

    # extract from even-date
    set year   $event_date_arr(year)
    set day    $event_date_arr(day)
    set month  $event_date_arr(month)

    if {$event_time ne ""} {
        # extract from event_time
        set hours $event_time_arr(hours)
        set minutes $event_time_arr(minutes)

        # AM/PM? (ben - OpenACS fix)
        if {[info exists event_time_arr(ampm)]} {
            if {$event_time_arr(ampm)} {
                if {$hours < 12} {
                    incr hours 12
                }
            } else {
                # This is the case where we're dealing with AM/PM
                # The one issue we have to worry about is 12am
                if {!$event_time_arr(ampm) && $hours == 12} {
                    set hours 0
                }
            }
        }

        if {$hours < 10} {
            set hours "0$hours"
        }
    }

    if {$month < 10} {
        set month "0$month"
    }

    if {$day < 10} {
        set day "0$day"
    }

    if {$event_time eq ""} {
        return "$year-$month-$day"
    } else {
        return "$year-$month-$day $hours:$minutes"
    }
}

d_proc calendar::create {
    owner_id
    private_p
    {calendar_name ""}
} {
    Create a new calendar.

    @param private_p defaults to true since the default calendar is a
                     private calendar.
} {

    # find out configuration info
    set package_id [ad_conn package_id]
    set creation_ip [ad_conn "peeraddr"]
    set creation_user [ad_conn "user_id"]

    # BMA:FIXME: this needs to be fixed a LOT more, but for now we patch the obvious
    if {$creation_user == 0} {
        set creation_user $owner_id
    }

    set calendar_id [db_exec_plsql create_new_calendar {
        begin
        :1 := calendar.new(
          owner_id      => :owner_id,
          private_p     => :private_p,
          calendar_name => :calendar_name,
          package_id    => :package_id,
          creation_user => :creation_user,
          creation_ip   => :creation_ip
        );
        end;
    }
    ]
    #removing inherited permissions
    permission::set_not_inherit -object_id $calendar_id

    return $calendar_id

}

d_proc -deprecated calendar::assign_permissions {
    calendar_id
    party_id
    cal_privilege
    {revoke ""}
} {
    Given a calendar_id, party_id and a permission this proc will
    assign the permission to the party the legal permissions are:

    public, private, calendar_read, calendar_write, calendar_delete

    If the revoke is set, then the given permission will be removed
    for the party.

    DEPRECATED: this api is a trivial wrapper to the permission api

    @see permission::grant
    @see permission::revoke
} {
    # Default privilege is being able to read.

    # If the permission is public, assign the magic object and set
    # permission to read.

    if {$cal_privilege eq "public"} {
        set party_id [acs_magic_object "the_public"]
        set cal_privilege "calendar_read"
    } elseif {$cal_privilege eq "private"} {
        set cal_privilege "calendar_read"
    }

    if { $revoke eq "" } {
        # grant the permissions
        permission::grant -object_id $calendar_id -party_id $party_id -privilege $cal_privilege
    } elseif {$revoke eq "revoke"} {
        # revoke the permissions
        permission::revoke -object_id $calendar_id -party_id $party_id -privilege $cal_privilege
    }
}

d_proc -public calendar::have_private_p {
    {-return_id 0}
    {-calendar_id_list {}}
    {-party_id party_id }
} {
    Check to see if the user has a private calendar.

    When the provided -return_id is 1, then proc will return the
    calendar_id

    @param calendar_id_list If you supply the calendar_id_list, then
                            we'll only search for a personal calendar
                            among the calendars supplied here.
    @param return_id when set to 1, this proc will return the
                     calendar_id

    @return boolean or the calendar_id according to 'return_id' flag.
} {
    # Check whether the user is logged in at all
    if { !$party_id } {
        return -1
    }

    if { [llength $calendar_id_list] > 0 } {
        set result [db_string get_calendar_info_calendar_id_list {} -default 0]
    } else {
        set result [db_string get_calendar_info {} -default 0]
    }

    if { $result != 0 } {
        if { $return_id == 1 } {
            return $result
        } else {
            return 1
        }
    } else {
        return 0
    }
}


ad_proc -public calendar::name { calendar_id } {
    Return a calendar's name
} {
    return [db_string get_calendar_name {} -default ""]
}


d_proc -private calendar::get_month_multirow_information {
    {-current_day:required}
    {-today_julian_date:required}
    {-first_julian_date_of_month:required}
} {
    Builds a multirow with information about the month. Used to
    display the month calendar view.

    @author Dirk Gomez (openacs@dirkgomez.de)
    @creation-date 20-July-2003
} {
    set first_day_of_week [lc_get firstdayofweek]
    set last_day_of_week [expr {($first_day_of_week + 6) % 7}]

    if {$current_day == $today_julian_date} {
        set today_p t
    } else {
        set today_p f
    }
    set day_number [expr {$current_day - $first_julian_date_of_month +1}]
    set weekday [expr {($current_day + 1) % 7}]

    set beginning_of_week_p f
    set end_of_week_p f
    if {$weekday == $last_day_of_week} {
        set end_of_week_p t
    } elseif {$weekday == $first_day_of_week} {
        set beginning_of_week_p t
    }
    return [list day_number $day_number \
                today_p $today_p \
                beginning_of_week_p $beginning_of_week_p \
                end_of_week_p $end_of_week_p \
                weekday $weekday]
}

d_proc -deprecated calendar::from_sql_datetime {
    {-sql_date:required}
    {-format:required}
} {
    Converts a date in a specified format into a templating date dict.

    @param sql_date a date in one of the supported format.
    @param format one of the supported format, "YYYY-MM-DD",
                  "HH12:MIam" or "HH24:MI". When unspecified or
                  invalid, we will try to treat the date as an ansi
                  date.

    DEPRECATED: this api has been superseded by api in acs-templating.

    @see template::data::from_sql::date
} {
    # for now, we recognize only "YYYY-MM-DD" "HH12:MIam" and "HH24:MI".
    set date [template::util::date::create]

    switch -exact -- $format {
        {YYYY-MM-DD} {
            regexp {([0-9]*)-([0-9]*)-([0-9]*)} $sql_date all year month day

            set date [template::util::date::set_property format $date {DD MONTH YYYY}]
            set date [template::util::date::set_property year $date $year]
            set date [template::util::date::set_property month $date $month]
            set date [template::util::date::set_property day $date $day]
        }

        {HH12:MIam} {
            regexp {([0-9]*):([0-9]*) *([aApP][mM])} $sql_date all hours minutes ampm

            set date [template::util::date::set_property format $date {HH12:MI am}]
            set date [template::util::date::set_property hours $date $hours]
            set date [template::util::date::set_property minutes $date $minutes]
            set date [template::util::date::set_property ampm $date [string tolower $ampm]]
        }

        {HH24:MI} {
            regexp {([0-9]*):([0-9]*)} $sql_date all hours minutes

            set date [template::util::date::set_property format $date {HH24:MI}]
            set date [template::util::date::set_property hours $date $hours]
            set date [template::util::date::set_property minutes $date $minutes]
        }

        {HH24} {
            set date [template::util::date::set_property format $date {HH24:MI}]
            set date [template::util::date::set_property hours $date $sql_date]
            set date [template::util::date::set_property minutes $date 0]
        }
        default {
            set date [template::util::date::set_property ansi $date $sql_date]
        }
    }

    return $date
}

d_proc -deprecated calendar::to_sql_datetime {
    {-date:required}
    {-time:required}
    {-time_p 1}
} {
    This takes two date chunks, one for date one for time,
    and combines them correctly.

    The issue here is the incoming format.
    date: ANSI SQL YYYY-MM-DD
    time: we return HH24.

    DEPRECATED: this api has been superseded by api in acs-templating.

    @see template::data::to_sql::date
} {
    # Set the time to 0 if necessary
    if {!$time_p} {
        set hours 0
        set minutes 0
    } else {
        set hours [template::util::date::get_property hours $time]
        set minutes [template::util::date::get_property minutes $time]
    }

    set year [template::util::date::get_property year $date]
    set month [template::util::date::get_property month $date]
    set day [template::util::date::get_property day $date]

    # put together the timestamp
    return "$year-$month-$day $hours:$minutes"
}

d_proc -public calendar::calendar_list {
    {-package_id ""}
    {-user_id ""}
    {-privilege ""}
} {
    @return a list of calendars
} {
    # If no user_id
    if {$user_id eq ""} {
        set user_id [ad_conn user_id]
    }

    if {$package_id eq ""} {
        set package_id [ad_conn package_id]
    }

    set permissions_clause {}
    if { $privilege ne "" } {
        set permissions_clause {and acs_permission.permission_p(calendar_id, :user_id, :privilege)}
    }

    set new_list [db_list_of_lists select_calendar_list [subst {
       select calendar_name,
              calendar_id,
              acs_permission.permission_p(calendar_id, :user_id, 'calendar_admin') as calendar_admin_p
       from   calendars
       where  (private_p = 'f' and package_id = :package_id $permissions_clause) or
              (private_p = 't' and owner_id = :user_id)
       order  by private_p asc, upper(calendar_name)
    }]]
}

d_proc -deprecated calendar::adjust_date {
    {-date ""}
    {-julian_date ""}
} {
    @return the date if it is provided. Otherwise, the julian date in ANSI
            format, if provided, or the system date.

    DEPRECATED: this proc implements a trivial defaulting logic that
                can be inlined just as well.

    @see dt_sysdate
    @see dt_julian_to_ansi
} {
    if {$date eq ""} {
        if {$julian_date ne ""} {
            set date [dt_julian_to_ansi $julian_date]
        } else {
            set date [dt_sysdate]
        }
    }

    return $date
}

d_proc -public calendar::new {
    {-owner_id:required}
    {-private_p "f"}
    {-calendar_name:required}
    {-package_id ""}
} {
    Create a new calendar

    @return the new calendar_id
} {
    if { $package_id eq "" } {
        set package_id [ad_conn package_id]
    }
    set extra_vars [ns_set create s \
                        owner_id $owner_id \
                        private_p $private_p \
                        calendar_name $calendar_name \
                        package_id $package_id \
                        context_id $package_id]

    set calendar_id [package_instantiate_object -extra_vars $extra_vars calendar]

    return $calendar_id
}

d_proc -public calendar::personal_p {
    {-calendar_id:required}
    {-user_id ""}
} {
    @return true (1) if this is the user's personal calendar, false (0) otherwise.

    @param user_id The user whose calendar you want to check
} {
    if { $user_id eq "" } {
        set user_id [ad_conn user_id]
    }
    calendar::get -calendar_id $calendar_id -array calendar
    if { [string is true -strict $calendar(private_p)] && $calendar(owner_id) == $user_id } {
        return 1
    } else {
        return 0
    }
}

d_proc -public calendar::get {
    {-calendar_id:required}
    {-array}
} {
    Get calendar info
} {
    if {[info exists array]} {
        upvar 1 $array row
    }
    db_1row select_calendar {} -column_array row
    return [array get row]
}


d_proc -public calendar::delete {
    {-calendar_id:required}
} {
    Delete a calendar
} {
    db_exec_plsql delete_calendar {}
}

d_proc -public calendar::get_item_types {
    {-calendar_id:required}
} {
    return the item types
} {
    return [list {{--} {}} {*}[db_list_of_lists select_item_types {}]]
}

d_proc -public calendar::item_type_new {
    {-calendar_id:required}
    {-item_type_id ""}
    {-type:required}
} {
    creates a new item type
} {
    if {$item_type_id eq ""} {
        set item_type_id [db_nextval cal_item_type_seq]
    }

    db_dml insert_item_type {}

    return $item_type_id
}

d_proc -public calendar::item_type_delete {
    {-calendar_id:required}
    {-item_type_id:required}
} {
    Delete an item type
} {
    db_transaction {
        # Remove the mappings for all events
        db_dml reset_item_types {}

        # Remove the item type
        db_dml delete_item_type {}
    }
}

d_proc -public calendar::attachments_enabled_p {
    -package_id
} {
    @param package_id the package_id, assumed to belong to a calendar
                      package instance. When not specified, we will
                      determine the package from the connection. When
                      no package can be determined, this proc will
                      return 0.

    @return 1 if the attachments are enabled, otherwise 0.
} {
    if {![info exists package_id]} {
        if {[ns_conn isconnected]} {
            set package_id [ad_conn package_id]
        } else {
            ad_log warning "calendar attachments: Cannot determine package_id. Returning 0"
            return 0
        }
    }

    set node_id [site_node::get_node_id_from_object_id -object_id $package_id]
    set nodes [site_node::get_children -package_key attachments -node_id $node_id]

    return [expr {[llength $nodes] > 0}]
}

d_proc -public calendar::rename {
    {-calendar_id:required}
    {-calendar_name:required}
} {
    rename a calendar
} {
    db_dml rename_calendar {}
}

ad_proc -private calendar::compare_day_items_by_current_hour {a b} {
    Compare a day item by the current hour (field 0).
    This is needed by the one-day view for sorting.
} {
    set a_criterium [lindex $a 0]
    set b_criterium [lindex $b 0]
    if {$a_criterium > $b_criterium} {
        return 1
    } elseif {$a_criterium < $b_criterium} {
        return -1
    }
    return 0
}

d_proc -public calendar::do_notifications {
    {-mode:required}
    {-cal_item_id:required}
} {
    Perform the notifications
} {
    # Select all the important information
    calendar::item::get -cal_item_id $cal_item_id -array cal_item

    set cal_item_id $cal_item(cal_item_id)
    set n_attachments $cal_item(n_attachments)
    set ansi_start_date $cal_item(start_date_ansi)
    set ansi_end_date $cal_item(end_date_ansi)
    set start_time $cal_item(start_time)
    set end_time $cal_item(end_time)
    set title $cal_item(name)
    set description $cal_item(description)
    set repeat_p $cal_item(recurrence_id)
    set item_type $cal_item(item_type)
    set item_type_id $cal_item(item_type_id)
    set calendar_id $cal_item(calendar_id)
    set time_p $cal_item(time_p)

    set url "[ad_url][ad_conn package_url]"

    set new_content ""
    append new_content "[_ calendar.Calendar]:  <a href=\"[ns_quotehtml $url]\">[ad_conn instance_name]</a><br>\n"
    append new_content "[_ calendar.Calendar_Item]: <a href=\"[ns_quotehtml ${url}cal-item-view?cal_item_id=$cal_item_id]\">$cal_item(name)</a><br>\n"
    append new_content "[_ calendar.Start_Time]: $cal_item(start_date_ansi) $cal_item(start_time)<br>\n"
    append new_content "[_ calendar.to]: $cal_item(end_date_ansi) $cal_item(end_time)<br>\n"

    if {$repeat_p ne "" && $repeat_p} {
        append new_content "[_ calendar.is_recurring]"
    }

    append new_content "\n<br>\n"
    append new_content $cal_item(description)

    acs_user::get -user_id $cal_item(creation_user) -array user_info
    append new_content "<br>Author: <a href=\"mailto:$user_info(email)\">$user_info(first_names) $user_info(last_name)</a><br>\n"

    # send text for now.
    set new_content [ad_html_to_text -- $new_content]

    if {[lang::message::message_exists_p en_US calendar.$mode]} {
        set mode [_ calendar.$mode]
    }

    # Do the notification for the calendar
    notification::new \
        -type_id [notification::type::get_type_id \
        -short_name calendar_notif] \
        -object_id [ad_conn package_id] \
        -response_id $cal_item(cal_item_id) \
        -notif_subject "$mode [_ calendar.Calendar_Item]: $cal_item(name)" \
        -notif_text $new_content

}


d_proc -public calendar::notification::get_url {
    object_id
} {
    @return a full URL to the object_id
} {
    return [site_node::get_url_from_object_id -object_id $object_id]
}



# Local variables:
#    mode: tcl
#    tcl-indent-level: 4
#    indent-tabs-mode: nil
# End: