4 * Web Service functionality for reminders.
5 * Uses XML (but not SOAP at this point since that would be
6 * overkill and require extra packages to install).
9 * Some of this code was borrowed from send_reminders.php.
11 * This functionality works somewhat independent of the email-based
12 * send_reminders.php script. If the end user intends to use
13 * client-side reminders, they should set "Event Reminders" to "No"
14 * in the "Email" section on the Prefernces page.
16 * This is read-only for the client side, so the client must
17 * keep track of whether or not they have displayed the reminder
18 * to the user. (No where in the database will it be recorded that
19 * the user received a reminder through this functionality.)
21 * Client apps must use the same authentication as the web browser.
22 * If WebCalendar is setup to use web-based authentication, then
23 * the login.php found in this directory should be used to obtain
28 // How many days ahead should we look for events.
29 // To handle case of an event 30 days from now where the user asked
30 // for a reminder 30 days before the event.
31 $DAYS_IN_ADVANCE = 30;
32 //$DAYS_IN_ADVANCE = 365;
35 // Show reminders for the next N days
39 // Load include files.
40 $basedir = ".."; // points to the base WebCalendar directory relative to
41 // current working directory
42 $includedir = "../includes";
44 include "$includedir/config.php";
45 include "$includedir/php-dbi.php";
46 include "$includedir/functions.php";
47 include "$includedir/$user_inc";
48 include "$includedir/validate.php";
49 include "$includedir/connect.php";
50 load_global_settings ();
51 load_user_preferences ();
52 include "$includedir/site_extras.php";
54 include "$includedir/translate.php";
56 $debug = false; // set to true to print debug info...
58 Header ( "Content-type: text/xml" );
59 //Header ( "Content-type: text/plain" );
61 echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
64 // If login is public user, make sure public can view others...
65 if ( $login == "__public__" && $login != $user ) {
66 if ( $public_access_others != 'Y' ) {
67 echo "<error>" . translate("Not authorized") . "</error>\n";
68 echo "</reminders>\n";
71 echo "<!-- Allowing public user to view other user's calendar -->\n";
74 if ( empty ( $user ) )
77 // If viewing different user then yourself...
78 if ( $login != $user ) {
79 if ( $allow_view_other != 'Y' ) {
80 echo "<error>" . translate("Not authorized") . "</error>\n";
81 echo "</reminders>\n";
84 echo "<!-- Allowing user to view other user's calendar -->\n";
87 // Make sure this user has enabled email reminders.
88 //if ( $EMAIL_REMINDER == 'N' ) {
89 // echo "Error: email reminders disabled for user \"$user\"\n";
94 $startdate = date ( "Ymd" );
95 $enddate = date ( "Ymd", time() + ( $DAYS_IN_ADVANCE * 24 * 3600 ) );
97 // Now read events all the repeating events
98 $repeated_events = query_events ( $user, true,
99 "AND (webcal_entry_repeats.cal_end > $startdate OR " .
100 "webcal_entry_repeats.cal_end IS NULL) " );
102 // Read non-repeating events
104 echo "Checking for events for $user from date $startdate to date $enddate\n";
105 $events = read_events ( $user, $startdate, $enddate );
107 echo "Found " . count ( $events ) . " events in time range.\n";
110 function indent ( $str ) {
111 return " " . str_replace ( "\n", "\n ", $str );
115 function escapeXml ( $str )
117 return ( str_replace ( "<", "<", str_replace ( ">", ">", $str ) ) );
120 // Send a reminder for a single event for a single day.
121 function list_reminder ( $id, $event_date, $remind_time ) {
122 global $site_extras, $debug,
123 $server_url, $application_name;
124 global $EXTRA_TEXT, $EXTRA_MULTILINETEXT, $EXTRA_URL, $EXTRA_DATE,
125 $EXTRA_EMAIL, $EXTRA_USER, $EXTRA_REMINDER, $LANGUAGE, $LOG_REMINDER;
127 $pri[1] = translate("Low");
128 $pri[2] = translate("Medium");
129 $pri[3] = translate("High");
131 // get participants first...
133 $sql = "SELECT cal_login FROM webcal_entry_user " .
134 "WHERE cal_id = $id AND cal_status IN ('A','W') " .
135 "ORDER BY cal_login";
136 $res = dbi_query ( $sql );
137 $participants = array ();
138 $num_participants = 0;
140 while ( $row = dbi_fetch_row ( $res ) ) {
141 $participants[$num_participants++] = $row[0];
145 // get external participants
146 $ext_participants = array ();
147 $num_ext_participants = 0;
148 if ( ! empty ( $allow_external_users ) && $allow_external_users == "Y" &&
149 ! empty ( $external_reminders ) && $external_reminders == "Y" ) {
150 $sql = "SELECT cal_fullname, cal_email FROM webcal_entry_ext_user " .
151 "WHERE cal_id = $id AND cal_email IS NOT NULL " .
152 "ORDER BY cal_fullname";
153 $res = dbi_query ( $sql );
155 while ( $row = dbi_fetch_row ( $res ) ) {
156 $ext_participants[$num_ext_participants] = $row[0];
157 $ext_participants_email[$num_ext_participants++] = $row[1];
162 if ( ! $num_participants && ! $num_ext_participants ) {
164 echo "No participants found for event id: $id\n";
171 "SELECT cal_create_by, cal_date, cal_time, cal_mod_date, " .
172 "cal_mod_time, cal_duration, cal_priority, cal_type, cal_access, " .
173 "cal_name, cal_description FROM webcal_entry WHERE cal_id = $id" );
175 echo "Db error: could not find event id $id.\n";
180 if ( ! ( $row = dbi_fetch_row ( $res ) ) ) {
181 echo "Error: could not find event id $id in database.\n";
185 $create_by = $row[0];
187 $description = $row[10];
190 echo " <remindDate>" . date ( "Ymd", $remind_time ) . "</remindDate>\n";
191 echo " <remindTime>" . date ( "Hi", $remind_time ) . "</remindTime>\n";
192 echo " <untilRemind>" . ( $remind_time - time() ) . "</untilRemind>\n";
194 echo " <id>$id</id>\n";
195 echo " <name>" . escapeXml ( $name ) . "</name>\n";
196 if ( ! empty ( $server_url ) ) {
197 if ( substr ( $server_url, -1, 1 ) == "/" ) {
198 echo " <url>" . $server_url . "view_entry.php?id=" . $id . "</url>\n";
200 echo " <url>" . $server_url . "/view_entry.php?id=" . $id . "</url>\n";
203 echo " <description>" . escapeXml ( $description ) . "</description>\n";
204 echo " <dateFormatted>" . date_to_str ( $event_date ) . "</dateFormatted>\n";
205 echo " <date>" . $event_date . "</date>\n";
206 if ( $row[2] >= 0 ) {
207 echo " <time>" . sprintf ( "%04d", $row[2] / 100 ) . "</time>\n";
208 echo " <timeFormatted>" . display_time ( $row[2] ) . "</timeFormatted>\n";
211 echo " <duration>" . $row[5] . "</duration>\n";
212 if ( ! $disable_priority_field )
213 echo " <priority>" . $pri[$row[6]] . "</priority>\n";
214 if ( ! $disable_access_field )
216 ( $row[8] == "P" ? translate("Public") : translate("Confidential") ) .
218 if ( ! strlen ( $single_user_login ) )
219 echo " <createdBy>" . $row[0] . "</createdBy>\n";
220 echo " <updateDate>" . date_to_str ( $row[3] ) . "</updateDate>\n";
221 echo " <updateTime>" . display_time ( $row[4] ) . "</updateTime>\n";
224 $extras = get_site_extra_fields ( $id );
225 echo " <siteExtras>\n";
226 for ( $i = 0; $i < count ( $site_extras ); $i++ ) {
227 $extra_name = $site_extras[$i][0];
228 $extra_descr = $site_extras[$i][1];
229 $extra_type = $site_extras[$i][2];
230 if ( $extras[$extra_name]['cal_name'] != "" ) {
231 $tag = preg_replace ( "/[^A-Za-z0-9]+/", "", translate ( $extra_descr ) );
232 $tag = strtolower ( $tag );
233 $tagname = str_replace ( '"', '', $extra_name );
234 echo " <siteExtra>\n";
235 echo " <number>$i</number>\n";
236 echo " <name>" . escapeXml ( $extra_name ) . "</name>\n";
237 echo " <description>" . escapeXml ( $extra_descr ) . "</description>\n";
238 echo " <type>" . $extra_type . "</type>\n";
240 if ( $extra_type == $EXTRA_DATE ) {
241 //echo date_to_str ( $extras[$extra_name]['cal_date'] );
242 echo $extras[$extra_name]['cal_date'];
243 } else if ( $extra_type == $EXTRA_MULTILINETEXT ) {
244 echo escapeXml ( $extras[$extra_name]['cal_data'] );
245 } else if ( $extra_type == $EXTRA_REMINDER ) {
246 echo ( $extras[$extra_name]['cal_remind'] > 0 ?
247 translate("Yes") : translate("No") );
249 // default method for $EXTRA_URL, $EXTRA_TEXT, etc...
250 echo escapeXml ( $extras[$extra_name]['cal_data'] );
252 echo "</value>\n </siteExtra>\n";
255 echo " </siteExtras>\n";
256 if ( $single_user != "Y" && ! $disable_participants_field ) {
257 echo " <participants>\n";
258 for ( $i = 0; $i < count ( $participants ); $i++ ) {
259 echo " <participant>" . $participants[$i] .
262 for ( $i = 0; $i < count ( $ext_participants ); $i++ ) {
263 echo " <participant>" . $ext_participants[$i] .
266 echo " </participants>\n";
269 echo "</reminder>\n";
275 // Process an event for a single day. Check to see if it has
276 // a reminder, when it needs to be sent and when the last time it
278 function process_event ( $id, $name, $event_date, $event_time ) {
279 global $site_extras, $debug;
280 global $EXTRA_REMINDER_WITH_OFFSET, $EXTRA_REMINDER_WITH_DATE, $CUTOFF;
283 printf ( "Event %d: \"%s\" at %s on %s \n",
284 $id, $name, $event_time, $event_date );
286 // Check to see if this event has any reminders
287 $extras = get_site_extra_fields ( $id );
288 for ( $j = 0; $j < count ( $site_extras ); $j++ ) {
289 $extra_name = $site_extras[$j][0];
290 $extra_type = $site_extras[$j][2];
291 $extra_arg1 = $site_extras[$j][3];
292 $extra_arg2 = $site_extras[$j][4];
294 // printf ( " name: %s\n type: %d\n arg1: %s\n arg2: %s\n",
295 // $extra_name, $extra_type, $extra_arg1, $extra_arg2 );
296 if ( ! empty ( $extras[$extra_name]['cal_remind'] ) ) {
298 echo " Reminder set for event. \n";
299 // how many minutes before event should we send the reminder?
300 $ev_h = (int) ( $event_time / 10000 );
301 $ev_m = ( $event_time / 100 ) % 100;
302 $ev_year = substr ( $event_date, 0, 4 );
303 $ev_month = substr ( $event_date, 4, 2 );
304 $ev_day = substr ( $event_date, 6, 2 );
305 $event_time = mktime ( $ev_h, $ev_m, 0, $ev_month, $ev_day, $ev_year );
306 if ( ( $extra_arg2 & $EXTRA_REMINDER_WITH_OFFSET ) > 0 ) {
307 $minsbefore = $extras[$extra_name]['cal_data'];
308 $remind_time = $event_time - ( $minsbefore * 60 );
309 } else if ( ( $extra_arg2 & $EXTRA_REMINDER_WITH_DATE ) > 0 ) {
310 $rd = $extras[$extra_name]['cal_date'];
311 $r_year = substr ( $rd, 0, 4 );
312 $r_month = substr ( $rd, 4, 2 );
313 $r_day = substr ( $rd, 6, 2 );
314 $remind_time = mktime ( 0, 0, 0, $r_month, $r_day, $r_year );
316 $minsbefore = $extra_arg1;
317 $remind_time = $event_time - ( $minsbefore * 60 );
320 echo " Mins Before: $minsbefore \n";
322 echo " Event time is: " . date ( "m/d/Y H:i", $event_time ) . "\n";
323 echo " Remind time is: " . date ( "m/d/Y H:i", $remind_time ) . "\n";
326 if ( time() >= $remind_time - ( $CUTOFF * 24 * 3600 ) ) {
328 echo " SENDING REMINDER! \n";
329 list_reminder ( $id, $event_date, $remind_time );
336 echo "<!-- reminders for user \"$user\", login \"$login\" -->\n";
338 $startdate = time(); // today
339 for ( $d = 0; $d < $DAYS_IN_ADVANCE; $d++ ) {
340 $date = date ( "Ymd", time() + ( $d * 24 * 3600 ) );
341 //echo "Date: $date\n";
342 // Get non-repeating events for this date.
343 // An event will be included one time for each participant.
344 $ev = get_entries ( $user, $date );
345 // Keep track of duplicates
346 $completed_ids = array ( );
347 for ( $i = 0; $i < count ( $ev ); $i++ ) {
348 $id = $ev[$i]['cal_id'];
349 if ( ! empty ( $completed_ids[$id] ) )
351 $completed_ids[$id] = 1;
352 process_event ( $id, $ev[$i]['cal_name'], $date, $ev[$i]['cal_time'] );
354 $rep = get_repeating_entries ( $user, $date );
355 for ( $i = 0; $i < count ( $rep ); $i++ ) {
356 $id = $rep[$i]['cal_id'];
357 if ( ! empty ( $completed_ids[$id] ) )
359 $completed_ids[$id] = 1;
360 process_event ( $id, $rep[$i]['cal_name'], $date, $rep[$i]['cal_time'] );
364 echo "</reminders>\n";