Файловый менеджер - Редактировать - /home/avadvi5/calendar.aeronextgen.com/WebCalendar.zip
Ðазад
PK �]�\��5� AUTHORSnu �[��� Most of the code was written by: Craig Knudsen <craig@k5n.us> New features and bug fixes provided by: Jukka Aittola <Jukka.AittolaAThut.fi> Mike Baptiste <baptisteATcc-concepts.com> Ralph Boßler <rbosslerATgmx.de> Toby Cabot <tobyATtoby.cabotATpobox.com> Antonio Costa <accmdqATesoterica.pt> Lachlan Cox <lachieATzip.com.au> Matthew Crosby <mcrosbyATmarthon.org> Dominik Fischer <dfischerATmegla.de> Tollef Fog Heen <tollefATadd.no> T.R. Fullhart <kayosATkayos.org> Ken Harris <kharrisATlhinfo.com> Florian Helmberger <fhATenemy.org> Michiel Holtkamp <michielATreseau.nl> Jeff Hoover* <jhoovATthebusstop.net> Lucie Houel <lyly134ATcaramail.com> Peter Huetmannsberger <huetmannATsite38.ping.at> Thomas James <tbjamesATbellsouth.net> Ian R. Justman <ianjATcalweb.com> Thorsten Klein <kleinATlfm.rwth-aachen.de> Ulrich Leodolter <ulrichATlab1.psy.univie.ac.at> Benoit Maisonny <benoitATsynclude.com> Jonathan Mark <jhmarkATxenops.com> Ed Palmer <palmeredATusers.sourceforge.net> Otto Paukner <Otto.PauknerATm-v-l.de> Paul Reisdorf <preisdorfATbinus.net> Adam Roben* <adam.robenATgmail.com> David Rodrigues <drodrigATnetextensions.com> Adam Shantz* <adamATadamshantzDOTcom> Andy Skunza <askunzaATdynamix-ltd.com> Oliver Teuber <teuberATdevicen.de> Romuald Texier <romualdATidp9001.com> Frederic Tyndiuk <email address suppressed> Jan Willamowius <janATmobile.de> Vadim Zaliva <lordATcrocodile.org> Ray Jones* <rjonesATumces.edu> Bruce Bannon* <bbannonATusersDOTsourceforgeDOTnet> * ( Development Team ) Translations: Bulgarian: Malen Malenov <malen_malenovATyahoo.com> Catalan: Traduït <infoATtraduit.com> Chinese-Big5: Liang-Kuan Liu <lianguanATpchome.com.tw> Croatian_utf8: Krunoslav Zubrinic <krunoslav.zubrinicATvip.hr> Czech: Hanuš Adler <hadATpenguin.cz> Danish: Allan Thraen <allanAT12go.dk> Jørgen Thomsen <jthATjth.net> Jens Th <photoATjens-th.com> Nicolaj Rasmussen <drlandauATmsn.com> Morten Nielsen <mniATit.dk> Leo Todaro <leotodaroAThotmail.com> Dutch: Marcel van der Boom <marcelAThsdev.com> Patrick Gutlich <pgutlichATcasema.net> Klaus Spithost <k.spithostATit-works.nl> Marieke Timmer <marieke.timmerATtijdhof.nl> Arnout Engelen <arnoutenATbzzt.net> Oliver Heesakkers <devATheesakkers.info> Estonian: Madis Listak <madisATnetbell.ee> Finnish: Juha-Matti Åberg <juffeATliveware.fi> Jussi Siponen <jussi.siponenATposiona.com> French: Luc Capronnier <email address suppressed> Olivier Piquerez <PiquerezATtopd.ch> Yves Moenner <yves.moennerATmailcity.com> Romuald Texier <romualdtATfree.fr> Wilfrid Hubert Gérard Delafond Mario Dragone <mario.dragoneATreims.iufm.fr> erational <http://www.erational.org> Ivan Machetto Emmanuel Rihn <acontrecourantATonline_fr> Galician: Raúl Araya Tauler <nubeiroATnubeiro.com> German: Markus Egartner <markus.egartnerATkh.hallein.at> Ralph Boßler <rbosslerATgmx.de> Peter Huetmannsberger <huetmannATsite38.ping.at> Greek: Paul Gessos <cham_gssAThotmail.com> Hebrew: Dov Zamir <dovATzamirfamily.com> Holo-Big5: Henry H. Tan-Tenn <share2002novATlomaji.com> Hungarian: Gyorgy Baffia <gyorgyATbaffia.hu> Laszlo Csecsy <boobaaATajrg.hu_> Istvan Bubreg <bubregATfreemail.hu> Icelandic: Kristofer Arnar Einarsson <kristoferATkristofer.com> Italian: Simone Cortesi <simoneATcortesi.com> Alessandro <a.orlandiATiol.it> Japanese: Makoto Hamanaka <VYA04230ATnifty.com> Tadashi Jokagi <elf2000ATusers.sourceforge.net> Korean: Joonyup Jeon <goodwillATwowbook.com> Norwegian: Pål Løberg/Magni Onsøien <initioATinitio.no> Hans Fredrik Nordhaug <hansfnATusers.sourceforge.net> Polish: Lipowczan Pawel <lpao2ATo2.pl> Jano <j4n0ATusers.sourceforge.net> Portuguese: Antonio Costa <accmdqATmail.esoterica.pt> Nuno Lopes <nuno.lopesATmaxitel.com> Portuguese/Brazil: Sérgio Oliveira <slolivATterra.com.br> Mauricio Piza <mpizaATformare.com.br> Paulino Michelazzo <paulinoATmichelazzo.com.br> José Roberto Kerne <joserobertoATdicaslinux.com.br> Nuno Lopes <nmlATmaxitel.pt> Andre Oliveira <zack22ATig.com.br> Romanian: Dan Protopopescu <protopopATphysics.gla.ac.uk> Russian: Andre E. Bar’yudin <baryudinATpob.huji.ac.il> Ilya G. Teterev <remirranATgmail.com> Spanish: Pedro Del Medico <pdmpATinterhoster.com> Pérez Rilo Eduardo Dominguez <lalo_notthispleaseATteligens.com> Mario Benito <mbenitoATmaberi.com> Swedish: Jesper Thörn <jesperATthorn.as> Bernt Sjöström <berntATsjostrom.pchemma.nu> Turkish: Atilla Kazanci <supportATdig-it-berlin.de> Welsh: Wyn James <wynjamesATonetel.net.uk> There are probably many others that I have inadvertantly missed. Thank you all for contributing to WebCalendar! PK �]�\o��Ö � edit_entry.phpnu �[��� <?php // $Id: edit_entry.php,v 1.227 2010/08/27 05:15:57 cknudsen Exp $ /** * Description: * Presents page to edit/add an event/task/journal * * Notes: * A SysAdmin can enable HTML for event full descriptions. If one of the * supported HTML edit widgets is also installed, users can use WYSIWYG editing. * See the WebCalendar page at * http://www.k5n.us/webcalendar.php?topic=Add-Ons * for download and install instructions for these packages. */ include_once 'includes/init.php'; /** * Generate HTML for a time selection for use in a form. * * @param string $prefix Prefix to use in front of form element names * @param string $time Currently selected time in HHMMSS * @param bool $trigger Add onchange event trigger that * calls javascript function $prefix_timechanged() * * @return string HTML for the selection box */ function time_selection ( $prefix, $time = '', $trigger = false ) { global $checked, $ENTRY_SLOTS, $selected, $TIME_FORMAT, $WORK_DAY_START_HOUR; $amsel = $pmsel = $ret = ''; $trigger_str = ( $trigger ? 'onchange="' . $prefix . 'timechanged() ' : '' ); if ( ! isset ( $time ) && $time != 0 ) { $hour = $WORK_DAY_START_HOUR; $minute = 0; } else { $hour = floor ( $time / 10000 ); $minute = ( ( $time / 100 ) % 100 ) % 60; } if ( $TIME_FORMAT == '12' ) { $maxhour = 12; if ( $hour < 12 || $hour == 24 ) $amsel = $checked; else $pmsel = $checked; $hour %= 12; if ( $hour == 0 ) $hour = 12; } else { $maxhour = 24; $hour = sprintf ( "%02d", $hour ); } $minute = sprintf ( "%02d", $minute ); $ret .= ' <select ' . 'name="' . $prefix . 'hour" id="' . $prefix . 'hour" ' . $trigger_str . '>'; for ( $i = 0; $i < $maxhour; $i++ ) { $ihour = ( $TIME_FORMAT == '24' ? sprintf ( "%02d", $i ) : $i ); if ( $i == 0 && $TIME_FORMAT == '12' ) $ihour = 12; $ret .= ' <option value="' . "$i\"" . ( $ihour == $hour ? $selected : '' ) . ">$ihour" . '</option>'; } $ret .= ' </select>: <select ' . 'name="' . $prefix . 'minute" id="' . $prefix . 'minute" ' . $trigger_str . '>'; // We use $TIME_SLOTS to populate the minutes pulldown. $found = false; for ( $i = 0; $i < 60; ) { $imin = sprintf ( "%02d", $i ); $isselected = ''; if ( $imin == $minute ) { $found = true; $isselected = $selected; } $ret .= ' <option value="' . "$i\"$isselected>$imin" . '</option>'; $i += ( 1440 / $ENTRY_SLOTS ); } // We'll add an option with the exact time if not found above. return $ret . ( $found ? '' : ' <option value="' . "$minute\" $selected>$minute" . '</option>' ) . ' </select>' . ( $TIME_FORMAT == '12' ? ' <label><input type="radio" name="' . $prefix . 'ampm" id="' . $prefix . 'ampmA" value="0" ' . $amsel . ' /> ' . translate ( 'am' ) . '</label> <label><input type="radio" name="' . $prefix . 'ampm" id="' . $prefix . 'ampmP" value="12" ' . $pmsel . ' /> ' . translate ( 'pm' ) . '</label>' : ' <input type="hidden" name="' . $prefix . 'ampm" value="0" />' ); } $daysStr = translate ( 'days' ); $hoursStr = translate ( 'hours' ); $minutStr = translate ( 'minutes' ); $saveStr = translate ( 'Save' ); load_user_categories(); // Default for using tabs is enabled. //$EVENT_EDIT_TABS = 'N'; if ( empty ( $EVENT_EDIT_TABS ) ) $EVENT_EDIT_TABS = 'Y'; // default $useTabs = ( $EVENT_EDIT_TABS == 'Y' ); // Make sure this is not a read-only calendar. $can_edit = false; $others_complete = 'yes'; $checked = ' checked="checked"'; $selected = ' selected="selected"'; $eType = getGetValue( 'eType' ); $id = getGetValue( 'id' ); $copy = getValue( 'copy', '[01]' ); $date = getValue( 'date', '-?[0-9]+' ); $day = getValue( 'day', '-?[0-9]+' ); $month = getValue( 'month', '-?[0-9]+' ); $year = getValue( 'year', '-?[0-9]+' ); $name = getValue( 'name' ); $description = getValue( 'desc' ); // Public access can only add events, not edit. if ( empty ( $login ) || ( $login == '__public__' && $id > 0 ) ) $id = 0; if ( empty ( $eType ) ) $eType = 'event'; if ( empty ( $date ) && empty ( $month ) ) { if ( empty ( $year ) ) $year = date ( 'Y' ); $month = date ( 'm' ); if ( empty ( $day ) ) $day = date ( 'd' ); $date = sprintf ( "%04d%02d%02d", $year, $month, $day ); } $BodyX = 'onload="onLoad();"'; $INC = array ( 'js/edit_entry.php/false/' . $user, 'js/visible.php' ); $textareasize = ( $ALLOW_HTML_DESCRIPTION === 'Y' ? '20' : '15' ); // Add Modal Dialog javascript/CSS $HEAD = '<script type="text/javascript" src="includes/js/scriptaculous/scriptaculous.js?load=builder,effects"></script> <script type="text/javascript" src="includes/js/modalbox/modalbox.js"></script> <link rel="stylesheet" href="includes/js/modalbox/modalbox.css" type="text/css" media="screen" /> <script type="text/javascript" src="includes/tabcontent/tabcontent.js"></script> <link type="text/css" href="includes/tabcontent/tabcontent.css" rel="stylesheet" /> '; $byday = $bymonth = $bymonthday = $bysetpos = $participants = $exceptions = $inclusions = $reminder = []; $byweekno = $byyearday = $catList = $catNames = $external_users = $rpt_count = ''; $create_by = $login; // This is the default per RFC2445. // We could override it and use $byday_names[$WEEK_START']. $wkst = 'MO'; $real_user = ( ( ! empty ( $user ) && strlen ( $user ) ) && ( $is_assistant || $is_admin ) ) ? $user : $login; print_header ( $INC, $HEAD, $BodyX ); if ( $readonly == 'Y' || $is_nonuser ) $can_edit = false; else if ( ! empty ( $id ) && $id > 0 ) { // First see who has access to edit this entry. if ( $is_admin ) $can_edit = true; $res = dbi_execute ( 'SELECT cal_create_by, cal_date, cal_time, cal_mod_date, cal_mod_time, cal_duration, cal_priority, cal_type, cal_access, cal_name, cal_description, cal_group_id, cal_location, cal_due_date, cal_due_time, cal_completed, cal_url FROM webcal_entry WHERE cal_id = ?', [$id] ); if ( $res ) { $row = dbi_fetch_row ( $res ); // If current user is creator of event, then they can edit. if ( $row[0] == $login ) $can_edit = true; $cal_date = ( ! empty ( $override ) && ! empty ( $date ) ? $date // Leave $cal_date to what was set in URL with date=YYYYMMDD. : $row[1] ); $create_by = $row[0]; if ( ( $user == $create_by ) && ( $is_assistant || $is_nonuser_admin ) ) $can_edit = true; $cal_time = sprintf ( "%06d", $row[2] ); $due_date = $row[13]; $due_time = $row[14]; $calTS = date_to_epoch ( $cal_date . $cal_time ); // Don't adjust for All Day entries. if ( $cal_time > 0 || ( $cal_time == 0 && $row[5] != 1440 ) ) { $cal_date = date ( 'Ymd', $calTS ); $cal_time = date ( 'His', $calTS ); } $hour = floor ( $cal_time / 10000 ); $minute = ( $cal_time / 100 ) % 100; $dueTS = date_to_epoch ( $due_date . $due_time ); $due_date = date ( 'Ymd', $dueTS ); $due_time = date ( 'His', $dueTS ); $due_hour = floor ( $due_time / 10000 ); $due_minute = ( $due_time / 100 ) % 100; $priority = $row[6]; $type = $row[7]; $access = $row[8]; $name = $row[9]; $description = $row[10]; $parent = $row[11]; $location = $row[12]; $completed = ( empty ( $row[15] ) ? date ( 'Ymd' ) : $row[15] ); $cal_url = $row[16]; // What kind of entry are we dealing with? if ( strpos ( 'EM', $type ) !== false ) $eType = 'event'; elseif ( strpos ( 'JO', $type ) !== false ) $eType = 'journal'; elseif ( strpos ( 'NT', $type ) !== false ) $eType = 'task'; // Public access has no access to tasks. if ( $login == '__public__' && $eType == 'task' ) etranslate( 'You are not authorized to edit this task.' ); // Check UAC. if ( access_is_enabled() ) $can_edit = access_user_calendar ( 'edit', $create_by, $login, $type, $access ); $day = $cal_date % 100; $month = ( $cal_date / 100 ) % 100; $year = intval ( $cal_date / 10000 ); $time = $row[2]; if ( $time >= 0 ) $duration = $row[5]; else { $duration = ''; $hour = -1; } // Check for repeating event info... // but not if we're overriding a single entry of an already repeating event... // confusing, eh? if ( ! empty ( $override ) ) { $rpt_end = 0; $rpt_end_date = $cal_date; $rpt_freq = 1; $rpt_type = 'none'; } else { $res = dbi_execute ( 'SELECT cal_id, cal_type, cal_end, cal_endtime, cal_frequency, cal_byday, cal_bymonth, cal_bymonthday, cal_bysetpos, cal_byweekno, cal_byyearday, cal_wkst, cal_count FROM webcal_entry_repeats WHERE cal_id = ?', [$id] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { $rpt_type = $row[1]; $rpt_end = ( $row[2] > 0 ? date_to_epoch ( $row[2] . $row[3] ) : 0 ); if ( empty ( $row[2] ) ) { $rpt_end_date = $cal_date; $rpt_end_time = $cal_time; } else { $rpt_endTS = date_to_epoch ( $row[2] . $row[3] ); $rpt_end_date = date ( 'Ymd', $rpt_endTS ); $rpt_end_time = date ( 'His', $rpt_endTS ); } $rpt_freq = $row[4]; if ( ! empty ( $row[5] ) ) $byday = explode ( ',', $row[5] ); $bydayStr = $row[5]; if ( ! empty ( $row[6] ) ) $bymonth = explode ( ',', $row[6] ); if ( ! empty ( $row[7] ) ) $bymonthday = explode ( ',', $row[7] ); $bymonthdayStr = $row[7]; if ( ! empty ( $row[8] ) ) $bysetpos = explode ( ',', $row[8] ); $bysetposStr = $row[8]; $byweekno = $row[9]; $byyearday = $row[10]; $wkst = $row[11]; $rpt_count = $row[12]; // Check to see if Weekends Only is applicable. $weekdays_only = ( $rpt_type == 'daily' && $byday == 'MO,TU,WE,TH,FR' ); } dbi_free_result ( $res ); } } $res = dbi_execute ( 'SELECT cal_login, cal_percent, cal_status FROM webcal_entry_user WHERE cal_id = ?', [$id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $overall_percent[] = $row; if ( $login == $row[0] || ( $is_admin && $user == $row[0] ) ) { $task_percent = $row[1]; $task_status = $row[2]; } } dbi_free_result ( $res ); } // Determine if Expert mode needs to be set. $expert_mode = ( count ( $byday ) || count ( $bymonth ) || count ( $bymonthday ) || count ( $bysetpos ) || isset ( $byweekno ) || isset ( $byyearday ) || isset ( $rpt_count ) ); // Get Repeat Exceptions. $res = dbi_execute ( 'SELECT cal_date, cal_exdate FROM webcal_entry_repeats_not WHERE cal_id = ?', [$id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { if ( $row[1] == 1 ) $exceptions[] = $row[0]; else $inclusions[] = $row[0]; } dbi_free_result ( $res ); } } if ( $CATEGORIES_ENABLED == 'Y' ) { $catById = get_categories_by_id ( $id, $real_user, true ); if ( ! empty ( $catById ) ) { $catNames = implode ( ', ', $catById ); $catList = implode ( ',', array_keys ( $catById ) ); } } //end CATEGORIES_ENABLED test // Get reminders. $reminder = getReminders ( $id ); $reminder_offset = ( empty ( $reminder ) ? 0 : $reminder['offset'] ); $rem_status = ( count ( $reminder ) ); $rem_use_date = ( ! empty ( $reminder['date'] ) ); // Get participants. $res = dbi_execute ( 'SELECT cal_login, cal_status FROM webcal_entry_user WHERE cal_id = ? AND cal_status IN ( "A", "W" )', [$id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $participants[$row[0]] = 1; $selectedStatus[$row[0]] = $row[1]; } dbi_free_result ( $res ); } // Not allowed for tasks or journals. if ( $eType == 'event' && ! empty ( $ALLOW_EXTERNAL_USERS ) && $ALLOW_EXTERNAL_USERS == 'Y' ) $external_users = event_get_external_users ( $id ); } else { // ########## New entry ################ $id = 0; // To avoid warnings below about use of undefined var. // We'll use $WORK_DAY_START_HOUR and $WORK_DAY_END_HOUR // as our starting and due times. $cal_time = $WORK_DAY_START_HOUR . '0000'; $completed = ''; $due_hour = $WORK_DAY_END_HOUR; $due_minute = $task_percent = 0; $due_time = $WORK_DAY_END_HOUR . '0000'; $overall_percent = []; // Get category if passed in URL as cat_id. $cat_id = getValue ( 'cat_id', '-?[0-9,\-]*', true ); if ( ! empty ( $cat_id ) ) { $res = dbi_execute ( 'SELECT cat_name FROM webcal_categories WHERE cat_id = ? AND ( cat_owner = ? OR cat_owner IS NULL )', [$cat_id, $real_user] ); if ( $res ) { $row = dbi_fetch_row ( $res ); $catNames = $row[0]; $catList = $cat_id; } } // Reminder settings. $reminder_offset = ( $REMINDER_WITH_DATE == 'N' ? $REMINDER_OFFSET : 0 ); $rem_status = ( $REMINDER_DEFAULT == 'Y' ); $rem_use_date = ( $reminder_offset == 0 && $REMINDER_WITH_DATE == 'Y' ); if ( $eType == 'task' ) $hour = $WORK_DAY_START_HOUR; // Anything other then testing for strlen breaks either hour=0 or no hour in URL. if ( strlen ( $hour ) ) $time = $hour * 100; else $hour = $time = -1; if ( ! empty ( $defusers ) ) { $tmp_ar = explode ( ',', $defusers ); for ( $i = 0, $cnt = count ( $tmp_ar ); $i < $cnt; $i++ ) { $participants[$tmp_ar[$i]] = 1; } } //Add the logged in user if none other supplied if ( count ( $participants ) == 0 ) $participants[$login] = 1; if ( $readonly == 'N' ) { // Is public allowed to add events? if ( $login == '__public__' && $PUBLIC_ACCESS_CAN_ADD != 'Y' ) $can_edit = false; else $can_edit = true; } } $dateYmd = date ( 'Ymd' ); $thisday = $day; $thismonth = $month; $thisyear = $year; if ( empty ( $rpt_type ) || ! $rpt_type ) $rpt_type = 'none'; // Avoid error for using undefined vars. if ( ! isset ( $hour ) || !is_numeric($hour)) $hour = 0; if (!isset ($minute)|| !is_numeric ($minute)) $minute = 0; else if ( isset ($hour) && is_numeric($hour) && $hour >= 0 ) { $cal_time = ( $hour * 10000 ) + ( $minute * 100 ); } $cal_time = ( $hour * 10000 ) + ( isset ( $minute ) ? $minute * 100 : 0 ); if ( empty ( $access ) ) $access = ''; if ( empty ( $cal_url ) ) $cal_url = ''; if ( empty ( $description ) || $description == '<br />' ) $description = ''; if ( empty ( $duration ) ) $duration = 0; if ( $duration == 1440 && $time == 0 ) { $duration = $hour = $minute = ''; $allday = 'Y'; } else $allday = 'N'; if ( empty ( $location ) ) $location = ''; if ( empty ( $name ) ) $name = ''; if ( empty ( $priority ) ) $priority = 5; if ( empty ( $rpt_end_date ) ) $rpt_end_date = 0; if ( empty ( $rpt_end_time ) ) $rpt_end_time = 0; if ( empty ( $rpt_freq ) ) $rpt_freq = 0; if ( empty ( $cal_date ) ) { $cal_date = ( ! empty ( $date ) && $eType != 'task' ? $date : $dateYmd ); if ( empty ( $due_date ) ) $due_date = $dateYmd; } if ( empty ( $thisyear ) ) $thisdate = $dateYmd; else { $thisdate = sprintf ( "%04d%02d%02d", $thisyear, empty ( $thismonth ) ? date ( 'm' ) : $thismonth, empty ( $thisday ) ? date ( 'd' ) : $thisday ); } if ( empty ( $cal_date ) || ! $cal_date ) $cal_date = $thisdate; if ( empty ( $due_date ) || ! $due_date ) $due_date = $thisdate; // Setup to display user's timezone difference if Admin or Assistant. // Even though event is stored in GMT, // an Assistant may need to know that the boss is in a different Timezone. if ( $is_assistant || $is_admin && ! empty ( $user ) ) { $tz_offset = date ( 'Z', date_to_epoch ( $cal_date . $cal_time ) ); $user_TIMEZONE = get_pref_setting ( $user, 'TIMEZONE' ); set_env ( 'TZ', $user_TIMEZONE ); $user_tz_offset = date ( 'Z', date_to_epoch ( $cal_date . $cal_time ) ); if ( $tz_offset != $user_tz_offset ) { // Different TZ_Offset. user_load_variables ( $user, 'temp' ); $tz_diff = ( $user_tz_offset - $tz_offset ) / 3600; $abs_diff = abs ( $tz_diff ); // translate ( 'is in a different timezone than you are. Currently' ) // translate ( 'hour ahead of you' ) translate ( 'hour behind you' ) // translate ( 'hours ahead of you' ) translate ( 'hours behind you' ) // translate ( 'XXX is in a different timezone (ahead)' ) // translate ( 'XXX is in a different timezone (behind)' ) // Line breaks in translates below are to bypass update_translation.pl. $TZ_notice = str_replace ( 'XXX', [$tempfullname, // TODO show hh:mm instead of abs. $abs_diff . ' ' . translate ( 'hour' . ( $abs_diff == 1 ? '' : 's' ) ), translate ( 'Time entered here is based on your Timezone.' )], translate ( 'XXX is in a different timezone (' . ( $tz_diff > 0 ? 'ahead)' : 'behind)' ) ) ); } // Return to $login TIMEZONE. set_env ( 'TZ', $TIMEZONE ); } $eType_label = ' ( ' . translate ( $eType ) . ' )'; echo ' <h2>' . ( $id ? translate ( 'Edit Entry' ) : translate ( 'Add Entry' ) ) . $eType_label . ' <img src="images/help.gif" alt="' . translate ( 'Help' ) . '" class="help" onclick="window.open( \'help_edit_entry.php' . ( empty ( $id ) ? '?add=1' : '' ) . '\', \'cal_help\', \'dependent,menubar,scrollbars,height=400,width=400,' . 'innerHeight=420,outerWidth=420\' );" /></h2>'; if ( $can_edit ) { $tabs_name = ['details']; $tabs_title = [translate ( 'Details' )]; if ( $DISABLE_PARTICIPANTS_FIELD != 'Y' ) { $tabs_name[] = 'participants'; $tabs_title[] = translate ( 'Participants' ); } if ( $DISABLE_REPEATING_FIELD != 'Y' ) { $tabs_name[] = 'pete'; $tabs_title[] = translate ( 'Repeat' ); } if ( $DISABLE_REMINDER_FIELD != 'Y' ) { $tabs_name[] = 'reminder'; $tabs_title[] = translate ( 'Reminders' ); } $tabs = '<ul id="viewtabs" class="shadetabs" style="margin-left: 10px;">'; for ( $i = 0, $cnt = count ( $tabs_name ); $i < $cnt; $i++ ) { $tabs .= '<li><a href="#" rel="' . $tabs_name[$i] . '"' . ( $i == 0 ? ' class="selected"' : '' ) . '>' . $tabs_title[$i] . '</a></li>' . "\n"; } $tabs .= "</ul>\n" . '<div style="border:1px solid gray; width:95%; margin-bottom: 1em; margin-left: 10px; margin-right: 10px; padding: 10px">'; $tabI = 0; echo ' <form action="edit_entry_handler.php" method="post" name="editentryform" ' . 'id="editentryform"> <input type="hidden" name="eType" value="' . $eType . '" />' . ( ! empty ( $id ) && ( empty ( $copy ) || $copy != '1' ) ? ' <input type="hidden" name="cal_id" value="' . $id . '" />' : '' ) /* We need an additional hidden input field. */ . ' <input type="hidden" name="entry_changed" value="" />' // Are we overriding an entry from a repeating event... . ( empty ( $override ) ? '' : ' <input type="hidden" name="override" value="1" /> <input type="hidden" name="override_date" value="' . $cal_date . '" />' ) // If assistant, need to remember boss = user. . ( $is_assistant || $is_nonuser_admin || ! empty ( $user ) ? ' <input type="hidden" name="user" value="' . $user . '" />' : '' ) // If has cal_group_id was set, need to set parent = $parent. . ( empty ( $parent ) ? '' : ' <input type="hidden" name="parent" value="' . $parent . '" />' ) . ' <!-- TABS -->' . ( $useTabs ? $tabs : '' ) . ' <!-- TABS BODY -->' . ( $useTabs ? ' <div id="' . $tabs_name[$tabI++] . '" class="tabcontent"> <!-- DETAILS -->' : ' <fieldset> <legend>' . translate ( 'Details' ) . '</legend>' ) . ' <table> <tr> <td class="tooltip" title="' . tooltip ( 'brief-description-help' ) . '"><label for="entry_brief">' . translate ( 'Brief Description' ) . ':</label></td> <td colspan="2"><input type="text" name="name" id="entry_brief" ' . 'size="25" value="' . htmlspecialchars ( $name ) . '" /></td> </tr> <tr> <td class="tooltip aligntop" title="' . tooltip ( 'full-description-help' ) . '"><label for="entry_full">' . translate ( 'Full Description' ) . ':</label></td> <td width="60%"><textarea name="description" id="entry_full" rows="' . $textareasize . '" cols="50"' . '>' . htmlspecialchars ( $description ) . '</textarea></td>' . '<td class="aligntop">' . ( ! empty ( $categories ) || $DISABLE_ACCESS_FIELD != 'Y' || ( $DISABLE_PRIORITY_FIELD != 'Y' ) /* New table for extra fields. */ ? ' <table width="90%">' : '' ) . ( $DISABLE_ACCESS_FIELD != 'Y' ? ' <tr> <td class="tooltip" title="' . tooltip ( 'access-help' ) . '"><label for="entry_access">' . translate ( 'Access' ) . ':</label></td> <td width="80%"> <select name="access" id="entry_access"> <option value="P"' . ( $access == 'P' || ! strlen ( $access ) ? $selected : '' ) . '>' . translate ( 'Public' ) . '</option> <option value="R"' . ( $access == 'R' ? $selected : '' ) . '>' . translate ( 'Private' ) . '</option> <option value="C"' . ( $access == 'C' ? $selected : '' ) . '>' . translate ( 'Confidential' ) . '</option> </select> </td> </tr>' : '' ); if ( $DISABLE_PRIORITY_FIELD != 'Y' ) { echo ' <tr> <td class="tooltip" title="' . tooltip ( 'priority-help' ) . '"><label for="entry_prio">' . translate ( 'Priority' ) . ': </label></td> <td> <select name="priority" id="entry_prio">'; $pri = ['', translate ( 'High' ), translate ( 'Medium' ), translate ( 'Low' )]; for ( $i = 1; $i <= 9; $i++ ) { echo ' <option value="' . $i . '"' . ( $priority == $i ? $selected : '' ) . '>' . $i . '-' . $pri[ceil ( $i / 3 )] . '</option>'; } echo ' </select> </td> </tr>'; } echo ( ! empty ( $categories ) && $CATEGORIES_ENABLED == 'Y' ? ' <tr> <td class="tooltip aligntop" title="' . tooltip ( 'category-help' ) . '"> <label for="entry_categories">' . translate ( 'Category' ) . ':<br /></label> <input type="button" value="' . translate ( 'Edit' ) . '" onclick="editCats( event )" /> </td> <td class="aligntop"> <span name="catnames" id="entry_categories" " onclick="editCats( event )" style="cursor: pointer;" />' . $catNames . '</span> <input type="hidden" id="cat_id" name="cat_id" value="' . $catList . '" /> </td> </tr>' : '' ) . ( ! empty ( $categories ) || $DISABLE_ACCESS_FIELD != 'Y' || ( $DISABLE_PRIORITY_FIELD != 'Y' ) ? ' </table>' : '' ); if ( $eType == 'task' ) { // Only for tasks. $completed_visible = ( strlen ( $completed ) ? 'visible' : 'hidden' ); echo '<br /> <table> <tr id="completed"> <td class="tooltip" title="' . tooltip ( 'completed-help' ) . '"><label for="task_percent">' . translate ( 'Date Completed' ) . ': </label></td> <td>' . date_selection ( 'completed_', $completed ) . '</td> </tr> <tr> <td class="tooltip" title="' . tooltip ( 'percent-help' ) . '"><label for="task_percent">' . translate ( 'Percent Complete' ) . ': </label></td> <td> <select name="percent" id="task_percent" ' . 'onchange="completed_handler()">'; for ( $i = 0; $i < 101; $i += 10 ) { echo ' <option value="' . "$i\" " . ( $task_percent == $i ? $selected : '' ) . '>' . $i . '</option>'; } echo ' </select> </td> </tr>'; if ( ! empty ( $overall_percent ) ) { echo ' <tr> <td colspan="2"> <table cellpadding="2" cellspacing="5"> <tr> <td colspan="2">' . translate ( 'All Percentages' ) . '</td> </tr>'; $others_complete = 'yes'; for ( $i = 0, $cnt = count ( $overall_percent ); $i < $cnt; $i++ ) { user_load_variables ( $overall_percent[$i][0], 'percent' ); echo ' <tr> <td>' . $percentfullname . '</td> <td>' . $overall_percent[$i][1] . '</td> </tr>'; if ( $overall_percent[$i][0] != $real_user && $overall_percent[$i][1] < 100 ) $others_complete = 'no'; } echo ' </table>'; } echo ' </td> </tr> </table> <input type="hidden" name="others_complete" value="' . $others_complete . '" />'; } //end tasks only echo ' </td> </tr>' . ( $DISABLE_LOCATION_FIELD != 'Y' ? ' <tr> <td class="tooltip" title="' . tooltip ( 'location-help' ) . '"><label for="entry_location">' . translate ( 'Location' ) . ':</label></td> <td colspan="2"><input type="text" name="location" ' . 'id="entry_location" size="55" value="' . htmlspecialchars ( $location ) . '" /></td> </tr>' : '' ) . ( $DISABLE_URL_FIELD != 'Y' ? ' <tr> <td class="tooltip" title="' . tooltip ( 'url-help' ) . '"><label for="entry_url">' . translate ( 'URL' ) . ':</label></td> <td colspan="2"><input type="text" name="entry_url" id="entry_url"' . ' size="100" value="' . htmlspecialchars ( $cal_url ) . '" /></td> </tr>' : '' ) . ' <tr> <td class="tooltip" title="' . tooltip ( 'date-help' ) . '"><label>' . ( $eType == 'task' ? translate ( 'Start Date' ) : translate ( 'Date' ) ) . ':</label></td> <td colspan="2">' . date_selection ( '', $cal_date ) . '</td> </tr> <tr> <td'; if ( $eType != 'task' ) { if (! isset($duration) || ! is_numeric($duration)) $duration = 0; $dur_h = intval ( $duration / 60 ); echo '> </td> <td colspan="2"> <select name="timetype" onchange="timetype_handler()"> <option value="U" ' . ( $allday != 'Y' && $hour == -1 ? $selected : '' ) . '>' . translate ( 'Untimed event' ) . '</option> <option value="T" ' . ( $allday != 'Y' && $hour >= 0 ? $selected : '' ) . '>' . translate ( 'Timed event' ) . '</option> <option value="A" ' . ( $allday == 'Y' ? $selected : '' ) . '>' . translate ( 'All day event' ) . '</option> </select> </td> </tr>' . ( empty ( $TZ_notice ) ? '' : ' <tr id="timezonenotice"> <td class="tooltip" title="' . tooltip ( 'Time entered here is based on your Timezone.' ) . '">' . translate ( 'Timezone Offset' ) . ':</td> <td colspan="2">' . $TZ_notice . '</td> </tr>' ) . ' <tr id="timeentrystart" style="visibility:hidden;"> <td class="tooltip" title="' . tooltip ( 'time-help' ) . '">' . translate ( 'Time' ) . ':' . '</td> <td colspan="2">' . time_selection ( 'entry_', $cal_time ); if ( $TIMED_EVT_LEN != 'E' ) { echo ' </td> </tr> <tr id="timeentryduration" style="visibility:hidden;"> <td><span class="tooltip" title="' . tooltip ( 'duration-help' ) . '">' . translate ( 'Duration' ) . ': </span></td> <td colspan="2"> <input type="text" name="duration_h" id="duration_h" size="2" ' . 'maxlength="2" value="'; if ( $allday != 'Y' ) printf ( "%d", $dur_h ); echo '" />: <input type="text" name="duration_m" id="duration_m" size="2" ' . 'maxlength="2" value="'; if ( $allday != 'Y' ) printf ( "%02d", $duration - ( $dur_h * 60 ) ); echo '" /> (<label for="duration_h">' . $hoursStr . '</label>: <label for="duration_m">' . $minutStr . '</label>) </td> </tr>'; } else echo ' <span id="timeentryend" class="tooltip" title="' . tooltip ( 'end-time-help' ) . '"> - ' . time_selection ( 'end_', ( $id ? add_duration ( $cal_time, $duration ) : $cal_time ) ) . '</span> </td> </tr>'; } else { // eType == task echo ' class="tooltip" title="' . tooltip ( 'time-help' ) . '">' . translate ( 'Start Time' ) . ':</td> <td colspan="2">' . time_selection ( 'entry_', $cal_time ) . '</td> </tr> <tr> <td colspan="3"> </td> </tr> <tr> <td class="tooltip" title="' . tooltip ( 'date-help' ) . '">' . translate ( 'Due Date' ) . ':</td> <td colspan="2">' . date_selection ( 'due_', $due_date ) . '</td> </tr> <tr> <td class="tooltip" title="' . tooltip ( 'time-help' ) . '">' . translate ( 'Due Time' ) . ':</td> <td colspan="2">' . time_selection ( 'due_', $due_time ) . '</td> </tr>'; } // Site-specific extra fields (see site_extras.php). // load and display any site-specific fields. if ( $id > 0 ) $extras = get_site_extra_fields ( $id ); $site_extracnt = count ( $site_extras ); echo ' </table>' . ( $site_extracnt ? ( ! empty ( $site_extras[0]['FIELDSET'] ) ? ' <div> <fieldset> <legend>' . translate ( 'Site Extras' ) . '</legend>' : '' ) . ' <table>' : '' ); for ( $i = 0; $i < $site_extracnt; $i++ ) { if ( $site_extras[$i] == 'FIELDSET' ) continue; $extra_name = $site_extras[$i][0]; $extra_descr = $site_extras[$i][1]; $extra_type = $site_extras[$i][2]; $extra_arg1 = $site_extras[$i][3]; $extra_arg2 = $site_extras[$i][4]; // Default value if needed. $defIdx = ( empty ( $extras[$extra_name]['cal_data'] ) ? $extra_arg2 : $extras[$extra_name]['cal_data'] ); echo ' <tr> <td class="aligntop bold">' . ( $extra_type == EXTRA_MULTILINETEXT ? '<br />' : '' ) . translate ( $extra_descr ) . ':</td> <td>'; if ( $extra_type == EXTRA_URL ) echo ' <input type="text" size="50" name="' . $extra_name . '" value="' . ( empty ( $extras[$extra_name]['cal_data'] ) ? '' : htmlspecialchars ( $extras[$extra_name]['cal_data'] ) ) . '" />'; elseif ( $extra_type == EXTRA_EMAIL ) echo ' <input type="text" size="30" name="' . $extra_name . '" value="' . ( empty ( $extras[$extra_name]['cal_data'] ) ? '' : htmlspecialchars ( $extras[$extra_name]['cal_data'] ) ) . '" />'; elseif ( $extra_type == EXTRA_DATE ) echo date_selection ( $extra_name, ( empty ( $extras[$extra_name]['cal_date'] ) ? $cal_date : $extras[$extra_name]['cal_date'] ) ); elseif ( $extra_type == EXTRA_TEXT ) { $size = ( $extra_arg1 > 0 ? $extra_arg1 : 50 ); echo ' <input type="text" size="' . $size . '" name="' . $extra_name . '" value="' . ( empty ( $extras[$extra_name]['cal_data'] ) ? '' : htmlspecialchars ( $extras[$extra_name]['cal_data'] ) ) . '" />'; } elseif ( $extra_type == EXTRA_MULTILINETEXT ) echo ' <textarea rows="' . ( $extra_arg2 > 0 ? $extra_arg2 : 5 ) . '" cols="' . ( $extra_arg1 > 0 ? $extra_arg1 : 50 ) . '" name="' . $extra_name . '">' . ( empty ( $extras[$extra_name]['cal_data'] ) ? '' : htmlspecialchars ( $extras[$extra_name]['cal_data'] ) ) . '</textarea>'; elseif ( $extra_type == EXTRA_USER ) { // Show list of calendar users... echo ' <select name="' . $extra_name . '"> <option value="">None</option>'; $userlist = get_my_users ( get_my_users ); $usercnt = count ( $userlist ); for ( $j = 0; $j < $usercnt; $j++ ) { if ( access_is_enabled() && ! access_user_calendar ( 'view', $userlist[$j]['cal_login'] ) ) continue; // Cannot view calendar so cannot add to their cal. echo ' <option value="' . $userlist[$j]['cal_login'] . '"' . ( ! empty ( $extras[$extra_name]['cal_data'] ) && ( $userlist[$j]['cal_login'] == $extras[$extra_name]['cal_data'] ) ? $selected : '' ) . '>' . $userlist[$j]['cal_fullname'] . '</option>'; } echo ' </select>'; } elseif ( $extra_type == EXTRA_SELECTLIST ) { // Show custom select list. $extraSelectArr = $isMultiple = $multiselect = ''; if ( is_array ( $extra_arg1 ) ) { $extra_arg1cnt = count ( $extra_arg1 ); if ( $extra_arg2 > 0 ) { $multiselect = ' multiple="multiple" size="' . min ( $extra_arg2, $extra_arg1cnt ) . '" '; $isMultiple = '[]'; if ( ! empty ( $extras ) ) $extraSelectArr = explode ( ',', $extras[$extra_name]['cal_data'] ); } echo ' <select name="' . $extra_name . $isMultiple . '"' . $multiselect . '>'; for ( $j = 0; $j < $extra_arg1cnt; $j++ ) { echo ' <option value="' . $extra_arg1[$j] . '" '; if ( ! empty ( $extras[$extra_name]['cal_data'] ) ) { if ( $extra_arg2 == 0 && $extra_arg1[$j] == $extras[$extra_name]['cal_data'] ) echo $selected; else if ( $extra_arg2 > 0 && in_array ( $extra_arg1[$j], $extraSelectArr ) ) echo $selected; } else echo ( $j == 0 ? $selected : '' ); echo '>' . $extra_arg1[$j] . '</option>'; } } echo ' </select>'; } elseif ( $extra_type == EXTRA_RADIO ) // Show custom radio selections. echo print_radio ( $extra_name, $extra_arg1, '', $defIdx ); elseif ( $extra_type == EXTRA_CHECKBOX ) // Show custom checkbox option. echo print_checkbox ( [$extra_name, $extra_arg1, '', $defIdx] ); echo ' </td> </tr>'; } if ( $site_extracnt ) { echo ' </table>' . ( empty ( $site_extras[0]['FIELDSET'] ) ? '' : ' </fieldset>' ); } // end site-specific extra fields echo ( $useTabs ? ' </div>' : ' </fieldset>' ) . ' <!-- PARTICIPANTS -->' . ( $useTabs ? ' <div id="' . $tabs_name[$tabI++] . '" class="tabcontent">' : ' <fieldset> <legend>' . translate ( 'Participants' ) . '</legend>' ) . ' <table cellpadding="10">'; // Only ask for participants if we are multi-user. $show_participants = ( $DISABLE_PARTICIPANTS_FIELD != 'Y' ); if ( $is_admin ) $show_participants = true; if ( $login == '__public__' && $PUBLIC_ACCESS_OTHERS != 'Y' ) $show_participants = false; if ( $single_user == 'N' && $show_participants ) { $groups = get_groups ( $real_user ); $userlist = get_my_users ( $create_by, 'invite' ); $num_users = $size = 0; $usercnt = count ( $userlist ); $myusers = $nonusers = $users = $grouplist = ''; for ( $i = 0; $i < $usercnt; $i++ ) { $f = $userlist[$i]['cal_fullname']; $l = $userlist[$i]['cal_login']; $q = ( ! empty ( $selectedStatus[$l] ) && $selectedStatus[$l] == 'W' ? ' (?)' : '' ); $size++; $users .= ' <option value="' . $l . '">' . $f . '</option>'; if ( $id > 0 ) { if ( ! empty ( $participants[$l] ) ) { $myusers .= ' <option value="' . $l . '">' . $f . $q . '</option>'; } } else { if ( ! empty ( $defusers ) && ! empty ( $userlist[$l] ) ) { // Default selection of participants was in the URL. $myusers .= ' <option value="' . $l . '">' . $f . $q . '</option>'; } if ( ! empty ( $user ) && ! empty ( $userlist[$l] ) ) { // Default selection of participants was in the URL. $myusers .= ' <option value="' . $l . '">' . $f . $q . '</option>'; } if ( ( $l == $login && ! $is_assistant && ! $is_nonuser_admin ) || ( ! empty ( $user ) && $l == $user ) ) // Default selection of participants is logged in user. $myusers .= ' <option value="' . $l . '">' . $f . '</option>'; if ( $l == '__public__' && ! empty ( $PUBLIC_ACCESS_DEFAULT_SELECTED ) && $PUBLIC_ACCESS_DEFAULT_SELECTED == 'Y' ) $myusers .= ' <option value="' . $l . '">' . $f . $q . '</option>'; } } if ( $NONUSER_ENABLED == 'Y' ) { // Include Public NUCs $mynonusers = get_my_nonusers ( $real_user, true ); for ( $i = 0, $cnt = count ( $mynonusers ); $i < $cnt; $i++ ) { $l = $mynonusers[$i]['cal_login']; $n = $mynonusers[$i]['cal_fullname']; $q = ( ! empty ( $selectedStatus[$l] ) && $selectedStatus[$l] == 'W' ? ' (?)' : '' ); $nonusers .= ' <option value="' . $l . '"> ' . $n . '</option>'; if ( ! empty ( $participants[$l] ) ) { $myusers .= ' <option value="' . $l . '">' . $n . $q .'</option>'; } else if ( ! empty ( $user ) && ! empty ( $mynonusers[$l] ) ) { // Default selection of participants was in the URL. $myusers .= ' <option value="' . $l . '">' . $n . $q . '</option>'; } } } if ( $GROUPS_ENABLED == 'Y' ) { for ( $i = 0, $cnt = count ( $groups ); $i < $cnt; $i++ ) { $grouplist .= ' <option value="' . $groups[$i]['cal_group_id'] . '">' . $groups[$i]['cal_name'] . '</option>'; } } $addStr = '" ' . translate ( 'Add' ) . ' "'; if ( $size > 50 ) $size = 15; else if ( $size > 10 ) $size = 10; else if ( $size > 5 ) $size = $size; else $size = 4; echo ' <tr title="' . tooltip ( 'avail_participants-help' ) . '"> <td class="tooltip aligntop" rowspan="2"><label>' . translate( 'Available' ) . '<br />' . translate ( 'Participants' ) . ':</label></td> <td class="boxleft boxtop"> </td> <td colspan="2"class="boxtop boxright">' . translate( 'Find Name' ) . '<input type="text" size="20" name="lookup" id="lookup" ' . 'onkeyup="lookupName()" /></td> </tr> <tr> <td width="160px" class="aligntop boxbottom boxleft"> <label>' . translate( 'Users' ) . '</label><br /> <select class="fixed" name="participants[]" id="entry_part" size="' . $size . '" multiple="multiple">' . $users . ' </select><br /> <input name="movert" type="button" value=' . $addStr . ' onclick="selAdd( this );" /></td> </td> <td class="boxbottom"> <label>' . translate( 'Resources' ) . '</label><br /> <select class="fixed" name="nonuserPart[]" id="res_part" size="' . $size . '" multiple="multiple">' . $nonusers . ' </select><br /> <input name="movert" type="button" value=' . $addStr . ' onclick="selResource( this );" /> </td> <td class="aligntop boxright boxbottom">' . ( $GROUPS_ENABLED == 'Y' ? ' <label>' . translate( 'Groups' ) . '</label><br /> <select class="fixed" name="groups" id="groups" size="' . $size . '" onclick="addGroup()" >' . $grouplist . ' </select><br /> <input name="movert" type="button" value=' . $addStr . ' onclick="selAdd( this );" />' : ' ' ) . ' </td> </tr> <tr> <td colspan="4"> </td> </tr> <tr title="' . tooltip ( 'participants-help' ) . '"> <td class="tooltip aligntop"><label>' . translate( 'Selected' ) . '<br />' . translate ( 'Participants' ) . ':</label></td> <td class="alignleft alignbottom boxtop boxbottom boxleft"> </td> <td class="boxtop boxright boxbottom" colspan="2"> <select class="fixed" name="selectedPart[]" id="sel_part" size="7" multiple="multiple">' . $myusers . ' </select><br />' . '<input name="movelt" type="button" value="' . translate ( 'Remove' ) .'" ' . 'onclick="selRemove( this );" /> <input type="button" onclick="showSchedule()" value="' . translate ( 'Availability' ) . '..." /> </td> </tr>' // External Users . ( ! empty ( $ALLOW_EXTERNAL_USERS ) && $ALLOW_EXTERNAL_USERS == 'Y' ? ' <tr title="' . tooltip ( 'external-participants-help' ) . '"> <td class="tooltip aligntop"><label for="entry_extpart">' . translate ( 'External Participants' ) . ':</label></td> <td colspan="6"><textarea name="externalparticipants" id="entry_extpart" rows="5"' . ' cols="75">' . $external_users . '</textarea></td> </tr>' : '' ); } echo ' </table>' . ( $useTabs ? ' </div>' : ' </fieldset>' ) /* $useTabs */ . ' <!-- REPEATING INFO -->'; if ( $DISABLE_REPEATING_FIELD != 'Y' ) { echo ( $useTabs ? ' <div id="' . $tabs_name[$tabI++] . '" class="tabcontent">' : ' <fieldset> <legend>' . translate ( 'Repeat' ) . '</legend>' ) . ' <table cellpadding="3"> <tr> <td class="tooltip" title="' . tooltip ( 'repeat-type-help' ) . '"><label for="rpttype">' . translate ( 'Type' ) . ':</label></td> <td colspan="2"> <select name="rpt_type" id="rpttype" ' . 'onchange="rpttype_handler(); rpttype_weekly()"> <option value="none"' . ( strcmp ( $rpt_type, 'none' ) == 0 ? $selected : '' ) . '>' . translate ( 'None' ) . '</option> <option value="daily"' . ( strcmp ( $rpt_type, 'daily' ) == 0 ? $selected : '' ) . '>' . translate ( 'Daily' ) . '</option> <option value="weekly"' . ( strcmp ( $rpt_type, 'weekly' ) == 0 ? $selected : '' ) . '>' . translate ( 'Weekly' ) . '</option> <option value="monthlyByDay"' . ( strcmp ( $rpt_type, 'monthlyByDay' ) == 0 ? $selected : '' ) // translate ( 'Monthly' ) translate ( 'by day' ) translate ( 'by date' ) // translate ( 'by position' ) . '>' . translate ( 'Monthly (by day)' ) . '</option> <option value="monthlyByDate"' . ( strcmp ( $rpt_type, 'monthlyByDate' ) == 0 ? $selected : '' ) . '>' . translate ( 'Monthly (by date)' ) . '</option> <option value="monthlyBySetPos"' . ( strcmp ( $rpt_type, 'monthlyBySetPos' ) == 0 ? $selected : '' ) . '>' . translate ( 'Monthly (by position)' ) . '</option> <option value="yearly"' . ( strcmp ( $rpt_type, 'yearly' ) == 0 ? $selected : '' ) . '>' . translate ( 'Yearly' ) . '</option> <option value="manual"' . ( strcmp ( $rpt_type, 'manual' ) == 0 ? $selected : '' ) . '>' . translate ( 'Manual' ) . '</option> </select> <label id="rpt_mode"><input ' . 'type="checkbox" name="rptmode" id="rptmode" value="y" ' . 'onclick="rpttype_handler()" ' . ( empty ( $expert_mode ) ? '' : $checked ) . ' />' . translate( 'Expert Mode' ) . '</label> </td> </tr> <tr id="rptenddate1" style="visibility:hidden;"> <td class="tooltip" title="' . tooltip ( 'repeat-end-date-help' ) . '" rowspan="3"><label for="rpt_day">' . translate ( 'Ending' ) . ':</label></td> <td colspan="2" class="boxtop boxright boxleft"><input type="radio" ' . 'name="rpt_end_use" id="rpt_untilf" value="f" ' . ( empty ( $rpt_end ) && empty ( $rpt_count ) ? $checked : '' ) . ' onclick="toggle_until()" /><label for="rpt_untilf">' . translate ( 'Forever' ) . '</label></td> </tr> <tr id="rptenddate2" style="visibility:hidden;"> <td class="boxleft"><input type="radio" name="rpt_end_use" ' . 'id="rpt_untilu" value="u" ' . ( empty ( $rpt_end ) ? '' : $checked ) . ' onclick="toggle_until()" /> <label for="rpt_untilu">' . translate ( 'Use end date' ) . '</label></td> <td class="boxright"><span class="end_day_selection" ' . 'id="rpt_end_day_select">' . date_selection ( 'rpt_', ( $rpt_end_date ? $rpt_end_date : $cal_date ) ) . '</span><span id="rpt_until_time_date"><br />' . time_selection ( 'rpt_', $rpt_end_time ) . '</span></td> </tr> <tr id="rptenddate3" style="visibility:hidden;"> <td class="boxbottom boxleft"><input type="radio" name="rpt_end_use" ' . 'id="rpt_untilc" value="c" ' . ( empty ( $rpt_count ) ? '' : $checked ) . ' onclick="toggle_until()" /> <label for="rpt_untilc">' . translate ( 'Number of times' ) . '</label></td> <td class="boxright boxbottom"><input type="text" name="rpt_count" ' . 'id="rpt_count" size="4" maxlength="4" value="' . $rpt_count . '" /></td> </tr> <tr id="rptfreq" style="visibility:hidden;" title="' . tooltip ( 'repeat-frequency-help' ) . '"> <td class="tooltip"><label for="entry_freq">' . translate ( 'Frequency' ) . ':</label></td> <td colspan="2"> <input type="text" name="rpt_freq" id="entry_freq" size="4" ' . 'maxlength="4" value="' . $rpt_freq . '" /> <label id="weekdays_only"><input type="checkbox" ' . 'name="weekdays_only" value="y" ' . ( empty ( $weekdays_only ) ? '' : $checked ) . ' />' . translate ( 'Weekdays Only' ) . '</label> <span id="rptwkst"> <select name="wkst">'; for ( $i = 0; $i < 7; $i++ ) { echo ' <option value="' . $byday_names[$i] . '" ' . ( $wkst == $byday_names[$i] ? $selected : '' ) . '>' . translate ( $byday_names[$i] ) . '</option>'; } echo ' </select> <label for="rptwkst">' . translate ( 'Week Start' ) . '</label> </span> </td> </tr> <tr> <td colspan="4"></td> </tr> <tr id="rptbydayextended" style="visibility:hidden;" title="' . tooltip ( 'repeat-bydayextended-help' ) . '"> <td class="tooltip"><label>' . translate ( 'ByDay' ) . ':</label></td> <td colspan="2" class="boxall"> <input type="hidden" name="bydayList" value="' . ( empty ( $bydayStr ) ? '' : $bydayStr ) . '" /> <input type="hidden" name="bymonthdayList" value="' . ( empty ( $bymonthdayStr ) ? '' : $bymonthdayStr ) . '" /> <input type="hidden" name="bysetposList" value="' . ( empty ( $bysetposStr ) ? '' : $bysetposStr ) . '" /> <table class="byxxx" cellpadding="2" cellspacing="2" ' . 'border="1"> <tr> <td></td>'; // Display byday extended selection. // We use BUTTONS in a triple state configuration, and store the values in // a javascript array until form submission. We then set the hidden field // bydayList to the string value of the array. for ( $rpt_byday_label = $WEEK_START; $rpt_byday_label <= ( $WEEK_START + 6 ); $rpt_byday_label++ ) { $rpt_byday_mod = $rpt_byday_label % 7; $class = ( is_weekend ( $rpt_byday_mod ) ? ' class="weekend" ' : '' ); echo ' <th width="50px"' . $class . '><label>' . translate ( $weekday_names[$rpt_byday_mod] ) . '</label></th>'; } echo ' </tr> <tr> <th>' . translate ( 'All' ) . '</th>'; for ( $rpt_byday_single = $WEEK_START; $rpt_byday_single <= ( $WEEK_START + 6 ); $rpt_byday_single++ ) { $rpt_byday_mod = $rpt_byday_single % 7; echo ' <td><input type="checkbox" name="bydayAll[]" id="' . $byday_names[$rpt_byday_mod] . '" value="' . "$byday_names[$rpt_byday_mod]\"" . ( in_array ( $byday_names[$rpt_byday_mod], $byday ) ? $checked : '' ) . ' /></td>'; } echo ' </tr> <tr id="rptbydayln" style="visibility:hidden;">'; for ( $loop_ctr = 1; $loop_ctr < 6; $loop_ctr++ ) { echo ' <th><label>' . $loop_ctr . '/' . ( $loop_ctr - 6 ) . '</label></th>'; for ( $rpt_byday = $WEEK_START; $rpt_byday <= ( $WEEK_START + 6 ); $rpt_byday++ ) { $rpt_byday_mod = $rpt_byday % 7; $buttonvalue = ( in_array ( $loop_ctr . $byday_names[$rpt_byday_mod], $byday ) ? $loop_ctr . translate ( $byday_names[$rpt_byday_mod] ) : ( in_array ( ( $loop_ctr - 6 ) . $byday_names[$rpt_byday_mod], $byday ) ? ( $loop_ctr - 6 ) . translate ( $byday_names[$rpt_byday_mod] ) : ' ' ) ); echo ' <td><input type="button" name="byday" id="_' . $loop_ctr . $rpt_byday_mod . '" value="' . $buttonvalue . '" onclick="toggle_byday( this )" /></td>'; } echo ' </tr>'; if ( $loop_ctr < 5 ) echo ' <tr id="rptbydayln' . $loop_ctr . '" style="visibility:hidden;">'; } echo ' </table> </td> </tr> <tr> <td colspan="4"></td> </tr> <tr id="rptbymonth" style="visibility:hidden;" title="' . tooltip ( 'repeat-month-help' ) . '"> <td class="tooltip">' . translate ( 'ByMonth' ) . ': </td> <td colspan="2" class="boxall">' /* Display bymonth selection. */ . ' <table cellpadding="5"> <tr>'; for ( $rpt_month = 1; $rpt_month < 13; $rpt_month++ ) { echo ' <td><label><input type="checkbox" name="bymonth[]" value="' . $rpt_month . '"' . ( in_array ( $rpt_month, $bymonth ) ? $checked : '' ) . ' /> ' . translate ( date ( 'M', mktime ( 0, 0, 0, $rpt_month, 1 ) ) ) . '</label></td>' . ( $rpt_month == 6 ? ' </tr> <tr>' : '' ); } echo ' </tr> </table> </td> </tr> <tr> <td colspan="4"></td> </tr> <tr id="rptbysetpos" style="visibility:hidden;" title="' . tooltip ( 'repeat-bysetpos-help' ) . '"> <td class="tooltip" id="BySetPoslabel">' . translate ( 'BySetPos' ) . ': </td> <td colspan="2" class="boxall">' /* Display bysetpos selection. */ . ' <table class="byxxx" cellpadding="2" ' . 'border="1"> <tr> <td></td>'; for ( $rpt_bysetpos_label = 1; $rpt_bysetpos_label < 11; $rpt_bysetpos_label++ ) { echo ' <th width="37px"><label>' . $rpt_bysetpos_label . '</label></th>'; } echo ' </tr> <tr>'; for ( $loop_ctr = 1; $loop_ctr < 32; $loop_ctr++ ) { $buttonvalue = ( in_array ( $loop_ctr, $bysetpos ) ? ( $loop_ctr ) : ( in_array ( ( $loop_ctr -32 ), $bysetpos ) ? ( $loop_ctr -32 ) : ' ' ) ); echo ( $loop_ctr == 1 || $loop_ctr == 11 || $loop_ctr == 21 ? ' <th><label>' . $loop_ctr . '-' . ( $loop_ctr + 9 ) . '</label></th>' : '' ) . ( $loop_ctr == 31 ? ' <th><label>31</label></th>' : '' ) . ' <td><input type="button" name="bysetpos" id="bysetpos' . $loop_ctr . '" value="' . $buttonvalue . '" onclick="toggle_bysetpos( this )" /></td>' . ( $loop_ctr % 10 == 0 ? ' </tr> <tr>' : '' ); } echo ' </tr> </table> </td> </tr> <tr> <td colspan="4"></td> </tr> <tr id="rptbymonthdayextended" style="visibility:hidden;" title="' . tooltip ( 'repeat-bymonthdayextended-help' ) . '"> <td class="tooltip" id="ByMonthDaylabel">' . translate ( 'ByMonthDay' ) . ': </td> <td colspan="2" class="boxall">' /* Display bymonthday extended selection. */ . ' <table class="byxxx" cellpadding="2" ' . 'border="1"> <tr> <td></td>'; for ( $rpt_bymonthday_label = 1; $rpt_bymonthday_label < 11; $rpt_bymonthday_label++ ) { echo ' <th width="37px"><label>' . $rpt_bymonthday_label . '</label></th>'; } echo ' </tr> <tr>'; for ( $loop_ctr = 1; $loop_ctr < 32; $loop_ctr++ ) { $buttonvalue = ( in_array ( $loop_ctr, $bymonthday ) ? ( $loop_ctr ) : ( in_array ( ( $loop_ctr -32 ), $bymonthday ) ? ( $loop_ctr - 32 ) : ' ' ) ); echo ( $loop_ctr == 1 || $loop_ctr == 11 || $loop_ctr == 21 ? ' <th><label>' . $loop_ctr . '-' . ( $loop_ctr + 9 ) . '</label></th>' : '' ) . ( $loop_ctr == 31 ? ' <th><label>31</label></th>' : '' ) . ' <td><input type="button" name="bymonthday" id="bymonthday' . $loop_ctr . '" value="' . $buttonvalue . '" onclick="toggle_bymonthday( this )" /></td>' . ( $loop_ctr % 10 == 0 ? ' </tr> <tr>' : '' ); } echo ' </tr> </table>'; // Populate Repeat Exceptions data for later use. $excepts = ''; $exceptcnt = count ( $exceptions ); for ( $i = 0; $i < $exceptcnt; $i++ ) { $excepts .= ' <option value="-' . $exceptions[$i] . '">-' . $exceptions[$i] . '</option>'; } // Populate Repeat Inclusions data for later use $includecnt = count ( $inclusions ); for ( $i = 0; $i < $includecnt; $i++ ) { $excepts .= ' <option value="+' . $inclusions[$i] . '">+' . $inclusions[$i] . '</option>'; } echo ' </td> </tr> <tr id="rptbyweekno" style="visibility:hidden;" title="' . tooltip ( 'repeat-byweekno-help' ) . '"> <td class="tooltip">' . translate ( 'ByWeekNo' ) . ':</td> <td colspan="2"><input type="text" name="byweekno" id="byweekno" ' . 'size="50" maxlength="100" value="' . $byweekno . '" /></td> </tr> <tr id="rptbyyearday" style="visibility:hidden;" title="' . tooltip ( 'repeat-byyearday-help' ) . '"> <td class="tooltip">' . translate ( 'ByYearDay' ) . ':</td> <td colspan="2"><input type="text" name="byyearday" id="byyearday" ' . 'size="50" maxlength="100" value="' . $byyearday . '" /></td> </tr> <tr id="rptexceptions" style="visibility:visible;" title="' . tooltip ( 'repeat-exceptions-help' ) . '"> <td class="tooltip"><label>' . translate ( 'Exclusions' ) . '/<br />' . translate ( 'Inclusions' ) . ':</label></td> <td colspan="2" class="boxtop boxright boxbottom boxleft"> <table width="250px"> <tr> <td colspan="2">' . date_selection ( 'except_', $rpt_end_date ? $rpt_end_date : $cal_date ) . '</td> </tr> <tr> <td class="alignright aligntop" width="100"> <label id="select_exceptions_not" style="visibility:' . ( empty ( $excepts ) ? 'visible' : 'hidden' ) . ';"></label> <select id="select_exceptions" name="exceptions[]" ' . 'multiple="multiple" style="visibility:' . ( empty ( $excepts ) ? 'hidden' : 'visible' ) . ';" size="4">' . $excepts . ' </select> </td> <td class="aligntop"> <input class="alignleft" type="button" name="addException" value="' . translate ( 'Add Exception' ) . '" onclick="add_exception(0)" /><br /> <input class="alignleft" type="button" name="addInclusion" value="' . translate ( 'Add Inclusion' ) . '" onclick="add_exception(1)" /><br /> <input class="alignleft" type="button" name="delSelected" value="' . translate ( 'Delete Selected' ) . '" onclick="del_selected()" /> </td> </tr> </table> </td> </tr> </table>' . ( $useTabs ? ' </div> <!-- End tabscontent_pete -->' : ' </fieldset>' ); } echo ' <!-- REMINDER INFO -->'; if ( $DISABLE_REMINDER_FIELD != 'Y' ) { $rem_minutes = $reminder_offset; // Will be specified in total minutes. $rem_days = intval ( $rem_minutes / 1440 ); $rem_minutes -= ( $rem_days * 1440 ); $rem_hours = intval ( $rem_minutes / 60 ); $rem_minutes -= ( $rem_hours * 60 ); $rem_before = ( empty ( $reminder['before'] ) || $reminder['before'] == 'Y' ); $rem_related = ( empty ( $reminder['related'] ) || $reminder['related'] == 'S' ); // Reminder Repeats. $rem_rep_count = ( isset ( $reminder['repeats'] ) ? $reminder['repeats'] : 0 ); $rem_rep_minutes = ( isset ( $reminder['duration'] ) ? $reminder['duration'] : 0 ); // Will be specified in total minutes. $rem_rep_days = intval ( $rem_rep_minutes / 1440 ); $rem_rep_minutes -= ( $rem_rep_days * 1440 ); $rem_rep_hours = intval ( $rem_rep_minutes / 60 ); $rem_rep_minutes -= ( $rem_rep_hours * 60 ); echo ( $useTabs ? ' <div id="' . $tabs_name[$tabI++] . '" class="tabcontent">' : ' <fieldset> <legend>' . translate ( 'Reminders' ) . '</legend>' ) . ' <table cellpadding="3"> <thead> <tr> <td class="tooltip"><label>' . translate ( 'Send Reminder' ) . ':</label></td> <td colspan="3"> <input type="hidden" name="rem_action" value="' . ( empty ( $reminder['action'] ) ? 'EMAIL' : $reminder['action'] ) . '" /> <input type="hidden" name="rem_last_sent" value="' . ( empty ( $reminder['last_sent'] ) ? 0 : $reminder['last_sent'] ) . '" /> <input type="hidden" name="rem_times_sent" value="' . ( empty ( $reminder['times_sent'] ) ? 0 : $reminder['times_sent'] ) . '" /> <label><input type="radio" name="reminder" ' . 'id="reminderYes" value="1"' . ( $rem_status ? $checked : '' ) . ' onclick="toggle_reminders()" />' . translate ( 'Yes' ) . '</label> <label><input type="radio" name="reminder" ' . 'id="reminderNo" value="0"' . ( $rem_status ? '' : $checked ) . ' onclick="toggle_reminders()" />' . translate ( 'No' ) . '</label> </td> </tr> </thead> <tbody id="reminder_when"> <tr> <td class="tooltip" rowspan="6"><label>' . translate ( 'When' ) . ':</label></td> <td class="boxtop boxleft" width="20%"><label><input type="radio" ' . 'name="rem_when" id="rem_when_date" value="Y" ' . ( $rem_use_date ? $checked : '' ) . ' onclick="toggle_rem_when()" />' . translate ( 'Use Date/Time' ) . ' </label></td> <td class="boxtop boxright" nowrap="nowrap" colspan="2">' . date_selection ( 'reminder_', ( empty ( $reminder['date'] ) ? $cal_date : $reminder['date'] ) ) . '</td> </tr> <tr> <td class="boxleft"> </td> <td class="boxright" colspan="2" nowrap="nowrap">' . time_selection ( 'reminder_', ( empty ( $reminder['time'] ) ? $cal_time : $reminder['time'] ) ) . '</td> </tr> <tr> <td class="boxright boxleft" height="20px" colspan="3"> </td> </tr> <tr> <td class="boxleft"><label><input type="radio" name="rem_when" ' . 'id="rem_when_offset" value="N" ' . ( $rem_use_date ? '' : $checked ) . ' onclick="toggle_rem_when()" />' . translate ( 'Use Offset' ) . ' </label></td> <td class="boxright" nowrap="nowrap" colspan="2"> <label><input type="text" size="2" name="rem_days" value="' . $rem_days . '" />' . $daysStr . '</label> <label><input type="text" size="2" name="rem_hours" ' . 'value="' . $rem_hours . '" />' . $hoursStr . '</label> <label><input type="text" size="2" name="rem_minutes" value="' . $rem_minutes . '" />' . $minutStr . '</label> </td> </tr> <tr> <td class="boxleft"> </td> <td><label><input type="radio" name="rem_before" ' . 'id="rem_beforeY" value="Y"' . ( $rem_before ? $checked : '' ) . ' />' . translate ( 'Before' ) . '</label> </td> <td class="boxright"><label><input type="radio" name="rem_before" ' . 'id="rem_beforeN" value="N"' . ( $rem_before ? '' : $checked ) . ' />' . translate ( 'After' ) . '</label></td> </tr> <tr> <td class="boxbottom boxleft"> </td> <td class="boxbottom"><label><input type="radio" ' . 'name="rem_related" id="rem_relatedS" value="S"' . ( $rem_related ? $checked : '' ) . ' />' . translate ( 'Start' ) . '</label> </td> <td class="boxright boxbottom"><label><input type="radio" ' . 'name="rem_related" id="rem_relatedE" value="E"' . ( $rem_related ? '' : $checked ) . ' />' . translate ( 'End/Due' ) . '</label></td> </tr> <tr> <td colspan="4"></td> </tr> </tbody> <tbody id="reminder_repeat"> <tr> <td class="tooltip" rowspan="2"><label>' . translate ( 'Repeat' ) . ':</label></td> <td class="boxtop boxleft"> <label>' . translate ( 'Times' ) . '</label></td> <td class="boxtop boxright" colspan="2"><input type="text" ' . 'size="2" name="rem_rep_count" value="' . $rem_rep_count . '" onchange="toggle_rem_rep();" /></td> </tr> <tr id="rem_repeats"> <td class="boxbottom boxleft"> <label>' . translate ( 'Every' ) . '</label></td> <td class="boxbottom boxright" colspan="2"> <label><input type="text" size="2" name="rem_rep_days" value="' . $rem_rep_days . '" />' . $daysStr . '</label> <input type="text" size="2" name="rem_rep_hours" value="' . $rem_rep_hours . '" /><label>' . $hoursStr . '</label> <input type="text" size="2" name="rem_rep_minutes" value="' . $rem_rep_minutes . '" /><label>' . $minutStr . '</label> </td> </tr> </tbody> </table>' . ( $useTabs ? ' </div> <!-- End tabscontent_pete -->' : ' </fieldset>' ); } echo $useTabs ? "</div>\n" : ''; if ( file_exists ( 'includes/classes/captcha/captcha.php' ) && $login == '__public__' && ! empty ( $ENABLE_CAPTCHA ) && $ENABLE_CAPTCHA == 'Y' ) { if ( function_exists ( 'imagecreatetruecolor' ) ) { include_once 'includes/classes/captcha/captcha.php'; echo captcha::form(); } else etranslate ( 'CAPTCHA Warning' ); } echo ' <table> <tr> <td> <script type="text/javascript"> <!-- <![CDATA[ document.writeln ( \'<input type="button" value="' . $saveStr . '" onclick="validate_and_submit()" />\' ) //]]> --> </script> <noscript><input type="submit" value="' . $saveStr . '" /></noscript> </td> </tr> </table> <input type="hidden" name="participant_list" value="" /> </form>'; if ( $id > 0 && ( $login == $create_by || $single_user == 'Y' || $is_admin ) ) echo ' <a href="del_entry.php?id=' . $id . '" onclick="return confirm( \'' . translate( 'Are you sure you want to delete this entry?' ) . '\' );">' . translate ( 'Delete entry' ) . '</a><br />'; } else etranslate( 'You are not authorized to edit this entry.' ); // end if ( $can_edit ) // Create a hidden div tag for editing categories... ?> <div id="editCatsDiv" style="display: none;"> <div id="innerDiv"> <form name="editCatForm" id="editCatForm"> <?php if ( ! empty ( $categories ) ) { foreach ( $categories as $K => $V ) { // None is index -1 and needs to be ignored if ( $K > 0 && ( ( $V['cat_owner'] == $login || $V['cat_global'] > 0 ) || $is_admin || substr ( $form, 0, 4 ) == 'edit' ) ) { $tmpStr = $K . '">' . $V['cat_name']; echo '<input type="checkbox" name="cat_' . $K . '" ' . 'id="cat_' . $K . '"><label for="cat_' . $K . '">' . htmlentities ( $V['cat_name'] ); if ( empty ( $V['cat_owner'] ) ) echo '<sup>*</sup>'; echo "</label><br />\n"; } } } ?> <center> <input type="button" value="<?php etranslate("Save");?>" onclick="catOkHandler()" /> </center> </form> </div> </div> <?php if ( $useTabs ) { ?> <script type="text/javascript"> // Initialize tabs var views=new ddtabcontent("viewtabs") views.setpersist(true) views.setselectedClassTarget("link") //"link" or "linkparent" views.init() // End init tabs </script> <?php } echo print_trailer(); ?> PK �]�\ ςe�* �* register.phpnu �[��� <?php // $Id: register.php,v 1.50.2.1 2012/02/28 15:43:10 cknudsen Exp $ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; require_valid_referring_url (); $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include_once 'includes/access.php'; include 'includes/gradient.php'; $WebCalendar->initializeSecondPhase(); load_global_settings(); // TODO make this an option for external users. $htmlmail = false; load_user_preferences( 'guest' ); $WebCalendar->setLanguage(); require 'includes/classes/WebCalMailer.class'; $mail = new WebCalMailer; $appStr = generate_application_name(); $notauth = print_not_auth(); $error = ( empty( $ALLOW_SELF_REGISTRATION ) || $ALLOW_SELF_REGISTRATION != 'Y' ? $notauth : '' ); if( empty( $SELF_REGISTRATION_FULL ) || $SELF_REGISTRATION_FULL != 'Y' ) $SELF_REGISTRATION_FULL = 'N'; $form_control = ( $SELF_REGISTRATION_FULL == 'Y' ? 'email' : 'full' ); /** * See if username and email are unique. * * param: $isWhat string What are we looking for; user login or user email? * param: $isWher string Where are we looking; "login" or "email"? * * Return true if all is OK. */ function checks( $isWhat, $isWher ) { global $control, $error; if( ! strlen( $isWhat ) ) { $error = ( $isWher == 'login' ? translate( 'Username cannot be blank.' ) : translate( 'Email address cannot be blank.' ) ); return false; } $res = dbi_execute( 'SELECT cal_' . $isWher . ' FROM webcal_user WHERE cal_' . $isWher . ' = ?', array( $isWhat ) ); if( $res ) { $row = dbi_fetch_row( $res ); if( $row[0] == $isWhat ) { $control = ''; $error = ( $isWher == 'login' ? translate( 'Username already exists.' ) : translate( 'Email address already exists.' ) ); return false; } } return true; } /** * Generate unique password. */ function generate_password() { $pass = ''; $pass_length = 8; $salt = 'abchefghjkmnpqrstuvwxyz0123456789'; srand( ( double ) microtime() * 1000000 ); $i = 0; while( $i < $pass_length ) { $pass .= substr( $salt, rand() % 33, 1 ); $i++; } return $pass; } $uemail = $ufirstname = $ulastname = $upassword1 = $upassword2 = $user = ''; // We can limit what domain is allowed to self register. // $self_registration_domain should have this format "192.168.220.0:255.255.240.0"; $valid_ip = validate_domain(); if( empty( $valid_ip ) ) $error = $notauth; // We could make $control a unique value if necessary. $control = getPostValue( 'control' ); $illegalCharStr = translate( 'Illegal characters in login XXX.' ); if( empty( $error ) && ! empty( $control ) ) { $uemail = getPostValue( 'uemail' ); $ufirstname = getPostValue( 'ufirstname' ); $uis_admin = 'N'; $ulastname = getPostValue( 'ulastname' ); $user = trim( getPostValue( 'user' ) ); if( $user != addslashes( $user ) ) $error = str_replace( 'XXX', htmlentities( $user ), $illegalCharStr ); // Check to make sure user doesn't already exist. checks( $user, 'login' ); // Check to make sure email address doesn't already exist. checks( $uemail, 'email' ); } if( empty( $error ) && ! empty( $control ) ) { if( $control == 'full' ) { // Process full account addition. $upassword1 = getPostValue( 'upassword1' ); $upassword2 = getPostValue( 'upassword2' ); // Do some checking of user info. if( ! empty( $user ) && ! empty( $upassword1 ) ) { if( get_magic_quotes_gpc() ) { $upassword1 = stripslashes( $upassword1 ); $user = stripslashes( $user ); } $user = trim( $user ); if( $user != addslashes( $user ) ) $error = str_replace( 'XXX', htmlentities( $user ), $illegalCharStr ); } elseif( $upassword1 != $upassword2 ) { $control = ''; $error = translate( 'The passwords were not identical.' ); } if( empty( $error ) ) { user_add_user( $user, $upassword1, $ufirstname, $ulastname, $uemail, $uis_admin ); activity_log( 0, 'system', $user, LOG_NEWUSER_FULL, translate( 'New user via self-registration.' ) ); } } elseif( $control == 'email' ) { // Process account info for email submission. // Need to generate unique passwords and email them to the new user. $new_pass = generate_password(); // TODO allow admin to approve account and emails prior to processing. user_add_user( $user, $new_pass, $ufirstname, $ulastname, $uemail, $uis_admin ); $tempName = trim( $ufirstname . ' ' . $ulastname ); $msg = str_replace( ', XXX.', ( strlen( $tempName ) ? ', ' . $tempName . '.' : '.' ), translate( 'Hello, XXX.' ) ) . "\n\n" . translate( 'A new WebCalendar account has been set up for you.' ) . "\n\n" . str_replace( 'XXX', $user, translate( 'Your username is XXX.' ) ) . "\n\n" . str_replace( 'XXX', $new_pass, translate( 'Your password is XXX.' ) ) . "\n\n" . str_replace( 'XXX', $appStr, translate( 'Please visit XXX to log in and start using your account!' ) ) . "\n"; // Add URL to event, if we can figure it out. if( ! empty( $SERVER_URL ) ) { $url = $SERVER_URL . 'login.php'; if( $htmlmail == 'Y' ) $url = activate_urls( $url ); $msg .= "\n\n" . $url; } $msg .= "\n\n" . translate( 'You may change your password after logging in the first time.' ) . "\n\n" . translate( 'If you received this email in error' ) . "\n\n"; $adminStr = translate( 'Administrator', true ); $name = $appStr . ' ' . translate( 'Welcome' ) . ': ' . $ufirstname; // Send via WebCalMailer class. $mail->WC_Send( $adminStr, $uemail, $ufirstname . ' ' . $ulastname, $name, $msg, $htmlmail, $EMAIL_FALLBACK_FROM ); activity_log( 0, 'system', $user, LOG_NEWUSER_EMAIL, translate( 'New user via email.' ) ); } } echo send_doctype( $appStr ) . ' <!--[if IE 5]><script src="includes/js/ie5.js"></script><![endif]--> <script src="includes/js/prototype.js"></script> <script> var validform = false, xlate = []; xlate[\'inputPassword\'] = \'' . translate( 'You have not entered a password.', true ) . '\', xlate[\'noBlankUsername\'] = \'' . translate( 'Username cannot be blank.', true ) . '\', xlate[\'passwordsNoMatch\'] = \'' . translate( 'The passwords were not identical.', true ) . '\'; </script> <script src="includes/js/register.js"></script> <link href="css_cacher.php?login=__public__" rel="stylesheet" /> <link href="includes/css/styles.css" rel="stylesheet" />' // Print custom header (since we do not call print_header function). . ( ! empty( $CUSTOM_SCRIPT ) && $CUSTOM_SCRIPT == 'Y' ? load_template( $login, 'S' ) : '' ) . ' </head> <body id="register"> <h2>' . $appStr . ' ' . translate( 'Registration' ) . '</h2>' . ( ! empty( $error ) ? ' <span style="color:#FF0000; font-weight:bold;">' . translate( 'Error' ) . ": $error" . '</span><br />' : '<br /><br />' . ( empty( $control ) ? '' : ' <form action="login.php" method="post"> <input type="hidden" name="login" value="' . $user . '" /> <table class="aligncenter" cellspacing="10" cellpadding="10"> <tr> <td rowspan="3"><img src="images/register.gif"></td> <td>' . translate( 'Welcome to WebCalendar' ) . '</td> </tr>' . ( $SELF_REGISTRATION_FULL == 'Y' ? ' <tr> <td colspan="3" class="aligncenter"><label>' . translate( 'Your email should arrive shortly.' ) . '</label></td> </tr>' : '' ) . ' <tr> <td colspan="3" class="aligncenter"><input type="submit" value="' . translate( 'Return to Login screen' ) . '" /></td> </tr> </table> </form>' ) . ' <form action="register.php" method="post" onSubmit="return valid_form()" name="selfreg"> <input type="hidden" name="control" value="' . $form_control . '" /> <table class="aligncenter" cellpadding="10" cellspacing="10"> <tr> <td rowspan="3"><img src="images/register.gif" alt="" /></td> <td class="alignright"><label class="colon">' . translate( 'Username' ) . '</label></td> <td class="alignleft"><input type="text" id="user" name="user" value="' . $user . '" size="20" maxlength="20" onChange="check_name();" /></td> </tr> <tr> <td class="alignright"><label class="colon">' . translate( 'First Name' ) . '</label></td> <td class="alignleft"><input type="text" name="ufirstname" value="' . $ufirstname . '" size="25" maxlength="25" /></td> </tr> <tr> <td class="alignright"><label class="colon">' . translate( 'Last Name' ) . '</label></td> <td class="alignleft"><input type="text" name="ulastname" value="' . $ulastname . '" size="25" maxlength="25" /></td> </tr> <tr> <td class="alignright" colspan="2"><label class="colon">' . translate( 'E-mail address' ) . '</label></td> <td class="alignleft"><input type="text" name="uemail" id="uemail" value="' . $uemail . '" size="40" maxlength="75" onChange="check_uemail();" /></td> </tr> <tr> <td ' . ( $SELF_REGISTRATION_FULL != 'Y' ? 'class="alignright" colspan="2"><label class="colon">' . translate( 'Password' ) . '</label></td> <td class="alignleft"><input name="upassword1" value="' . $upassword1 . '" size="15" type="password" /></td> </tr> <tr> <td class="alignright" colspan="2"><label>' . translate( 'Password (again)' ) . '</label></td> <td class="alignleft"><input name="upassword2" value="' . $upassword2 . '" size="15" type="password" />' : 'colspan="3" class="aligncenter"><label>' . translate( 'Your account information will be emailed to you.' ) . '</label>' ) . '</td> </tr> <tr> <td colspan="3" class="aligncenter"><input type="submit" value="' . translate( 'Submit' ) . '" /></td> </tr> </table> </form>' ) . '<br /><br /><br /><br /><br /><br /><br /><br /> <span class="cookies">' . translate( 'cookies-note' ) . '</span><br /> <hr /> <br /><br /> <a href="' . $PROGRAM_URL . '" id="programname">' . $PROGRAM_NAME . '</a>'; // Print custom trailer (since we do not call print_trailer function). if( ! empty( $CUSTOM_TRAILER ) && $CUSTOM_TRAILER == 'Y' ) { $res = dbi_execute( 'SELECT cal_template_text FROM webcal_report_template WHERE cal_template_type = \'T\' and cal_report_id = 0' ); if( $res ) { if( $row = dbi_fetch_row( $res ) ) echo $row[0]; dbi_free_result( $res ); } } ?> </body> </html> PK �]�\%�>�� � ajax.phpnu �[��� <?php /** * Description * This is the handler for Ajax httpXmlRequests. */ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; require_valid_referring_url (); $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include 'includes/access.php'; include 'includes/validate.php'; $WebCalendar->initializeSecondPhase(); load_global_settings(); load_user_preferences(); $WebCalendar->setLanguage(); $cat_id = getValue ( 'cat_id', '-?[0-9]*', true ); $name = getPostValue ( 'name' ); $page = getPostValue ( 'page' ); // We're processing edit_remotes Calendar ID field. if ( $page == 'edit_remotes' || $page == 'edit_nonuser' ) { $res = dbi_execute ( 'SELECT cal_login FROM webcal_nonuser_cals WHERE cal_login = ?', [$NONUSER_PREFIX . $name] ); if ( $res ) { $row = dbi_fetch_row ( $res ); // Presuming we are using '_NUC_' as $NONUSER_PREFIX. if ( $name == substr ( $row[0], strlen ( $NONUSER_PREFIX ) ) ) echo str_replace ( 'XXX', $name, translate ( 'Duplicate Name XXX', true ) ); } } elseif ( $page == 'register' || $page == 'edit_user' ) { // We're processing username field. $res = dbi_execute ( 'SELECT cal_login FROM webcal_user WHERE cal_login = ?', [$name] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row[0] == $name ) echo str_replace ( 'XXX', $name, translate ( 'Username XXX already exists.', true ) ); } } elseif ( $page == 'email' ) { // We're processing email field from any page. $res = dbi_execute ( 'SELECT cal_email FROM webcal_user WHERE cal_email = ?', [$name] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row[0] == $name ) echo str_replace ( 'XXX', $name, translate ( 'Email address XXX already exists.', true ) ); } } elseif ( $page == 'minitask' ) { $name = ( empty ( $name ) ? 0 : $name ); require_once 'includes/classes/Event.class'; require_once 'includes/classes/RptEvent.class'; include_once 'includes/gradient.php'; $column_array = ['we.cal_priority', 'we.cal_name', 'we.cal_due_date', 'weu.cal_percent']; $task_filter = ' ORDER BY ' . $column_array[$name % 4] . ( $name > 3 ? ' ASC' : ' DESC' ); echo display_small_tasks ( $cat_id ); } ?> PK �]�\0럕� � view_entry.phpnu �[��� <?php // $Id: view_entry.php,v 1.185.2.2 2013/01/07 16:52:13 cknudsen Exp $ /** * Description: * Presents page to view an event with links to edit, delete * confirm, copy, add event * * Input Parameters: * id (*) - cal_id of requested event * date - yyyymmdd format of requested event * user - user to display * log - show activity log (any non-empty value) * (*) required field */ include_once 'includes/init.php'; include 'includes/xcal.php'; // only to display recurrance info // Load Doc classes for attachments and comments include 'includes/classes/Doc.class'; include 'includes/classes/DocList.class'; include 'includes/classes/AttachmentList.class'; include 'includes/classes/CommentList.class'; // Make sure this user is allowed to look at this calendar. $can_approve = $can_edit = $can_view = false; $is_my_event = false; // Is this user owner or participant? $is_confidential = $is_private = $rss_view = false; $error = $eType = $event_status = ''; $log = getGetValue ( 'log' ); $show_log = ! empty ( $log ); $can_email = 'Y'; $areYouSureStr = translate( 'Are you sure you want to delete this entry?' ); $pri[1] = translate ( 'High' ); $pri[2] = translate ( 'Medium' ); $pri[3] = translate ( 'Low' ); if ( empty ( $id ) || $id <= 0 || ! is_numeric ( $id ) ) $error = translate ( 'Invalid entry id.' ); $hide_details = ( $login == '__public__' && ! empty ( $OVERRIDE_PUBLIC ) && $OVERRIDE_PUBLIC == 'Y' ); // Check if we can display basic info for RSS FEED $rssuser = getGetValue ( 'rssuser' ); if ( ! empty ( $rssuser ) ) { $user_rss_enabled = get_pref_setting ( $rssuser, 'USER_RSS_ENABLED' ); $user_remote_access = get_pref_setting ( $rssuser, 'USER_REMOTE_ACCESS' ); $user_rss_timezone = get_pref_setting ( $rssuser, 'TIMEZONE' ); $rss_view = ( $RSS_ENABLED == 'Y' && $user_rss_enabled == 'Y' && $friendly == 1 && ! empty ( $rssuser ) && isset ( $user_remote_access ) ); if ( $rss_view == true ) { if ( $login == '__public__') $user = $rssuser; $hide_details = false; // Make sure the displayed time is accurate. set_env ( 'TZ', $user_rss_timezone ); } } // Is this user a participant or the creator of the event? // If assistant is doing this, then we need to switch login to user in the sql. $sqlparm = ( $is_assistant ? $user : $login ); $res = dbi_execute ( 'SELECT we.cal_id, we.cal_create_by FROM webcal_entry we, webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND we.cal_id = ? AND ( we.cal_create_by = ? OR weu.cal_login = ? )', [$id, $sqlparm, $sqlparm] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row && $row[0] > 0 ) { $can_view = $is_my_event = true; $creator = $row[1]; } dbi_free_result ( $res ); } // Update the task percentage for this user. if ( ! empty ( $_POST ) && $is_my_event ) { require_valid_referring_url (); $upercent = getPostValue ( 'upercent' ); if ( $upercent >= 0 && $upercent <= 100 ) { dbi_execute ( 'UPDATE webcal_entry_user SET cal_percent = ? WHERE cal_login = ? AND cal_id = ?', [$upercent, $login, $id] ); activity_log ( $id, $login, $creator, LOG_UPDATE_T, translate ( 'Update Task Percentage' ) . ' ' . $upercent . '%' ); } // Check if all other user percent is 100%, if so, set cal_complete date. $others_complete = getPostValue ( 'others_complete' ); if ( $upercent == 100 && $others_complete == 'yes' ) { dbi_execute ( 'UPDATE webcal_entry SET cal_completed = ? WHERE cal_id = ?', [gmdate ( 'Ymd', time() ), $id] ); activity_log ( $id, $login, $creator, LOG_UPDATE_T, translate ( 'Completed' ) ); } } // Load event info now. $res = dbi_execute ( 'SELECT cal_create_by, cal_date, cal_time, cal_mod_date, cal_mod_time, cal_duration, cal_priority, cal_type, cal_access, cal_name, cal_description, cal_location, cal_url, cal_due_date, cal_due_time, cal_completed FROM webcal_entry WHERE cal_id = ?', [$id] ); if ( ! $res ) $error = str_replace ('XXX', $id, translate ( 'Invalid entry id XXX.' ) ); else { $row = dbi_fetch_row ( $res ); if ( $row ) { $create_by = $row[0]; $orig_date = $row[1]; $event_time = $row[2]; $mod_date = $row[3]; $mod_time = sprintf ( "%06d", $row[4] ); $duration = $row[5]; $cal_priority = $row[6]; $cal_type = $row[7]; $cal_access = $row[8]; if ( strpos ( 'NT', $cal_type ) !== false ) $eType = 'task'; if ( $hide_details ) { $description = $name = $overrideStr = translate ( $OVERRIDE_PUBLIC_TEXT ); if ( ! empty ( $row[11] ) ) $location = $overrideStr; if ( ! empty ( $row[12] ) ) $url = $overrideStr; } else { $name = $row[9]; $description = $row[10]; $location = $row[11]; $url = $row[12]; } $due_date = $row[13]; $due_time = $row[14]; $cal_completed = $row[15]; } else $error = str_replace ('XXX', $id, translate ( 'Invalid entry id XXX.' ) ); dbi_free_result ( $res ); } if ( empty ( $error ) ) { // don't shift date if All Day or Untimed $display_date = ( $event_time > 0 || ( $event_time == 0 && $duration != 1440 ) ? date ( 'Ymd', date_to_epoch ( $orig_date . sprintf ( "%06d", $event_time ) ) ) : $orig_date ); if ( ! empty ( $year ) ) $thisyear = $year; if ( ! empty ( $month ) ) $thismonth = $month; // Check UAC. $euser = ( empty ( $user ) ? ( $is_my_event ? $login : $create_by ) : $user ); $time_only = 'N'; if ( access_is_enabled() ) { $can_approve = access_user_calendar ( 'approve', $euser, $login, $cal_type, $cal_access ); $can_edit = access_user_calendar ( 'edit', $create_by, $login, $cal_type, $cal_access ); $can_view = access_user_calendar ( 'view', $euser, $login, $cal_type, $cal_access ); $time_only = access_user_calendar ( 'time', $euser, $login, $cal_type, $cal_access ); } if ( $is_admin || $is_nonuser_admin || $is_assistant ) $can_view = true; // Commented out by RJ. Not sure of the reason for this code // if ( ($login != '__public__') && ($PUBLIC_ACCESS_OTHERS == 'Y') ) { // $can_view = true; // } $can_edit = ( $can_edit || $is_admin || $is_nonuser_admin && $user == $create_by || ( $is_assistant && ! $is_private && $user == $create_by ) || ( $readonly != 'Y' && ( $login == $create_by || $single_user == 'Y' ) ) ); if ( $readonly == 'Y' || $is_nonuser || ( $PUBLIC_ACCESS == 'Y' && $login == '__public__' ) ) $can_edit = false; if ( ! $can_view ) { // if not a participant in the event, must be allowed to look at // other user's calendar. $check_group = ( $login == '__public__' && $PUBLIC_ACCESS_OTHERS == 'Y' ) || $ALLOW_VIEW_OTHER == 'Y'; // If $check_group is true, it means this user can look at the event only if // they are in the same group as some of the people in the event. This gets // kind of tricky. If there is a participant from a different group, do we // still show it? For now, the answer is no. This could be configurable // somehow, but how many lines of text would it need in the admin page to // describe this scenario? Would confuse 99.9% of users. // In summary, make sure at least one event participant is in one of // this user's groups. $my_users = get_my_users(); $my_usercnt = count ( $my_users ); if ( is_array ( $my_users ) && $my_usercnt ) { $sql_params = []; $sql = 'SELECT we.cal_id FROM webcal_entry we, webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND we.cal_id = ? AND weu.cal_login IN ( '; $sql_params[] = $id; for ( $i = 0; $i < $my_usercnt; $i++ ) { $sql .= ( $i > 0 ? ', ' : '' ) . '?'; $sql_params[] = $my_users[$i]['cal_login']; } $res = dbi_execute ( $sql . ' )', $sql_params ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row && $row[0] > 0 ) $can_view = true; dbi_free_result ( $res ); } } // If we didn't indicate we need to check groups, // then this user can't view this event. if ( ! $check_group || access_is_enabled() ) $can_view = false; } } //end $error test // If they still cannot view, make sure they are not looking at a nonuser // calendar event where the nonuser is the _only_ participant. if ( empty ( $error ) && ! $can_view && ! empty ( $NONUSER_ENABLED ) && $NONUSER_ENABLED == 'Y' ) { $nonusers = get_nonuser_cals(); $nonuser_lookup = []; for ( $i = 0, $cnt = count ( $nonusers ); $i < $cnt; $i++ ) { $nonuser_lookup[$nonusers[$i]['cal_login']] = 1; } $res = dbi_execute ( 'SELECT cal_login FROM webcal_entry_user WHERE cal_id = ? AND cal_status IN ("A","W")', [$id] ); $found_nonuser_cal = $found_reg_user = false; if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { if ( ! empty ( $nonuser_lookup[$row[0]] ) ) $found_nonuser_cal = true; else $found_reg_user = true; } dbi_free_result ( $res ); } // Does this event contain only nonuser calendars as participants? // If so, then grant access. if ( $found_nonuser_cal && ! $found_reg_user && ! access_is_enabled() ) $can_view = true; } // Final case. If 'public visible by default' is on and 'public' is // a participant to this event, then anyone can view the event. if ( ! $can_view && ! empty ( $PUBLIC_ACCESS_DEFAULT_VISIBLE ) && $PUBLIC_ACCESS_DEFAULT_VISIBLE == 'Y' ) { // check to see if 'public' was a participant $res = dbi_execute ( 'SELECT cal_login FROM webcal_entry_user WHERE cal_id = ? AND cal_login = "__public__" AND cal_status IN ("A","W")', [$id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { if ( ! empty ( $row[0] ) && $row[0] == '__public__' ) { // public is participant $can_view = true; } } dbi_free_result ( $res ); } } $printerStr = generate_printer_friendly ( 'view_entry.php' ); print_header(); if ( ! empty ( $error ) ) { echo print_error ( $error ) . print_trailer(); exit; } if ( ! empty ( $user ) && $login != $user ) { // If viewing another user's calendar, check the status of the // event on their calendar (to see if it's deleted). $res = dbi_execute ( 'SELECT cal_status FROM webcal_entry_user WHERE cal_login = ? AND cal_id = ?', [$user, $id] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) $event_status = $row[0]; dbi_free_result ( $res ); } } else { // We are viewing event on user's own calendar, so check the // status on their own calendar. $res = dbi_execute ( 'SELECT cal_id, cal_status FROM webcal_entry_user WHERE cal_login = ? AND cal_id = ?', [$login, $id] ); if ( $res ) { $row = dbi_fetch_row ( $res ); $event_status = $row[1]; dbi_free_result ( $res ); } } // This section commented out by RJ // This code allows viewing events not otherwise authorized // At this point, if we don't have the event status, then this user is not // viewing an event from his own calendar and not viewing an event from someone // else's calendar. They probably got here from the search results page // (or possibly by hand typing in the URL.) // Check to make sure that it hasn't been deleted from everyone's calendar. //if ( empty ( $event_status ) ) { // $res = dbi_execute ( 'SELECT cal_status FROM webcal_entry_user // WHERE cal_status <> "D" // ORDER BY cal_status', [] ); // if ( $res ) { // if ( $row = dbi_fetch_row ( $res ) ) // $event_status = $row[0]; // dbi_free_result ( $res ); // } //} // If we have no event status yet, it must have been deleted. if ( ( empty ( $event_status ) && ! $is_admin ) || ( ! $can_view && empty ( $rss_view ) ) ) { echo print_not_auth ( true ) . print_trailer(); exit; } // We can bypass $can_view if coming from RSS if ( ( ! $can_view && empty ( $rss_view ) ) ) { echo print_not_auth ( true ) . print_trailer(); exit; } // save date so the trailer links are for the same time period $thisyear = intval ( $orig_date / 10000 ); $thismonth = ( $orig_date / 100 ) % 100; $thisday = $orig_date % 100; // $subject is used for mailto URLs. $subject = generate_application_name() . ': ' . $name; // Remove the '"' character since it causes some mailers to barf $subject = str_replace ( ' "', '', $subject ); $subject = htmlspecialchars ( $subject ); $event_repeats = false; // Build info string for repeating events and end date. $res = dbi_execute ( 'SELECT cal_type FROM webcal_entry_repeats WHERE cal_id = ?', [$id] ); $rep_str = ''; if ( $res ) { if ( $tmprow = dbi_fetch_row ( $res ) ) $event_repeats = true; dbi_free_result ( $res ); } /* calculate end time */ $end_str = ( $event_time >= 0 && $duration > 0 ? '-' . display_time ( $display_date . add_duration ( $event_time, $duration % 1440 ), 2 ) : '' ); // get the email adress of the creator of the entry user_load_variables ( $create_by, 'createby_' ); $email_addr = empty ( $createby_email ) ? '' : $createby_email; // If Private and not this user's event or // Confidential and not user's and not assistant, // then they cannot see name or description. // if ( $row[8] == "R" && ! $is_my_event && ! $is_admin ) { if ( $cal_access == 'R' && ! $is_my_event && ! access_is_enabled() ) { $is_private = true; $description = $name = '[' . translate ( 'Private' ) . ']'; } else if ( $cal_access == 'C' && ! $is_my_event && ! $is_assistant && ! access_is_enabled() ) { $is_confidential = true; $description = $name = '[' . translate ( 'Confidential' ) . ']'; } $event_date = ( $event_repeats && ! empty ( $date ) ? $date : $orig_date ); // Get category Info if ( $CATEGORIES_ENABLED == 'Y' ) { $categories = get_categories_by_id ( $id, ( ( ! empty ( $user ) && strlen ( $user ) ) && ( $is_assistant || $is_admin ) ? $user : $login ), true ); $category = implode ( ', ', $categories ); } // get reminders $reminder = getReminders ( $id, true ); echo ' <h2>' . $name . ( $is_nonuser_admin || ( $is_admin && ! empty ( $user ) && $user == '__public__' ) ? ' ( ' . translate ( 'Admin mode' ) . ' )' : '' ) . ( $is_assistant ? ' ( ' . translate ( 'Assistant mode' ) . ' )' : '' ) . '</h2> <table> <tr> <td class="aligntop bold colon" width="10%">' . translate ( 'Description' ) . '</td> <td>'; if ( ! empty ( $ALLOW_HTML_DESCRIPTION ) && $ALLOW_HTML_DESCRIPTION == 'Y' ) { $str = $description; // $str = str_replace ( '&', '&', $description ); $str = str_replace ( '&amp;', '&', $str ); // If there is no HTML found, then go ahead and replace // the line breaks ("\n") with the HTML break. echo ( strstr ( $str, '<' ) && strstr ( $str, '>' ) ? $str // found some html... : nl2br ( activate_urls ( $str ) ) ); } else echo nl2br ( activate_urls ( htmlspecialchars ( $description ) ) ); echo '</td> </tr>' . ( $DISABLE_LOCATION_FIELD != 'Y' && ! empty ( $location ) ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Location' ) . '</td> <td>' . $location . '</td> </tr>' : '' ) . ( $DISABLE_URL_FIELD != 'Y' && ! empty ( $url ) ? ' <tr> <td class="aligntop bold colon">' . translate ( 'URL' ) . '</td> <td>' . activate_urls ( $url ) . '</td> </tr>' : '' ); if ( $event_status != 'A' && ! empty ( $event_status ) ) { echo ' <tr> <td class="aligntop bold colon">' . translate ( 'Status' ) . '</td> <td>'; if ( $event_status == 'D' ) echo ( $eType == 'task' ? translate ( 'Declined' ) : translate ( 'Deleted' ) ); elseif ( $event_status == 'R' ) echo translate ( 'Rejected' ); elseif ( $event_status == 'W' ) echo ( $eType == 'task' ? translate ( 'Needs-Action' ) : translate ( 'Waiting for approval' ) ); echo '</td> </tr>'; } echo ' <tr> <td class="aligntop bold colon">' . ( $eType == 'task' ? translate ( 'Start Date' ) : translate ( 'Date' ) ) . '</td> <td>' . date_to_str ( $display_date ) . ( $eType == 'task' ? '</td> </tr>' . ( $event_time >= 0 ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Start Time' ) . '</td> <td>' . display_time ( $display_date . sprintf ( "%06d", $event_time ), 2 ) . '</td> </tr>' : '' ) . ' <tr> <td class="aligntop bold colon">' . translate ( 'Due Date' ) . '</td> <td>' . date_to_str ( $due_date ) . '</td> </tr> <tr> <td class="aligntop bold colon">' . translate ( 'Due Time' ) . '</td> <td>' . display_time ( $due_date . sprintf ( "%06d", $due_time ), 2 ) . '</td> </tr>' . ( ! empty ( $cal_completed ) ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Completed' ) . '</td> <td>' . date_to_str ( $cal_completed ) : '' ) : '' ) . '</td> </tr>' . ( $event_repeats ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Repeat Type' ) . '</td> <td>' . export_recurrence_ical ( $id, true ) . '</td> </tr>' : '' ) . ( $eType != 'task' && $event_time >= 0 ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Time' ) . '</td> <td>' . ( $duration == 1440 && $event_time == 0 ? translate ( 'All day event' ) : display_time ( $display_date . sprintf ( "%06d", $event_time ), // Display TZID if no end time ( empty ( $end_str ) ? 2 : 0 ) ) . $end_str ) . '</td> </tr>' : '' ); if ( $duration > 0 && $duration != 1440 ) { $dur_h = intval ( $duration / 60 ); $dur_m = $duration - ( $dur_h * 60 ); echo ' <tr> <td class="aligntop bold colon">' . translate ( 'Duration' ) . '</td> <td>' . ( $dur_h > 0 ? $dur_h . ' ' . translate ( 'hour' . ( $dur_h == 1 ? '' : 's' ) ) . ' ' : '' ) . ( $dur_m > 0 ? $dur_m . ' ' . translate ( 'minutes' ) : '' ) . '</td> </tr>'; } echo ( $DISABLE_PRIORITY_FIELD != 'Y' ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Priority' ) . '</td> <td>' . $cal_priority . '-' . $pri[ceil($cal_priority/3)] .'</td> </tr>' : '' ) . ( $DISABLE_ACCESS_FIELD != 'Y' ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Access' ) . '</td> <td>' . ( $cal_access == "P" ? translate ( 'Public' ) : ( $cal_access == 'C' ? translate ( 'Confidential' ) : translate ( 'Private' ) ) ) . '</td> </tr>' : '' ) . ( $CATEGORIES_ENABLED == 'Y' && ! empty ( $category ) ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Category' ) . '</td> <td>' . $category . '</td> </tr>' : '' ); // Display who originally created event // useful if assistant or Admin $proxy_fullname = ''; if ( ! empty ( $DISPLAY_CREATED_BYPROXY ) && $DISPLAY_CREATED_BYPROXY == 'Y' ) { $res = dbi_execute ( 'SELECT cal_login FROM webcal_entry_log WHERE webcal_entry_log.cal_entry_id = ? AND webcal_entry_log.cal_type = \'C\'', [$id] ); if ( $res ) { $row3 = dbi_fetch_row ( $res ); if ( $row3 ) { user_load_variables ( $row3[0], 'proxy_' ); $proxy_fullname = ( $createby_fullname == $proxy_fullname ? '' : ' ( ' . translate ( 'by' ) . ' ' . $proxy_fullname . ' )' ); } dbi_free_result ( $res ); } } if ( $single_user == 'N' && ! empty ( $createby_fullname ) ) { echo ' <tr> <td class="aligntop bold colon">' . translate ( 'Created by' ) . '</td> <td>'; if ( $is_private && ! access_is_enabled() ) echo '[' . translate ( 'Private' ) . ']</td> </tr>'; else if ( $is_confidential && ! access_is_enabled() ) echo '[' . translate ( 'Confidential' ) . ']</td> </tr>'; else { if ( access_is_enabled() ) $can_email = access_user_calendar ( 'email', $create_by ); $pubAccStr = ( $row[0] == '__public__' ? translate ( 'Public Access' ) : $createby_fullname ); echo ( strlen ( $email_addr ) && $can_email != 'N' ? '<a href="mailto:' . $email_addr . '?subject=' . $subject . '">' . $pubAccStr . '</a>' : $pubAccStr ) . $proxy_fullname . '</td> </tr>'; } } echo ' <tr> <td class="aligntop bold colon">' . translate ( 'Updated' ) . '</td> <td>' . ( ! empty ( $GENERAL_USE_GMT ) && $GENERAL_USE_GMT == 'Y' ? date_to_str ( $mod_date ) . ' ' . display_time ( $mod_date . $mod_time, 3 ) : date_to_str ( date ( 'Ymd', date_to_epoch ( $mod_date . $mod_time ) ) ) . ' ' . display_time ( $mod_date . $mod_time, 2 ) ) . '</td> </tr>' // Display the reminder info if found. . ( ! empty ( $reminder ) ? ' <tr> <td class="aligntop bold colon">' . translate ( 'Send Reminder' ) . '</td> <td>' . $reminder . '</td> </tr>' : '' ); // load any site-specific fields and display them $extras = get_site_extra_fields ( $id ); $site_extracnt = count ( $site_extras ); for ( $i = 0; $i < $site_extracnt; $i++ ) { if ( $site_extras[$i] == 'FIELDSET' ) continue; $extra_name = $site_extras[$i][0]; $extra_type = $site_extras[$i][2]; $extra_arg1 = $site_extras[$i][3]; $extra_arg2 = $site_extras[$i][4]; if ( ! empty ( $site_extras[$i][5] ) ) $extra_view = $site_extras[$i][5] & EXTRA_DISPLAY_VIEW; if ( ! empty ( $extras[$extra_name]['cal_name'] ) && ! empty ( $extra_view ) ) { echo ' <tr> <td class="aligntop bold colon">' . translate ( $site_extras[$i][1] ) . '</td> <td>'; if ( $extra_type == EXTRA_URL ) { $target = ( ! empty ( $extra_arg1 ) ? ' target="' . $extra_arg1 . '" ' : '' ); echo ( strlen ( $extras[$extra_name]['cal_data'] ) ? '<a href="' . $extras[$extra_name]['cal_data'] . '"' . $target . '>' . $extras[$extra_name]['cal_data'] . '</a>' : '' ); } elseif ( $extra_type == EXTRA_EMAIL ) echo ( strlen ( $extras[$extra_name]['cal_data'] ) ? '<a href="mailto:' . $extras[$extra_name]['cal_data'] . '?subject=' . $subject . '">' . $extras[$extra_name]['cal_data'] . '</a>' : '' ); elseif ( $extra_type == EXTRA_DATE ) echo ( $extras[$extra_name]['cal_date'] > 0 ? date_to_str ( $extras[$extra_name]['cal_date'] ) : '' ); elseif ( $extra_type == EXTRA_TEXT || $extra_type == EXTRA_MULTILINETEXT ) echo nl2br ( $extras[$extra_name]['cal_data'] ); elseif ( $extra_type == EXTRA_USER || $extra_type == EXTRA_SELECTLIST || $extra_type == EXTRA_CHECKBOX ) echo $extras[$extra_name]['cal_data']; elseif ( $extra_type == EXTRA_RADIO ) echo $extra_arg1[$extras[$extra_name]['cal_data']]; echo '</td> </tr>'; } } // participants // Only ask for participants if we are multi-user. $allmails = []; $show_participants = ( $DISABLE_PARTICIPANTS_FIELD != 'Y' ); if ( $is_admin ) $show_participants = true; if ( $PUBLIC_ACCESS == 'Y' && $login == '__public__' && ( $PUBLIC_ACCESS_OTHERS != 'Y' || $PUBLIC_ACCESS_VIEW_PART == 'N' ) ) $show_participants = false; if ( $single_user == 'N' && $show_participants ) { echo ' <tr> <td class="aligntop bold colon">' . translate ( 'Participants' ) . '</td> <td>'; $num_app = $num_rej = $num_wait = 0; if ( $is_private && ! access_is_enabled() ) echo '[' . translate ( 'Private' ) . ']'; else if ( $is_confidential && ! access_is_enabled() ) echo '[' . translate ( 'Confidential' ) . ']'; else { $res = dbi_execute ( 'SELECT cal_login, cal_status, cal_percent FROM webcal_entry_user WHERE cal_id = ?' . ( $eType == 'task' ? ' AND cal_status IN ( \'A\', \'W\' )' : '' ), [$id] ); $first = 1; if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $participants[] = $row; $pname = $row[0]; if ( $row[1] == 'A' ) $approved[$num_app++] = $pname; elseif ( $row[1] == 'R' ) $rejected[$num_rej++] = $pname; elseif ( $row[1] == 'W' ) $waiting[$num_wait++] = $pname; } dbi_free_result ( $res ); } else db_error() . '<br />'; } if ( $eType == 'task' ) { echo ' <table border="1" width="80%" cellpadding="1"> <th class="aligncenter">' . translate ( 'Participants' ) . '</th> <th class="aligncenter" colspan="2">' . translate ( 'Percentage Complete' ) . '</th>'; $others_complete = 'yes'; for ( $i = 0, $cnt = count ( $participants ); $i < $cnt; $i++ ) { user_load_variables ( $participants[$i][0], 'temp' ); if ( access_is_enabled() ) $can_email = access_user_calendar ( 'email', $templogin ); $spacer = 100 - $participants[$i][2]; $percentage = $participants[$i][2]; if ( $participants[$i][0] == $login ) $login_percentage = $participants[$i][2]; else if ( $participants[$i][2] < 100 ) $others_complete = 'no'; echo ' <tr> <td width="30%">'; if ( strlen ( $tempemail ) && $can_email != 'N' ) { echo '<a href="mailto:' . $tempemail . '?subject=' . $subject . '"> ' . $tempfullname . '</a>'; $allmails[] = $tempemail; } else echo ' ' . $tempfullname; echo '</td> <td width="5%" class="aligncenter">' . $percentage . '%</td> <td width="65%"> <img src="images/pix.gif" width="' . $percentage . '%" height="10"> <img src="images/spacer.gif" width="' . $spacer . '" height="10"> </td> </tr>'; } echo ' </table>'; } else { for ( $i = 0; $i < $num_app; $i++ ) { user_load_variables ( $approved[$i], 'temp' ); if ( access_is_enabled() ) $can_email = access_user_calendar ( 'email', $templogin ); echo ' '; if ( strlen ( $tempemail ) > 0 && $can_email != 'N' ) { echo '<a href="mailto:' . $tempemail . '?subject=' . $subject . '">' . $tempfullname . '</a>'; $allmails[] = $tempemail; } else echo $tempfullname; echo '<br />'; } // show external users here... if ( ! empty ( $ALLOW_EXTERNAL_USERS ) && $ALLOW_EXTERNAL_USERS == 'Y' ) { $external_users = event_get_external_users ( $id, 1 ); $ext_users = explode ( "\n", $external_users ); if ( is_array ( $ext_users ) ) { $externUserStr = translate ( 'External User' ); for ( $i = 0, $cnt = count ( $ext_users ); $i < $cnt; $i++ ) { if ( ! empty ( $ext_users[$i] ) ) { echo ' ' . $ext_users[$i] . ' (' . $externUserStr . ')<br />'; if ( preg_match ( '/mailto: (\S+)"/', $ext_users[$i], $match ) ) $allmails[] = $match[1]; } } } } for ( $i = 0; $i < $num_wait; $i++ ) { user_load_variables ( $waiting[$i], 'temp' ); if ( access_is_enabled() ) $can_email = access_user_calendar ( 'email', $templogin ); echo ' '; if ( strlen ( $tempemail ) > 0 && $can_email != 'N' ) { echo '<a href="mailto:' . $tempemail . '?subject=' . $subject . '">' . $tempfullname . '</a>'; $allmails[] = $tempemail; } else echo $tempfullname; echo ' (?)<br />'; } for ( $i = 0; $i < $num_rej; $i++ ) { user_load_variables ( $rejected[$i], 'temp' ); if ( access_is_enabled() ) $can_email = access_user_calendar ( 'email', $templogin ); echo ' <strike>' . ( strlen ( $tempemail ) > 0 && $can_email != 'N' ? '<a href="mailto:' . $tempemail . '?subject=' . $subject . '">' . $tempfullname . '</a>' : $tempfullname ) . '</strike> (' . translate ( 'Rejected' ) . ')<br />'; } } echo ' </td> </tr>'; } // end participants $can_edit = ( $can_edit || $is_admin || $is_nonuser_admin && ( $user == $create_by ) || ( $is_assistant && ! $is_private && ( $user == $create_by ) ) || ( $readonly != 'Y' && ( $login != '__public__' && $login == $create_by || $single_user == 'Y' ) ) ); if ( empty ( $event_status ) ) { // this only happens when an admin views a deleted event that he is // not a participant for. Set to $event_status to "D" just to get // rid of all the edit/delete links below. $event_status = 'D'; } if ( $eType == 'task' ) { // allow user to update their task completion percentage if ( empty ( $user ) && $readonly != 'Y' && $is_my_event && ( $login != '__public__' ) && ! $is_nonuser && $event_status != 'D' ) { echo ' <tr> <td class="aligntop bold"> <form action="view_entry.php?id=' . $id . '" method="post" name="setpercentage"> <input type="hidden" name="others_complete" value="' . $others_complete . '" />' . translate ( 'Update Task Percentage' ) . ' </td> <td> <select name="upercent" id="task_percent">'; for ( $i = 0; $i <= 100; $i += 10 ) { echo ' <option value="' . "$i\" " . ( $login_percentage == $i ? ' selected="selected"':'' ) . ' >' . $i . '</option>'; } echo ' </select> <input type="submit" value="' . translate ( 'Update' ) . '" /> </form> </td> <tr>'; } } if ( Doc::attachmentsEnabled() && $rss_view == false ) { echo ' <tr> <td class="aligntop bold colon">' . translate ( 'Attachments' ) . '</td> <td>'; $attList = new AttachmentList( $id ); for ( $i = 0; $i < $attList->getSize(); $i++ ) { $a = $attList->getDoc ( $i ); echo ' ' . $a->getSummary() // show delete link if user can delete . ( $is_admin || $login == $a->getLogin() || user_is_assistant( $login, $a->getLogin() ) || $login == $create_by || user_is_assistant( $login, $create_by ) ? ' <a href="docdel.php?blid=' . $a->getId() . '" onclick="return confirm( \'' . $areYouSureStr . '\' );">' . '<img src="images/delete.png"/></a>' : '' ) . '<br />'; } $num_app = $num_rej = $num_wait = 0; $num_attach = $attList->getSize(); echo ( $num_attach == 0 ? ' ' . translate ( 'None' ) . '<br />' :'' ) . ' </td> </tr>'; } if ( Doc::commentsEnabled() ) { echo ' <tr> <td class="aligntop bold colon">' . translate ( 'Comments' ) . '</td> <td>'; $comList = new CommentList( $id ); $num_comment = $comList->getSize(); $comment_text = ''; for ( $i = 0; $i < $num_comment; $i++ ) { $cmt = $comList->getDoc ( $i ); user_load_variables ( $cmt->getLogin(), 'cmt_' ); $comment_text .= ' <strong>' . htmlspecialchars ( $cmt->getDescription() ) . '</strong> - ' . $cmt_fullname . ' ' . translate ( 'at' ) . ' ' . date_to_str ( $cmt->getModDate(), '', false, true ) . ' ' . display_time ( $cmt->getModTime(), 2 ) // show delete link if user can delete . ( $is_admin || $login == $cmt->getLogin() || user_is_assistant( $login, $cmt->getLogin() ) || $login == $create_by || user_is_assistant( $login, $create_by ) ? ' <a href="docdel.php?blid=' . $cmt->getId() . '" onclick="return confirm( \'' . $areYouSureStr . '\' );"><img src="images/delete.png"/></a>' : '' )// end show delete link . '<br /> <blockquote id="eventcomment">'; if ( ! empty ( $ALLOW_HTML_DESCRIPTION ) && $ALLOW_HTML_DESCRIPTION == 'Y' ) { $str = $cmt->getData(); $str = str_replace ( '&amp;', '&', $str ); // If there is no HTML found, then go ahead and replace // the line breaks ("\n") with the HTML break. $comment_text .= ( strstr ( $str, '<' ) && strstr ( $str, '>' ) ? $str // found some html... : nl2br ( activate_urls ( $str ) ) ); } else { $comment_text .= nl2br ( activate_urls ( htmlspecialchars( $cmt->getData() ) ) ); } $comment_text .= '</blockquote><div style="clear:both"></div>'; } if ( $num_comment == 0 ) echo translate ( 'None' ) . '<br />'; else { echo ' ' . $num_comment . ' ' . translate ( 'comments' ) . ' <input id="showbutton" type="button" value="' . translate ( 'Show' ) . '" onclick="showComments();" /> <input id="hidebutton" type="button" value="' . translate ( 'Hide' ) . '" onclick="hideComments();" /><br /> <div id="comtext">' . $comment_text . '</div>'; // We could put the following JS in includes/js/view_entry.php, // but we won't need it in many cases and we don't know whether // we need it until after would need to include it. // So, we will include it here instead. ?> <script> <!-- <![CDATA[ function showComments() { var x = document.getElementById ( "comtext" ) if ( x ) { x.style.display = "block"; } x = document.getElementById ( "showbutton" ) if ( x ) { x.style.display = "none"; } x = document.getElementById ( "hidebutton" ) if ( x ) { x.style.display = "block"; } } function hideComments() { var x = document.getElementById ( "comtext" ) if ( x ) { x.style.display = "none"; } x = document.getElementById ( "showbutton" ) if ( x ) { x.style.display = "block"; } x = document.getElementById ( "hidebutton" ) if ( x ) { x.style.display = "none"; } } hideComments(); //]]> --> </script> <?php } $num_app = $num_rej = $num_wait = 0; echo '</td> </tr>'; } $rdate = ( $event_repeats ? '&date=' . $event_date : '' ); $u_url = ( ! empty ( $user ) && $login != $user ? "&user=$user" : '' ); echo ' </table> <ul class="nav">'; // Show a printer-friendly link if ( empty ( $friendly ) ) echo $printerStr; if ( ( $is_my_event || $is_nonuser_admin || $is_assistant || $can_approve ) && $readonly == 'N' && $login != '__public__') { if ( $event_status != 'A' ) { $approveStr = translate( 'Approve/Confirm entry' ); echo ' <li><a title="' . $approveStr . '" class="nav" href="approve_entry.php?id=' . $id . $u_url . '&type=E" onclick="return confirm( \'' . translate( 'Approve this entry?', true ) . '\' );">' . $approveStr . '</a></li>'; } if ( $event_status != 'R' ) { $rejectStr = translate( 'Reject entry' ); echo ' <li><a title="' . $rejectStr . '" class="nav" href="reject_entry.php?id=' . $id . $u_url . '&type=E" onclick="return confirm( \'' . translate( 'Reject this entry?', true ) . '\' );">' . $rejectStr . '</a></li>'; } } // TODO add these permissions to the UAC list $can_add_attach = ( Doc::attachmentsEnabled() && $login != '__public__' && ( ( $login == $create_by ) || ( $is_my_event && $ALLOW_ATTACH_PART == 'Y' ) || ( $ALLOW_ATTACH_ANY == 'Y' ) || $is_admin ) ); $can_add_comment = ( Doc::commentsEnabled() && $login != '__public__' && ( ( $login == $create_by ) || ( $is_my_event && $ALLOW_COMMENTS_PART == 'Y' ) || ( $ALLOW_COMMENTS_ANY == 'Y' ) || $is_admin ) ); if ( $can_add_attach && $event_status != 'D' ) { $addAttchStr = translate ( 'Add Attachment' ); echo ' <li><a title="' . $addAttchStr . '" class="nav" href="docadd.php?type=A&id=' . $id . $u_url . '">' . $addAttchStr . '</a></li>'; } if ( $can_add_comment && $event_status != 'D' ) { $addCommentStr = translate ( 'Add Comment' ); echo ' <li><a title="' . $addCommentStr . '" class="nav" href="docadd.php?type=C&id=' . $id . $u_url . '">' . $addCommentStr . '</a></li>'; } // If approved, but event category not set (and user does not have permission // to edit where they could also set the category), then allow them to // set it through set_cat.php. if ( empty ( $user ) && $CATEGORIES_ENABLED == 'Y' && $readonly != 'Y' && $is_my_event && $login != '__public__' && ! $is_nonuser && $event_status != 'D' && ! $can_edit ) { $setCatStr = translate ( 'Set category' ); echo ' <li><a title="' . $setCatStr . '" class="nav" href="set_entry_cat.php?id=' . $id . $rdate . '">' . $setCatStr . '</a></li>'; } $addToMineStr = translate ( 'Add to My Calendar' ); $copyStr = translate ( 'Copy entry' ); $deleteAllStr = translate ( 'This will delete this entry for all users.', true ); $deleteEntryStr = translate ( 'Delete entry' ); $editEntryStr = translate ( 'Edit entry' ); //TODO Don't show if $user != $login and not assistant // This will be easier with UAC always on if ( $can_edit && $event_status != 'D' && ! $is_nonuser && $readonly != 'Y' ) { if ( $event_repeats ) { $editAllDatesStr = translate ( 'Edit repeating entry for all dates' ); $deleteAllDatesStr = translate ( 'Delete repeating event for all dates' ); echo ' <li><a title="' . $editAllDatesStr . '" class="nav" href="edit_entry.php?id=' . $id . $u_url . '">' . $editAllDatesStr . '</a></li>'; // Don't allow override of first event if ( ! empty ( $date ) && $date != $orig_date ) { $editThisDateStr = translate ( 'Edit entry for this date' ); echo ' <li><a title="' . $editThisDateStr . '" class="nav" ' . 'href="edit_entry.php?id=' . $id . $u_url . $rdate . '&override=1">' . $editThisDateStr . '</a></li>'; } echo ' <li><a title="' . $deleteAllDatesStr . '" class="nav" href="del_entry.php?id=' . $id . $u_url . '&override=1" onclick="return confirm( \'' . $areYouSureStr . "\\n\\n" . $deleteAllStr . '\' );">' . $deleteAllDatesStr . '</a></li>'; // Don't allow deletion of first event if ( ! empty ( $date ) && $date != $orig_date ) { $deleteOnlyStr = translate ( 'Delete entry only for this date' ); echo ' <li><a title="' . $deleteOnlyStr . '" class="nav" href="del_entry.php?id=' . $id . $u_url . $rdate . '&override=1" onclick="return confirm( \'' . $areYouSureStr . "\\n\\n" . $deleteAllStr . '\' );">' . $deleteOnlyStr . '</a></li>'; } } else { if ( ! empty( $user ) && $user != $login && ! $is_assistant ) { user_load_variables( $user, 'temp_' ); $delete_str = str_replace( 'XXX', $temp_fullname, translate( 'Delete entry from calendar of XXX' ) ); } else { $delete_str = $deleteEntryStr; } echo ' <li><a title="' . $editEntryStr . '" class="nav" href="edit_entry.php?id=' . $id . $u_url . '">' . $editEntryStr . '</a></li> <li><a title="' . $delete_str . '" class="nav" href="del_entry.php?id=' . $id . $u_url . $rdate . '" onclick="return confirm( \'' . $areYouSureStr . "\\n\\n" . ( empty ( $user ) || $user == $login || $is_assistant ? $deleteAllStr : '' ) . '\' );">' . $delete_str; echo '</a></li>'; } echo ' <li><a title="' . $copyStr . '" class="nav" href="edit_entry.php?id=' . $id . $u_url . '&copy=1">' . $copyStr . '</a></li>'; } elseif ( $readonly != 'Y' && ( $is_my_event || $is_nonuser_admin || $can_edit ) && ( $login != '__public__' ) && ! $is_nonuser && $event_status != 'D' ) { $delFromCalStr = translate ( 'This will delete the entry from your XXX calendar.', true ); echo ' <li><a title="' . $deleteEntryStr . '" class="nav" href="del_entry.php?id=' . $id . $u_url . $rdate . '" onclick="return confirm( \'' . $areYouSureStr . "\\n\\n" . str_replace ( 'XXX ', ( $is_assistant ? translate ( 'boss' ) . ' ' : '' ), $delFromCalStr ) // ( $is_assistant // ? translate ( 'This will delete the entry from your boss calendar.', true ) // : translate ( 'This will delete the entry from your calendar.', true ) ) . '\' );">' . $deleteEntryStr . ( $is_assistant ? ' ' . translate ( 'from your boss calendar' ) : '' ) . '</a></li> <li><a title="' . $copyStr . '" class="nav" href="edit_entry.php?id=' . $id . '&copy=1">' . $copyStr . '</a></li>'; } if ( $readonly != 'Y' && ! $is_my_event && ! $is_private && ! $is_confidential && $event_status != 'D' && $login != '__public__' && ! $is_nonuser ) echo ' <li><a title="' . $addToMineStr . '" class="nav" href="add_entry.php?id=' . $id . '" onclick="return confirm( \'' . translate ( 'Do you want to add this entry to your calendar?', true ) . "\\n\\n" . translate ( 'This will add the entry to your calendar.', true ) . '\' );">' . $addToMineStr . '</a></li>'; if ( $login != '__public__' && count ( $allmails ) > 0 ) { $emailAllStr = translate ( 'Email all participants' ); echo ' <li><a title="' . $emailAllStr . '" class="nav" href="mailto:' . implode ( ',', $allmails ) . '?subject=' . rawurlencode ( $subject ) . '">' . $emailAllStr . '</a></li>'; } $can_show_log = $is_admin; // default if access control is not enabled if ( access_is_enabled() ) $can_show_log = access_can_access_function ( ACCESS_ACTIVITY_LOG ); if ( $can_show_log ) { $hideActivityStr = translate ( 'Hide activity log' ); $showActivityStr = translate ( 'Show activity log' ); echo ' <li><a title="' . ( ! $show_log ? $showActivityStr . '" class="nav" href="view_entry.php?id=' . $id . '&log=1">' . $showActivityStr : $hideActivityStr . '" class="nav" href="view_entry.php?id=' . $id . '">' . $hideActivityStr ) . '</a></li>'; } echo ' </ul>'; if ( $can_show_log && $show_log ) { $PAGE_SIZE = 25; // number of entries to show at once echo generate_activity_log ( $id ); } if ( access_can_access_function ( ACCESS_EXPORT ) && ( ( ! $is_private && ! $is_confidential ) || ! access_is_enabled() ) && ! $hide_details ) { $exportStr = translate ( 'Export' ); $exportThisStr = translate ( 'Export this entry to' ); $palmStr = translate ( 'Palm Pilot' ); $selectStr = generate_export_select(); $userStr = ( ! empty ( $user ) ? '<input type="hidden" name="user" value="' . $user . '" />' : '' ); echo <<<EOT <br /> <form method="post" name="exportform" action="export_handler.php"> <label for="exformat">{$exportThisStr}: </label> {$selectStr} <input type="hidden" name="id" value="{$id}" /> {$userStr} <input type="submit" value="{$exportStr}" /> </form> EOT; } echo print_trailer ( empty ( $friendly ) ); ?> PK �]�\A��`� � edit_entry_handler.phpnu �[��� <?php // $Id: edit_entry_handler.php,v 1.204.2.1 2012/02/28 15:43:10 cknudsen Exp $ include_once 'includes/init.php'; require_valid_referring_url (); require 'includes/classes/WebCalMailer.class'; $mail = new WebCalMailer; load_user_categories(); $do_override = false; $error = ''; $old_id = -1; $dateStr = translate( 'Date XXX' ); $descStr = translate( 'Description XXX' ); $helloStr = translate( 'Hello, XXX.' ); $newAppStr = translate( 'XXX has made a new appointment.' ); $subjStr = translate( 'Subject XXX' ); $timeStr = translate( 'Time XXX' ); $updAppStr = translate( 'XXX has updated an appointment.' ); /** * Put byday values in logical sequence. */ function sort_byday( $a, $b ) { global $byday_values; $len_a = strlen( $a ); $len_b = strlen( $b ); $val_a = $byday_values[substr( $a, -2 )]; $val_b = $byday_values[substr( $b, -2 )]; if( $len_a != $len_b ) return ( $len_a < $len_b ? -1 : 1 ); elseif( $len_a == 2 ) return strcmp( $val_a, $val_b ); else { // They start with numeric offsets. $offset_a = substr( $a, 0, $len_a - 2 ); $offset_b = substr( $b, 0, $len_b - 2 ); if( $offset_a == $offset_b ) return strcmp( $val_a, $val_b ); else // Add weight to weekday value to help sort. return strcmp( abs( $offset_a ) + $val_a * 10, abs( $offset_b ) + $val_b * 10 ); } } $confirm_conflicts = getPostValue( 'confirm_conflicts' ); $id = getPostValue( 'cal_id' ); $override = getPostValue( 'override' ); $override_date = getPostValue( 'override_date' ); if( ! empty( $override ) && ! empty( $override_date ) ) { // Override date specified. // User is going to create an exception to a repeating event. $do_override = true; $old_id = $id; } $old_status = array(); // Pass all string values through getPostValue. $access = getPostValue( 'access' ); $location = getPostValue( 'location', '', 'XSS' ); $name = getPostValue( 'name', '', 'XSS' ); $priority = getPostValue( 'priority' ); $user = getPostValue( 'user' ); // Remember previous cal_group_id if present. $parent = getPostValue( 'parent' ); $old_id = ( empty( $parent ) ? $old_id : $parent ); // Not sure which of these to keep. $participants = getPostValue( 'participants' ); $participants = getPostValue( 'selectedPart' ); $byday = getPostValue( 'byday' ); $bydayAll = getPostValue( 'bydayAll' ); $bydayList = getPostValue( 'bydayList' ); $bymonth = getPostValue( 'bymonth' ); $bymonthday = getPostValue( 'bymonthday' ); $bymonthdayList = getPostValue( 'bymonthdayList' ); $bysetpos = getPostValue( 'bysetpos' ); $bysetposList = getPostValue( 'bysetposList' ); $byweekno = getPostValue( 'byweekno' ); $byyearday = getPostValue( 'byyearday' ); $cat_id = getValue ( 'cat_id', '-?[0-9,\-]*', true ); $completed_day = getPostValue( 'completed_day' ); $completed_hour = getPostValue( 'completed_hour' ); $completed_minute = getPostValue( 'completed_minute' ); $completed_month = getPostValue( 'completed_month' ); $completed_year = getPostValue( 'completed_year' ); $description = getPostValue( 'description', '', 'XSS' ); $due_ampm = getPostValue( 'due_ampm' ); $due_day = getPostValue( 'due_day' ); $due_hour = getPostValue( 'due_hour' ); $due_minute = getPostValue( 'due_minute' ); $due_month = getPostValue( 'due_month' ); $due_year = getPostValue( 'due_year' ); $eType = getPostValue( 'eType' ); // entry_changed is calculated client-side with javascript. $entry_changed = getPostValue( 'entry_changed' ); $entry_url = getPostValue( 'entry_url' ); $exceptions = getPostValue( 'exceptions' ); $rem_action = getPostValue( 'rem_action' ); $rem_before = getPostValue( 'rem_before' ); $rem_days = getPostValue( 'rem_days' ); $rem_hours = getPostValue( 'rem_hours' ); $rem_last_sent = getPostValue( 'rem_last_sent' ); $rem_minutes = getPostValue( 'rem_minutes' ); $rem_related = getPostValue( 'rem_related' ); $rem_rep_count = getPostValue( 'rem_rep_count' ); $rem_rep_days = getPostValue( 'rem_rep_days' ); $rem_rep_hours = getPostValue( 'rem_rep_hours' ); $rem_rep_minutes = getPostValue( 'rem_rep_minutes' ); $rem_times_sent = getPostValue( 'rem_times_sent' ); $rem_when = getPostValue( 'rem_when' ); $reminder = getPostValue( 'reminder' ); $reminder_ampm = getPostValue( 'reminder_ampm' ); $reminder_day = getPostValue( 'reminder_day' ); $reminder_hour = getPostValue( 'reminder_hour' ); $reminder_minute = getPostValue( 'reminder_minute' ); $reminder_month = getPostValue( 'reminder_month' ); $reminder_type = getPostValue( 'reminder_type' ); $reminder_year = getPostValue( 'reminder_year' ); $rpt_ampm = getPostValue( 'rpt_ampm' ); $rpt_count = getPostValue( 'rpt_count' ); $rpt_day = getPostValue( 'rpt_day' ); $rpt_end_use = getPostValue( 'rpt_end_use' ); $rpt_freq = getPostValue( 'rpt_freq' ); $rpt_hour = getPostValue( 'rpt_hour' ); $rpt_minute = getPostValue( 'rpt_minute' ); $rpt_month = getPostValue( 'rpt_month' ); $rpt_type = getPostValue( 'rpt_type' ); $rpt_year = getPostValue( 'rpt_year' ); $rptmode = getPostValue( 'rptmode' ); $timetype = getPostValue( 'timetype' ); $weekdays_only = getPostValue( 'weekdays_only' ); $wkst = getPostValue( 'wkst' ); $description = ( strlen( $description ) == 0 || $description == '<br />' ? $name : $description ); // For public events, we don't EVER allow HTML tags. There is just too // many bad things a malicious user can do. // See this for an example of how someone could create an admin account in // webcalendar: // https://www.upsploit.com/index.php/advisories/download/UPS-2010-0011 // This same technique could be used to delete all events and other bad stuff. if ( $login == '__public__' ) { $name = strip_tags ( $name ); $description = strip_tags ( $description ); $location = strip_tags ( $location ); } // Don't allow certain HTML tags in description. // Malicious users could use meta refresh to redirect users to another // site (possibly a malware site). This could be from a public submission // on an event calendar, and the admin gets sent to the malware site when // viewing the event to approve/reject it. foreach( array( 'APPLET', 'BODY', 'HEAD', 'HTML', 'LINK', 'META', 'OBJECT', 'SCRIPT', 'TITLE' ) as $i ) { if( preg_match( "/<\s*$i/i", $description ) ) { $error = translate( 'Security violation!' ); activity_log( 0, $login, $login, SECURITY_VIOLATION, 'Hijack attempt:edit_entry' ); } } // Pass all numeric values through getPostValue. $entry_ampm = getPostValue( 'entry_ampm' ); $entry_hour = getPostValue( 'entry_hour' ); $entry_minute = getPostValue( 'entry_minute' ); $end_ampm = getPostValue( 'end_ampm' ); $end_hour = getPostValue( 'end_hour' ); $end_minute = getPostValue( 'end_minute' ); $day = getPostValue( 'day' ); $month = getPostValue( 'month' ); $year = getPostValue( 'year' ); $percent = getPostValue( 'percent' ); // Ensure variables are not empty. if( empty( $eType ) ) $eType = 'event'; if( empty( $percent ) ) $percent = 0; if( empty( $timetype ) ) $timetype = 'T'; $duration_h = getValue( 'duration_h' ); $duration_m = getValue( 'duration_m' ); if( empty( $duration_h ) || $duration_h < 0 ) $duration_h = 0; if( empty( $duration_m ) || $duration_m < 0 ) $duration_m = 0; // Reminder values could be valid as 0. if( empty( $rem_days ) ) $rem_days = 0; if( empty( $rem_hours ) ) $rem_hours = 0; if( empty( $rem_minutes ) ) $rem_minutes = 0; if( empty( $rem_rep_days ) ) $rem_rep_days = 0; if( empty( $rem_rep_hours ) ) $rem_rep_hours = 0; if( empty( $rem_rep_minutes ) ) $rem_rep_minutes = 0; if( empty( $reminder_hour ) ) $reminder_hour = 0; if( empty( $reminder_minute ) ) $reminder_minute = 0; // Timed event. if( $timetype == 'T' ) { $entry_hour += $entry_ampm; if( $eType == 'task' ) $due_hour += $due_ampm; } // Use end times if( $TIMED_EVT_LEN == 'E' && $eType != 'task' ) $end_hour += $end_ampm; else $end_hour = $end_minute = 0; // If "all day event" was selected, then we set the event time to be 12AM with a // duration of 24 hours. We don't actually store the "all day event" flag per se. // This method makes conflict checking much simpler. We just need to make sure // that we don't screw up the day view (which normally starts with the first // timed event). Note that if someone actually wants to create an event that // starts at midnight and lasts exactly 24 hours, it will be treated in the // same manner. // All Day Event. if( $timetype == 'A' ) $duration_h = 24; // Untimed Event if( $timetype == 'U' ) $duration_h = 0; if( strpos( 'AU', $timetype ) !== false ) { $duration_m = $end_hour = $end_minute = $entry_hour = $entry_minute = 0; } // Combine all values to create event start date/time. $eventstart = ( $timetype != 'T' ? gmmktime( $entry_hour, $entry_minute, 0, $month, $day, $year ) : mktime( $entry_hour, $entry_minute, 0, $month, $day, $year ) ); if( $eType == 'task' ) { // Combine all values to create event due date/time - User Time. $eventdue = mktime( $due_hour, $due_minute, 0, $due_month, $due_day, $due_year ); // Combine all values to create completed date if( ! empty( $completed_year ) && ! empty( $completed_month ) && ! empty( $completed_day ) ) $eventcomplete = sprintf( "%04d%02d%02d", $completed_year, $completed_month, $completed_day ); } // Create event stop from event duration/end values. // Note: for any given event, either end times or durations are 0 if( $TIMED_EVT_LEN == 'E' ) { // User might have entered midnight as an end time // if so, we need to jump to next day if( $end_hour === 0 && $end_ampm == 0 ) $day++; $eventstophour = $end_hour + $duration_h; $eventstopmin = $end_minute + $duration_m; } else { $eventstophour = $entry_hour + $duration_h; $eventstopmin = $entry_minute + $duration_m; } $duration = 0; if( $eType != 'task' ) { $eventstop = ( $timetype != 'T' ? gmmktime( $eventstophour, $eventstopmin, 0, $month, $day, $year ) : mktime( $eventstophour, $eventstopmin, 0, $month, $day, $year ) ); // Calculate event duration. if( $timetype == 'A' ) $duration = 1440; elseif( $timetype == 'T' ) { $duration = ( $eventstop - $eventstart ) / 60; if( $duration < 0 ) $duration = 0; } } /* Make sure this user is really allowed to edit this event. * Otherwise, someone could hand type in the URL to edit someone else's event. * Can edit if: * - new event * - user is admin * - user created event * - user is participant */ $can_doall = $can_edit = false; // Value may be needed later for recreating event. $old_create_by = ( empty( $user ) ? '' : $user ); if( empty( $id ) ) { // New event... $can_edit = (!empty($readonly) && $readonly != 'Y'); if (access_is_enabled()) $can_edit = access_can_access_function(ACCESS_EVENT_EDIT, $user); if ($login == '__public__') $can_edit = access_is_enabled()? $can_edit: $PUBLIC_ACCESS_CAN_ADD == 'Y'; if (!$is_admin && !$is_assistant && !$is_nonuser_admin) { if ($is_nonuser) $can_edit = false; else if (!empty($user) && $user != $login && $user != '__public__') $can_edit = false; } } else { // Event owner or assistant? $res = dbi_execute( 'SELECT cal_create_by FROM webcal_entry WHERE cal_id = ?', array( $id ) ); if( $res ) { $row = dbi_fetch_row( $res ); // Value may be needed later for recreating event. $old_create_by = $row[0]; if( ( $row[0] == $login ) || ( ( $user == $row[0] ) && ( $is_assistant || $is_nonuser_admin ) ) ) $can_edit = true; dbi_free_result( $res ); } else $error = $dberror . dbi_error(); } if( $is_admin ) $can_edit = true; elseif( access_is_enabled() && ! empty( $old_create_by ) ) $can_edit = access_user_calendar( 'edit', $old_create_by, $login ); if( empty( $error ) && ! $can_edit ) { // Is user a participant of the event? $res = dbi_execute( 'SELECT cal_id FROM webcal_entry_user WHERE cal_id = ? AND cal_login = ? AND cal_status IN( \'W\', \'A\' )', array( $id, $login ) ); if( $res ) { $row = dbi_fetch_row( $res ); if( ! empty( $row[0] ) ) $can_edit = true; // Is participant. dbi_free_result( $res ); } else $error = $dberror . dbi_error(); } if( ! $can_edit && empty( $error ) ) $error = print_not_auth(); // CAPTCHA if( file_exists( 'includes/classes/captcha/captcha.php' ) && $login == '__public__' && ! empty( $ENABLE_CAPTCHA ) && $ENABLE_CAPTCHA == 'Y' ) { if( function_exists( 'imagecreatetruecolor' ) ) { include_once 'includes/classes/captcha/captcha.php'; $res = captcha::check(); if( ! $res ) $error = translate( 'You must enter the anti-spam text on the previous page.' ); } else { // Should have seen warning on edit_entry.php, so no warning here... } } // If display of participants is disabled, set the participant list to the event // creator. This also works for single-user mode. Basically, if no participants // were selected (because there was no selection list available in the form or // because the user refused to select any participant from the list), then we // will assume the only participant is the current user. if( empty( $participants[0] ) ) { $participants[0] = $login; // There might be a better way to do this, // but if Admin sets this value, WebCalendar should respect it. if( ! empty( $PUBLIC_ACCESS_DEFAULT_SELECTED ) && $PUBLIC_ACCESS_DEFAULT_SELECTED == 'Y' ) $participants[1] = '__public__'; } if( empty( $DISABLE_REPEATING_FIELD ) || $DISABLE_REPEATING_FIELD == 'N' ) { // Process only if Expert Mode or Weekly. if( $rpt_type == 'weekly' || ! empty( $rptmode ) ) { $bydayAr = explode( ',', $bydayList ); if( ! empty( $bydayAr ) ) { foreach( $bydayAr as $bydayElement ) { if( strlen( $bydayElement ) > 2 ) $bydayAll[] = $bydayElement; } } if( ! empty( $bydayAll ) ) { $bydayAll = array_unique( $bydayAll ); // Call special sort algorithm. usort( $bydayAll, 'sort_byday' ); $byday = implode( ',', $bydayAll ); // Strip off leading comma if present. if( substr( $byday, 0, 1 ) == ',' ) $byday = substr( $byday, 1 ); } } // This allows users to select on weekdays if daily. if( $rpt_type == 'daily' && ! empty( $weekdays_only ) ) $byday = 'MO,TU,WE,TH,FR'; // Process only if expert mode and MonthbyDate or Yearly. if( ( $rpt_type == 'monthlyByDate' || $rpt_type == 'yearly' ) && ! empty( $rptmode ) ) { $bymonthdayAr = explode( ',', $bymonthdayList ); if( ! empty( $bymonthdayAr ) ) { sort( $bymonthdayAr ); $bymonthdayAr = array_unique( $bymonthdayAr ); $bymonthday = implode( ',', $bymonthdayAr ); } // Strip off leading comma if present. if( substr( $bymonthday, 0, 1 ) == ',' ) $bymonthday = substr( $bymonthday, 1 ); } if( $rpt_type == 'monthlyBySetPos' ) { $bysetposAr = explode( ',', $bysetposList ); if( ! empty( $bysetposAr ) ) { sort( $bysetposAr ); $bysetposAr = array_unique( $bysetposAr ); $bysetpos = implode( ',', $bysetposAr ); } // Strip off leading comma if present. if( substr( $bysetpos, 0, 1 ) == ',' ) $bysetpos = substr( $bysetpos, 1 ); } // If expert mode not selected, // we need to set the basic value for monthlyByDay events. if( $rpt_type == 'monthlyByDay' && empty( $rptmode ) && empty( $byday ) ) $byday = ceil( $day / 7 ) . $byday_names[ date( 'w', $eventstart ) ]; $bymonth = ( empty( $bymonth ) ? '' : implode( ',', $bymonth ) ); if( ! empty( $rpt_end_use ) ) { $rpt_hour += $rpt_ampm; $rpt_until = mktime( $rpt_hour, $rpt_minute, 0, $rpt_month, $rpt_day, $rpt_year ); } $exception_list = $inclusion_list = array(); if( empty( $exceptions ) ) $exceptions = array(); else { foreach( $exceptions as $i ) { if( substr( $i, 0, 1 ) == '+' ) $inclusion_list[] = substr( $i, 1, 8 ); else $exception_list[] = substr( $i, 1, 8 ); } } } // end test for $DISABLE_REPEATING_FIELD // Make sure we initialize these variables. if( empty( $byday ) ) $byday = ''; if( empty( $bymonth ) ) $bymonth = ''; if( empty( $bymonthday ) ) $bymonthday = ''; if( empty( $bysetpos ) ) $bysetpos = ''; if( empty( $byweekno ) ) $byweekno = ''; if( empty( $byyearday ) ) $byyearday = ''; if( empty( $count ) ) $count = ''; if( empty( $rpt_freq ) ) $rpt_freq = 1; if( empty( $rpt_type ) ) $rpt_type = ''; if( empty( $wkst ) ) $wkst = 'MO'; // First check for any schedule conflicts. if( empty( $ALLOW_CONFLICT_OVERRIDE ) || $ALLOW_CONFLICT_OVERRIDE != 'Y' ) $confirm_conflicts = ''; // Security precaution. if( $ALLOW_CONFLICTS != 'Y' && empty( $confirm_conflicts ) && strlen( $entry_hour ) > 0 && $timetype != 'U' && $eType != 'task' ) { $conf_until = ( empty( $rpt_until ) ? '' : $rpt_until ); $conf_count = ( empty( $rpt_count ) ? 999 : $rpt_count ); $dates = get_all_dates( $eventstart, $rpt_type, $rpt_freq, $bymonth, $byweekno, $byyearday, $bymonthday, $byday, $bysetpos, $conf_count, $conf_until, $wkst, $exception_list, $inclusion_list ); // Make sure at least start date is in array. if( empty( $dates ) ) $dates[0] = $eventstart; // Make sure $thismonth and $thisyear are set for use in query_events(). $thismonth = $month; $thisyear = $year; $conflicts = check_for_conflicts( $dates, $duration, $eventstart, $participants, $login, empty( $id ) ? 0 : $id ); } //end check for any schedule conflicts if( empty( $error ) && ! empty( $conflicts ) ) $error = translate( 'The following conflicts with the suggested time' ) . ': <ul>$conflicts</ul>'; $msg = ''; if( empty( $error ) ) { $newevent = true; // Now add the entries. if( empty( $id ) || $do_override ) { $res = dbi_execute( 'SELECT MAX(cal_id) FROM webcal_entry' ); if( $res ) { $row = dbi_fetch_row( $res ); $id = $row[0] + 1; dbi_free_result( $res ); } else $id = 1; } else { $newevent = false; // Save old values of participants. $res = dbi_execute( 'SELECT cal_login, cal_status, cal_percent FROM webcal_entry_user WHERE cal_id = ? ', array( $id ) ); if( $res ) { for( $i = 0; $tmprow = dbi_fetch_row( $res ); $i++ ) { $old_status[$tmprow[0]] = $tmprow[1]; $old_percent[$tmprow[0]] = $tmprow[2]; } dbi_free_result( $res ); } else $error = $dberror . dbi_error(); if( empty( $error ) ) { foreach( array( 'entry', 'entry_ext_user', 'entry_repeats', 'entry_user', 'site_extras' ) as $d ) { dbi_execute( 'DELETE FROM webcal_' . $d . ' WHERE cal_id = ?', array( $id ) ); } } $newevent = false; } if( $do_override ) { if( ! dbi_execute( 'INSERT INTO webcal_entry_repeats_not ( cal_id, cal_date, cal_exdate ) VALUES ( ?, ?, ? )', array( $old_id, $override_date, 1 ) ) ) $error = $dberror . dbi_error(); } $query_params = array( $id ); if( $old_id > 0 ) $query_params[] = $old_id; $query_params[] = ( empty( $old_create_by ) ? $login : $old_create_by ); $query_params[] = gmdate( 'Ymd', $eventstart ); $query_params[] = ( ( strlen( $entry_hour ) > 0 && $timetype != 'U' ) ? gmdate( 'His', $eventstart ) : '-1' ); if( ! empty( $eventcomplete ) ) $query_params[] = $eventcomplete; // Just set $eventdue to something. $eventdue = ( empty( $eventdue ) ? $eventstart : $eventdue ); $query_params[] = gmdate( 'Ymd', $eventdue ); $query_params[] = gmdate( 'His', $eventdue ); $query_params[] = gmdate( 'Ymd' ); $query_params[] = gmdate( 'Gis' ); $query_params[] = sprintf( "%d", $duration ); $query_params[] = ( empty( $priority ) ? '5' : sprintf( "%d", $priority ) ); $query_params[] = ( empty( $access ) ? 'P' : $access ); $tmpRpt = ( ! empty( $rpt_type ) && $rpt_type != 'none' ); if( $eType == 'event' ) $query_params[] = ( $tmpRpt ? 'M' : 'E' ); elseif( $eType == 'journal' ) $query_params[] = ( $tmpRpt ? 'O' : 'J' ); elseif( $eType == 'task' ) $query_params[] = ( $tmpRpt ? 'N' : 'T' ); $query_params[] = ( strlen( $name ) == 0 ? 'Unnamed Event' : $name ); $query_params[] = $description; if( ! empty( $location ) ) $query_params[] = $location; if( ! empty( $entry_url ) ) $query_params[] = $entry_url; if( empty( $error ) && ! dbi_execute( 'INSERT INTO webcal_entry ( cal_id,' . ( $old_id > 0 ? ' cal_group_id,' : '' ) . ' cal_create_by, cal_date, cal_time,' . ( empty( $eventcomplete ) ? '' : ' cal_completed,' ) . ' cal_due_date, cal_due_time, cal_mod_date, cal_mod_time, cal_duration, cal_priority, cal_access, cal_type, cal_name, cal_description' . ( empty( $location ) ? '' : ', cal_location ' ) . ( empty( $entry_url ) ? '' : ', cal_url ' ) . ' ) VALUES ( ?' . str_repeat( ',?', count( $query_params ) - 1 ) . ' )', $query_params ) ) $error = $dberror . dbi_error(); // Log add/update. if( $eType == 'task' ) { $log_c = LOG_CREATE_T; $log_u = LOG_UPDATE_T; } elseif( $eType == 'journal' ) { $log_c = LOG_CREATE_J; $log_u = LOG_UPDATE_J; } else { $log_c = LOG_CREATE; $log_u = LOG_UPDATE; } activity_log( $id, $login, ( $is_assistant || $is_nonuser_admin ? $user : $login ), $newevent ? $log_c : $log_u, '' ); if( $single_user == 'Y' ) $participants[0] = $single_user_login; // Add categories. $cat_owner = ( ( ! empty( $user ) && strlen( $user ) ) && ( $is_assistant || $is_admin ) ? $user : $login ); dbi_execute( 'DELETE FROM webcal_entry_categories WHERE cal_id = ? AND ( cat_owner = ? OR cat_owner IS NULL )', array( $id, $cat_owner ) ); if( ! empty( $cat_id ) ) { $categories = explode( ',', $cat_id ); $j = 0; foreach( $categories as $i ) { $j++; $names = array( 'cal_id', 'cat_id' ); $values = array( $id, abs( $i ) ); // We set cat_id negative in form if global. if( $i > 0 ) { $names[] = 'cat_owner'; $values[] = $cat_owner; $values[] = $j; } else $values[] = 99; // Force global categories to the end of lists. $names[] = 'cat_order'; if( ! dbi_execute( 'INSERT INTO webcal_entry_categories ( ' . implode( ',', $names ) . ' ) VALUES ( ?' // Build the variable placeholders - comma-separated question marks. . str_repeat( ',?', count( $values ) - 1 ) . ' )', $values ) ) { $error = $dberror . dbi_error(); break; } } } // Add site extras. $extra_email_data = ''; foreach( $site_extras as $i ) { if( ! empty( $error ) ) break; if( $i == 'FIELDSET' ) continue; $extra_name = $i[0]; $extra_type = $i[2]; $extra_arg1 = $i[3]; $extra_arg2 = $i[4]; if( ! empty( $i[5] ) ) $extra_email = $i[5] & EXTRA_DISPLAY_EMAIL; //$value = $$extra_name; $value = getPostValue( $extra_name ); $sql = ''; $query_params = array(); if( strlen( $extra_name ) || $extra_type == EXTRA_DATE ) { if( $extra_type == EXTRA_CHECKBOX || $extra_type == EXTRA_EMAIL || $extra_type == EXTRA_MULTILINETEXT || $extra_type == EXTRA_RADIO || $extra_type == EXTRA_SELECTLIST || $extra_type == EXTRA_TEXT || $extra_type == EXTRA_URL || $extra_type == EXTRA_USER ) { // We were passed an array instead of a string. if( $extra_type == EXTRA_SELECTLIST && $extra_arg2 > 0 ) $value = implode( ',', $value ); $sql = 'INSERT INTO webcal_site_extras ( cal_id, cal_name, cal_type, cal_data ) VALUES ( ?, ?, ?, ? )'; $query_params = array( $id, $extra_name, $extra_type, $value ); if( ! empty( $extra_email ) ) { $value = ( $extra_type == EXTRA_RADIO ? $extra_arg1[$value] : $value ); $extra_email_data .= $extra_name . ': ' . $value . "\n"; } } elseif( $extra_type == EXTRA_DATE ) { $edate = sprintf( "%04d%02d%02d", getPostValue( $extra_name . 'year' ), getPostValue( $extra_name . 'month' ), getPostValue( $extra_name . 'day' ) ); $sql = 'INSERT INTO webcal_site_extras ( cal_id, cal_name, cal_type, cal_date ) VALUES ( ?, ?, ?, ? )'; $query_params = array( $id, $extra_name, $extra_type, $edate ); if( ! empty( $extra_email ) ) $extra_email_data .= $extra_name . ': ' . $edate . "\n"; } } if( strlen( $sql ) && empty( $error ) ) { if( ! dbi_execute( $sql, $query_params ) ) $error = $dberror . dbi_error(); } } //end for site_extras loop // Process reminder. if( ! dbi_execute( 'DELETE FROM webcal_reminders WHERE cal_id = ?', array( $id ) ) ) $error = $dberror . dbi_error(); if( $DISABLE_REMINDER_FIELD != 'Y' && $reminder == true ) { if( empty( $rem_before ) ) $rem_before = 'Y'; // If entry has changed, reset the reminder. if( $entry_changed ) { $rem_last_sent = $rem_times_sent = '0'; } if( empty( $rem_last_sent ) ) $rem_last_sent = '0'; if( empty( $rem_related ) ) $rem_related = 'S'; $reminder_date = $reminder_duration = $reminder_offset = $reminder_repeats = 0; if( $rem_when == 'Y' ) { // Use date. $reminder_hour += $reminder_ampm; $reminder_date = mktime( $reminder_hour, $reminder_minute, 0, $reminder_month, $reminder_day, $reminder_year ); } else // Use offset. $reminder_offset = ( $rem_days * 1440 ) + ( $rem_hours * 60 ) + $rem_minutes; if( $rem_rep_count > 0 ) { $reminder_repeats = $rem_rep_count; $reminder_duration = ( $rem_rep_days * 1440 ) + ( $rem_rep_hours * 60 ) + $rem_rep_minutes; } if( ! dbi_execute( 'INSERT INTO webcal_reminders ( cal_id, cal_date, cal_offset, cal_related, cal_before, cal_repeats, cal_duration, cal_action, cal_last_sent, cal_times_sent ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )', array( $id, $reminder_date, $reminder_offset, $rem_related, $rem_before, $reminder_repeats, $reminder_duration, $rem_action, $rem_last_sent, $rem_times_sent ) ) ) $error = $dberror . dbi_error(); } if( empty( $error ) ) { // Clearly, we want to delete the old repeats, before inserting new... foreach( array( 'repeats', 'repeats_not' ) as $d ) { if( ! dbi_execute( 'DELETE FROM webcal_entry_' . $d . ' WHERE cal_id = ?', array( $id ) ) ) $error .= $dberror . dbi_error(); } // Add repeating info. if( ! empty( $rpt_type ) && strlen( $rpt_type ) && $rpt_type != 'none' ) { $names = array( 'cal_id', 'cal_type', 'cal_frequency' ); $values = array( $id, $rpt_type, ( $rpt_freq ? $rpt_freq : 1 ) ); if( ! empty( $bymonth ) ) { $names[] = 'cal_bymonth'; $values[] = $bymonth; } if( ! empty( $bymonthday ) ) { $names[] = 'cal_bymonthday'; $values[] = $bymonthday; } if( ! empty( $byday ) ) { $names[] = 'cal_byday'; $values[] = $byday; } if( ! empty( $bysetpos ) ) { $names[] = 'cal_bysetpos'; $values[] = $bysetpos; } if( ! empty( $byweekno ) ) { $names[] = 'cal_byweekno'; $values[] = $byweekno; } if( ! empty( $byyearday ) ) { $names[] = 'cal_byyearday'; $values[] = $byyearday; } if( ! empty( $wkst ) ) { $names[] = 'cal_wkst'; $values[] = $wkst; } if( ! empty( $rpt_count ) && is_numeric( $rpt_count ) ) { $names[] = 'cal_count'; $values[] = $rpt_count; } if( ! empty ( $rpt_end_use ) && $rpt_end_use == 'u' && ! empty( $rpt_until ) ) { $names[] = 'cal_end'; $values[] = gmdate( 'Ymd', $rpt_until ); $names[] = 'cal_endtime'; $values[] = gmdate( 'His', $rpt_until ); } $sql = 'INSERT INTO webcal_entry_repeats ( ' . implode( ',', $names ) . ' ) VALUES ( ?' . str_repeat( ',?', count( $values ) - 1 ) . ' )'; dbi_execute( $sql, $values ); $msg .= '<span class="bold">SQL:</span> ' . $sql . '<br /><br />'; } //end add repeating info // We manually created exceptions. This can be done without repeats. if( ! empty( $exceptions ) ) { foreach( $exceptions as $i ) { if( ! dbi_execute( 'INSERT INTO webcal_entry_repeats_not ( cal_id, cal_date, cal_exdate ) VALUES ( ?, ?, ? )', array( $id, substr( $i, 1, 8 ), ( ( substr( $i, 0, 1 ) == '+' ) ? 0 : 1 ) ) ) ) $error = $dberror . dbi_error(); } } //end exceptions } // EMAIL PROCESSING $from = $login_email; if( empty( $from ) && ! empty( $EMAIL_FALLBACK_FROM ) ) $from = $EMAIL_FALLBACK_FROM; // Check if participants have been removed and send out emails. if( ! $newevent && count( $old_status ) > 0 ) { while( list( $old_participant, $dummy ) = each( $old_status ) ) { $found_flag = false; foreach( $participants as $i ) { if( $i == $old_participant ) { $found_flag = true; break; } } // Check UAC. $can_email = 'Y'; if( access_is_enabled() ) $can_email = access_user_calendar( 'email', $old_participant, $login ); $is_nonuser_admin = user_is_nonuser_admin( $login, $old_participant ); // Don't send mail if editing a non-user calendar and we are the admin. if( ! $found_flag && ! $is_nonuser_admin && $can_email == 'Y' ) { // Only send mail if their email address is filled in. $do_send = get_pref_setting( $old_participant, 'EMAIL_EVENT_DELETED' ); $htmlmail = get_pref_setting( $old_participant, 'EMAIL_HTML' ); $t_format = get_pref_setting( $old_participant, 'TIME_FORMAT' ); $user_language = get_pref_setting( $old_participant, 'LANGUAGE' ); $user_TIMEZONE = get_pref_setting( $old_participant, 'TIMEZONE' ); set_env( 'TZ', $user_TIMEZONE ); user_load_variables( $old_participant, 'temp' ); if( $old_participant != $login && ! empty( $tempemail ) && $do_send == 'Y' && $SEND_EMAIL != 'N' ) { reset_language( empty( $user_language ) || $user_language == 'none' ? $LANGUAGE : $user_language ); $fmtdate = ( $timetype == 'T' ? date( 'Ymd', $eventstart ) : gmdate( 'Ymd', $eventstart ) ); $msg = str_replace( 'XXX', $tempfullname, $helloStr ) . "\n\n" . str_replace( 'XXX', $login_fullname, translate( 'XXX has canceled an appointment.' ) ) . "\n" . str_replace( 'XXX', $name, $subjStr ) . "\n\n" . str_replace( 'XXX', $description, $descStr ) . "\n" . str_replace( 'XXX', date_to_str( $fmtdate ), $dateStr ) . "\n" // Apply user's GMT offset and display their TZID. . ( $timetype != 'T' ? '' : str_replace( 'XXX', display_time( '', 2, $eventstart, $t_format ), $timeStr . "\n\n\n" ) ); // Add URL to event, if we can figure it out. if( ! empty( $SERVER_URL ) ) { // DON'T change & to & here. Email will handle it. $url = $SERVER_URL . 'view_entry.php?id=' . $id . '&em=1'; if( $htmlmail == 'Y' ) $url = activate_urls( $url ); $msg .= $url . "\n\n"; } $mail->WC_Send( $login_fullname, $tempemail, $tempfullname, $name, $msg, $htmlmail, $from, ( get_pref_setting( $old_participant, 'EMAIL_ATTACH_ICS', 'N' ) == 'Y' ? $id : '' ) ); activity_log( $id, $login, $old_participant, LOG_NOTIFICATION, translate( 'User removed from participants list.' ) ); } } } } $send_own = get_pref_setting( $login, 'EMAIL_EVENT_CREATE' ); // Now add participants and send out notifications. foreach( $participants as $i ) { // Is the person adding the nonuser calendar admin? $is_nonuser_admin = user_is_nonuser_admin( $login, $i ); // If public access, require approval unless // $PUBLIC_ACCESS_ADD_NEEDS_APPROVAL is set to 'N' if( $login == '__public__' ) { $status = ( ! empty( $PUBLIC_ACCESS_ADD_NEEDS_APPROVAL ) && $PUBLIC_ACCESS_ADD_NEEDS_APPROVAL == 'N' ? 'A' // No approval needed. : 'W' // Approval required. ); // Percent will always be 0 for Public $new_percent = 0; } elseif( ! $newevent ) { // Keep the old status if no email will be sent. $send_user_mail = ( empty( $old_status[$i] ) || $entry_changed ); $tmp_status = ( ! empty( $old_status[$i] ) && ! $send_user_mail ? $old_status[$i] : 'W' ); $status = ( $i != $login && boss_must_approve_event( $login, $i ) && $REQUIRE_APPROVALS == 'Y' && ! $is_nonuser_admin ? $tmp_status : 'A' ); // Set percentage to old_percent if not owner. $tmp_percent = ( empty( $old_percent[$i] ) ? 0 : $old_percent[$i] ); // TODO: This logic needs work. $new_percent = ( $i != $login ? $tmp_percent : $percent ); // If user is admin and this event was previously approved for public, // keep it as approved even though date/time may have changed. // This goes against stricter security, but it confuses users to have // to re-approve events they already approved. if( $i == '__public__' && $is_admin && ( empty( $old_status['__public__'] ) || $old_status['__public__'] == 'A' ) ) $status = 'A'; } else { // New Event. $send_user_mail = true; $status = ( $i != $login && boss_must_approve_event( $login, $i ) && $REQUIRE_APPROVALS == 'Y' && ! $is_nonuser_admin ? 'W' : 'A' ); $new_percent = ( $i != $login ? 0 : $percent ); // If admin, no need to approve Public Access Events. if( $i == '__public__' && $is_admin ) $status = 'A'; } //end new/old event // Some users report that they get an error on duplicate keys // on the following add... As a safety measure, delete any // existing entry with the id. Ignore the result. dbi_execute( 'DELETE FROM webcal_entry_user WHERE cal_id = ? AND cal_login = ?', array( $id, $i ) ); if( ! dbi_execute( 'INSERT INTO webcal_entry_user ( cal_id, cal_login, cal_status, cal_percent ) VALUES ( ?, ?, ?, ? )', array( $id, $i, $status, $new_percent ) ) ) { $error = $dberror . dbi_error(); break; } else { // Check UAC. $can_email = 'Y'; if( access_is_enabled() ) $can_email = access_user_calendar( 'email', $i, $login ); // Don't send mail if we are editing a non-user calendar and are the admin. if( ! $is_nonuser_admin && $can_email == 'Y' ) { // Only send mail if their email address is filled in. $do_send = get_pref_setting( $i, $newevent ? 'EMAIL_EVENT_ADDED' : 'EMAIL_EVENT_UPDATED' ); $htmlmail = get_pref_setting( $i, 'EMAIL_HTML' ); $t_format = get_pref_setting( $i, 'TIME_FORMAT' ); $user_language = get_pref_setting( $i, 'LANGUAGE' ); $user_TIMEZONE = get_pref_setting( $i, 'TIMEZONE' ); set_env( 'TZ', $user_TIMEZONE ); user_load_variables( $i, 'temp' ); if( boss_must_be_notified( $login, $i ) && ! empty( $tempemail ) && $do_send == 'Y' && $send_user_mail && $SEND_EMAIL != 'N' ) { // We send to creator if they want it. if( $send_own != 'Y' && ( $i == $login ) ) continue; reset_language( empty( $user_language ) || $user_language == 'none' ? $LANGUAGE : $user_language ); $fmtdate = ( $timetype == 'T' ? date( 'Ymd', $eventstart ) : gmdate( 'Ymd', $eventstart ) ); $msg = str_replace( 'XXX', $tempfullname, $helloStr ) . "\n\n" . str_replace( 'XXX', $login_fullname, ( $newevent || ( empty( $old_status[$i] ) ) ? $newAppStr : $updAppStr ) ) . "\n" . str_replace( 'XXX', $name, $subjStr ) . "\n\n" . str_replace( 'XXX', $description, $descStr ) . "\n" . str_replace( 'XXX', date_to_str( $fmtdate ), $dateStr ) . "\n" // Apply user's GMT offset and display their TZID. . ( $timetype != 'T' ? '' : str_replace( 'XXX', display_time( '', 2, $eventstart, $t_format ), $timeStr ) . "\n" ) // Add Site Extra Date if permitted. . $extra_email_data . str_replace( 'XXX', generate_application_name(), ( $REQUIRE_APPROVALS == 'Y' ? translate( 'Please look on XXX to accept or reject this appointment.' ) : translate( 'Please look on XXX to view this appointment.' ) ) ); // Add URL to event, if we can figure it out. if( ! empty( $SERVER_URL ) ) { // DON'T change & to & here. Email will handle it. $url = $SERVER_URL . 'view_entry.php?id=' . $id . '&em=1'; if( $htmlmail == 'Y' ) $url = activate_urls( $url ); $msg .= "\n\n" . $url; } // Use WebCalMailer class. $mail->WC_Send( $login_fullname, $tempemail, $tempfullname, $name, $msg, $htmlmail, $from, ( get_pref_setting( $i, 'EMAIL_ATTACH_ICS', 'N' ) == 'Y' ? $id : '' ) ); activity_log( $id, $login, $i, LOG_NOTIFICATION, '' ); } } } } //end for loop participants // Add external participants. $ext_emails = $ext_names = $matches = array(); $ext_count = 0; $externalparticipants = getPostValue( 'externalparticipants' ); if( $single_user == 'N' && ! empty( $ALLOW_EXTERNAL_USERS ) && $ALLOW_EXTERNAL_USERS == 'Y' && ! empty( $externalparticipants ) ) { $lines = explode( "\n", $externalparticipants ); if( ! is_array( $lines ) ) $lines = array( $externalparticipants ); if( is_array( $lines ) ) { $linecnt = count( $lines ); for( $i = 0; $i < $linecnt; $i++ ) { $ext_words = explode( ' ', $lines[$i] ); if( ! is_array( $ext_words ) ) $ext_words = array( $lines[$i] ); if( is_array( $ext_words ) ) { $ext_emails[$ext_count] = $ext_names[$ext_count] = ''; foreach( $ext_words as $j ) { // Use regexp matching to pull email address out. $j = chop( $j ); // Remove any \r. if( preg_match( '/<?\\S+@\\S+\\.\\S+>?/', $j, $matches ) ) { $ext_emails[$ext_count] = $matches[0]; $ext_emails[$ext_count] = preg_replace( '/[<>]/', '', $ext_emails[$ext_count] ); } else { if( strlen( $ext_names[$ext_count] ) ) $ext_names[$ext_count] .= ' '; $ext_names[$ext_count] .= $j; } } // Test for duplicate Names. if( $i > 0 ) { for( $k = $i - 1; $k > 0; $k-- ) { if( $ext_names[$i] == $ext_names[$k] ) $ext_names[$i] .= "[$k]"; } } if( strlen( $ext_emails[$ext_count] ) && empty( $ext_names[$ext_count] ) ) $ext_names[$ext_count] = $ext_emails[$ext_count]; $ext_count++; } } } } // Send notification if enabled. if( is_array( $ext_names ) && is_array( $ext_emails ) ) { $ext_namescnt = count( $ext_names ); for( $i = 0; $i < $ext_namescnt; $i++ ) { if( strlen( $ext_names[$i] ) ) { if( ! dbi_execute( 'INSERT INTO webcal_entry_ext_user ( cal_id, cal_fullname, cal_email ) VALUES ( ?, ?, ? )', array( $id, $ext_names[$i], ( strlen( $ext_emails[$i] ) ? $ext_emails[$i] : null ) ) ) ) $error = $dberror . dbi_error(); // Send mail notification if enabled. // TODO: Move this code into a function... if( $EXTERNAL_NOTIFICATIONS == 'Y' && $SEND_EMAIL != 'N' && strlen( $ext_emails[$i] ) > 0 ) { if( ( ! $newevent && isset( $EXTERNAL_UPDATES ) && $EXTERNAL_UPDATES == 'Y' ) || $newevent ) { $fmtdate = ( $timetype == 'T' ? date( 'Ymd', $eventstart ) : gmdate( 'Ymd', $eventstart ) ); // Strip [\d] from duplicate Names before emailing. $ext_names[$i] = trim( preg_replace( '/\[[\d]]/', '', $ext_names[$i] ) ); $msg = str_replace( 'XXX', $ext_names[$i], $helloStr ) . "\n\n" . str_replace( 'XXX', $login_fullname, ( $newevent ? $newAppStr : $updAppStr ) ) . "\n" . str_replace( 'XXX', $name, $subjStr ) . "\n\n" . str_replace( 'XXX', $description, $descStr ) . "\n\n" . str_replace( 'XXX', date_to_str( $fmtdate ), $dateStr ) . "\n" . ( $timetype == 'T' ? str_replace( 'XXX', display_time( '', ( ! empty( $GENERAL_USE_GMT ) && $GENERAL_USE_GMT == 'Y' ? 3 // Do not apply TZ offset & display TZID, which is GMT. : 6 // Display time in server's timezone. ), $eventstart ), $timeStr ) : '' ) // Add Site Extra Date if permitted. . $extra_email_data; // Don't send HTML to external adresses. // Always attach iCalendar file to external users $mail->WC_Send( $login_fullname, $ext_emails[$i], $ext_names[$i], $name, $msg, 'N', $from, $id ); } } } } } //end external mail } //end empty error // If we were editing this event, // then go back to the last view (day, month, week). // If this is a new event, // then go to the preferred view for the date range where this event was added. if( empty( $error ) && empty( $mailerError ) ) { $return_view = get_last_view(); if( ! empty( $return_view ) ) do_redirect( $return_view ); else { $xdate = sprintf( "%04d%02d%02d", $year, $month, $day ); $user_args = ( empty( $user ) ? '' : 'user=' . $user ); send_to_preferred_view( $xdate, $user_args ); } } if( ! empty( $conflicts ) ) { print_header(); echo ' <h2>' . translate( 'Scheduling Conflict' ) . '</h2> ' . translate( 'Your suggested time of' ) . ' <span class="bold">'; if( $timetype == 'A' ) echo translate( 'All day event' ); else { $time = sprintf( "%d%02d00", $entry_hour, $entry_minute ); // Pass the adjusted timestamp in case the date changed due to GMT offset. echo display_time( '', 0, $eventstart ); if( $duration > 0 ) echo '-' . display_time( '', 0, $eventstart + ( $duration * 60 ) ); } echo '</span> ' . translate( 'conflicts with the following existing calendar entries' ) . ': <ul>' . $conflicts . ' </ul> ' // User can confirm conflicts. . '<form name="confirm" method="post">'; foreach( $_POST as $xkey => $xval ) { if( is_array( $xval ) ) { $xkey .= "[]"; foreach( $xval as $ykey => $yval ) { if( get_magic_quotes_gpc() ) $yval = stripslashes( $yval ); // $yval = htmlentities( $yval ); echo ' <input type="hidden" name="' . $xkey . '" value="' . $yval . '" />'; } } else { if( get_magic_quotes_gpc() ) $xval = stripslashes( $xval ); echo ' <input type="hidden" name="' . $xkey . '" value="' . $xval . '" />'; } } echo // Allow them to override a conflict if server settings allow it. ( ! empty( $ALLOW_CONFLICT_OVERRIDE ) && $ALLOW_CONFLICT_OVERRIDE == 'Y' ? ' <input type="submit" name="confirm_conflicts" value="' . translate( 'Save' ) . '" />' : '' ) . ' <input type="button" value="' . translate( 'Cancel' ) . '" onclick="history.back()" /> </form>'; } else // Process errors. $mail->MailError( $mailerError, $error ); ?> PK �]�\��<�� � edit_remotes_handler.phpnu �[��� <?php include_once 'includes/init.php'; require_valid_referring_url (); include_once 'includes/xcal.php'; // Only available in php 5.x Used for hCalendar parsing. if ( function_exists ( 'simplexml_load_string' ) ) require_once 'includes/classes/hKit/hkit.class.php'; $error = ''; $layer_found = false; $save = getPostValue ( 'Save' ); $add = getPostValue ( 'Add' ); $delete = getPostValue ( 'delete' ); $reload = getPostValue ( 'reload' ); $nid = getPostValue ( 'nid' ); $nfirstname = getPostValue ( 'nfirstname' ); $nlastname = getPostValue ( 'nlastname' ); $nadmin = getPostValue ( 'nadmin' ); $nurl = getPostValue ( 'nurl' ); $reload = getPostValue ( 'reload' ); $nlayer = getPostValue ( 'nlayer' ); $nlayercolor = getPostValue ( 'layercolor' ); if ( ! empty ( $delete ) ) { // Delete events from this remote calendar. delete_events ( $nid ); // Delete any layers other users may have that point to this user. dbi_execute ( 'DELETE FROM webcal_user_layers WHERE cal_layeruser = ?', [$nid] ); // Delete any UAC calendar access entries for this user. dbi_execute ( 'DELETE FROM webcal_access_user WHERE cal_login = ? OR cal_other_user = ?', [$nid, $nid] ); // Delete any UAC function access entries for this user. dbi_execute ( 'DELETE FROM webcal_access_function WHERE cal_login = ?', [$nid] ); // Delete user. if ( ! dbi_execute ( 'DELETE FROM webcal_nonuser_cals WHERE cal_login = ?', [$nid] ) ) $error = db_error(); } else { if ( ! empty ( $nid ) && ! empty ( $save ) ) { // Updating $query_params = []; $sql = 'UPDATE webcal_nonuser_cals SET '; if ( $nlastname ) { $sql .= ' cal_lastname = ?, '; $query_params[] = $nlastname; } if ( $nfirstname ) { $sql .= ' cal_firstname = ?, '; $query_params[] = $nfirstname; } $sql .= ' cal_url = ?, cal_is_public = ?, cal_admin = ? WHERE cal_login = ?'; $query_params[] = $nurl; $query_params[] = 'N'; $query_params[] = $nadmin; $query_params[] = $nid; if ( ! dbi_execute ( $sql, $query_params ) ) $error = db_error(); } else if ( ! empty ( $add ) ) { // Adding if ( preg_match ( '/^[\w]+$/', $nid ) ) { $nid = $NONUSER_PREFIX . $nid; if ( ! dbi_execute ( 'INSERT INTO webcal_nonuser_cals ( cal_login, cal_firstname, cal_lastname, cal_admin, cal_is_public, cal_url ) VALUES ( ?, ?, ?, ?, ?, ? )', [$nid, $nfirstname, $nlastname, $nadmin, 'N', $nurl] ) ) $error = db_error(); } else $error = translate( 'Calendar ID' ) . translate( 'word characters only' ); // Add new layer if requested. if ( ! empty ( $nlayer ) && $nlayer == 'Y' ) { $res = dbi_execute ( 'SELECT MAX( cal_layerid ) FROM webcal_user_layers' ); $layerid = 1; if ( $res ) { $row = dbi_fetch_row ( $res ); $layerid += $row[0]; } dbi_execute ( 'INSERT INTO webcal_user_layers ( cal_layerid, cal_login, cal_layeruser, cal_color, cal_dups ) VALUES ( ?, ?, ?, ?, ? )', [$layerid, $login, $nid, $layercolor, 'N'] ); $layer_found = true; } } // Add entry in UAC access table for new admin and remove for old admin. // First delete any record for this user/nuc combo. dbi_execute ( 'DELETE FROM webcal_access_user WHERE cal_login = ? AND cal_other_user = ?', [$nadmin, $nid] ); if ( ! dbi_execute ( 'INSERT INTO webcal_access_user ( cal_login, cal_other_user, cal_can_view, cal_can_edit, cal_can_approve, cal_can_invite, cal_can_email, cal_see_time_only ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )', [$nadmin, $nid, 511, 511, 511, 'Y', 'Y', 'N'] ) ) die_miserable_death ( translate ( 'Database error' ) . ': ' . dbi_error() ); } if ( ! empty ( $reload ) ) { $data = []; $calUser = $nid; $overwrite = true; $type = 'remoteics'; // We will check ics first. $data = parse_ical ( $nurl, $type ); // TODO it may be a vcs file. // if ( count ( $data ) == 0 ) { // $data = parse_vcal ( $nurl ); // } // We may be processing an hCalendar. // $data sometimes has a count of 1 but is not a valid array. if ( ( count ( $data ) == 0 || ! isset ( $data[0] ) ) && function_exists ( 'simplexml_load_string' ) ) { $h = new hKit; $h->tidy_mode = 'proxy'; $result = $h->getByURL ( 'hcal', $nurl ); $type = 'hcal'; $data = parse_hcal ( $result, $type ); } $errorStr = '<br /><br /> <b>' . translate ( 'Error' ) . ':</b> '; print_header ( '', '', '', true, false, true ); if ( count ( $data ) && empty ( $errormsg ) ) { // Delete existing events. delete_events ( $nid ); // Import new events. import_data ( $data, $overwrite, $type ); echo ' <p>' . translate ( 'Import Results' ) . '</p><br /><br /> ' . translate ( 'Events successfully imported' ) . ': ' . $count_suc . '<br />'; if ( $layer_found == false ) { // We may have just added layer. load_user_layers(); foreach ( $layers as $layer ) { if ( $layer['cal_layeruser'] == $nid ) $layer_found = true; } } if ( $layer_found == false ) echo ' <p>' . translate( 'Create a new layer to view this calendar.' ) . '</p>'; } elseif ( ! empty ( $errormsg ) ) { echo ' ' . translate ( 'Errors' ) . ': ' . $error_num . '<br /><br /> ' . $errorStr . $errormsg . '<br />'; } else { echo $errorStr . translate( 'There was an error parsing the import file or no events were returned.' ) . '<br />'; } echo print_trailer ( false, true, true ); } function delete_events ( $nid ) { // Get event ids for all events this user is a participant. $events = get_users_event_ids ( $nid ); // Now count number of participants in each event... // If just 1, then save id to be deleted. $delete_em = []; for ( $i = 0, $cnt = count ( $events ); $i < $cnt; $i++ ) { $res = dbi_execute ( 'SELECT COUNT( * ) FROM webcal_entry_user WHERE cal_id = ?', [$events[$i]] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( ! empty ( $row ) && $row[0] == 1 ) $delete_em[] = $events[$i]; dbi_free_result ( $res ); } } // Now delete events that were just for this user. for ( $i = 0, $cnt = count ( $delete_em ); $i < $cnt; $i++ ) { dbi_execute ( 'DELETE FROM webcal_entry_repeats WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_repeats_not WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_log WHERE cal_entry_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_import_data WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_site_extras WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_ext_user WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_reminders WHERE cal_id =? ', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_blob WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry WHERE cal_id = ?', [$delete_em[$i]] ); } // Delete user participation from events. dbi_execute ( 'DELETE FROM webcal_entry_user WHERE cal_login = ?', [$nid] ); } echo error_check ( 'users.php?tab=remotes', false ); ?> PK �]�\��y�! ! reject_entry.phpnu �[��� <?php include_once 'includes/init.php'; require_valid_referring_url (); require ( 'includes/classes/WebCalMailer.class' ); $mail = new WebCalMailer; $error = ''; if ( $readonly == 'Y' ) $error = print_not_auth(); // Give user a chance to add comments to rejection email. if ( ! empty ( $_POST ) ) $comments = getPostValue ( 'comments' ); else { print_header(); echo ' <form action="reject_entry.php' . ( empty ( $_SERVER['QUERY_STRING'] ) ? '' : '?' . $_SERVER['QUERY_STRING'] ) . '" method="post" name="add_comments"> <table cellspacing="5"> <tr> <td class="aligncenter alignbottom"><h3>' . translate ( 'Additional Comments (optional)' ) . '</h3></td> </tr> <tr> <td class="aligncenter"><textarea name="comments" rows="5" cols="60">' . '</textarea></td> </tr> <tr> <td class="aligncenter"><input type="submit" value="' . translate ( 'Continue' ) . '" /></td> </tr> <tr> <td>' . translate ( '(Your comments will be emailed to the other participants.)' ) . '</td> </tr> </table> </form> </body> </html>'; exit; } $user = getValue ( 'user' ); $id = getValue ( 'id' ); // Allow administrators to approve public events. $app_user = ( $PUBLIC_ACCESS == 'Y' && ! empty ( $public ) && $is_admin ? '__public__' : ( $is_assistant || $is_nonuser_admin ? $user : $login ) ); // If User Access Control is enabled, // we check to see if they are allowed to approve for the specified user. if ( access_is_enabled() && ! empty ( $user ) && $user != $login ) { if ( access_user_calendar ( 'approve', $user ) ) $app_user = $user; } if ( empty ( $error ) && $id > 0 ) { update_status ( 'R', $app_user, $id, getGetValue ( 'type' ) ); // Email participants to notify that it was rejected. // Get list of participants. $res = dbi_execute ( 'SELECT cal_login FROM webcal_entry_user WHERE cal_id = ? AND cal_status = "A"', [$id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $partlogin[] = $row[0]; } dbi_free_result ( $res ); } // Get the name of the event. $res = dbi_execute ( 'SELECT cal_name, cal_description, cal_date, cal_time FROM webcal_entry WHERE cal_id = ?', [$id] ); if ( $res ) { $row = dbi_fetch_row ( $res ); $name = $row[0]; $description = $row[1]; $fmtdate = $row[2]; $time = sprintf ( "%06d", $row[3] ); dbi_free_result ( $res ); } $eventstart = date_to_epoch ( $fmtdate . $time ); for ( $i = 0, $cnt = count ( $partlogin ); $i < $cnt; $i++ ) { // Does this user want email for this? $send_user_mail = get_pref_setting ( $partlogin[$i], 'EMAIL_EVENT_REJECTED' ); // Check UAC. $can_mail = 'Y'; if ( access_is_enabled() ) $can_mail = access_user_calendar ( 'email', $partlogin[$i], $login ); $htmlmail = get_pref_setting ( $partlogin[$i], 'EMAIL_HTML' ); $t_format = get_pref_setting ( $partlogin[$i], 'TIME_FORMAT' ); user_load_variables ( $partlogin[$i], 'temp' ); $user_TIMEZONE = get_pref_setting ( $partlogin[$i], 'TIMEZONE' ); set_env ( 'TZ', $user_TIMEZONE ); $user_language = get_pref_setting ( $partlogin[$i], 'LANGUAGE' ); if ( $send_user_mail == 'Y' && strlen ( $tempemail ) && $SEND_EMAIL != 'N' && $can_mail == 'Y' ) { reset_language ( empty ( $user_language ) || $user_language == 'none' ? $LANGUAGE : $user_language ); $msg = str_replace ( 'XXX', $tempfullname, translate ( 'Hello, XXX.' ) ) . ' ' . str_replace ( 'XXX', $login_fullname, translate ( 'XXX has rejected an appointment.' ) ) . ' ' . str_replace ( 'XXX', $name, translate ( 'Subject XXX' ) ) . ' ' . str_replace ( 'XXX', $description, translate ( 'Description XXX' ) ) . ' ' . str_replace ( 'XXX', translate ( date_to_str ( $fmtdate ), 'N' ), translate ( 'Date XXX' ) ) . ' ' . ( empty ( $hour ) && empty ( $minute ) ? '' : // Display using user's TIMEZONE and display TZID. str_replace ( 'XXX', translate ( display_time ( '', 2, $eventstart, $t_format ), 'N' ), translate ( 'Time XXX' ) ) ); if ( ! empty ( $SERVER_URL ) ) { // DON'T change & to & here. Email will handle it. $url = $SERVER_URL . 'view_entry.php?id=' . $id . '&em=1'; $msg .= ' ' . ( $htmlmail == 'Y' ? activate_urls ( $url ) : $url ); } if ( strlen ( $comments ) ) $msg .= ' ' . str_replace ( 'XXX', $comments, translate ( 'Comments XXX' ) ); $from = $EMAIL_FALLBACK_FROM; if ( strlen ( $login_email ) ) $from = $login_email; // Send via WebCalMailer class. $mail->WC_Send ( $login_fullname, $tempemail, $tempfullname, $name, $msg, $htmlmail, $from ); activity_log ( $id, $login, $partlogin[$i], LOG_NOTIFICATION, str_replace ( 'XXX', $app_user, translate ( 'Rejected by XXX.' ) ) ); } } } // Return to login TIMEZONE. set_env ( 'TZ', $TIMEZONE ); if ( empty ( $error ) && empty ( $mailerError ) ) { if ( ! empty ( $ret ) && $ret == 'listall' ) do_redirect ( 'list_unapproved.php' ); else do_redirect ( ( ! empty ( $ret ) && $ret == 'list' ? 'list_unapproved.php?' : 'view_entry.php?id=' . $id . '&' ) . 'user=' . $app_user ); exit; } // Process errors. $mail->MailError ( $mailerError, $error ); ?> PK �]�\#��~� � add_entry.phpnu �[��� <?php include_once 'includes/init.php'; $error = ''; // Only proceed if id was passed. if ( $id > 0 ) { // Double check to make sure user doesn't already have the event. $is_my_event = $is_private = false; $res = dbi_execute ( 'SELECT cal_id FROM webcal_entry_user WHERE cal_login = ? AND cal_id = ?', [$login, $id] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row[0] == $id ) { $is_my_event = true; echo str_replace ( 'XXX', $id, translate ( 'Event XXX is already on your calendar.' ) ); exit; } dbi_free_result ( $res ); } // Now lets make sure the user is allowed to add the event (not private). $res = dbi_execute ( 'SELECT cal_access FROM webcal_entry WHERE cal_id = ?', [$id] ); if ( ! $res ) { echo str_replace ( 'XXX', $id, translate ( 'Invalid entry id XXX.' ) ); exit; } $mayNotAddStr = translate ( 'a XXX event may not be added to your calendar' ); $row = dbi_fetch_row ( $res ); if ( ! $is_my_event ) { if ( $row[0] == 'C' && ! $is_assistant && ! $is_nonuser_admin ) { // Assistants are allowed to see confidential stuff. $is_private = true; echo str_replace ( 'XXX', translate ( 'confidential' ), $mayNotAddStr ); exit; } else if ( $row[0] == 'R' ) { $is_private = true; echo str_replace ( 'XXX', translate ( 'private' ), $mayNotAddStr ); exit; } } // Add the event. if ( $readonly == 'N' && ! $is_my_event && ! $is_private ) { if ( ! dbi_execute ( 'INSERT INTO webcal_entry_user ( cal_id, cal_login, cal_status ) VALUES ( ?, ?, ? )', [$id, $login, 'A'] ) ) $error = str_replace ( 'XXX', dbi_error(), translate ( 'Error adding event XXX.' ) ); } } send_to_preferred_view(); exit; ?> PK �]�\�UO�: : events_ajax.phpnu �[��� <?php /** * Description * Handler for AJAX requests for viewing events in combo.php, * which provides views for day, week, month, year and agenda and * a view of the task list. * * We use JSON for some of the data we send back to the AJAX request. * Because JSON support was not built-in to PHP until 5.2, we have our * own implmentation in includes/JSON.php. * * Most of the event handling is identical to the non-AJAX PHP pages except * that we store the local user's version of each event's date and time * in the Event and RptEvent classes. * * TODO: hide private events of other users. */ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; require_once 'includes/classes/Event.class'; require_once 'includes/classes/RptEvent.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; require_valid_referring_url (); $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include 'includes/access.php'; include 'includes/validate.php'; include 'includes/JSON.php'; include 'includes/ajax.php'; // Load Doc classes for attachments and comments include 'includes/classes/Doc.class'; include 'includes/classes/DocList.class'; include 'includes/classes/AttachmentList.class'; include 'includes/classes/CommentList.class'; $WebCalendar->initializeSecondPhase(); load_global_settings(); load_user_preferences(); $WebCalendar->setLanguage(); load_user_layers(); $debug = getValue ( 'debug' ); $debug = ! empty ( $debug ); $action = getValue ( 'action' ); if ( empty ( $action ) ) $action = 'get'; $user = getValue ( 'user', '[A-Za-z0-9_\.=@,\-]*', true ); if ( ! empty ( $user ) ) { // Make sure this user has permission to view the other user's calendar if ( ! access_user_calendar( 'view', $user ) ) { // Not allowed. $user = $login; ajax_send_error ( translate('Not authorized') ); exit; } } if ( empty ( $user ) ) $user = $login; $get_unapproved = true; $sendPlainText = false; $format = getValue ( 'format' ); if ( ! empty ( $format ) && ( $format == 'text' || $format == 'plain' ) ); $sendPlainText = true; $startdate = getIntValue ( 'startdate' ); if ( empty ( $startdate ) ) $startdate = date ( "Ym" ) . '01'; $startyear = substr ( $startdate, 0, 4 ); $startmonth = substr ( $startdate, 4, 2 ); $startday = substr ( $startdate, 6, 2 ); $startTime = mktime ( 3, 0, 0, $startmonth, $startday, $startyear ); $enddate = getIntValue ( 'enddate' ); if ( empty ( $enddate ) ) $enddate = date ( "Ymd", mktime ( 3, 0, 0, $startmonth + 1, $startday, $startyear ) ); $endyear = substr ( $enddate, 0, 4 ); $endmonth = substr ( $enddate, 4, 2 ); $endday = substr ( $enddate, 6, 2 ); $endTime = mktime ( 3, 0, 0, $endmonth, $endday, $endyear ); $error = ''; $can_edit = false; if ( $readonly == 'Y' || $is_nonuser ) { $can_edit = false; } else if ( $is_admin ) { $can_edit = true; } else if ( $login == '__public__' ) { // Is public allowed to add events? if ( $PUBLIC_ACCESS_CAN_ADD == 'Y' ) $can_edit = true; } // Allow user access control to override permissions if ( $can_edit && access_is_enabled () ) { if ( ! access_user_calendar ( 'edit', $user, $login ) ) $can_edit = false; } if ( $action == 'get' ) { $dates = $eventCats = $ids = $tasks = []; /* Pre-Load the repeated events for quicker access */ $wkstart = get_weekday_before ( $startyear, $startmonth ); $startTime = $wkstart; if ( $debug ) echo "startdate: $startdate <br />enddate: $enddate<br />startTime: $startTime<br />"; $repeated_events = read_repeated_events ( $user, $startTime, $endTime ); /* Pre-load the non-repeating events for quicker access */ $events = read_events ( $user, $startTime, $endTime ); if ( $DISPLAY_TASKS_IN_GRID == 'Y' ) $tasks = read_tasks ( $user, $enddate ); // Gather the category IDs for each for ( $i = 0; $i < count ( $events ); $i++ ) { $id = $events[$i]->getID(); $ids[$id] = $id; } for ( $i = 0; $i < count ( $repeated_events ); $i++ ) { $id = $repeated_events[$i]->getID(); $ids[$id] = $id; } for ( $i = 0; $i < count ( $tasks ); $i++ ) { $id = $tasks[$i]->getID(); $ids[$id] = $id; } // Load all category IDs for the specified event IDs //echo "<pre>"; print_r ( $ids ); echo "</pre>"; if ( ! empty ( $id ) ) load_category_ids ( $ids ); // TODO: We need to be able to start a week on ANY day. $monthend = date ( 'Ymd', mktime ( 0, 0, 0, $startmonth + 1, 0, $startyear ) ); for ( $i = $wkstart; date ( 'Ymd', $i ) <= $monthend; $i += 604800 ) { $tmp = $i + 172800; // 48 hours. for ( $j = 0; $j < 7; $j++ ) { // Add 12 hours just so we don't have DST problems. $date = $i + ( $j * 86400 + 43200 ); $dateYmd = date ( 'Ymd', $date ); $myEvents = get_entries ( $dateYmd, $get_unapproved ); $myRepEvents = get_repeating_entries( $user, $dateYmd ); $ev = combine_and_sort_events ( $myEvents, $myRepEvents ); setLocalTimes ( $ev ); setCategories ( $ev ); //echo "<pre>"; print_r ( $ev ); echo "</pre>\n"; $dates[$dateYmd] = $ev; } } $objects = ['dates' => $dates]; if ( $debug ) { echo "<pre>"; print_r ( $objects ); echo "</pre>\n"; } ajax_send_objects ( $objects, $sendPlainText ); } else if ( $action == 'gett' ) { // Get Tasks $eventCats = $ids = $tasks = []; $thisyear = date ( 'Y' ); $thismonth = date ( 'm' ); $task_list = query_events ( $user, false, '', '', true ); foreach ( $task_list as $E ) { // Check UAC. $task_owner = $E->getLogin(); if ( access_is_enabled() ) { $can_access = access_user_calendar ( 'view', $task_owner, '', $E->getCalType(), $E->getAccess() ); if ( $can_access == 0 ) continue; } $tasks[] = $E; $id = $E->getID(); $ids[$id] = $id; } // TODO: include repeated tasks???? // Load all category IDs for the specified event IDs //echo "<pre>"; print_r ( $ids ); echo "</pre>"; if ( ! empty ( $id ) ) load_category_ids ( $ids ); setLocalTimes ( $tasks ); setCategories ( $tasks ); $objects = ['tasks' => $tasks]; if ( $debug ) { echo "<h2>Return</h2><pre>"; print_r ( $objects ); echo "</pre>\n"; } ajax_send_objects ( $objects, $sendPlainText ); } else if ( $action == 'eventinfo' ) { // TODO: enforce user access control here... $id = getIntValue ( 'id' ); $res = dbi_execute ( 'SELECT cal_login, cal_status FROM webcal_entry_user WHERE cal_id = ?', [$id] ); $attachments = $comments = $parts = []; if ( ! $res ) { $error = translate("Database error") . ': ' . dbi_error(); } else { while ( $row = dbi_fetch_row ( $res ) ) { $parts[] = ['login' => $row[0], 'status' => $row[1]]; } dbi_free_result ( $res ); } // Get list of attachments. if ( Doc::attachmentsEnabled() ) { $attList = new AttachmentList ( $id ); for ( $i = 0; $i < $attList->getSize(); $i++ ) { $a = $attList->getDoc ( $i ); // Set link target to '_blank' so that we don't lose our place. // If we go to another page, the back button will re-init the page // so the user loses his place. $attachments[] = [ 'summary' => $a->getSummary ( '_blank' ), 'id' => $a->getId(), 'owner' => $a->getLogin()]; } } if ( Doc::commentsEnabled() ) { $comList = new CommentList ( $id ); $comment_text = ''; for ( $i = 0; $i < $comList->getSize(); $i++ ) { $cmt = $comList->getDoc ( $i ); $comments[] = [ 'description' => htmlspecialchars ( $cmt->getDescription() ), 'owner' => $cmt->getLogin(), 'datetime' => date_to_str ( $cmt->getModDate(), '', false, true ) . ' ' . display_time ( $cmt->getModTime(), 2 ), 'text' => nl2br ( activate_urls ( htmlspecialchars ( $cmt->getData() ) ) )]; } } $objects = [ 'participants' => $parts, 'comments' => $comments, 'attachments' => $attachments]; if ( empty ( $error ) ) { ajax_send_objects ( $objects, $sendPlainText ); } else { ajax_send_error ( translate('Unknown error.') ); } } else if ( $action == 'addevent' ) { // This is a simple add event function. It will be added as // an untimed event, so we don't need to check for conflicts. if ( ! $can_edit ) { ajax_send_error ( translate('Not authorized') ); exit; } $date = getPostValue ( 'date' ); $cat_id = getPostValue ( 'category' ); $name = getPostValue ( 'name' ); $description = getPostValue ( 'description' ); if ( $description == '' ) $description = $name; $participants = getPostValue ( 'participants' ); if ( empty ( $participants ) ) $participants = $login; //$user = $login; // Get new ID $id = 1; $res = dbi_query ( "SELECT MAX(cal_id) FROM webcal_entry" ); if ( $row = dbi_fetch_row ( $res ) ) { $id = $row[0] + 1; } dbi_free_result ( $res ); $mod_date = gmdate ( 'Ymd' ); $mod_time = gmdate ( 'His' ); $sql = 'INSERT INTO webcal_entry ( cal_id, cal_create_by, cal_date, ' . 'cal_time, cal_mod_date, cal_mod_time, ' . 'cal_duration, cal_priority, cal_access, cal_type, cal_name, ' . 'cal_description ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )'; $values = [$id, $login, $date, -1, $mod_date, $mod_time, 0, 5, 'P', 'E', $name, $description]; if ( ! dbi_execute ( $sql, $values ) ) { ajax_send_error ( translate('Database error') . ": " . dbi_error() ); exit; } if ( $cat_id > 0 ) { $sql = 'INSERT INTO webcal_entry_categories ( cal_id, cat_id, cat_owner ) ' . 'VALUES ( ?, ?, ? )'; $values = [$id, $cat_id, $user]; if ( ! dbi_execute ( $sql, $values ) ) { ajax_send_error ( translate('Database error') . ": " . dbi_error() ); exit; } } // Add to each participant $userList = explode ( ',', $participants ); for ( $i = 0; $i < count ( $userList ); $i++ ) { $user = $userList[$i]; $status = ( $user != $login && boss_must_approve_event ( $login, $user ) && $REQUIRE_APPROVALS == 'Y' && ! $is_nonuser_admin ) ? 'W' : 'A'; if ( ! dbi_execute ( 'INSERT INTO webcal_entry_user ( cal_id, cal_login, cal_status ) VALUES ( ?, ?, ? )', [$id, $user, $status] ) ) { ajax_send_error ( translate('Database error') . ": " . dbi_error() ); } activity_log ( $id, $login, $user, LOG_CREATE, '' ); // TODO: send email notification! } ajax_send_success(); } else if ( $action == 'addtask' ) { // This is a simple add task function. It will be added as // an untimed task, so we don't need to check for conflicts. if ( ! $can_edit ) { ajax_send_error ( translate('Not authorized') ); exit; } $startdate = getPostValue ( 'startdate' ); $duedate = getPostValue ( 'duedate' ); $cat_id = getPostValue ( 'category' ); $name = getPostValue ( 'name' ); $description = getPostValue ( 'description' ); if ( $description == '' ) $description = $name; $user = $login; // Get new ID $id = 1; $res = dbi_query ( "SELECT MAX(cal_id) FROM webcal_entry" ); if ( $row = dbi_fetch_row ( $res ) ) { $id = $row[0] + 1; } dbi_free_result ( $res ); $mod_date = gmdate ( 'Ymd' ); $mod_time = gmdate ( 'His' ); $sql = 'INSERT INTO webcal_entry ( cal_id, cal_create_by, cal_date, ' . 'cal_time, cal_due_date, cal_due_time, cal_mod_date, cal_mod_time, ' . 'cal_duration, cal_priority, cal_access, cal_type, cal_name, ' . 'cal_description ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )'; $values = [$id, $login, $startdate, -1, $duedate, -1, $mod_date, $mod_time, 0, 5, 'P', 'T', $name, $description]; if ( ! dbi_execute ( $sql, $values ) ) { ajax_send_error ( translate('Database error') . ": " . dbi_error() ); exit; } if ( $cat_id > 0 ) { $sql = 'INSERT INTO webcal_entry_categories ( cal_id, cat_id, cat_owner ) ' . 'VALUES ( ?, ?, ? )'; $values = [$id, $cat_id, $user]; if ( ! dbi_execute ( $sql, $values ) ) { ajax_send_error ( translate('Database error') . ": " . dbi_error() ); exit; } } if ( ! dbi_execute ( 'INSERT INTO webcal_entry_user ( cal_id, cal_login, cal_status ) VALUES ( ?, ?, ? )', [$id, $user, 'A'] ) ) { ajax_send_error ( translate('Database error') . ": " . dbi_error() ); } ajax_send_success(); activity_log ( $id, $login, $user, LOG_CREATE_T, '' ); } else { ajax_send_error ( translate('Unknown error.') ); } // For each event in our list, also set the local time for the current // user. This way, the client-side javascript will not need to worry // about converting times between timezones. function setLocalTimes ( $eventList ) { for ( $i = 0; $i < count ( $eventList ); $i++ ) { $event = $eventList[$i]; $d = date_to_str ( $event->getDate(), '__yyyy__,__n__,__dd__', false ); $args = explode ( ',', $d ); $localDate = sprintf ( "%04d%02d%02d", $args[0], $args[1], $args[2] ); $event->setLocalDate ( $localDate ); if ( $event->getTime() <= 0 ) { $event->setLocalTime ( $event->getTime() ); } else { // Get time in local user time in HHMMSS format. $localTime = display_time ( $event->getDatetime(), 0, '', '24' ); $localTime = str_replace ( ':', '', $localTime ); $event->setLocalTime ( $localTime ); } } } function setCategories ( $eventList ) { global $eventCats; for ( $i = 0; $i < count ( $eventList ); $i++ ) { $event = $eventList[$i]; $id = $event->getID(); if ( ! empty ( $eventCats[$id] ) ) { $event->setCategories ( $eventCats[$id] ); } } } // Get all categories for each event. function load_category_ids ( $ids ) { global $eventCats, $user, $debug; //$ids = array_unique ( sort ( $ids, SORT_NUMERIC ) ); $idList = implode ( ",", $ids ); if ( $debug ) echo "load_category_ids: $idList <br />\n\n"; $sql = 'SELECT cal_id, cat_id FROM webcal_entry_categories WHERE cal_id IN ( ' . $idList . ' ) AND ( cat_owner = "' . $user . '" OR cat_owner IS NULL ) ORDER BY cat_order'; if ( $debug ) echo "SQL: $sql <br />"; $res = dbi_execute ( $sql, [] ); $eventCats = []; if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $eventId = $row[0]; $catId = $row[1]; if ( ! empty ( $eventCats[$eventId] ) && is_array ( $eventCats[$eventId] ) ) { $eventCats[$eventId][] = $catId; } else { $eventCats[$eventId] = [$catId]; } } dbi_free_result ( $res ); } else { ajax_send_error ( translate('Database error') . ": " . dbi_error() ); exit; } if ( $debug ) { echo "<pre>"; print_r ( $eventCats ); echo "</pre>"; } } exit; ?> PK �]�\|l� � � nulogin.phpnu �[��� <?php // $Id: nulogin.php,v 1.22 2009/11/22 16:47:45 bbannon Exp $ /** * This page handles logins for nonuser calendars. */ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include_once 'includes/access.php'; include 'includes/gradient.php'; $WebCalendar->initializeSecondPhase(); load_global_settings(); $WebCalendar->setLanguage(); if ( $single_user == 'Y'/* No login for single-user mode.*/ || $use_http_auth )/* No web login for HTTP-based authentication.*/ die_miserable_death ( print_not_auth() ); $login = getValue ( 'login' ); if ( empty ( $login ) ) die_miserable_death( translate( 'A login must be specified.' ) ); $date = getValue ( 'date' ); $return_path = getValue ( 'return_path' ); // Was a return path set? $url = ( ! empty ( $return_path ) ? clean_whitespace ( $return_path . ( ! empty ( $date ) ? '?date=' . $date : '' ) ) : 'index.php' ); if ( $login == '__public__' ) do_redirect ( $url ); if ( ! nonuser_load_variables ( $login, 'temp_' ) ) die_miserable_death ( translate ( 'No such nonuser calendar' ) . ": $login" ); if ( empty ( $temp_is_public ) || $temp_is_public != 'Y' ) die_miserable_death ( print_not_auth() ); // calculate path for cookie if ( empty ( $PHP_SELF ) ) $PHP_SELF = $_SERVER['PHP_SELF']; $cookie_path = str_replace ( 'nulogin.php', '', $PHP_SELF ); // echo "Cookie path: $cookie_path\n"; if ( get_magic_quotes_gpc() ) $login = stripslashes ( $login ); $login = trim ( $login ); $badLoginStr = translate ( 'Illegal characters in login XXX.' ); if ( $login != addslashes ( $login ) ) die_miserable_death ( str_replace ( 'XXX', htmlentities ( $login ), $badLoginStr ) ); // Allow proper login using NUC name $encoded_login = encode_string ( $login . '|nonuser' ); // set login to expire in 365 days SetCookie ( 'webcalendar_session', $encoded_login, ( ! empty ( $remember ) && $remember == 'yes' ? 31536000 + time() : 0 ), $cookie_path ); do_redirect ( $url ); ?> PK �]�\N�� � � docadd.phpnu �[��� <?php /** * Page Description: * This page will handle adding blobs into the database. It will * present the form page on a GET and handle updating the database * on a POST. * This includes: * Add comment to an event * Add attachment to an event * * Input Parameters: * For GET: * id - event id (optional for some types) * type - C=comment, A=attachment * For POST: * id - event id (optional for some types) * type - C=comment, A=attachment * description - (for type=C and A) * comment - (for type=C) * FileName - (for type=A) * * Comments: * TODO: add email notification when attachment or comment is added */ include_once 'includes/init.php'; $id = getValue ( 'id', '-?[0-9]+' ); $type = getValue ( 'type' ); $user = getValue ( 'user' ); $error = ''; switch ( $type ) { case 'C': if ( empty ( $id ) ) $error = 'No id specified'; $title = translate ( 'Add Comment' ); break; case 'A': if ( empty ( $id ) ) $error = 'No id specified'; $title = translate ( 'Add Attachment' ); $upload = ini_get ( 'file_uploads' ); $upload_enabled = ! empty ( $upload ) && preg_match ( "/(On|1|true|yes)/i", $upload ); if ( ! $upload_enabled ) { $error = 'You must enable file_uploads in php.ini'; } break; default: $error = 'Invalid type'; break; } $can_add = false; if ( $is_admin ) $can_add = true; // Get event details if this is associated with an event if ( empty ( $error ) && ! empty ( $id ) ) { // is this user a participant or the creator of the event? $res = dbi_execute ( 'SELECT we.cal_id FROM webcal_entry we, webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND we.cal_id = ? AND ( we.cal_create_by = ? OR weu.cal_login = ? )', [$id, $login, $login] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row && $row[0] > 0 ) $is_my_event = true; // user is participant dbi_free_result ( $res ); } } if ( $type == 'A' ) { if ( empty ( $ALLOW_ATTACH ) || $ALLOW_ATTACH != 'Y' ) $error = print_not_auth(); else if ( empty ( $error ) && $ALLOW_ATTACH_PART == 'Y' && $is_my_event ) $can_add = true; else if ( $ALLOW_ATTACH_ANY == 'Y' ) $can_add = true; } else if ( $type == 'C' ) { if ( empty ( $ALLOW_COMMENTS ) || $ALLOW_COMMENTS != 'Y' ) $error = print_not_auth(); else if ( empty ( $error ) && $ALLOW_COMMENTS_PART == 'Y' && $is_my_event ) $can_add = true; else if ( $ALLOW_COMMENTS_ANY == 'Y' ) $can_add = true; } //check UAC if ( access_is_enabled() ) { $can_add = $can_add || access_user_calendar ( 'edit', $user ); } if ( ! $can_add ) $error = print_not_auth(); if ( ! empty ( $error ) ) { print_header(); echo print_error ( $error ); echo print_trailer(); exit; } // Handle possible POST first if ( empty ( $REQUEST_METHOD ) ) $REQUEST_METHOD = $_SERVER['REQUEST_METHOD']; if ( $REQUEST_METHOD == 'POST' ) { // get next id first $res = dbi_execute ( 'SELECT MAX( cal_blob_id ) FROM webcal_blob' ); if ( ! $res ) die_miserable_death ( str_replace ( 'XXX', dbi_error(), translate ( 'Database error XXX.' ) ) ); $row = dbi_fetch_row ( $res ); $nextid = ( ! empty ( $row ) ? $row[0] + 1 : 1 ); dbi_free_result ( $res ); if ( $type == 'C' ) { // Comment $description = getValue ( 'description' ); $comment = getValue ( 'comment' ); if ( ! dbi_execute ( 'INSERT INTO webcal_blob ( cal_blob_id, cal_id, cal_login, cal_name, cal_description, cal_size, cal_mime_type, cal_type, cal_mod_date, cal_mod_time, cal_blob ) VALUES ( ?,?,?,?,?,?,?,?,?,?,? )', [$nextid, $id, $login, NULL, $description, 0, 'text/plain', 'C', date ( 'Ymd' ), date ( 'His' ), NULL] ) ) $error = db_error(); else { if ( ! dbi_update_blob ( 'webcal_blob', 'cal_blob', "cal_blob_id = $nextid", $comment ) ) $error = db_error(); else { // success! redirect to view event page activity_log ( $id, $login, $login, LOG_COMMENT, '' ); do_redirect ( "view_entry.php?id=$id" ); } } } else if ( $type == 'A' ) { // Attachment $description = getValue ( 'description' ); if ( ! empty ( $_FILES['FileName'] ) ) $file = $_FILES['FileName']; if ( empty ( $file['file'] ) ) $error = 'File Upload error!<br />'; //print_r ( $file ); exit; $mimetype = $file['type']; $filesize = $file['size']; $filename = $file['name']; $tmpfile = $file['tmp_name']; if ( empty ( $description ) ) $description = $filename; $data = ''; $fd = @fopen ( $tmpfile, 'r' ); if ( ! $fd ) die_miserable_death ( "Error reading temp file: $tmpfile" ); if ( ! empty ( $error ) ) { while ( ! feof ( $fd ) ) { $data .= fgets ( $fd, 4096 ); } } fclose ( $fd ); $comment = getValue ( 'description' ); if ( ! dbi_execute ( 'INSERT INTO webcal_blob ( cal_blob_id, cal_id, cal_login, cal_name, cal_description, cal_size, cal_mime_type, cal_type, cal_mod_date, cal_mod_time, cal_blob ) VALUES ( ?,?,?,?,?,?,?,?,?,?,? )', [$nextid, $id, $login, substr($filename,0,30), $description, $filesize, $mimetype, 'A', date ( 'Ymd' ), date ( 'His' ), NULL] ) ) $error = db_error(); else { if ( ! dbi_update_blob ( 'webcal_blob', 'cal_blob', "cal_blob_id = $nextid", $data ) ) { $error = db_error(); } else { // success! redirect to view event page activity_log ( $id, $login, $login, LOG_ATTACHMENT, $filename ); do_redirect ( "view_entry.php?id=$id" ); } } } else { die_miserable_death ( 'Unsupported type' ); // programmer error } if ( ! empty ( $error ) ) { print_header(); echo print_error ( $error ); echo print_trailer(); exit; } } print_header(); ?> <h2><?php echo $title;?></h2> <?php if ( $type == 'C' ) { // Comment ?> <form action="docadd.php" method="post" name="docform"> <input type="hidden" name="id" value="<?php echo $id?>" /> <input type="hidden" name="type" value="C" /> <table> <tr><td class="aligntop"><label for="description"> <?php etranslate ( 'Subject' )?>:</label></td> <td><input type="text" name="description" size="50" maxlength="127" /></td></tr> <tr><td class="aligntop"><label for="comment"> <?php etranslate ( 'Comment' )?>:</label></td> <td><textarea name="comment" rows="15" cols="60" wrap="auto"></textarea></td></tr> <tr><td colspan="2"> <input type="submit" value="<?php etranslate ( 'Add Comment' )?>" /></td></tr> </table> </form> <?php } else if ( $type == 'A' ) { // Attachment ?> <form action="docadd.php" method="post" name="docform" enctype="multipart/form-data"> <input type="hidden" name="id" value="<?php echo $id?>" /> <input type="hidden" name="type" value="A" /> <table> <tr class="browse"><td> <label for="fileupload"><?php etranslate ( 'Upload file' );?>:</label></td><td> <input type="file" name="FileName" id="fileupload" size="45" maxlength="50" /> <tr><td class="aligntop"><label for="description"> <?php etranslate ( 'Description' )?>:</label></td> <td><input type="text" name="description" size="50" maxlength="127" /></td></tr> <tr><td colspan="2"> <input type="submit" value="<?php etranslate ( 'Add Attachment' )?>" /></td></tr> </table> </form> <?php } echo print_trailer(); ?> PK �]�\(��7� � datesel.phpnu �[��� <?php // $Id: datesel.php,v 1.57 2009/11/22 16:47:44 bbannon Exp $ include_once 'includes/init.php'; $fday = getGetValue ( 'fday' ); $fmonth = getGetValue ( 'fmonth' ); $fyear = getGetValue ( 'fyear' ); $form = getGetValue ( 'form' ); $date = getGetValue ( 'date' ); if ( strlen ( $date ) > 0 ) { $thisyear = substr ( $date, 0, 4 ); $thismonth = substr ( $date, 4, 2 ); } else { $thisyear = date ( 'Y' ); $thismonth = date ( 'm' ); } $href = 'href="datesel.php?form=' . $form . '&fday=' . $fday . '&fmonth=' . $fmonth . '&fyear=' . $fyear . '&date='; $nextdate = $href . date ( 'Ym01"', mktime ( 0, 0, 0, $thismonth + 1, 1, $thisyear ) ); $nextStr = translate ( 'Next' ); $prevdate = $href . date ( 'Ym01"', mktime ( 0, 0, 0, $thismonth - 1, 1, $thisyear )); $previousStr = translate ( 'Previous' ); $monthStr = month_name ( $thismonth - 1 ); $wkstart = get_weekday_before ( $thisyear, $thismonth ); $monthstartYmd = date ( 'Ymd', mktime ( 0, 0, 0, $thismonth, 1, $thisyear ) ); $monthendYmd = date ( 'Ymd', mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear ) ); print_header ( '','', '', true, false, true, true, true ); //build weekday names $wkdys = ''; for ( $i = 0; $i < 7; $i++ ) { $wkdys .= '<td>' . weekday_name ( ( $i + $WEEK_START ) % 7, 'D' ) . '</td>'; } //build month grid $todayYmd = date ( 'Ymd' ); $mdays = ''; for ( $i = $wkstart; date ( 'Ymd', $i ) <= $monthendYmd; $i += 604800 ) { $mdays .= ' <tr>'; for ( $j = 0; $j < 7; $j++ ) { $date = $i + ( $j * 86400 ) + 43200; $dateYmd = date ( 'Ymd', $date ); $class=' class="field "'; if ( $dateYmd == $todayYmd ) $class .= ' id="today" '; $mdays .= ' <td' . ( ( $dateYmd >= $monthstartYmd && $dateYmd <= $monthendYmd ) || $DISPLAY_ALL_DAYS_IN_MONTH == 'Y' ? $class . '><a href="javascript:sendDate(\'' . $dateYmd . '\')">' . date ( 'j', $date ) . '</a>' : '>' ) . '</td>'; } $mdays .= ' </tr>'; } $mdays .= ' </table> </td> </tr> </table> </div> '; echo <<<EOT <div class="aligncenter"> <table class="aligncenter"> <tr> <td class="aligncenter aligntop"> <table class="aligncenter" cellpadding="3" cellspacing="2"> <tr> <td><a title="{$previousStr}" class="prev" {$prevdate}> <img src="images/leftarrowsmall.gif" alt="{$previousStr}" /></a></td> <th colspan="5"> {$monthStr} {$thisyear} </th> <td><a title="{$nextStr}"class="next" {$nextdate}> <img src="images/rightarrowsmall.gif" alt="{$nextStr}" /></a></td> </tr> <tr class="day"> {$wkdys} </tr> {$mdays} <!--We'll leave this javascript here to speed things up. --> <script> <!-- <![CDATA[ function sendDate ( date ) { year = date.substring ( 0, 4 ); month = date.substring ( 4, 6 ); day = date.substring ( 6, 8 ); sday = window.opener.document.{$form}.{$fday}; smonth = window.opener.document.{$form}.{$fmonth}; syear = window.opener.document.{$form}.{$fyear}; sday.selectedIndex = day - 1; smonth.selectedIndex = month - 1; for ( i = 0; i < syear.length; i++ ) { if ( syear.options[i].value == year ) { syear.selectedIndex = i; } } window.close(); } //]]> --> </script> EOT; echo print_trailer ( false, true, true ); ?> PK �]�\���o� � remotes.phpnu �[��� <?php // $Id: remotes.php,v 1.13 2009/11/22 16:47:45 bbannon Exp $ defined ( '_ISVALID' ) or die ( 'You cannot access this file directly!' ); $newRemoteStr = translate ( 'Add New Remote Calendar' ); $targetStr = 'target="remotesiframe" onclick="showFrame( \'remotesiframe\' );">'; if ( ! $NONUSER_PREFIX ) { echo print_error_header() . translate ( 'NONUSER_PREFIX not set' ) . ' </body> </html>'; exit; } $add = getValue ( 'add' ); echo ' <a name="tabnonusers"></a> <div id="tabscontent_remotes">'; if ( empty ( $error ) ) { echo ' <a title="' . $newRemoteStr . '" href="edit_remotes.php?add=1"' . $targetStr . $newRemoteStr . '</a><br />'; // Displaying Remote Calendars $userlist = get_nonuser_cals ( $login, true ); if ( ! empty ( $userlist ) ) { echo ' <ul>'; for ( $i = 0, $cnt = count ( $userlist ); $i < $cnt; $i++ ) { echo ' <li><a title="' . $userlist[$i]['cal_fullname'] . '" href="edit_remotes.php?nid=' . $userlist[$i]['cal_login'] . '"' . $targetStr . $userlist[$i]['cal_fullname'] . '</a></li>'; } echo ' </ul>'; } } echo ' <iframe name="remotesiframe" id="remotesiframe" style="width: 90%; ' . 'border: 0; height: 250px;"></iframe> </div>'; ?> PK �]�\8P4?� � layers_ajax.phpnu �[��� <?php /** * Description * Handler for AJAX requests from layers.php. * We use JSON for some of the data we send back to the AJAX request. * Because JSON support was not built-in to PHP until 5.2, we have our * own implmentation in includes/JSON.php. */ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; require_valid_referring_url (); $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include 'includes/access.php'; include 'includes/validate.php'; include 'includes/JSON.php'; include 'includes/ajax.php'; $WebCalendar->initializeSecondPhase(); load_global_settings(); load_user_preferences(); $WebCalendar->setLanguage(); $action = getValue ( 'action' ); $public = getValue ( 'public' ); $sendPlainText = false; $format = getValue ( 'format' ); if ( ! empty ( $format ) && ( $format == 'text' || $format == 'plain' ) ); $sendPlainText = true; $error = ''; if ( $is_admin && ! empty ( $public ) && $PUBLIC_ACCESS == 'Y' ) { $updating_public = true; $layer_user = '__public__'; } else { $layer_user = $login; } if ( $action == 'enable' || $action == 'disable' ) { // Toggle LAYER_STATUS in the user's preferences between N and Y. dbi_execute( 'DELETE FROM webcal_user_pref WHERE cal_login = ? AND cal_setting = "LAYERS_STATUS"', [$layer_user] ); if( ! dbi_execute( 'INSERT INTO webcal_user_pref ( cal_login, cal_setting, cal_value ) VALUES ( ?, \'LAYERS_STATUS\', ? )', [$layer_user, ( $action === 'enable' ? 'Y' : 'N' )] ) ) { ajax_send_error ( translate ( 'Unable to update preference' ) . ': ' . dbi_error() ); } else { // Success ajax_send_success(); } } else if ( $action == 'list' ) { // Use JSON to encode our list of layers. load_user_layers ( $layer_user, 1 ); $ret_layers = []; foreach ( $layers as $layer ) { user_load_variables ( $layer['cal_layeruser'], 'layer' ); $ret_layers[] = ['id' => $layer['cal_layerid'], 'source' => $layer['cal_layeruser'], 'color' => $layer['cal_color'], 'dups' => $layer['cal_dups'], 'fullname' => $layerfullname]; } ajax_send_object ( 'layers', $ret_layers, $sendPlainText ); } else if ( $action == 'save' ) { // TODO: we should do some additional checking here to make // sure someone isn't asking for a layer they are not authorized to view. if ( $ALLOW_VIEW_OTHER != 'Y' ) { $error = print_not_auth (7); } else { save_layer ( getPostValue('layeruser'), getPostValue('source'), getPostValue('color'), getPostValue('dups') == 'Y' ? 'Y' : 'N', getPostValue('id') ); } if ( $error == '' ) ajax_send_success(); else ajax_send_error ( $error ); } else if ( $action == 'delete' ) { // TODO: we should so some additional checking here to make // sure someone isn't asking for a layer they are not authorized to view. if ( $ALLOW_VIEW_OTHER != 'Y' ) { $error = print_not_auth (7); } else { $id = getPostValue ( 'id' ); if ( $id <= 0 ) { $error = translate('Invalid entry id.'); } else { delete_layer ( getPostValue('layeruser'), $id ); } } if ( $error == '' ) ajax_send_success(); else ajax_send_error ( $error ); } else { ajax_send_error ( translate('Unknown error.') ); } exit; function delete_layer ( $user, $id ) { global $error, $layers; if ( ! dbi_execute ( 'DELETE FROM webcal_user_layers ' . ' WHERE cal_layerid = ? AND cal_login = ?', [$id, $user] ) ) { $error = translate ( "Database error" ) . ": " . dbi_error(); } } function save_layer ( $user, $source, $layercolor, $dups, $id ) { global $error, $layers; if ( $user == $source ) $error = translate ( 'You cannot create a layer for yourself.' ); load_user_layers ( $user, 1 ); if ( ! empty ( $source ) && $error == '' ) { // Existing layer entry. if ( ! empty ( $layers[$id]['cal_layeruser'] ) ) { // Update existing layer entry for this user. $layerid = $layers[$id]['cal_layerid']; dbi_execute ( 'UPDATE webcal_user_layers SET cal_layeruser = ?, cal_color = ?, cal_dups = ? WHERE cal_layerid = ?', [$source, $layercolor, $dups, $layerid] ); } else { // New layer entry. // Check for existing layer for user. Can only have one layer per user. $res = dbi_execute ( 'SELECT COUNT( cal_layerid ) FROM webcal_user_layers WHERE cal_login = ? AND cal_layeruser = ?', [$user, $source] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row[0] > 0 ) $error = translate ( 'You can only create one layer for each user.' ); dbi_free_result ( $res ); } if ( $error == '' ) { $res = dbi_execute ( 'SELECT MAX( cal_layerid ) FROM webcal_user_layers' ); if ( $res ) { $row = dbi_fetch_row ( $res ); $layerid = $row[0] + 1; } else $layerid = 1; dbi_execute ( 'INSERT INTO webcal_user_layers ( cal_layerid, cal_login, cal_layeruser, cal_color, cal_dups ) VALUES ( ?, ?, ?, ?, ? )', [$layerid, $user, $source, $layercolor, $dups] ); } } } } ?> PK �]�\��� � assistant_edit_handler.phpnu �[��� <?php include_once 'includes/init.php'; require_valid_referring_url (); $user = getPostValue ( 'user' ); $users = getPostValue ( 'users' ); $error = ''; if ( $user != $login ) $user = ( ( $is_admin || $is_nonuser_admin ) && $user ) ? $user : $login; # update user list dbi_execute ( 'DELETE FROM webcal_asst WHERE cal_boss = ?', [$user] ); if ( ! empty ( $users ) ) { for ( $i = 0, $cnt = count ( $users ); $i < $cnt; $i++ ) { dbi_execute ( 'INSERT INTO webcal_asst ( cal_boss, cal_assistant ) VALUES ( ?, ? )', [$user, $users[$i]] ); } } echo error_check ( 'assistant_edit.php' . ( ( $is_admin || $is_nonuser_admin ) && $login != $user ? '?user=' . $user : '' ) ); ?> PK �]�\�wefO fO upcoming.phpnu �[��� <?php // $Id: upcoming.php,v 1.97.2.5 2013/01/24 21:15:09 cknudsen Exp $ /** * Description: * Show a list of upcoming events (and possibly tasks). * * This script is intended to be used outside of normal WebCalendar * use, typically as an iframe in another page. * * You must have public access enabled in System Settings to use this * page (unless you modify the $public_must_be_enabled setting below * in this file). * * Typically, this is how you would reference this page from another: * * <iframe height="250" width="300" * scrolling="yes" src="upcoming.php"></iframe> * * By default (if you do not edit this file), events for the public * calendar will be loaded for either: * - the next 30 days * - the next 10 events * * The output of this page conforms to the hCalendar standard for events. * You can read more about hCalendar at: * http://microformats.org/wiki/hcalendar * * Input parameters: * You can override settings by changing the URL parameters: * - days: number of days ahead to look for events (be sure to also * change "maxEvents" from its default of 10. * - maxEvents: max number of events to show (default is 10) * - cat_id: specify a category id to filter on * - user: login name of calendar to display (instead of public * user), if allowed by System Settings. You must have the * following System Settings configured for this: * Allow viewing other user's calendars: Yes * Public access can view others: Yes * - tasks: specify a value of '1' to show just tasks (if permitted * by system settings and config settings below). This will * show only tasks and not show any events. * - showTitle (boolean, set to 1 or 0) whether the page title is shown or not * - upcoming_title: The page title to print. There is a default but this overrides it. * Of course it will only be printed if showTitle so indicates. * - showMore (boolean, set to 1 or 0) whether "more" at the end is shown or not, * with a link to your main calendar page * - showTime ((boolean, set to 1 or 0) whether the event time should be shown * * if calling as an include file can pre-set these variables in your PHP file * before including upcoming.php (you can't use URL parameters when calling * an include file). Remember that after debugging you can use @include to suppress * PHP warnings. * $numDays default 30 * $cat_id default ALL * $username default __public__ * $maxEvents default 10 * $showTasks bool default true * $showTitle bool default false * $upcoming_title default "Upcoming Events" * $showMore bool default true * $showTime bool default false * $showPopups bool default true * $hcalendar_output bool default false * * To do: Cache results, used cached results mostly, only update occasionally. This * is pretty simple to do and greatly speeds up the include file if you have a large * calendar. * * Security: * TBD */ //only go through the requires & includes & function declarations once, // in case upcoming.php is included twice on one page //this trick allows the upcoming events to be displayed twice on one page //(perhaps with different parameters) without causing problems if if ( empty ($upcoming_initialized)) { $upcoming_initialized=true; //The following lines allow this include file to be called from another directory //it saves the current working directory (to be restored just before exiting) //and then changes the working directory to the dir that this file is currently //in. That allows this file to load its includes normally even if called //from some other directory. $save_current_working_dir= getcwd(); chdir(dirname(__FILE__)); foreach( array( 'config', 'dbi4php', 'formvars', 'functions', 'site_extras', 'translate', ) as $i ) { include_once 'includes/' . $i . '.php'; } foreach( array( 'WebCalendar', 'Event', 'RptEvent', ) as $i ) { require_once 'includes/classes/' . $i . '.class'; } $WebCalendar = new WebCalendar( __FILE__ ); $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; //set default hCalendar but allow it to be overridden //this will include hidden values that can gleaned by hCalendar // clients $hcalendar_output = getGetValue ( 'hcalendar_output' ); if ( empty ( $hcalendar_output ) ) $hcalendar_output = false; //added to support hCalendar if ( $hcalendar_output ) include 'includes/xcal.php'; $WebCalendar->initializeSecondPhase(); //This must contain the file name that this file is saved under. It is //used to determine whether the file is being run independently or //as an include file. Change as necessary! //Note that if you use any other name than "upcoming.php" you must //also change the corresponding line in includes/classes/WebCalendar.class, about //line 54, like this: // '/^(nulogin|login|freebusy|publish|register|rss|upcoming|upcoming-.*|week_ssi|minical|controlpanel)\.php$/' => //Using upcoming-.* allows you to use names like upcoming-1.php, upcoming-2.php etc. //if you want have different upcoming-*.php files with variants. $name_of_this_file='/upcoming.php/'; //echo "$showTitle $showMore $maxEvents $numDays $cat_id<p>"; load_global_settings(); $error = ''; // Make sure 'Upcoming Events' is enabled in System Settings. if ( empty ( $UPCOMING_EVENTS ) || $UPCOMING_EVENTS != 'Y' ) { $error = print_not_auth(); } $WebCalendar->setLanguage(); /** * Print the details of an upcoming event * This function is here, inside the 'if' that runs only the first time this * file is included within an external document, so that the function isn't * declared twice in case of this file being included twice or more within the same doc. */ function print_upcoming_event ( $e, $date ) { global $display_link, $link_target, $SERVER_URL, $charset, $login, $display_tzid, $showTime, $showPopups, $eventinfo, $username, $hcalendar_output, $UPCOMING_DISPLAY_CAT_ICONS; $popupid = 'pop' . $e->getId() . '-' . $date; $private = $confidential = false; // Access: P=Public, R=Private, C=Confidential if ( $e->getAccess() == 'R' ) { // not a public event, so we will just display "Private" $private = true; } else if ( $e->getAccess() == 'C' ) { // not a public event, so we will just display "Confidential" $confidential = true; } if ( ! empty ( $SERVER_URL ) && ! $private && ! $confidential) { echo "<div class=\"vevent\">\n"; if ( $display_link ) { if ( $showPopups ) { $timestr = ''; if ( $e->isAllDay() ) { $timestr = translate ( 'All day event' ); } else if ( $e->getTime() >= 0 ) { $timestr = display_time ( $e->getDatetime() ); if ( $e->getDuration() > 0 ) { $timestr .= ' - ' . display_time ( $e->getEndDateTime() ); } } $eventinfo .= build_entry_popup ( 'eventinfo-' . $popupid, $username, $e->getDescription(), $timestr, site_extras_for_popup ( $e->getId() ), $e->getLocation(), $e->getName(), $e->getId() ); } $link = "<a class=\"entry\" id=\"$popupid\" title=\"" . htmlspecialchars ( $e->getName() ) . '" href="' . $SERVER_URL . 'view_entry.php?id=' . $e->getID() . "&date=$date&user=" . $e->getLogin() . ( empty( $link_target ) ? '>' : "\" target=\"$link_target\">" ); if ( empty ( $UPCOMING_DISPLAY_CAT_ICONS ) || $UPCOMING_DISPLAY_CAT_ICONS != 'N' ) { $catNum = abs ( $e->getCategory() ); if ( $catNum > 0 ) { $catIcon = 'icons/cat-' . $catNum . '.gif'; if ( ! file_exists ( $catIcon ) ) $catIcon = 'icons/cat-' . $catNum . '.png'; if ( file_exists ( $catIcon ) ) echo $link . '<img src="' . $catIcon . '" alt="category icon"></a>'; } } echo $link; } } if ( $private ) { echo '[' . translate ( 'Private' ) . ']'; } else if ( $confidential ) { echo '[' . translate ( 'Confidential' ) . ']'; } else { echo '<span class="summary">' . htmlspecialchars ( $e->getName() ) . '</span>'; } if ( $display_link && ! empty ( $SERVER_URL ) && ! $private ) { echo '</a>'; } //added for hCalendar if ( $hcalendar_output ) { echo '<abbr class="dtstart" title="'. export_ts_utc_date ($e->getDateTimeTS() ) .'">' . $e->getDateTime() . "</abbr>\n"; echo '<abbr class="dtend" title="'. export_ts_utc_date ($e->getEndDateTimeTS() ) . '">' . $e->getEndDateTimeTS() . "</abbr>\n"; echo '<span class="description">' . $e->getDescription() . "</span>\n"; if ( strlen ( $e->getLocation() ) > 0 ) echo '<span class="location">' . $e->getLocation() . "</span>\n"; $categories = get_categories_by_id ( $e->getId(), $username ); $category = implode ( ', ', $categories); if ( strlen( $category ) > 0 ) echo '<span class="categories">' . htmlentities ( $category ) . "</span>\n"; if ( strlen ( $e->getUrl() ) > 0 ) echo '<span class="url">' . $e->getUrl() . "</span>\n"; $rrule = export_recurrence_ical( $e->getId() ); if ( strlen ( $rrule ) > 6 ) echo '<span class="rrule">' . substr ( $rrule, 6 ) . "</span>\n"; } if ( $showTime ) { //show event time if requested (default=don't show) if ( $e->isAllDay() ) { echo ' (' . translate ( 'All day event' ) . ")\n"; } else if ( $e->getTime() != -1 ) { echo ' (' . display_time ( $e->getDateTime(), $display_tzid ) . ")\n"; } } echo "</div>\n"; } //end function } //end condition initialization /* * Configurable settings for this file. You may change the settings * below to change the default settings. * This settings will likely move into the System Settings in the * web admin interface in a future release. * */ // Set this to false if you still want to access this page even // though you do not have public access enabled. // Set this to true to require public access enabled for this page to // function at all. $public_must_be_enabled = false; // Do we include a link to view the event? If so, what target // should we use. $display_link = ( empty ( $UPCOMING_DISPLAY_LINKS ) || $UPCOMING_DISPLAY_LINKS == 'Y' ); $link_target = '_top'; // Default time window of events to load // Can override with "upcoming.php?days=60" //bhugh, 1/28/2006, if(empty and !== false constructions allow these vars to be passed //from another php program in case upcoming.php is called as an include file //(you can't pass ?days=60 type parameters when you use include) $numDays = getIntValue ( 'numDays' ); if (empty ($numDays)) $numDays = 30; $showTitle = ( getGetValue ( 'showTitle', "[01]", true ) == '1' ); $showTitle = ( ! empty ( $showTitle ) && $showTitle !== false ? true : false ); $showMore = getGetValue ( 'showMore', "[01]", true ); $showMore = ( ! empty ( $showMore ) && $showMore !== false ? true : false ); $showTime = getGetValue ( 'showTime', "[01]", true ); $showTime = ( ! empty ( $showTime ) && $showTime !== false ? true : false ); //sets the URL used in the (optional) page title and //(optional) "...more" tag at the end. If you want them to //go to a different URL you can specify that here. $title_more_url=$SERVER_URL; //set default upcoming title but allow it to be overridden $upcoming_title = getValue ( 'upcoming_title' ); if (empty ($upcoming_title)) $upcoming_title= '<a href="'. $title_more_url . '">Upcoming Events</a>'; //echo "$numDays $showTitle $maxEvents <p>"; // Max number of events (including tasks) to display $maxEvents = getIntValue ( 'maxEvents' ); if (empty ($maxEvents)) $maxEvents = 10; // Should we include tasks? // (Only relavant if tasks are enabled in system settings AND enabled for // display in calendar view for this user. So, this is really // a way to disable tasks from showing up. It will not display // them if specified user has not enabled "Display tasks in Calendars" // in their preferences.) $showTasks = getValue ( 'showTasks' ); if ( empty ( $showTasks ) ) $showTasks = false; // Show event popups $showPopups = ( empty ( $UPCOMING_DISPLAY_POPUPS ) || $UPCOMING_DISPLAY_POPUPS == 'Y' ); if ( getGetValue ( 'showPopups' ) != '' ) { $showPopups = ( getGetValue ( 'showPopups', "[01]", true ) != '0' ); } // Allow the URL to override the user setting such as // "upcoming.php?user=craig" $allow_user_override = ( ! empty ( $UPCOMING_ALLOW_OVR ) && $UPCOMING_ALLOW_OVR == 'Y' ); // Load layers $load_layers = ( ! empty ( $UPCOMING_DISPLAY_LAYERS ) && $UPCOMING_DISPLAY_LAYERS == 'Y' ); // Load just a specified category (by its id) // Leave blank to not filter on category (unless specified in URL) // Can override in URL with "upcoming.php?cat_id=4" $cat_id = getIntValue ( 'cat_id' ); // Display timezone abbrev name // 1 = Display all times as GMT wo/TZID // 2 = Adjust times by user's GMT offset Show TZID // 3 = Display all times as GMT w/TZID $display_tzid = 2; // End configurable settings... // Login of calendar user to use // '__public__' is the login name for the public user $username = '__public__'; if ( $allow_user_override ) { $username = getValue ( 'user' ); if (empty ($username)) $username = '__public__'; } else { if ( getValue ( 'user' ) != '' ) { $error = print_not_auth(); } } // Set for use elsewhere as a global $login = $username; // Load user preferences for DISPLAY_UNAPPROVED load_user_preferences(); if ( $public_must_be_enabled && $PUBLIC_ACCESS != 'Y' ) { $error = print_not_auth(); } if ( $error == '' ) { if ( $allow_user_override ) { $u = getValue ( 'user', "[A-Za-z0-9_\.=@,\-]+", true ); if ( ! empty ( $u ) ) { $username = $u; $login = $u; $TIMEZONE = get_pref_setting ( $username, 'TIMEZONE' ); $DISPLAY_UNAPPROVED = get_pref_setting ( $username, 'DISPLAY_UNAPPROVED' ); $DISPLAY_TASKS_IN_GRID = get_pref_setting ( $username, 'DISPLAY_TASKS_IN_GRID' ); // We also set $login since some functions assume that it is set. } } $get_unapproved = ( ! empty ( $DISPLAY_UNAPPROVED ) && $DISPLAY_UNAPPROVED == 'Y' ); if ( $CATEGORIES_ENABLED == 'Y' ) { $x = getValue ( 'cat_id', '-?[0-9]+', true ); if ( ! empty ( $x ) ) { $cat_id = $x; } } $x = getGetValue ( 'upcoming_title', true ); if ( ! empty ( $x ) ) { $upcoming_title = $x; } $x = getGetValue ( 'showMore', true ); if ( strlen( $x ) > 0 ) { $showMore= $x; } $x = getGetValue ( 'showTime', true ); if ( strlen( $x ) > 0 ) { $showTime= $x; } $x = getGetValue ( 'showTitle', true ); if ( strlen( $x ) > 0 ) { $showTitle = $x; } if ( $load_layers ) { load_user_layers ( $username ); } //load_user_categories(); // Calculate date range $date = getValue ( 'date', '-?[0-9]+', true ); if ( empty ( $date ) || strlen ( $date ) != 8 ) { // If no date specified, start with today $date = date ( 'Ymd' ); } $thisyear = substr ( $date, 0, 4 ); $thismonth = substr ( $date, 4, 2 ); $thisday = substr ( $date, 6, 2 ); $startDate = mktime ( 0, 0, 0, $thismonth, $thisday, $thisyear ); $x = getValue ( 'days', '-?[0-9]+', true ); if ( ! empty ( $x ) ) { $numDays = $x; } // Don't let a malicious user specify more than 365 days if ( $numDays > 365 ) { $numDays = 365; } $endDate = mktime ( 23, 59, 59, $thismonth, $thisday + $numDays, $thisyear ); // If 'showEvents=0' is in URL, then just include tasks in list $show_events = getGetValue ( 'showEvents', "[01]", true ); $tasks_only = ( $show_events == '0' ); if ( $tasks_only ) { $repeated_events = $events = array(); } else { /* Pre-Load the repeated events for quckier access */ $repeated_events = read_repeated_events ( $username, $startDate, $endDate, $cat_id ); /* Pre-load the non-repeating events for quicker access */ $events = read_events ( $username, $startDate, $endDate, $cat_id ); } // Pre-load tasks for quicker access */ if ( ( ( empty ( $DISPLAY_TASKS_IN_GRID ) || $DISPLAY_TASKS_IN_GRID == 'Y' ) ) || $showTasks ) { /* Pre-load tasks for quicker access */ $tasks = read_tasks ( $username, $endDate, $cat_id ); } } // Determine if this script is being called directly, or via an include. if ( empty ( $PHP_SELF ) && ! empty ( $_SERVER ) && ! empty ( $_SERVER['PHP_SELF'] ) ) { $PHP_SELF = $_SERVER['PHP_SELF']; } // If called directly print header stuff. if ( ! empty ( $PHP_SELF ) && preg_match ( $name_of_this_file, $PHP_SELF ) ) { // Print header without custom header and no style sheet. echo send_doctype ( generate_application_name() ); ?> <!-- This style sheet is here mostly to make it easier for others to customize the appearance of the page. In the not too distant future, the admin UI will allow configuration of the stylesheet elements on this page. --> <style> body { background-color: #ffffff; } dt { font-family: arial,helvetica; font-weight: bold; font-size: 12px; color: #000000; } dd { font-family: arial,helvetica; color: #3030a0; font-size: 12px; } a { font-family: arial,helvetica; color: #3030a0; } a:hover { font-family: arial,helvetica; color: #ffffff; background-color: #3030a0; } .popup { color: #ffffff; background-color: #3030a0; text-decoration: none; position: absolute; z-index: 20; visibility: hidden; top: 0px; left: 0px; border: 1px solid #000000; padding: 3px; } .popup dl { margin: 0px; padding: 0px; } .popup dt { font-size: 10px; font-weight: bold; margin: 0px; padding: 0px; color: #ffffff; } .popup dd { font-size: 10px; margin-left: 20px; color: #ffffff; } .dtstart, .dtend, .description, .location, .categories, .url, .rrule { visibility:hidden; } </style> <?php if ( ! empty ( $showPopups ) && empty ( $error ) ) { echo '<script src="includes/js/util.js"></script> <script src="includes/js/popups.js"></script>'; } ?> </head> <body> <?php } //end test for direct call if ( ! empty ( $error ) ) { echo print_error ( $error ); echo "</body></html>"; //restore previous working directory before exit if (strlen($save_current_working_dir)) chdir($save_current_working_dir); exit; } if ($showTitle) echo '<h3 class="cal_upcoming_title">'. translate ($upcoming_title) . '</h3>'; ?> <div class="vcalendar"> <?php echo "<dl>\n"; echo "<!-- \nstartTime: $startDate (" . date('Ymd H:i:s', $startDate ) . ")\n" . "endTime: $endDate (" . date('Ymd H:i:s', $endDate ) . ")\n" . "startDate: " . "$date\nnumDays: $numDays\nuser: $username\nevents: " . count ( $events ) . "\nrepeated_events: " . count ( $repeated_events ) . " -->\n"; $eventinfo = ''; $numEvents = 0; $endDateYmd = date ( 'Ymd', $endDate ); for ( $i = $startDate; date ( 'Ymd', $i ) <= $endDateYmd && $numEvents < $maxEvents; $i += 86400 ) { echo "<!-- i = $i; startDate = $startDate; date(Ymd)= " . date ( 'Ymd', $i ) . "; endDateYmd = $endDateYmd; numEvents: $numEvents; maxEvents: $maxEvents -->\n"; $d = date ( 'Ymd', $i ); $entries = get_entries ( $d, $get_unapproved ); $rentries = get_repeating_entries ( $username, $d, $get_unapproved ); $ev = combine_and_sort_events ( $entries, $rentries ); $tentries = get_tasks ( $d, $get_unapproved ); $ev = combine_and_sort_events ( $ev, $tentries ); $ev_cnt = count ( $ev ); echo "<!-- $d " . count ( $ev ) . " -->\n"; if ( $ev_cnt > 0 ) { echo "<!-- XXX -->\n"; //print "<dt>" . date_to_str( $d, translate( '__month__ __dd__' ), // true, true ) . "</dt>\n<dd>"; echo '<dt>' . date_to_str ( $d ) . "</dt>\n<dd>"; for ( $j = 0; $j < $ev_cnt && $numEvents < $maxEvents; $j++ ) { print_upcoming_event ( $ev[$j], $d ); $numEvents++; } echo "</dd>\n"; } } echo "</dl>\n"; if ( $showMore ) echo '<center><i><a href="'. $title_more_url . '"> . . . ' . translate ( 'more' ) . '</a></i></center>'; ?> </div> <?php echo $eventinfo; if ( ! empty ( $PHP_SELF ) && preg_match ( $name_of_this_file, $PHP_SELF ) ) { echo "</body>\n</html>"; } //restore previous working directory before exit if (strlen($save_current_working_dir)) chdir($save_current_working_dir); ?> PK �]�\���% % export_handler.phpnu �[��� <?php /** * Description: * Handler for exporting webcalendar events to various formats. * * Comments: * All-day events and untimed events are treated differently. An * all-day event is a 12am event with duration 24 hours. We store * untimed events with a start time of -1 in the webcalendar database. * * TODO: * Add support for categories for other than ical * *********************************************************************/ include_once 'includes/init.php'; require_valid_referring_url (); include_once 'includes/xcal.php'; $user = getPostValue ( 'user' ); if ( empty ( $user ) || $user == $login ) load_user_layers(); // Convert time in ("hhmmss") format, plus duration (as a number of minutes), // to end time ($hour = number of hours, $min = number of minutes). // FIXME: doesn't handle wrap to next day correctly. function get_end_time ( $time, $duration, &$hour, &$min ) { $hour = intval ( $time / 10000 ); $min = ( $time / 100 ) % 100; $minutes = $hour * 60 + $min + $duration; $hour = $minutes / 60; $min = $minutes % 60; } // Convert calendar date to a format suitable for the // install-datebook utility (part of pilot-link) function pilot_date_time ( $date, $time, $duration, $csv = false ) { $mday = $date % 100; $month = intval ( ( $date / 100 ) % 100 ); $year = intval ( $date / 10000 ); get_end_time ( $time, $duration, $hour, $min ); // All times are now stored as GMT. // TODO Palm uses local time, so convert to users' time. $tz_offset = date ( 'Z' ); // in seconds $tzh = intval ( $tz_offset / 3600 ); $tzm = intval ( ( $tz_offset / 60 ) % 60 ); $tzsign = '+'; if ( $tzh < 0 ) { $tzsign = '-'; $tzh = abs ( $tzh ); } return ( $csv ? sprintf ( "%04d-%02d-%02d%s%02d:%02d:00", $year, $month, $mday, $csv, $hour, $min ) : sprintf ( "%04d/%02d/%02d %02d%02d GMT%s%d%02d", $year, $month, $mday, $hour, $min, $tzsign, $tzh, $tzm ) ); } function export_install_datebook ( $id ) { $res = export_get_event_entry ( $id ); while ( $row = dbi_fetch_row ( $res ) ) { $start_time = pilot_date_time ( $row[3], $row[4], 0 ); $end_time = pilot_date_time ( $row[3], $row[4], $row[8] ); printf ( "%s\t%s\t\t%s\n", $start_time, $end_time, $row[1] ); echo 'Start time: ' . $start_time . ' End time: ' . $end_time . ' Duration: ' . $row[8] . ' Name: ' . $row[1] . "\n"; } } function get_cal_ent_extras ( $id, $from, $where = false ) { $res = dbi_execute ( 'SELECT * FROM ' . $from . 'WHERE cal_id = ?' . ( $where ? ' AND ( ' . $where . ' )' : '' ), [$id] ); return ( $res ? ( dbi_fetch_row ( $res ) ) : ( false ) ); } /** * export_pilot_csv (needs description) */ function export_pilot_csv( $id ) { /* To be imported to a Palm with: * pilot-datebook -r csv -f webcalendar-export.txt -w hotsync */ $res = export_get_event_entry ( $id ); echo 'uid,attributes,category,untimed,beginDate,beginTime,endDate,endTime,' . 'description,note,alarm,advance,advanceUnit,repeatType,repeatForever,' . 'repeatEnd,repeatFrequency,repeatDay,repeatWeekdays,repeatWeekstart' . "\n"; while ( $row = dbi_fetch_row ( $res ) ) { // uid (long) echo $row[0], ',' /* attributes (int) 128 = 0x80 : Deleted 64 = 0x40 : Dirty 32 = 0x20 : Busy 16 = 0x10 : Secret/Private */ . ( $row[7] == 'C' || $row[7] == 'R' ? '16,' : '0,' ) // category (int: 0=Unfiled) . '0,'; // untimed (int: 0=Appointment, 1=Untimed) // Note: Palm "Untimed" is WebCalendar "AllDay". if ( $row[4] < 0 ) { echo '1,', // untimed substr ( $row[3], 0, 4 ), '-', // beginDate (str: YYYY-MM-DD) + beginTime substr ( $row[3], 4, 2 ), '-', substr ( $row[3], 6, 2 ), ',00:00:00,', substr ( $row[3], 0, 4 ), '-', // endDate + endTime substr ( $row[3], 4, 2 ), '-', substr ( $row[3], 6, 2 ), ',00:00:00,'; } else { echo '0,', // untimed pilot_date_time ( $row[3], $row[4], 0, ',' ), ',', // beginDate,beginTime pilot_date_time ( $row[3], $row[4], $row[8], ',' ), ','; //endDate,endTime } //end if ( $row[4] < 0 ) // description (str) echo '"', preg_replace ( '/\x0D?\n/', "\\n", $row[1] ), '",' // note (str) . '"', preg_replace ( '/\x0D?\n/', "\\n", $row[9] ), '",'; // alarm, advance, advanceUnit // alarm (int: 0=no alarm, 1=alarm) // FIXME: verify if WebCal. DB interpreted correctly // advance (int), advanceUnit (int: 0=minutes, 1=hours, 2=days) // FIXME: better adjust unit $ext = get_cal_ent_extras ( $row[0], 'webcal_reminders' ); if ( $ext ) echo '1,', $ext[2], ',0,'; else echo '0,0,0,'; // repeat: // repeatType (int: 0=none, 1=daily, 2=weekly, 3=monthly, 4=monthly/weekday, // repeatForever (int: 0=not forever, 1=forever) 5=yearly) // repeatEnd (time) // repeatFrequency (int) // repeatDay (int: day# or 0..6=Sun..Sat 1st, 7..13 2nd, 14..20 3rd, // 21..27 4th, 28-34 last week) // repeatWeekdays (int: add - 1=Sun,2=Mon,4=Tue,8=Wed,16=Thu,32=Fri,64=Sat) // repeatWeekstart (int) $ext = get_cal_ent_extras ( $row[0], 'webcal_entry_repeats' ); if ( $ext ) { switch ( $ext[1] ) { case 'daily': $repType = 1; break; case 'weekly': $repType = 2; break; case 'monthlyByDate': $repType = 3; break; case 'monthlyByDay': $repType = 4; break; case 'yearly': $repType = 5; break; default: $repType = 0; } } else $repType = 0; if ( $repType ) { echo $repType, ','; // repeatType if ( $ext[2] ) { echo '0,', // repeatForever substr ( $ext[2], 0, 4 ), '-', // repeatEnd substr ( $ext[2], 4, 2 ), '-', substr ( $ext[2], 6, 2 ), ' 00:00:00,'; } else echo '1,,'; // repeatForever,repeatEnd echo $ext[3], ','; // repeatFrequency switch ( $repType ) { case 2: // weekly echo '0,', bindec ( strtr ( strrev ( $ext[4] ), 'yn', '10' ) ), ",1\n"; break; case 3: // monthly/weekday // repeatDay (0..6=Sun..Sat 1st, 7..13 2nd, 14..20 3rd, // 21..27 4th, 28-34 last week) echo floor ( substr ( $row[3], 6, 2 ) / 7 ) * 7 + date ( 'w', date_to_epoch ( $row[3] ) ), ",0,0\n"; break; case 1: // daily case 4: // monthly case 5: // yearly echo "0,0,0\n"; } //end switch } else echo "0,0,,0,0,0,0\n"; } //end if ( $repType ) } /** * transmit_header (needs description) */ function transmit_header( $mime, $file ) { // header ( 'Content-Type: application/octet-stream' ); header ( 'Content-Type: ' . $mime ); header ( 'Content-Disposition: attachment; filename="' . $file . '"' ); header ( 'Pragma: private' ); header ( 'Cache-control: private, must-revalidate' ); } /* ********************************** */ /* Let's go */ /* ********************************** */ $format = getValue ( 'format' ); if ( $format != 'ical' && $format != 'vcal' && $format != 'pilot-csv' && $format != 'pilot-text' ) die_miserable_death ( 'Invalid format "' . htmlspecialchars($format) . '"' ); $id = getValue ( 'id', '-?[0-9]+', true ); $use_all_dates = getPostValue ( 'use_all_dates' ); if ( strtolower ( $use_all_dates ) != 'y' ) $use_all_dates = ''; $include_layers = getPostValue ( 'include_layers' ); if ( strtolower ( $include_layers ) != 'y' ) $include_layers = ''; $include_deleted = getPostValue ( 'include_deleted' ); if ( strtolower ( $include_deleted ) != 'y' ) $include_deleted = ''; $cat_filter = getPostValue ( 'cat_filter' ); if ( $cat_filter == 0 ) $cat_filter = ''; $endday = getValue ( 'endday', '-?[0-9]+', true ); $endmonth = getValue ( 'endmonth', '-?[0-9]+', true ); $endyear = getValue ( 'endyear', '-?[0-9]+', true ); $fromday = getValue ( 'fromday', '-?[0-9]+', true ); $frommonth = getValue ( 'frommonth', '-?[0-9]+', true ); $fromyear = getValue ( 'fromyear', '-?[0-9]+', true ); $modday = getValue ( 'modday', '-?[0-9]+', true ); $modmonth = getValue ( 'modmonth', '-?[0-9]+', true ); $modyear = getValue ( 'modyear', '-?[0-9]+', true ); $startdate = sprintf ( "%04d%02d%02d", $fromyear, $frommonth, $fromday ); $enddate = sprintf ( "%04d%02d%02d", $endyear, $endmonth, $endday ); $moddate = sprintf ( "%04d%02d%02d", $modyear, $modmonth, $modday ); mt_srand ( ( float ) microtime() * 1000000 ); if ( empty ( $id ) ) $id = 'all'; $outputName = 'webcalendar-' . "$login-$id"; if ( substr ( $format, 0, 4 ) == 'ical' ) { transmit_header ( 'text/calendar', $outputName . '.ics' ); export_ical ( $id ); } elseif ( $format == 'vcal' ) { transmit_header ( 'text/x-vCalendar', $outputName . '.vcs' ); export_vcal ( $id ); } elseif ( $format == 'pilot-csv' ) { transmit_header ( 'text/csv', $outputName . '.csv' ); export_pilot_csv ( $id ); } elseif ( $format == 'pilot-text' ) { transmit_header ( 'text/plain', $outputName . '.txt' ); export_install_datebook ( $id ); } else { print_header(); $errorStr = translate ( 'Error' ); echo ' <h2>' . translate ( 'Export' ) . ' ' . $errorStr . '</h2> <span class="bold">' . $errorStr . ':</span> ' . translate( 'export format not defined or incorrect.' ) . '<br /> ' . print_trailer(); } //end if ($format == "ical") ?> PK �]�\>r�f� � docdel.phpnu �[��� <?php /** * Page Description: * This page will handle deletion of an entry in webcal_blob. * This could be a comment or an attachment. * * Input Parameters: * For GET: * blid - unique id, corresponds to webcal_blob.cal_blob_id * * Security: * Only the creator of the comment, the creator of the associated * event, or an admin can delete. * (An assistant can also delete their boss' documents.) * Comments: * TODO: perhaps add email notification on this */ include_once 'includes/init.php'; include_once 'includes/classes/Doc.class'; $blid = getValue ( 'blid', '-?[0-9]+', true ); $can_delete = false; // until proven otherwise $error = $name = $owner = $type = ''; $event_id = -1; if ( $is_admin ) $can_delete = true; $res = dbi_execute ( Doc::getSQLForDocId ( $blid ) ); if ( ! $res ) $error = db_error(); else { if ( $row = dbi_fetch_row ( $res ) ) { $doc = new Doc( $row ); $event_id = $doc->getEventId(); $name = $doc->getName(); $owner = $doc->getLogin(); $type = $doc->getType(); if ( $owner == $login || user_is_assistant ( $login, $owner ) ) $can_delete = true; } else // document not found $error = str_replace ( 'XXX', $blid, translate ( 'Invalid entry id XXX.' ) ); dbi_free_result ( $res ); } if ( empty ( $error ) && ! $can_delete && $event_id > 0 ) { // See if current user is creator of associated event $res = dbi_execute ( 'SELECT cal_create_by FROM webcal_entry WHERE cal_id = ?', [$event_id] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { $event_owner = $row[0]; if ( $event_owner == $login || user_is_assistant ( $login, $event_owner ) ) $can_delete = true; } dbi_free_result ( $res ); } } if ( empty ( $error ) && ! $can_delete ) $error = print_not_auth(); if ( empty ( $error ) && $can_delete ) { if ( ! dbi_execute ( 'DELETE FROM webcal_blob WHERE cal_blob_id = ?', [$blid] ) ) $error = db_error(); else { if ( $event_id > 0 ) { $removeStr = translate ( 'Removed' ); if ( $type == 'A' ) activity_log ( $event_id, $login, $login, LOG_ATTACHMENT, $removeStr . ': ' . $name ); elseif ( $type == 'C' ) activity_log ( $event_id, $login, $login, LOG_COMMENT, $removeStr ); } if ( $event_id > 0 ) do_redirect ( 'view_entry.php?id=' . $event_id ); do_redirect ( get_preferred_view() ); } } // Some kind of error... print_header(); echo print_error ( $error ) . print_trailer(); ?> PK �]�\�l�� rss_activity_log.phpnu �[��� <?php // $Id: rss_activity_log.php,v 1.9 2010/10/05 17:16:59 cknudsen Exp $ /** * Description: * Generates RSS 2.0 output of the activity log. * * Like icalclient.php, this file does not use the standard web-based * user authentication. It always uses HTTP-based user authentication * since that is what RSS readers will expect. * * For details on the RSS 2.0 specification: * http://cyber.law.harvard.edu/rss/rss.html * * Input parameters: * None * * Security: * If User Access Control is on, the user must have access to * ACCESS_ACTIVITY_LOG or be an admin user. * If User Access Control is off, the user must be an admin user. * * Notes: * Changes in functionality should be coordinated with activity_log.php * since there is common code in the two files. * * If running as CGI, the following instructions should set the * PHP_AUTH_xxxx variables. This has only been tested with apache2, * so far. If using php as CGI, you'll need to include this in your * httpd.conf file or possibly in an .htaccess file. * * <IfModule mod_rewrite.c> * RewriteEngine on * RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L] * </IfModule> */ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; include 'includes/access.php'; $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include_once 'includes/validate.php'; include 'includes/site_extras.php'; // This next step will send a redirect to login.php, which we don't want. $WebCalendar->initializeSecondPhase(); $appStr = generate_application_name(); if ( empty ( $_SERVER['PHP_AUTH_USER'] ) && ! empty ( $_ENV['REMOTE_USER'] ) ) { list ( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) = explode ( ':', base64_decode ( substr ( $_ENV['REMOTE_USER'], 6 ) ) ); $_SERVER['PHP_AUTH_USER'] = trim ( $_SERVER['PHP_AUTH_USER'] ); $_SERVER['PHP_AUTH_PW'] = trim ( $_SERVER['PHP_AUTH_PW'] ); } unset ( $_ENV['REMOTE_USER'] ); if ( empty ( $login ) ) { if ( isset ( $_SERVER['PHP_AUTH_USER'] ) && user_valid_login ( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], true ) ) $login = $_SERVER['PHP_AUTH_USER']; if ( empty ( $login ) || $login != $_SERVER['PHP_AUTH_USER'] ) { $_SERVER['PHP_AUTH_PW'] = $_SERVER['PHP_AUTH_USER'] = ''; unset ( $_SERVER['PHP_AUTH_USER'] ); unset ( $_SERVER['PHP_AUTH_PW'] ); header ( 'WWW-Authenticate: Basic realm="' . $appStr . '"' ); header ( 'HTTP/1.0 401 Unauthorized' ); exit; } } load_global_settings(); load_user_preferences(); $WebCalendar->setLanguage(); // Load user name, etc. user_load_variables ( $login, '' ); // Make sure the have privileges to access the activity log if ( ! $is_admin || ( access_is_enabled() && ! access_can_access_function ( ACCESS_ACTIVITY_LOG ) ) ) die_miserable_death ( print_not_auth (2) ); $charset = ( empty ( $LANGUAGE ) ? 'iso-8859-1' : translate ( 'charset' ) ); // This should work ok with RSS, may need to hardcode fallback value. $lang = languageToAbbrev ( $LANGUAGE == 'Browser-defined' || $LANGUAGE == 'none' ? $lang : $LANGUAGE ); if ( $lang == 'en' ) $lang = 'en-us'; //the RSS 2.0 default. $appStr = generate_application_name(); $descr = $appStr . ' - ' . translate ( 'Activity Log' ); //header ( 'Content-type: application/rss+xml'); header ( 'Content-type: text/xml' ); echo '<?xml version="1.0" encoding="' . $charset . '"?> <?xml-stylesheet href="rss-style.css" ?> <rss version="2.0" xml:lang="' . $lang . '"> <channel> <title><![CDATA[' . $appStr . ']]></title> <link>' . $SERVER_URL . '</link> <description><![CDATA[' . $descr . ']]></description> <language>' . $lang . '</language> <generator>WebCalendar ' . $PROGRAM_VERSION . '</generator> <image> <title><![CDATA[' . $appStr . ']]></title> <link>' . $SERVER_URL . '</link> <url>http://www.k5n.us/k5n_small.gif</url> </image>' . "\n"; $num = getIntValue ( false, 'num' ); if ( empty ( $num ) || $num <= 0 || $num > 100 ) $num = 100; echo rss_activity_log ( false, $num ); echo " </channel>\n</rss>\n"; exit; /** * Generate the activity log. */ function rss_activity_log ( $sys, $entries ) { global $SERVER_URL, $ALLOW_HTML_DESCRIPTION, $login; $sql_params = array(); $limit = $where = ''; switch ( $GLOBALS['db_type'] ) { case 'mysqli': case 'mysql': case 'postgresql': $limit .= ' LIMIT ' . $entries; break; case 'oracle': $where .= ' AND ROWNUM <= ' . $entries; break; } $sql = 'SELECT wel.cal_login, wel.cal_user_cal, wel.cal_type, wel.cal_date, wel.cal_time, wel.cal_text, ' . ( $sys ? 'wel.cal_log_id FROM webcal_entry_log wel WHERE wel.cal_entry_id = 0' : 'we.cal_id, we.cal_name, wel.cal_log_id, we.cal_type, we.cal_description FROM webcal_entry_log wel, webcal_entry we WHERE wel.cal_entry_id = we.cal_id' . $where ) . ' ORDER BY wel.cal_log_id DESC' . $limit; $rows = dbi_get_cached_rows ( $sql, $sql_params ); $ret = ''; for ( $i = 0; $i < count ( $rows ) && $i < $entries; $i++ ) { $row = $rows[$i]; $num = 0; $l_login = $row[0]; $l_user = $row[1]; $l_type = $row[2]; $l_date = $row[3]; $l_time = $row[4]; $l_text = $row[5]; if ( $sys ) { $l_id = $row[6]; $l_description = ''; } else { $l_eid = $row[6]; $l_ename = $row[7]; $l_id = $row[8]; $l_etype = $row[9]; $l_description = $row[10]; // convert lines to <br /> if no HTML formatting found if ( strpos ( $l_description, "</" ) == false ) { $l_description = nl2br ( $l_description ); } } $num++; $unixtime = date_to_epoch ( $l_date . $l_time ); $subject = display_activity_log ( $l_type, $l_text, "\n" ); $ret .= "<item>\n" . ' <title><![CDATA[' . $subject . ': ' . htmlspecialchars( $l_ename ) . ']]></title>' . "\n <link>" . $SERVER_URL . 'view_entry.php?id=' . $l_eid . "</link>\n" . ' <description>'; if ( $ALLOW_HTML_DESCRIPTION == 'Y' ) { $x = str_replace ( '&', '&', $l_description ); $x = str_replace ( '&amp;', '&', $x ); $ret .= $x; } else $ret .= '<![CDATA[' . $l_description . ']]>'; $ret .= '</description>'; $ret .= "\n" // . ' <category><![CDATA[' . $category . ']]></category>' . "\n" /* RSS 2.0 date format Wed, 02 Oct 2002 13:00:00 GMT */ . '<pubDate>' . gmdate( 'D, d M Y H:i:s', $unixtime ) . ' GMT</pubDate>' . "\n" . ' <guid>' . $SERVER_URL . 'view_entry.php?id=' . $l_eid . '&friendly=1&rssuser=' . $login . '&date=' . $l_date . "</guid>\n" . "</item>\n\n"; } return $ret; } ?> PK �]�\��+� � doc.phpnu �[��� <?php /** * Description: * Obtain a binary object from the database and send it back to * the browser using the correct mime type. * * Input Parameters: * blid - The unique identifier for this blob (required) */ include_once 'includes/init.php'; include_once 'includes/classes/Doc.class'; $blid = getValue ( 'blid', '-?[0-9]+', true ); $error = $res = ''; $invalidIDStr = translate ( 'Invalid entry id XXX.' ); if ( empty ( $blid ) ) $error = translate ( 'Invalid blob id' ); else { $res = dbi_execute ( Doc::getSQLForDocId ( $blid ) ); if ( ! $res ) $error = db_error(); } if ( empty ( $error ) ) { $row = dbi_fetch_row ( $res ); if ( ! $row ) { $error = str_replace ( 'XXX', $blid, $invalidIDStr ); } else { $doc = new Doc( $row ); $description = $doc->getDescription(); $filedata = $doc->getData(); $filename = $doc->getName(); $id = $doc->getId(); $mimetype = $doc->getMimeType(); $owner = $doc->getLogin(); $size = $doc->getSize(); $type = $doc->getType(); } dbi_free_result ( $res ); } // Make sure this user is allowed to look at this file. // If the blob is associated with an event, then the user must be able // to view the event in order to access this file. // TODO: move all this code (and code in view_entry.php) to a common // function named can_view_event or something similar. $can_view = false; $is_my_event = false; $is_private = $is_confidential = false; $log = getGetValue ( 'log' ); $show_log = ! empty ( $log ); if ( empty ( $id ) ) $can_view = true; // not associated with an event if ( ! empty ( $id ) && empty ( $error ) ) { if ( $is_admin || $is_nonuser_admin || $is_assistant ) $can_view = true; if ( empty ( $id ) || $id <= 0 || ! is_numeric ( $id ) ) $error = str_replace ( 'XXX', $id, $invalidIDStr ); if ( empty ( $error ) ) { // is this user a participant or the creator of the event? $res = dbi_execute ( 'SELECT we.cal_id FROM webcal_entry we, webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND we.cal_id = ? AND ( we.cal_create_by = ? OR weu.cal_login = ? )', [$id, $login, $login] ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row && $row[0] > 0 ) { $can_view = true; $is_my_event = true; } dbi_free_result ( $res ); } if ( ($login != '__public__') && ($PUBLIC_ACCESS_OTHERS == 'Y') ) { $can_view = true; } if ( ! $can_view ) { $check_group = false; // if not a participant in the event, must be allowed to look at // other user's calendar. if ( $login == '__public__' ) { if ( $PUBLIC_ACCESS_OTHERS == 'Y' ) $check_group = true; } else { if ( $ALLOW_VIEW_OTHER == 'Y' ) $check_group = true; } // If $check_group is true now, it means this user can look at the // event only if they are in the same group as some of the people in // the event. // This gets kind of tricky. If there is a participant from a different // group, do we still show it? For now, the answer is no. // This could be configurable somehow, but how many lines of text would // it need in the admin page to describe this scenario? Would confuse // 99.9% of users. // In summary, make sure at least one event participant is in one of // this user's groups. $my_users = get_my_users(); $cnt = count ( $my_users ); if ( is_array ( $my_users ) && $cnt ) { $sql = 'SELECT we.cal_id FROM webcal_entry we, webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND we.cal_id = ? AND weu.cal_login IN ( ?' . str_repeat ( ',?', $cnt - 1 ); $query_params = [$id]; for ( $i = 0; $i < $cnt; $i++ ) { $query_params[] = $my_users[$i]['cal_login']; } $res = dbi_execute ( $sql . ' )', $query_params ); if ( $res ) { $row = dbi_fetch_row ( $res ); if ( $row && $row[0] > 0 ) $can_view = true; dbi_free_result ( $res ); } } // If we didn't indicate we need to check groups, then this user // can't view this event. if ( ! $check_group && ! access_is_enabled() ) $can_view = false; } } $hide_details = ( $login == '__public__' && ! empty ( $OVERRIDE_PUBLIC ) && $OVERRIDE_PUBLIC == 'Y' ); // If they still cannot view, make sure they are not looking at a nonuser // calendar event where the nonuser is the _only_ participant. if ( empty ( $error ) && ! $can_view && ! empty ( $NONUSER_ENABLED ) && $NONUSER_ENABLED == 'Y' ) { $nonusers = get_nonuser_cals(); $nonuser_lookup = []; for ( $i = 0, $cnt = count ( $nonusers ); $i < $cnt; $i++ ) { $nonuser_lookup[$nonusers[$i]['cal_login']] = 1; } $res = dbi_execute ( 'SELECT cal_login FROM webcal_entry_user WHERE cal_id = ? AND cal_status IN ( "A", "W" )', [$id] ); $found_nonuser_cal = $found_reg_user = false; if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { if ( ! empty ( $nonuser_lookup[$row[0]] ) ) $found_nonuser_cal = true; else $found_reg_user = true; } dbi_free_result ( $res ); } // Does this event contain only nonuser calendars as participants? // If so, then grant access. if ( $found_nonuser_cal && ! $found_reg_user ) $can_view = true; } if ( empty ( $error ) && ! $can_view ) $error = print_not_auth(); } if ( ! empty ( $error ) ) { print_header(); echo print_error ( $error, true) . print_trailer(); exit; } $disp = ( $type == 'A' ? 'attachment' : 'inline' ); // Print out data now. Header ( 'Content-Length: ' . $size ); Header ( 'Content-Type: ' . $mimetype ); $description = preg_replace ( "/\n\r\t+/", ' ', $description ); Header ( 'Content-Description: ' . $description ); // Don't allow spaces in filenames. //$filename = preg_replace ( "/\n\r\t+/", "_", $filename ); //Header ( "Content-Disposition: $disp; filename=$filename" ); Header ( 'Content-Disposition: filename=' . $filename ); echo $filedata; exit; ?> PK �]�\5�� � combo.phpnu �[��� <?php /** * This page handles displaying the Day/Week/Month/Year views in a single * page with tabs. Content is loaded dynamically with AJAX. * So, requests for previous & next will not force a page reload. * * TODO: * - Week view * - Task view * - Print layout * - Delete event (?) * - Honor access_can_access_function ( ACCESS_WEEK/ACCESS_MONTH/ACCESS_DAY ) * * Possibilities for later: * - Include tab for unapproved events where users could approve from * this page. * * Note: some of the icons for this page were downloaded from the following * page. If you want to add more icons, check there first. * http://rrze-icon-set.berlios.de/gallery.html * License info (Creative Commons 3.0) * http://rrze-icon-set.berlios.de/licence.html */ include_once 'includes/init.php'; // Load Doc classes for attachments and comments include 'includes/classes/Doc.class'; include 'includes/classes/DocList.class'; include 'includes/classes/AttachmentList.class'; include 'includes/classes/CommentList.class'; //send_no_cache_header(); $LOADING = '<div style="height: 220px; padding-top: 190px;"><center><img src="images/loading_animation.gif" alt="" /></center></div>'; $SMALL_LOADING = '<img src="images/loading_animation_small.gif" alt="..." width="16" height="16" />'; if ( $CATEGORIES_ENABLED == 'Y' ) load_user_categories(); $date = getIntValue ( 'date' ); if ( empty ( $date ) ) $date = date ( 'Ymd' ); $thisyear = substr ( $date, 0, 4 ); $thismonth = substr ( $date, 4, 2 ); $thisday = substr ( $date, 6, 2 ); $next = mktime ( 0, 0, 0, $thismonth + 1, 1, $thisyear ); $nextYmd = date ( 'Ymd', $next ); $nextyear = substr ( $nextYmd, 0, 4 ); $nextmonth = substr ( $nextYmd, 4, 2 ); $prev = mktime ( 0, 0, 0, $thismonth - 1, 1, $thisyear ); $prevYmd = date ( 'Ymd', $prev ); $prevyear = substr ( $prevYmd, 0, 4 ); $prevmonth = substr ( $prevYmd, 4, 2 ); $user = getValue ( 'user', '[A-Za-z0-9_\.=@,\-]*', true ); if ( ! empty ( $user ) ) { // Make sure this user has permission to view the other user's calendar if ( ! access_user_calendar( 'view', $user ) ) { // Not allowed. $user = $login; } } // Can the user see event participants? $show_participants = ( $DISABLE_PARTICIPANTS_FIELD != 'Y' ); if ( $is_admin ) $show_participants = true; if ( $PUBLIC_ACCESS == 'Y' && $login == '__public__' && ( $PUBLIC_ACCESS_OTHERS != 'Y' || $PUBLIC_ACCESS_VIEW_PART == 'N' ) ) $show_participants = false; // Get width/height settings for modal dialog used to view event. $view_width = empty ( $VIEW_EVENT_DIALOG_WIDTH ) ? "350" : $VIEW_EVENT_DIALOG_WIDTH; $view_height = empty ( $VIEW_EVENT_DIALOG_HEIGHT ) ? "300" : $VIEW_EVENT_DIALOG_HEIGHT; // Get width/height settings for modal dialog used for "quick add" $quick_add_width = empty ( $QUICK_ADD_DIALOG_WIDTH ) ? "550" : $QUICK_ADD_DIALOG_WIDTH; $quick_add_height = empty ( $QUICK_ADD_DIALOG_HEIGHT ) ? "200" : $QUICK_ADD_DIALOG_HEIGHT; $can_add = true; if ( $readonly == 'Y' ) $can_add = false; else if ( access_is_enabled() ) $can_add = access_can_access_function ( ACCESS_EVENT_EDIT ); else { if ( $login == '__public__' ) $can_add = ( $GLOBALS['PUBLIC_ACCESS_CAN_ADD'] == 'Y' ); else if ( $is_nonuser ) $can_add = false; } $bodyExtras = 'onload="onLoadInit()"'; // Add ModalBox javascript/CSS & Tab code, Auto-complete $headExtras = ' <script type="text/javascript" src="includes/tabcontent/tabcontent.js"></script> <link type="text/css" href="includes/tabcontent/tabcontent.css" rel="stylesheet" /> <script type="text/javascript" src="includes/js/modalbox/modalbox.js"></script> <link rel="stylesheet" href="includes/js/modalbox/modalbox.css" type="text/css" media="screen" /> <script type="text/javascript" src="includes/js/autocomplete.js"></script> '; print_header( array( 'js/popups.js/true', 'js/visible.php', 'js/datesel.php' ), $headExtras, $bodyExtras ); ?> <div class="headerinfo"> <table> <tr> <?php if ( $single_user == 'N' ) { user_load_variables ( ! empty ( $user ) ? $user : $login, 'user_' ); echo "<td class=\"aligntop username\"><nobr>" . htmlspecialchars ( $user_fullname ) . "</nobr></td>"; } if ( $CATEGORIES_ENABLED == 'Y' ) { ?> <td class="aligntop" id="categoryselection">Categories:</td> <td class="aligntop" onmouseover="setCategoryVisibility(true)" onmouseout="setCategoryVisibility(false)"> <img id="catexpand" src="images/expand.gif" /> <span id="selectedcategories">All</span><br /> <div id="categorylist" style="display:none"> <?php foreach ( $categories as $catId => $val ) { $name = "cat-" . $catId; if ( $catId > 0 ) { ?> <nobr><input type="checkbox" id="<?php echo $name;?>" name="<?php echo $name;?>" onclick="handleCategoryCheckboxChange()" value="Y" /><label for="<?php echo $name;?>"> <?php echo htmlspecialchars ( $categories[$catId]['cat_name'] ) ?> </label></nobr> <?php //$catIconFile = 'icons/cat-' . $catId . '.gif'; //if ( file_exists ( $catIconFile ) ) } } ?> <br /><input style="font-size: 80%" type="button" value="<?php etranslate("Select All");?>" onclick="selectAllCategories()" /> <input style="font-size: 80%" type="button" value="<?php etranslate("Select None");?>" onclick="selectNoCategories()" /> <?php ?> </div> <?php } ?> </tr></table> </div> <ul id="viewtabs" class="shadetabs" style="margin-left: 10px;"> <li><a href="#" rel="contentDay" class="selected"><?php etranslate('Day');?></a></li> <li><a href="#" rel="contentWeek"><?php etranslate('Week');?></a></li> <li><a href="#" rel="contentMonth"><?php etranslate('Month')?></a></li> <li><a href="#" rel="contentYear"><?php etranslate('Year')?></a></li> <li><a href="#" rel="contentAgenda"><?php etranslate("Agenda");?></a></li> <li><a href="#" rel="contentTasks"><?php etranslate('Tasks');?></a></li> </ul> <div style="border:1px solid gray; width:95%; margin-bottom: 1em; margin-left: 10px; margin-right: 10px; padding: 10px"> <div id="contentDay" class="tabcontent"> Day content goes here... </div> <div id="contentWeek" class="tabcontent"> Week content goes here... </div> <div id="contentMonth" class="tabcontent"> Month content goes here... </div> <div id="contentYear" class="tabcontent"> Year content goes here... </div> <div id="contentAgenda" class="tabcontent"> Agenda content goes here... </div> <div id="contentTasks" class="tabcontent"> <table id="tasktable"> </table> <br/> <span id="addtask" class="clickable fakebutton" onclick="taskAddPopup()"/><?php etranslate('Add Task');?></span> </div> </div> <div id="viewEventDiv" style="display: none;"> <table> <tr><td colspan="2"><h3 id="name" class="eventName"> </h3></td></tr> <tr><td class="aligntop bold"><?php etranslate("Description")?>:</td> <td id="description"> </td></tr> <tr><td class="aligntop bold"><?php etranslate("Date")?>:</td> <td id="date"> </td></tr> <tr><td class="aligntop bold"><?php etranslate("Time")?>:</td> <td id="time"> </td></tr> <?php if ( $DISABLE_PRIORITY_FIELD != 'Y' ) { ?> <tr><td class="aligntop bold"><?php etranslate("Priority")?>:</td> <td id="priority"> </td></tr> <?php } ?> <tr><td class="aligntop bold"><?php etranslate("Access")?>:</td> <td id="access"> </td></tr> <?php if ( $single_user == 'N' ) { ?> <tr><td class="aligntop bold"><?php etranslate("Created by")?>:</td> <td id="createdby"> </td></tr> <?php } ?> <tr><td class="aligntop bold"><?php etranslate("Updated")?>:</td> <td id="updated"> </td></tr> <?php if ( $show_participants ) { ?> <tr><td class="aligntop bold"><?php etranslate("Participants")?>:</td> <td id="participants"> </td></tr> <?php } ?> <?php if ( Doc::attachmentsEnabled() ) { ?> <tr><td class="aligntop bold"><?php etranslate("Attachments")?>:</td> <td id="attachments"> </td></tr> <?php } ?> <?php if ( Doc::commentsEnabled() ) { ?> <tr><td class="aligntop bold"><?php etranslate("Comments")?>:</td> <td id="comments"> </td></tr> <?php } ?> <tr><td colspan="2"> </td></tr> <tr><td colspan="2" id="eventlink" class="aligncenter"> </td></tr> </table> </div> <!-- Hidden div tag for Quick Add dialog --> <div id="quickAddDiv" style="display: none;"> <input type="hidden" name="quickAddParticipants" id="quickAddParticipants" value="" /> <table> <tr><td class="aligntop bold"><?php etranslate('Date');?>:</td> <td><?php echo datesel_Print ( 'quickAddDate', $date );?> </td></tr> <tr><td class="aligntop bold"><?php etranslate('Brief Description');?>:</td> <td><input id="quickAddName" name="quickAddName" onfocus="this.select();" /></td></tr> <tr><td class="aligntop bold"><?php etranslate('Full Description');?>:</td> <td><textarea id="quickAddDescription" name="quickAddDescription" rows="4" cols="40" wrap="virtual"></textarea></td></tr> <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> <tr><td class="aligntop bold"><?php etranslate('Category');?>:</td> <td><select id="quickAddCategory" name="quickAddCategory"> <option value="-1"><?php etranslate('None');?></option> <?php foreach ( $categories as $K => $V ) { if ( $K > 1 ) { echo '<option value="' . $K . '">' . htmlspecialchars ( $categories[$K]['cat_name'] ) . "</option>\n"; } } ?> </select></td></tr> <?php } ?> <tr><td class="aligntop bold"><?php etranslate('Participants');?>:</td> <td><span id="quickAddParticipantList"></span> <input type="text" id="quickAddNewParticipant" name="quickAddNewParticipant" size="20" /></td></tr> <tr><td colspan="2"> </td></tr> <tr><td colspan="2"><input type="button" value="<?php etranslate('Save');?>" onclick="eventAddHandler()" /><br /> <span class="clickable" onclick="addEventDetail()"><?php etranslate("Add event detail");?></span> </td></tr> </table> </div> <!-- Hidden div tag for Add Task dialog --> <div id="taskAddDiv" style="display: none;"> <form name="taskAddForm" id="taskAddForm"> <table> <tr><td class="aligntop bold"><?php etranslate('Start Date');?>:</td> <td><?php echo datesel_Print ( 'task_start_date', $date );?></td></tr> <tr><td class="aligntop bold"><?php etranslate('Due Date');?>:</td> <td><?php echo datesel_Print('task_due_date', $date); ?></td></tr> <tr><td class="aligntop bold"><?php etranslate('Brief Description');?>:</td> <td><input id="taskAddName" name="taskAddName" /></td></tr> <tr><td class="aligntop bold"><?php etranslate('Full Description');?>:</td> <td><textarea id="taskAddDescription" name="taskAddDescription" rows="4" cols="40" wrap="virtual"></textarea></td></tr> <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> <tr><td class="aligntop bold"><?php etranslate('Category');?>:</td> <td><select id="taskAddCategory" name="taskAddCategory"> <option value="-1"><?php etranslate('None');?></option> <?php foreach ( $categories as $K => $V ) { if ( $K > 1 ) { echo '<option value="' . $K . '">' . htmlspecialchars ( $categories[$K]['cat_name'] ) . "</option>\n"; } } ?> </select></td></tr> <?php } ?> <tr><td colspan="2"> </td></tr> <tr><td colspan="2"><input type="button" value="<?php etranslate('Save');?>" onclick="taskAddHandler()" /><br /> <span class="clickable" onclick="taskAddDetail()"><?php etranslate("Add task detail");?></span> </td></tr> </table> </form> </div> <script type="text/javascript"> // Called when page is loaded. // Load events for the current month. // Load all tasks. function onLoadInit () { ajax_get_events('<?php echo $thisyear;?>','<?php echo intval($thismonth);?>', '<?php echo intval($thisday);?>'); ajax_get_tasks(); } // Initialize tabs var views=new ddtabcontent("viewtabs") views.setpersist(true) views.setselectedClassTarget("link") //"link" or "linkparent" views.init() // End init tabs var login = '<?php echo $login;?>'; var user = '<?php echo $user;?>'; var currentYear = null, currentMonth = null, currentDay = null; var switchingToDayView = false; // Sort mode for task table var SORT_BY_NAME = 0, SORT_BY_DUE_DATE = 1, SORT_BY_PRIORITY = 2, SORT_BY_CATEGORY = 3; var taskSortAsc = true; var taskSortCol = SORT_BY_DUE_DATE; var dateYmd = ''; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> var allCatsSelected = true; var selectedCats = []; var categories = []; <?php // Create a javascript array of all categories this user can see that // includes category name, owner, colors, global status, icon. foreach ( $categories as $catId => $val ) { if ( $catId > 0 ) { echo 'categories[' . $catId . '] = ' . '{ id : ' . $catId . ', state: 1' . ', owner: "' . $categories[$catId]['cat_owner'] . '"' . ', name: "' . $categories[$catId]['cat_name'] . '"' . ', color: "' . $categories[$catId]['cat_color'] . '"' . ', global: ' . ( $categories[$catId]['cat_global'] ? '0' : '1' ); $gifIconFile = 'icons/cat-' . $catId . '.gif'; $pngIconFile = 'icons/cat-' . $catId . '.png'; $jpgIconFile = 'icons/cat-' . $catId . '.jpg'; if ( file_exists ( $gifIconFile ) ) { echo ', icon: "' . $gifIconFile . '"'; } else if ( file_exists ( $pngIconFile ) ) { echo ', icon: "' . $pngIconFile . '"'; } else if ( file_exists ( $jpgIconFile ) ) { echo ', icon: "' . $jpgIconFile . '"'; } echo " };\n"; } } ?> <?php } ?> var viewDialogIsVisible = false; var quickAddDialogIsVisible = null; var catsVisible = false; var events = tasks = []; // loadedMonths is used to keep track of which months we have loaded events // for. This prevents us from re-loading a month's events that we // previously loaded. var loadedMonths = []; // Key will be format "200801" For Jan 2008 // loadedTasks set to true when tasks have been loaded. We don't load tasks // based on date, so it is a single scalar variable rather than an array. var loadedTasks = false; var months = [ <?php // Create javascript array of month names localized to the user's // language preference. for ( $i = 0; $i < 12; $i++ ) { if ( $i ) echo ", "; echo "'" . month_name ( $i ) . "'"; } ?> ]; var shortMonths = [ <?php // Create javascript array of shortened month names localized to the user's // language preference. for ( $i = 0; $i < 12; $i++ ) { if ( $i ) echo ", "; echo "'" . month_name ( $i, 'M' ) . "'"; } ?> ]; var weekdays = [ <?php // Create javascript array of weekday names localized to the user's // language preference. for ( $i = 0; $i < 7; $i++ ) { if ( $i ) echo ", "; echo "'" . weekday_name ( $i, 'l' ) . "'"; } ?> ]; var shortWeekdays = [ <?php // Create javascript array of shortened weekday names localized to the // user's language preference. for ( $i = 0; $i < 7; $i++ ) { if ( $i ) echo ", "; echo "'" . weekday_name ( $i, 'D' ) . "'"; } ?> ]; var daysPerMonth = [ <?php echo implode ( ", ", $days_per_month ); ?> ]; var leapDaysPerMonth = [ <?php echo implode ( ", ", $ldays_per_month ); ?> ]; var userLogins = []; var userNames = []; var users = []; <?php // Create a javascript array of all users this user has access to see. // Note: not using this yet in the javascript anywhere.... $users = user_get_users(); for ( $i = 0; $i < count ( $users ); $i++ ) { $fname = $users[$i]['cal_fullname']; if ( empty ( $fname ) ) $fname = $users[$i]['cal_login']; $fname = str_replace ( "'", "", $fname ); echo 'userLogins[' . $i . '] = \'' . $users[$i]['cal_login'] . "';\n"; echo 'userNames[' . $i . '] = \'' . $fname . "';\n"; echo 'users["' . $users[$i]['cal_login'] . '"] = \'' . $fname . "';\n"; } ?> // Callback for autocomplete on usernames. We return an object // that includes matching user logins and names. function autocompleteUserSearch ( q ) { var suggestions = []; var data = []; var cnt = 0; var words = q.toLowerCase().split ( ' ' ); for ( var i = 0; i < userLogins.length; i++ ) { var match = 0; for ( var j = 0; j < words.length && ! match; j++ ) { var q1 = words[j]; if ( q1.length == 0 ) { // ignore } else if ( userLogins[i].toLowerCase().indexOf ( q1 ) >= 0 ) { match = 1; } else if ( userNames[i].toLowerCase().indexOf ( q1 ) >= 0 ) { match = 1; } } if ( match ) { suggestions[cnt] = userNames[i]; data[cnt] = userLogins[i]; cnt++; } } var resp = { suggestions: suggestions, data: data }; //alert('resp.suggestions=' + resp.suggestions + ", cnt=" + cnt ); return resp; } <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> function setCategoryVisibility (newIsVisible) { if ( newIsVisible ) { $('categorylist').style.display = "block"; $('catexpand').src = "images/collapse.gif"; catsVisible = true; } else { $('categorylist').style.display = "none"; $('catexpand').src = "images/expand.gif"; catsVisible = false; } } function selectAllCategories() { <?php foreach ( $categories as $catId => $val ) { if ( $catId > 0 ) { $checkboxName = "cat-" . $catId; echo " $('" . $checkboxName . "').checked = true;\n"; } } ?> handleCategoryCheckboxChange(); } function selectNoCategories() { <?php foreach ( $categories as $catId => $val ) { if ( $catId > 0 ) { $checkboxName = "cat-" . $catId; echo " $('" . $checkboxName . "').checked = false;\n"; } } ?> handleCategoryCheckboxChange(); } function handleCategoryCheckboxChange() { var newText = ''; var cnt = 0, cntOff = 0; var all = false; selectedCats = []; <?php foreach ( $categories as $catId => $val ) { if ( $catId > 0 ) { $checkboxName = "cat-" . $catId; $varName = "cat" . $catId; echo " var $varName = document.getElementById('$checkboxName');\n"; echo " if ( " . $varName . ' && ' . $varName . '.checked ) {' . "\n"; echo ' selectedCats[cnt] = ' . $catId . ';' . "\n"; echo " if ( cnt++ > 0 ) newText += ', ';\n"; echo " newText += \"" . $categories[$catId]['cat_name'] . "\";\n"; echo ' categories[' . $catId . '].state = 1;' . "\n"; echo ' } else { ' . "\n"; echo ' cntOff++;' . "\n"; echo ' categories[' . $catId . '].state = 0;' . "\n"; echo ' }' . "\n"; } } ?> if ( cnt == 0 || cntOff == 0 ) { newText = '<?php etranslate('All');?>'; for ( var catId in categories ) { categories[catId].state = 1; } allCatsSelected = true; } else { allCatsSelected = false; } $('selectedcategories').innerHTML = newText; // Update display update_display ( currentYear, currentMonth, currentDay ); } <?php } ?> // Load events for the specified month AND update ALL the event tabs // (year, month, day, agenda). We pass in the day so we know // which day of the month to put in the day view. // NOTE: This does not affect the "Tasks" tab. function ajax_get_events ( year, month, day ) { var startdate = "" + year + ( month < 10 ? "0" : "" ) + month + "01"; // First, check to see if we already have loaded the content for // the specified month. var monthKey = "" + year + ( month < 10 ? "0" : "" ) + month; if ( loadedMonths[monthKey] > 0 ) { //alert ( "Already loaded " + monthKey ); update_display ( year, month, day ); return; } //alert ( "Loading startdate=" + startdate ); $('contentDay').innerHTML = '<?php echo $LOADING;?>'; $('contentWeek').innerHTML = '<?php echo $LOADING;?>'; $('contentMonth').innerHTML = '<?php echo $LOADING;?>'; $('contentYear').innerHTML = '<?php echo $LOADING;?>'; $('contentAgenda').innerHTML = '<?php echo $LOADING;?>'; new Ajax.Request('events_ajax.php', { method:'get', parameters: { action: 'get', startdate: startdate, user: user }, onSuccess: function( transport ) { if ( ! transport.responseText ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('no response from server');?>' + ': events_ajax.php?action=get' ); return; } //alert ( "Response:\n" + transport.responseText ); try { var response = transport.responseText.evalJSON(); // Hmmm... The Prototype JSON above doesn't seem to work! //var response = eval('(' + transport.responseText + ')'); } catch ( err ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('JSON error');?> - ' + err + "\n\n" + transport.responseText ); return; } if ( response.error ) { alert ( '<?php etranslate('Error');?>: ' + response.message ); return; } for ( var key in response.dates ) { events[key] = response.dates[key]; } loadedMonths[monthKey] = 1; update_display ( year, month, day ); }, onFailure: function() { alert( '<?php etranslate( 'Error' );?>' ) } }); switchingToDayView = false; return true; } // Load all tasks and update the "Tasks" tab accordingly. // Note: this does not affect the event tabs (year, month, day, agenda). function ajax_get_tasks () { if ( loadedTasks ) { //alert ( "Already loaded " + monthKey ); update_task_display (); return; } //$('contentTasks').innerHTML = '<?php echo $LOADING;?>'; new Ajax.Request('events_ajax.php', { method:'get', parameters: { action: 'gett', user: user }, onSuccess: function( transport ) { if ( ! transport.responseText ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('no response from server');?>' + ': events_ajax.php?action=gett' ); return; } //alert ( "Get Tasks Response:\n" + transport.responseText ); try { var response = transport.responseText.evalJSON(); // Hmmm... The Prototype JSON above doesn't seem to work! //var response = eval('(' + transport.responseText + ')'); } catch ( err ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('JSON error');?> - ' + err + "\n\n" + transport.responseText ); return; } if ( response.error ) { alert ( '<?php etranslate('Error');?>: ' + response.message ); return; } tasks = []; var i = 0; for ( var i = 0; i < response.tasks.length; i++ ) { tasks[i] = response.tasks[i]; } loadedTasks = true; update_task_display (); }, onFailure: function() { alert( '<?php etranslate( 'Error' );?>' ) } }); return true; } // View the event // key is the array index of the events[] object (which returns an array) // location is the index in the array function view_event ( key, location ) { var myEvent = null; var found = 0; if ( events && events[key] ) { var daysEvents = events[key]; if ( daysEvents && daysEvents[location] ) { var myEvent = daysEvents[location]; found = 1; } } if ( ! found ) { alert ( "Argh! Event not found." ); return; } // Use the modal dialog to display the event. // First update the <div> content with the information from this // event. function viewWindowClosed() { viewDialogIsVisible = false; } Modalbox.show($('viewEventDiv'), {title: '<?php etranslate('View Event');?>', width: 450, onHide: viewWindowClosed, closeString: '<?php etranslate('Cancel');?>' }); //Modalbox.resizeToContent(); viewDialogIsVisible = true; $('name').innerHTML = myEvent._name; $('description').innerHTML = format_description ( myEvent._description ); $('date').innerHTML = format_date ( myEvent._localDate, true ); $('time').innerHTML = format_time ( myEvent._localTime, false ); $('updated').innerHTML = format_date ( myEvent._localDate, false ) + ' ' + format_time ( myEvent._modtime, false ) + ' GMT'; $('createdby').innerHTML = users[myEvent._owner] ? users[myEvent._owner] : myEvent._owner; if ( myEvent._priority < 4 ) $('priority').innerHTML = '<?php etranslate('High');?>'; else if ( myEvent._priority < 7 ) $('priority').innerHTML = '<?php etranslate('Medium');?>'; else $('priority').innerHTML = '<?php etranslate('Low');?>'; if ( myEvent._access == 'P' ) $('access').innerHTML = '<?php etranslate('Public');?>'; else if ( myEvent._access == 'C' ) $('access').innerHTML = '<?php etranslate('Confidential');?>'; else $('access').innerHTML = '<?php etranslate('Private');?>'; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> <?php } ?> $('eventlink').innerHTML = '<a href="view_entry.php?id=' + myEvent._id + <?php if ( ! empty ( $user ) && $login != $user ) { echo "'&user=$user' + "; } ?> '" class="fakebutton"><?php etranslate('View Event')?></a>'; // For now, blank out participants. $('participants').innerHTML = '<?php echo $SMALL_LOADING;?>'; <?php if ( Doc::attachmentsEnabled() ) { ?> $('attachments').innerHTML = '<?php echo $SMALL_LOADING;?>'; <?php } ?> <?php if ( Doc::commentsEnabled() ) { ?> $('comments').innerHTML = '<?php echo $SMALL_LOADING;?>'; <?php } ?> // Load participants via AJAX new Ajax.Request('events_ajax.php', { method:'get', parameters: { action: 'eventinfo', id: myEvent._id }, onSuccess: function( transport ) { if ( ! transport.responseText ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('no response from server');?>' + ': events_ajax.php?action=eventinfo&id=' + myEvent._id ); return; } //alert ( "Response:\n" + transport.responseText ); try { var response = transport.responseText.evalJSON(); // Hmmm... The Prototype JSON above doesn't seem to work! //var response = eval('(' + transport.responseText + ')'); } catch ( err ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('JSON error');?> - ' + err + "\n\n" + transport.responseText ); return; } if ( response.error ) { alert ( '<?php etranslate('Error');?>: ' + response.message ); return; } var text = ''; for ( var i = 0; i < response.participants.length; i++ ) { var participant = response.participants[i]; var login = participant.login; var fullname = users[login] ? users[login] : login; if ( text.length > 0 ) text += "<br />"; text += fullname; if ( participant.status == 'W' ) text += ' (?)'; } $('participants').innerHTML = text; <?php if ( Doc::attachmentsEnabled() ) { ?> text = ''; for ( var i = 0; i < response.attachments.length; i++ ) { var attachment = response.attachments[i]; var summary = attachment.summary; if ( text.length > 0 ) text += "<br />"; text += summary; } if ( response.attachments.length == 0 ) text = '<?php etranslate('None');?>'; $('attachments').innerHTML = text; <?php } ?> <?php if ( Doc::commentsEnabled() ) { ?> text = '<dl style="margin-top: 0;">'; for ( var i = 0; i < response.comments.length; i++ ) { var comment = response.comments[i]; text += "<dt>" + comment.description + "<br />" + comment.owner + " @ " + comment.datetime + "</dt>" + "<dd>" + comment.text + "</dd>"; } text += "</dl>\n"; if ( response.comments.length == 0 ) text = '<?php etranslate('None');?>'; $('comments').innerHTML = text; <?php } ?> }, onFailure: function() { alert( '<?php etranslate( 'Error' );?>' ) } }); } // Update the day, week, month and agenda content (but not the tasks which // are loaded by a different ajax call). // This is called from ajax_get_events (which loads new event data) and // the callbacks for selecting categories. function update_display ( year, month, day ) { currentYear = year; currentMonth = month; currentDay = day; $('contentDay').innerHTML = build_day_view ( year, month, day ); // set scroll location to 8AM (50 pixels/hour) $('daydiv').scrollTop = 400; // TODO: save the position of the scrollbar so we can preserve on next/prev // TODO: Use start work hour from preferences. $('contentWeek').innerHTML = "Not yet implemented..."; $('contentMonth').innerHTML = build_month_view ( year, month ); $('contentYear').innerHTML = build_year_view ( year, month ); $('contentAgenda').innerHTML = build_agenda_view ( year, month ); var today = new Date (); dateYmd = "" + year; if ( month < 10 ) dateYmd += '0'; dateYmd += "" + month; if ( day < 10 ) dateYmd += '0'; dateYmd += "" + day; } // Update the task display. function update_task_display () { build_task_view (); } function prev_day_link ( year, month, day ) { day--; if ( day == 0 ) { month--; if ( month == 0 ) { year--; month = 12; } day = ( year % 4 == 0 ) ? leapDaysPerMonth[month] : daysPerMonth[month]; } return "<span id=\"prevday\" class=\"clickable fakebutton noprint\" onclick=\"ajax_get_events(" + year + "," + month + "," + day + ")\"><</span>"; } function next_day_link ( year, month, day ) { day++; var daysInMonth = ( year % 4 == 0 ) ? leapDaysPerMonth[month] : daysPerMonth[month]; if ( day > daysInMonth ) { day = 1; month++; if ( month > 12 ) { year++; month = 1; } } return "<span id=\"nextday\" class=\"clickable fakebutton noprint\" onclick=\"ajax_get_events(" + year + "," + month + "," + day + ")\">></span>"; } function prev_month_link_dayview ( year, month, day ) { month--; if ( month < 1 ) { month = 12; year--; } return "<span id=\"prevmonthdayview\" class=\"clickable fakebutton noprint\" onclick=\"ajax_get_events(" + year + "," + month + "," + day + ")\"><<</span>"; } function next_month_link_dayview ( year, month, day ) { month++; if ( month > 12 ) { month = 1; year++; } return "<span id=\"nextmonthdayview\" class=\"clickable fakebutton noprint\" onclick=\"ajax_get_events(" + year + "," + month + "," + day + ")\">>></span>"; } function prev_month_link ( year, month ) { var m, y; if ( month == 1 ) { m = 12; y = parseInt(year) - 1; } else { m = parseInt(month) - 1; y = year; } return '<span id="prevmonth" class="clickable noprint" onclick="ajax_get_events(' + y + ',' + m + ',1)"><img src="images/combo-prev.png" alt="' + shortMonths[m-1] + '"/></span>'; } function next_month_link ( year, month ) { var m, y; if ( month == 12 ) { m = 1; y = parseInt(year) + 1; } else { m = parseInt(month) + 1; y = year; } return '<span id="nextmonth" class="clickable noprint" onclick="ajax_get_events(' + y + ',' + m + ',1)"><img src="images/combo-next.png" alt="' + shortMonths[m-1] + '"/></span>'; } // Build a table of quick links to all the months in the current // year and a link to the next and previous years. function month_view_nav_links ( year, month ) { var ret, i; ret = '<table class="noprint monthnavlinks">'; ret += '<tr><td rowspan="2" class="aligncenter clickable" onclick="ajax_get_events(' + (parseInt(year)-1) + ',' + month + ',1)">' + '<img src="images/combo-prev.png"/><br/>' + (year-1) + '</td>'; for ( i = 1; i <= 6; i++ ) { ret += '<td class="'; if ( i == month ) ret += 'currentMonthLink '; ret += 'clickable" onclick="ajax_get_events(' + year + ',' + i + ',1)">' + shortMonths[i-1] + '</td>'; } ret += '<td rowspan="2" class="aligncenter clickable" onclick="ajax_get_events(' + (parseInt(year)+1) + ',' + parseInt(month) + ',1)">' + '<img src="images/combo-next.png"/><br/>' + (parseInt(year)+1) + '</td>'; // Add link to today var today = new Date(); var d = today.getDate(); var m = today.getMonth() + 1; var y = today.getYear() + 1900; ret += '<td rowspan="2" class="aligncenter clickable" onclick="ajax_get_events(' + y + ',' + m + ',' + d + ')">' + '<img src="images/combo-today.png" style="vertical-align: middle;" />' + "<br/><?php etranslate('Today');?></td></tr>"; // Jul - Dec for ( i = 7; i <= 12; i++ ) { ret += '<td class="'; if ( i == month ) ret += 'currentMonthLink '; ret += 'clickable" onclick="ajax_get_events(' + year + ',' + i + ',1)">' + shortMonths[i-1] + '</td>'; } ret += '</table>'; return ret; } function prev_year_link ( year, month ) { year = parseInt(year); return "<span id=\"prevyear\" class=\"clickable fakebutton noprint\" onclick=\"ajax_get_events(" + ( year - 1 ) + "," + month + ",1)\"><<" + ( year -1 ) + "</span>"; } function next_year_link ( year, month ) { year = parseInt(year); return "<span id=\"nextyear\" class=\"clickable fakebutton noprint\" onclick=\"ajax_get_events(" + ( year + 1 ) + "," + month + ",1)\">" + ( year + 1 ) + ">></span>"; } function today_link() { var today = new Date(); var d = today.getDate(); var m = today.getMonth() + 1; var y = today.getYear() + 1900; return "<span class=\"clickable fakebutton noprint\" onclick=\"ajax_get_events(" + y + "," + m + "," + d + ")\">" + '<img src="images/combo-today.png" style="vertical-align: middle;" />' + " <?php etranslate('Today');?></span>"; } // Callback for the user clicking on a cell in the month view, which // will allow the user to create a new event. function monthCellClickHandler ( dateYmd ) { // Make sure user has not opened the view dialog. When a user clicks // on an event to view it, we will still receive the onclick event for // the td cell onclick handler below it. if ( viewDialogIsVisible ) return; // If user clicked on the day in the month view, we are switching to // the day view, so ignore the click event. if ( switchingToDayView ) return; function addWindowClosed() { quickAddDialogIsOpen = false; } // Display quick add popup Modalbox.show($('quickAddDiv'), {title: '<?php etranslate('Add Entry');?>', width: <?php echo $quick_add_width;?>, transitions: false, onHide: addWindowClosed, closeString: '<?php etranslate('Cancel');?>' }); Modalbox.resizeToContent(); $('quickAddName').setAttribute ( 'value', "<?php etranslate('Unnamed Event');?>" ); $('quickAddName').select(); $('quickAddName').focus(); $('quickAddDescription').innerHTML = ""; $('quickAddDate_YMD').setAttribute ( 'value', dateYmd ); $('quickAddDate_fmt').innerHTML = format_date ( "" + dateYmd, true ); $('quickAddCategory').selectedIndex = 0; $('quickAddParticipants').value = '<?php echo $login;?>'; buildHiddenParticipantList (); // Initialize auto-complete of username new Autocomplete('quickAddNewParticipant', { //serviceUrl:'users_ajax.php', localServiceFunction: autocompleteUserSearch, maxHeight:400, width:300, deferRequestBy:100, // callback function: onSelect: function(value, data){ //alert('data= "' + data + '", value="' + value + '"' ); quickAddNewParticipant ( data ); } }); } // Add the specified user to the list of participants. function quickAddNewParticipant ( username ) { var value = $('quickAddParticipants').value; if ( value.length > 0 ) value += ','; value += username; $('quickAddParticipants').value = value; buildHiddenParticipantList (); // Clear out text input $('quickAddNewParticipant').value = ''; } function buildHiddenParticipantList () { var html = ''; var ar = $('quickAddParticipants').value.split ( ',' ); ar.sort (); for ( var i = 0; i < ar.length; i++ ) { if ( ar[i].length > 0 ) html += quickAddBuildUserElement ( ar[i] ); } $('quickAddParticipantList').innerHTML = html; } // Remove the specified login from the list of participants in // the quick add dialog. function quickAddRemoveUser ( login ) { var newv = []; var cnt = 0; var value = $('quickAddParticipants').value; var logins = value.split ( ',' ); for ( var i = 0; i < logins.length; i++ ) { if ( logins[i] != login ) { newv[cnt] = logins[i]; cnt++; } } $('quickAddParticipants').value = newv; buildHiddenParticipantList (); } function quickAddBuildUserElement ( login ) { var ret = '<span class="participant" id="p_' + login + '">' + login + '<span class="partX">' + '<img src="images/close.png" onclick="quickAddRemoveUser(\'' + login + '\')" alt="x" />' + '</span></span>'; return ret; } // Handler for user clicking the "Save" button in the Add Event dialog // window. function eventAddHandler() { var name = $('quickAddName').value; var description = $('quickAddDescription').value; var dateYmd = $('quickAddDate_YMD').value; var participants = $('quickAddParticipants').value; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> var catObj = $('quickAddCategory'); var category = catObj.options[catObj.selectedIndex].value; <?php } ?> //alert ( 'name: ' + name + '\ndescription: ' + description + // '\ndate: ' + dateYmd + '\ncategory: ' + category ); new Ajax.Request('events_ajax.php', { method:'post', parameters: { action: 'addevent', date: dateYmd, name: name, description: description, participants: participants<?php if ( $CATEGORIES_ENABLED == 'Y' ) { echo ', category: category';} ?> }, onSuccess: function( transport ) { if ( ! transport.responseText ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('no response from server');?>' + ': events_ajax.php?action=addevent' ); return; } //alert ( "Response:\n" + transport.responseText ); try { var response = transport.responseText.evalJSON(); // Hmmm... The Prototype JSON above doesn't seem to work! //var response = eval('(' + transport.responseText + ')'); } catch ( err ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('JSON error');?> - ' + err + "\n\n" + transport.responseText ); return; } if ( response.error ) { alert ( '<?php etranslate('Error');?>: ' + response.message ); return; } // Successfully added :-) //alert('Event added'); // force reload of data. Modalbox.hide (); var monthKey = "" + currentYear + ( currentMonth < 10 ? "0" : "" ) + currentMonth; loadedMonths[monthKey] = 0; ajax_get_events ( currentYear, currentMonth, currentDay ); }, onFailure: function() { alert( '<?php etranslate( 'Error' );?>' ) } }); } // Send the user to a new page where they can create an event with more // advanced options (select other participants, repeating, reminders, etc.) function addEventDetail() { var url = 'edit_entry.php?date=' + $('quickAddDate_YMD').value; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> var catObj = $('quickAddCategory'); var category = catObj.options[catObj.selectedIndex].value; if ( category > 0 ) url += '&cat_id=' + category; <?php } ?> url += '&name=' + escape($('quickAddName').value) + '&desc=' + escape($('quickAddDescription').value); window.location.href = url; return true; } // Callback for the user pressing the "Add Task" button. // Show the "Add Task" popup dialog allowing the user to create a new task. function taskAddPopup () { var today = new Date (); var ymd = "" + ( today.getYear () + 1900 ); if ( today.getMonth() - 1 < 10 ) ymd += '0'; ymd += ( today.getMonth() + 1 ); if ( today.getDate() < 10 ) ymd += '0'; ymd += today.getDate (); Modalbox.show($('taskAddDiv'), {title: '<?php etranslate('Add Task');?>', width: <?php echo $quick_add_width;?>, transitions: false, closeString: '<?php etranslate('Cancel');?>' }); Modalbox.resizeToContent(); $('taskAddName').setAttribute ( 'value', "<?php etranslate('Unnamed Task');?>" ); $('taskAddName').select(); $('taskAddName').focus(); $('taskAddDescription').innerHTML = ""; var dateStr = "" + ( today.getMonth() + 1 ) + "/" + today.getDate() + "/" + ( today.getYear() + 1900 ); //$('taskAddStartDate').setAttribute ( 'value', dateStr ); //$('taskAddDueDate').setAttribute ( 'value', dateStr ); //$('taskAddDateFormatted').innerHTML = format_date ( "" + dateYmd, true ); $('taskAddCategory').selectedIndex = 0; } // Handler for user click the "Save" button in the Add Task dialog // window. function taskAddHandler() { var name = $('taskAddName').value; var description = $('taskAddDescription').value; var startDate = $('task_start_date_YMD').value; var dueDate = $('task_due_date_YMD').value; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> var catObj = $('taskAddCategory'); var category = catObj.options[catObj.selectedIndex].value; <?php } ?> //alert ( 'name: ' + name + '\ndescription: ' + description + // '\ndate: ' + dateYmd + '\ncategory: ' + category ); new Ajax.Request('events_ajax.php', { method:'post', parameters: { action: 'addtask', startdate: startDate, duedate: dueDate, name: name, description: description<?php if ( $CATEGORIES_ENABLED == 'Y' ) { echo ', category: category';} ?> }, onSuccess: function( transport ) { if ( ! transport.responseText ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('no response from server');?>' + ': events_ajax.php?action=addtask' ); return; } //alert ( "Response:\n" + transport.responseText ); try { var response = transport.responseText.evalJSON(); } catch ( err ) { alert ( '<?php etranslate('Error');?>: <?php etranslate('JSON error');?> - ' + err + "\n\n" + transport.responseText ); return; } if ( response.error ) { alert ( '<?php etranslate('Error');?>: ' + response.message ); return; } // Successfully added :-) //alert('Task added'); Modalbox.hide (); // force reload of data. // may need to get tasks when we start showing task due dates // in calendar... //var monthKey = "" + currentYear + ( currentMonth < 10 ? "0" : "" ) + currentMonth; //loadedMonths[monthKey] = 0; //ajax_get_events ( currentYear, currentMonth, currentDay ); loadedTasks = false; ajax_get_tasks (); }, onFailure: function() { alert( '<?php etranslate( 'Error' );?>' ) } }); } // Forget all events, reload events for the current month, and update // the display accordingly. function refresh() { loadedMonths = []; // forget all events... ajax_get_events ( currentYear, currentMonth, currentDay ); } // Build the HTML for the month view function build_month_view ( year, month ) { var ret = ""; //if ( month.substring ( 0, 1 ) == '0' ) // month = month.substring ( 1 ); try { var dateYmd; ret = '<table><tr><td class="aligncenter" width="70%">' + '<table><tr><td width="30%" class="alignright">' + prev_month_link ( year, month ) + '</td><td width="40%" class="aligncenter">' + '<span class="monthtitle">' + months[month-1] + " " + year + "</span>" + '<span id="monthstatus"> </span>' + '</td><td width="30%" class="alignleft">' + next_month_link ( year, month ) + '</td></tr></table>' + '</td><td class="alignright">' + month_view_nav_links ( year, month ) + '</td></tr></table>' + "<table id=\"month_main\" class=\"main\" border=\"1\"><tr>"; for ( var i = 0; i < 7; i++ ) { ret += "<th>" + weekdays[i] + "</th>"; } ret += "</tr>\n"; var d = new Date(); var today = new Date(); d.setYear ( year ); d.setMonth ( month - 1 ); d.setDate ( 1 ); var wday = d.getDay(); var startDay = 1 - wday; var daysThisMonth = ( year % 4 == 0 ) ? leapDaysPerMonth[month] : daysPerMonth[month]; for ( var i = startDay, j = 0; i <= daysThisMonth || j % 7 != 0; i++, j++ ) { if ( j % 7 == 0 ) ret += "<tr>"; if ( i < 1 ) { ret += "<td class=\"othermonth\"> </td>\n"; } else if ( i > daysThisMonth ) { ret += "<td class=\"othermonth\"> </td>\n"; } else { var key = "" + year + ( month < 10 ? "0" : "" ) + month + ( i < 10 ? "0": "" ) + i; var eventArray = events[key]; var className = ( j % 7 == 0 || j % 7 == 6 ) ? 'weekend' : ''; if ( year == ( today.getYear() + 1900 ) && ( month - 1 ) == today.getMonth() && i == today.getDate() ) className = 'today'; // The following two lines will change the cell background to indicate // that there are events on that day. //if ( eventArray && eventArray.length > 0 ) // className += ' entry hasevents'; ret += "<td class=\"" + className + "\""; <?php if ( $can_add ) { ?> ret += " onclick=\"return monthCellClickHandler(" + key + ")\""; <?php } ?> ret += "><span class=\"dayofmonth\">" + '<a href="#" onclick="switchingToDayView=true;ajax_get_events('+year+','+month+','+i+');views.expandit(0);">' + i + "</a></span><br />"; // If eventArray is null here, that means we have not loaded // event data for that date. for ( var l = 0; eventArray && l < eventArray.length; l++ ) { var myEvent = eventArray[l]; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> // See if this event matches selected categories. if ( ! allCatsSelected ) { if ( ! eventMatchesSelectedCats ( myEvent ) ) continue; } <?php } ?> var iconImg = ''; var catColorClass = 'cat_none'; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> if ( categories && categories.length ) { var catId = myEvent._category; if ( catId < 0 ) catId = 0 - catId; if ( categories[catId] && categories[catId].icon ) { iconImg += '<img src="' + categories[catId].icon + '" />'; } if ( categories[catId] && categories[catId].color ) { catColorClass = "cat_" + catId; } } <?php } ?> var id = 'popup-' + key + "-" + myEvent._id; var eventRet = "<div class=\"event clickable " + catColorClass + "\" onmouseover=\"showPopUp(event,'" + id + "')\"" + " onmouseout=\"hidePopUp('" + id + "')\"" + " onclick=\"view_event('" + key + "'," + l + ")\""; //if ( catColor.length ) // eventRet += ' "style=background-color:' + catColor + ';"'; eventRet += ">"; if ( iconImg == '' ) { //eventRet += '<img src="images/event.gif" alt="." />'; } else { eventRet += iconImg; } eventRet += '<span class="eventname">'; // Display time of event if ( myEvent._localTime > 0 ) { eventRet += format_time ( myEvent._localTime, true ); <?php if ( $DISPLAY_END_TIMES == 'Y' ) { ?> eventRet += '-' + format_time ( add_time_duration ( myEvent._localTime, myEvent._duration ), true ); <?php } ?> eventRet += '<?php echo $TIME_SPACER;?>'; } eventRet += myEvent._name; //eventRet += "cat=" + myEvent._category; eventRet += "</span></div>"; ret += month_view_event ( eventRet ); // Create popup if ( ! document.getElementById ( id ) ) { var popup = document.createElement('dl'); popup.setAttribute ( 'id', id ); popup.className = "popup"; popup.innerHTML = "<dt>" + format_description ( myEvent._description ) + "</dt>"; document.body.appendChild ( popup ); } } ret += "</td>\n"; } if ( j % 7 == 6 ) ret += "</tr>\n"; } ret += "</table>\n"; } catch ( err ) { alert ( "JavaScript exception:\n" + err ); } return ret; } // Right now this doesn't do much. We may use it in the future to // add rounded corners. Most I've tried don't work well in this layout :-( // Most rounded corner implementations want static content 8-( function month_view_event ( content ) { return content; } // Build the HTML for the year view. // Right now we are just showing dates and no event info. // We may add event info later, but I'm not sure I want to ask for a year's // worth of events for every user every time the come to the combo.php page. // That could have some significant performance implications. function build_year_view ( year, month ) { var ret = ""; try { var dateYmd; ret = prev_year_link ( year, month ) + next_year_link ( year, month ) + "<span id=\"refresh\" class=\"clickable fakebutton noprint\" onclick=\"refresh()\">" + '<img src="images/combo-refresh.png" style="vertical-align: middle;" alt="<?php etranslate('Refresh');?>" /></span>' + today_link() + " " + "<span class=\"yeartitle\">" + year + "</span>" + "<span id=\"yearstatus\"> </span>" + "<table id=\"year_main\" class=\"main\">"; var d = new Date(); var today = new Date(); d.setYear ( year ); for ( var n = 0; n < 12; n++ ) { if ( n % 4 == 0 ) ret += "<tr>"; ret += "<td class=\"monthblock aligntop aligncenter\" width=\"25%\">"; ret += '<a href="#" onclick="ajax_get_events('+year+','+(n+1)+',1);views.expandit(2);">' + months[n] + "</a><br/>\n"; ret += "<table class=\"monthtable\">"; d.setMonth ( n ); month = n + 1; d.setDate ( 1 ); var wday = d.getDay(); var startDay = 1 - wday; var daysThisMonth = ( year % 4 == 0 ) ? leapDaysPerMonth[month] : daysPerMonth[month]; ret += "<tr>\n"; for ( var i = 0; i < 7; i++ ) { ret += "<th>" + shortWeekdays[i] + "</th>"; } ret += "</tr>\n"; for ( var i = startDay, j = 0; i <= daysThisMonth || j % 7 != 0; i++, j++ ) { if ( j % 7 == 0 ) ret += "<tr>"; if ( i < 1 ) { ret += "<td class=\"empty dom\"> </td>\n"; } else if ( i > daysThisMonth ) { ret += "<td class=\"empty dom\"> </td>\n"; } else { ret += "<td class=\"dom\">" + i + "</td>"; } if ( j % 7 == 6 ) ret += "</tr>\n"; } ret += "</table>\n"; ret += "</td>\n"; if ( n % 4 == 3 ) ret += "</tr>\n"; } ret += "</table>\n"; } catch ( err ) { alert ( "JavaScript exception:\n" + err ); } return ret; } // Build the HTML for the Agenda view // This will display a list of all events for the specified month. // We may want to adopt the google calendar approach where we display // just events from today forward and give them the option to load months // further into the future with a "More events" button at the bottom. function build_agenda_view ( year, month ) { var ret = ""; try { ret = prev_month_link ( year, month ) + next_month_link ( year, month ) + prev_year_link ( year, month ) + next_year_link ( year, month ) + "<span id=\"refresh\" class=\"clickable fakebutton noprint\" onclick=\"refresh()\">" + '<img src="images/combo-refresh.png" style="vertical-align: middle;" alt="<?php etranslate('Refresh');?>" /></span>' + today_link() + " " + "<span class=\"monthtitle\">" + months[month-1] + " " + year + "</span>" + "<span id=\"agendastatus\"> </span>" + "<table>\n"; var d = new Date(); var today = new Date(); d.setYear ( year ); d.setMonth ( month - 1 ); d.setDate ( 1 ); var wday = d.getDay(); var startDay = 1 - wday; var daysThisMonth = ( year % 4 == 0 ) ? leapDaysPerMonth[month] : daysPerMonth[month]; var cnt = 0; for ( var i = 0; i < daysThisMonth; i++ ) { var key = "" + year + ( month < 10 ? "0" : "" ) + month + ( i < 10 ? "0": "" ) + i; var dateYmd = key + ( i < 10 ? "0" : "" ) + i; var eventArray = events[key]; var className = cnt % 2 == 0 ? 'even' : 'odd'; var leadIn = ''; if ( eventArray && eventArray.length > 0 ) { if ( year == ( today.getYear() + 1900 ) && ( month - 1 ) == today.getMonth() && i == today.getDate() ) className += ' today'; if ( eventArray && eventArray.length > 0 ) className += ' entry hasevents'; className += " clickable"; leadIn += "<td class=\"aligntop alignright\"" + className + "\""; <?php if ( $can_add ) { ?> leadIn += ' title="<?php etranslate('Click to add entry');?>" ' + " onclick=\"return monthCellClickHandler(" + dateYmd + ")\""; <?php } ?> leadIn += ">" + format_date ( dateYmd, true ) + "</td>\n" + "<td class=\"aligntop " + className + "\">"; for ( var l = 0; eventArray && l < eventArray.length; l++ ) { var myEvent = eventArray[l]; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> // See if this event matches selected categories. if ( ! allCatsSelected ) { if ( ! eventMatchesSelectedCats ( myEvent ) ) continue; } <?php } ?> var id = 'popup-' + key + "-" + myEvent._id; ret += leadIn + "<div class=\"event clickable\" onmouseover=\"showPopUp(event,'" + id + "')\"" + " onmouseout=\"hidePopUp('" + id + "')\"" + " onclick=\"view_event('" + key + "'," + l + ")\">"; if ( leadIn != '' ) cnt++; leadIn = ''; var iconImg = ''; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> if ( categories && categories.length ) { var catId = myEvent._category; if ( catId < 0 ) catId = 0 - catId; if ( categories[catId] && categories[catId].icon ) { iconImg += '<img src="' + categories[catId].icon + '" />'; } } <?php } ?> if ( iconImg == '' ) { ret += '<img src="images/event.gif" alt="." />'; } else { ret += iconImg; } ret += myEvent._name + "</div>"; // Create popup if ( ! document.getElementById ( id ) ) { var popup = document.createElement('dl'); popup.setAttribute ( 'id', id ); popup.className = "popup"; popup.innerHTML = "<dt>" + format_description ( myEvent._description ) + "</dt>"; document.body.appendChild ( popup ); } } ret += "</td></tr>\n"; } } ret += "</table>\n"; } catch ( err ) { alert ( "JavaScript exception:\n" + err ); } return ret; } // Callback handler for the user clicking on the column header in the task // table. If it is a new column, sort asc/desc dependent on the column type // (see below). If same column, toggle between ascending and descending. function task_sort_handler ( col ) { if ( taskSortCol != col ) { if ( col == SORT_BY_DUE_DATE || col == SORT_BY_NAME || col == SORT_BY_CATEGORY ) taskSortAsc = true; else taskSortAsc = false; } else { taskSortAsc = ! taskSortAsc; } taskSortCol = col; build_task_view (); } // Emulate the C strcmp function (and why doesn't JavaScript have a // strcmp function???) Lame, lame, lame... // -1 if string1 comes first, 1 if string2 comes first, 0 if equal function strcmp ( string1, string2 ) { // Handle null values first if ( string1 == null && string2 == null ) return 0; if ( string1 == null ) return -1; else if ( string2 == null ) return 1; // Compare non-null values var str1 = string1.toLowerCase (); var str2 = string2.toLowerCase (); if ( str1 == str2 ) return 0; for ( var i = 0; i < str1.length && i < str2.length; i++ ) { if ( str1.charAt ( i ) < str2.charAt ( i ) ) return -1; else if ( str1.charAt ( i ) > str2.charAt ( i ) ) return 1; } if ( str1.length < str2.length ) return -1; else if ( str1.length > str2.length ) return 1; // Shouldn't ever reach here... alert ( 'strcmp bug! string1= "' + str1 + '", string2= "' + str2 + '"' ); } function intcmp ( int1, int2 ) { if ( int1 == int2 ) return 0; if ( int1 < int2 ) return -1; else return 1; } // Compare two tasks (used to sort tasks). function compare_tasks ( task1, task2 ) { if ( taskSortCol == SORT_BY_NAME ) { if ( taskSortAsc ) { return strcmp ( task1._name, task2._name ); } else { return strcmp ( task2._name, task1._name ); } } else if ( taskSortCol == SORT_BY_DUE_DATE ) { if ( taskSortAsc ) { return intcmp ( task1._dueDate, task2._dueDate ); } else { return intcmp ( task2._dueDate, task1._dueDate ); } } else if ( taskSortCol == SORT_BY_PRIORITY ) { if ( taskSortAsc ) { return intcmp ( task2._priority, task1._priority ); } else { return intcmp ( task1._priority, task2._priority ); } } else if ( taskSortCol == SORT_BY_CATEGORY ) { if ( taskSortAsc ) { return intcmp ( task1._category, task2._category ); } else { return intcmp ( task2._category, task1._category ); } } } // Build the HTML for the Task view function build_task_view () { // Sort tasks first tasks.sort ( compare_tasks ); var img = ['sort-none', 'sort-none', 'sort-none', 'sort-none']; img[taskSortCol] = ( taskSortAsc ? 'sort-up' : 'sort-down' ); var content = '<tr><th class="clickable" onclick="task_sort_handler(0)"><?php etranslate('Name');?><img src="images/' + img[0] + '.png"/></th>' + '<th class="clickable" onclick="task_sort_handler(1)"><?php etranslate('Due Date');?><img src="images/' + img[1] + '.png"/></th>' + '<th class="clickable" onclick="task_sort_handler(2)"><?php etranslate('Priority');?><img src="images/' + img[2] + '.png"/></th>' + '<th class="clickable" onclick="task_sort_handler(3)"><?php etranslate('Category');?><img src="images/' + img[3] + '.png"/></th>' + '</tr>' + "\n"; for ( var i = 0; i < tasks.length; i++ ) { var task = tasks[i]; if ( ! tasks[i] || ! tasks[i]._name ) continue; var iconImg = ''; var catId = task._category; if ( catId && catId > 0 && categories[catId] && categories[catId].icon ) { iconImg += '<img src="' + categories[catId].icon + '" />'; } var cl = ( i % 2 == 0 ) ? 'even' : 'odd'; content += '<tr><td class="' + cl + '">' + iconImg + task._name + '</td><td class="' + cl + '">' + format_date ( task._dueDate, false ) + '</td><td class="' + cl + '">'; if ( task._priority < 4 ) content += '<?php etranslate('High');?>'; else if ( task._priority < 7 ) content += '<?php etranslate('Medium');?>'; else content += '<?php etranslate('Low');?>'; content += '</td><td class="' + cl + '">'; var catId = task._category; if ( catId < 0 ) catId = 0 - catId; if ( catId == 0 ) { content += " "; } else { if ( categories[catId] ) content += categories[catId].name; else content += "Unknown category (" + catId + ")"; } content += '</td></tr>' + "\n"; } $('tasktable').innerHTML = content; // some test code for testing the strcmp function. //alert ( 'strcmp(AAA,BBB) = ' + strcmp('AAA','BBB' ) + "\n" + // 'strcmp(BBB,AAA) = ' + strcmp('BBB','AAA' ) + "\n" + // 'strcmp(abc,ABC) = ' + strcmp('abc','ABC' ) + "\n" + // 'strcmp(B,AAA) = ' + strcmp('B','A' ) + "\n" + // 'strcmp(BBB,aaa) = ' + strcmp('BBB','aaa' ) + "\n" + // 'strcmp(20100801,20110801) = ' + strcmp('20100801','20110801' ) + "\n" + // 'strcmp(ABC,DEF) = ' + strcmp('ABC','DEF' ) + "\n" ); } // Build the HTML for the Day view // TODO: Handle events that overlap. Right now, they will just cover // each other up. function build_day_view ( year, month, day ) { var ret = ""; var dateYmd = year + ( month < 10 ? "0" : "" ) + month + ( day < 10 ? "0" : "" ) + day; var eventArray = events[dateYmd]; try { ret = prev_day_link ( year, month, day ) + next_day_link ( year, month, day ) + prev_month_link_dayview ( year, month, day ) + next_month_link_dayview ( year, month, day ) + "<span id=\"refresh\" class=\"clickable fakebutton noprint\" onclick=\"refresh()\">" + '<img src="images/combo-refresh.png" style="vertical-align: middle;" alt="<?php etranslate('Refresh');?>" /></span>' + today_link() + " " + "<span class=\"daytitle\">" + format_date ( dateYmd, true ) +"</span>" + "<span id=\"daystatus\"> </span>"; var untimedEvents = ''; var timedEvents = ''; for ( var l = 0; eventArray && l < eventArray.length; l++ ) { var myEvent = eventArray[l]; var isTimed = ( myEvent._time >= 0 ); var thisEvent = ''; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> // See if this event matches selected categories. if ( ! allCatsSelected ) { if ( ! eventMatchesSelectedCats ( myEvent ) ) continue; } <?php } ?> var id = 'popup-' + dateYmd + "-" + myEvent._id; thisEvent += "<div class=\"event clickable" + ( isTimed ? " daytimedevent" : "" ) + "\" onmouseover=\"showPopUp(event,'" + id + "')\"" + " onmouseout=\"hidePopUp('" + id + "')\"" + " onclick=\"view_event('" + dateYmd + "'," + l + ")\""; var pos = '0'; if ( isTimed ) { // TODO: handle overlapping events. Right now, the <div> // areas will overlap, possibly obscuring each other. // Would be nice to allow mouse-over to raise the z-index to // the top and have conflicting events shifted 50 pixels to // the right so we could always mouse over some part of the <div>. var mins = myEvent._localTime % 100; var y = ( ( myEvent._localTime - mins ) / 100 ) * 50; y += ( mins / 60 ) * 50; thisEvent += " style=\"position: absolute; left: 52px; top: " + y + "px;"; if ( myEvent._duration > 0 ) { var h = ( myEvent._duration / 60 ) * 50; h = Math.ceil ( h ) - 2; // subtract 2 for border thisEvent += " height: " + h + "px;"; } thisEvent += "\""; } thisEvent += ">"; var iconImg = ''; <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> if ( categories && categories.length ) { var catId = myEvent._category; if ( catId < 0 ) catId = 0 - catId; if ( categories[catId] && categories[catId].icon ) { iconImg += '<img src="' + categories[catId].icon + '" />'; } } <?php } ?> if ( iconImg == '' ) { thisEvent += '<img src="images/event.gif" alt="." />'; } else { thisEvent += iconImg; } thisEvent += myEvent._name + "</div>"; // Create popup if ( ! document.getElementById ( id ) ) { var popup = document.createElement('dl'); popup.setAttribute ( 'id', id ); popup.className = "popup"; popup.innerHTML = "<dt>" + format_description ( myEvent._description ) + "</dt>"; document.body.appendChild ( popup ); } if ( isTimed ) { // timed event timedEvents += thisEvent; } else { // Untimed event untimedEvents += thisEvent; } } if ( untimedEvents != '' ) { ret += "<div id=\"dayuntimed\">" + untimedEvents + "</div>\n"; } ret += "<div id=\"daydiv\">\n" + "<div id=\"dayinnerdiv\">"; for ( var h = 0; h < 24; h++ ) { var y = h * 50; ret += "<div class=\"hourblockleft\" style=\"top: " + y + "px;\">" + "<span class=\"timeofday\">"; if ( h == 0 ) ret += "12am"; else if ( h < 12 ) ret += h + "am"; else if ( h == 12 ) ret += "12pm"; else ret += ( h - 12 ) + "pm"; ret += "</span></div>\n"; ret += "<div class=\"hourblockright\" style=\"top: " + y + "px;\"></div>"; } // Now add in event info... ret += timedEvents; // End event info ret += "</div>\n</div>\n"; } catch ( err ) { alert ( "JavaScript exception:\n" + err ); } return ret; } <?php if ( $CATEGORIES_ENABLED == 'Y' ) { ?> // Does the specified event match the list of currently selected categories? function eventMatchesSelectedCats ( event ) { if ( ! event._categories || event._categories.length == 0 ) return false; for ( var i = 0; i < event._categories.length; i++ ) { var catId = event._categories[i]; if ( isInArray ( catId, selectedCats ) ) { return true; } } return false; } // Convenience function... function isInArray ( val, searchArr ) { for ( var i = 0; i < searchArr.length; i++ ) { if ( searchArr[i] == val ) return true; } return false; } <?php } ?> function getUserSuggestion ( str ) { var ret = []; var cnt = 0; for ( var i = 0; i < userLogins.length; i++ ) { if ( userLogins[i].match(/str/i) ) { ret[cnt++] = userLogins[i]; } } return ret; } // This function mimics the date_to_str PHP function found in // includes/functions.php. function format_date ( dateStr, showWeekday ) { var fmt = '<?php echo $DATE_FORMAT;?>'; var y = dateStr.substr ( 0, 4 ); var m = dateStr.substr ( 4, 2 ); var d = dateStr.substr ( 6, 2 ); var ret = fmt; ret = ret.replace ( /__dd__/, d ); ret = ret.replace ( /__j__/, d ); ret = ret.replace ( /__mm__/, m ); ret = ret.replace ( /__mon__/, shortMonths[m-1] ); ret = ret.replace ( /__month__/, months[m-1] ); ret = ret.replace ( /__n__/, m ); ret = ret.replace ( /__yy__/, y % 100 ); ret = ret.replace ( /__yyyy__/, y ); var w = ''; if ( showWeekday ) { var myD = new Date(); myD.setYear ( y ); myD.setMonth ( m - 1 ); myD.setDate ( d ); wday = myD.getDay(); w = weekdays[wday] + ', '; } return w + ret; } // TODO: modify this to handle different time formats, timezones, etc... // The code for different timezones could get ugly here... // This is assumed to be the current local time in "HHMMSS" or "HHMM" format. function format_time ( timeStr, abbreviate ) { if ( timeStr < 0 ) return ''; var h = timeStr.substr ( 0, 2 ); var m = timeStr.substr ( 2, 2 ); var ret; <?php if ( $TIME_FORMAT == '12' ) { ?> if ( h < 0 ) h += 24; var ampm = ( h >= 12 ? '<?php etranslate('pm')?>' : '<?php etranslate('am')?>' ); h %= 12; if ( h == 0 ) h = 12; if ( m == 0 && abbreviate ) ret = h + ampm; else ret = h + ':' + m + ampm; <?php } else { ?> ret = h + ':' + m; <?php } ?> return ret; } // Take a HHMM formatted time and add the specified duration (in minutes) // Return time in HHMM format function add_time_duration ( timeStr, duration ) { if ( timeStr < 0 ) return ''; var h = timeStr.substr ( 0, 2 ); var m = timeStr.substr ( 2, 2 ); while ( duration > 60 ) { h++; duration -= 60; } m += duration; if ( m >= 60 ) { h++; m -= 60; } if ( h >= 24 ) h -= 24; var ret = ''; if ( h < 10 ) ret = '0'; ret += "" + h; if ( m < 10 ) ret += "0"; ret += "" + m; return ret; } function format_description ( desc ) { var ret; <?php if ( ! empty ( $ALLOW_HTML_DESCRIPTION ) && $ALLOW_HTML_DESCRIPTION == 'Y' ) { ?> // HTML is allowed in description if ( desc.indexOf ( '<' ) >= 0 ) { ret = desc; } else { // No HTML found, replace \n with line breaks ret = desc.replace (/\n/g,"<br />"); } <?php } else { ?> // HTML not allowed in description // TODO: convert URLs into active links ret = desc.replace (/\n/g,"<br />"); <?php } ?> return ret; } </script> <?php echo print_trailer(); ?> PK �]�\4�� tools/upgrade_to_0.9.7.plnu ȯ�� #!/usr/local/bin/perl # # This script will update a pre-0.9.7 WebCalendar database to have the # correct tables for 0.9.7. # (FYI, these changes were necessary to add support for other databases # like Oracle.) # $mysql_path = "/usr/local/mysql/bin:/opt/mysql/bin"; $dbname = "intranet"; $tables = "cal_entry cal_entry_user cal_user cal_user_pref"; $out = "commands.sql"; # look for the mysql executable and mysqldump programs sub find_executable { my ( $app ) = @_; my ( $path, $dir, $file, @dirs ); my ( $path ) = $ENV{"PATH"} . ":" . $mysql_path; @dirs = split ( /:/, $path ); foreach $dir ( @dirs ) { $file = "$dir/$app"; return $file if ( -x $file ); } die "Could not find $app executable in:\n$path\n"; } sub string_or_null { my ( $in ) = @_; my ( $ret ); if ( $in eq "\\N" || length ( $in ) == 0 ) { $ret = "NULL"; } else { $in =~ s/'/\\'/g; $ret = "\'$in\'"; } return $ret; } sub num_or_zero { my ( $in ) = @_; return "NULL" if ( $in eq "\\N" ); return "0" if ( $in eq "" ); return $in; } sub date_to_int { my ( $in ) = @_; my ( $ret ); if ( $in =~ /(\d\d\d\d)-(\d\d)-(\d\d)/ ) { $ret = sprintf "%04d%02d%02d", $1, $2, $3; } else { $ret = "NULL"; } #print STDERR "Date \"$in\" -> $ret\n"; return $ret; } sub time_to_int { my ( $in ) = @_; my ( $ret ); if ( $in =~ /(\d\d):(\d\d):(\d\d)/ ) { $ret = sprintf "%02d%02d%02d", $1, $2, $3; } else { $ret = "NULL"; } #print STDERR "Time \"$in\" -> $ret\n"; return $ret; } $mysql = &find_executable ( "mysql" ); $mysqldump = &find_executable ( "mysqldump" ); print "mysql found: $mysql\n"; print "mysqldump found: $mysqldump\n"; # Get a current dump of the db $dir = "./data"; mkdir ( $dir, 0755 ) if ( ! -d $dir ); $cmd = "$mysqldump --no-create-info -T $dir $dbname $tables"; print "Command: $cmd\n"; system ( $cmd ); # use datafiles to create a series of SQL Insert commands open ( OUT, ">$out" ) || die "Error writing output file: $!\n"; print OUT<<EOF; #DROP TABLE webcal_user; CREATE TABLE webcal_user ( cal_login VARCHAR(25) NOT NULL, cal_passwd VARCHAR(25), cal_lastname VARCHAR(25), cal_firstname VARCHAR(25), cal_is_admin CHAR(1) DEFAULT 'N', cal_email VARCHAR(75) NULL, PRIMARY KEY ( cal_login ) ); #DROP TABLE webcal_entry; CREATE TABLE webcal_entry ( cal_id INT NOT NULL, cal_group_id INT NULL, cal_create_by VARCHAR(25) NOT NULL, cal_date INT NOT NULL, cal_time INT NULL, cal_mod_date INT, cal_mod_time INT, cal_duration INT NOT NULL, cal_priority INT DEFAULT 2, cal_type CHAR(1) DEFAULT 'E', cal_access CHAR(1) DEFAULT 'P', cal_name VARCHAR(80) NOT NULL, cal_description TEXT, PRIMARY KEY ( cal_id ) ); #DROP TABLE webcal_entry_user; CREATE TABLE webcal_entry_user ( cal_id int(11) DEFAULT '0' NOT NULL, cal_login varchar(25) DEFAULT '' NOT NULL, cal_status char(1) DEFAULT 'A', PRIMARY KEY (cal_id,cal_login) ); #DROP TABLE webcal_user_pref; CREATE TABLE webcal_user_pref ( cal_login varchar(25) NOT NULL, cal_setting varchar(25) NOT NULL, cal_value varchar(50) NULL, PRIMARY KEY ( cal_login, cal_setting ) ); EOF open ( IN, "$dir/cal_user.txt" ); print OUT "\n\n\n"; while ( <IN> ) { chop; @fields = split /\t/; print OUT "INSERT INTO webcal_user ( cal_login, cal_passwd, cal_lastname,\n" . "cal_firstname, cal_is_admin )\n VALUES ( "; print OUT &string_or_null ( $fields[0] ) . ", "; print OUT &string_or_null ( $fields[1] ) . ", "; print OUT &string_or_null ( $fields[2] ) . ", "; print OUT &string_or_null ( $fields[3] ) . ", "; print OUT &string_or_null ( $fields[4] ) . " );\n"; } close ( IN ); open ( IN, "$dir/cal_entry.txt" ); print OUT "\n\n\n"; while ( <IN> ) { chop; while ( /\\$/ ) { s/[\\\r\n]+$//g; chop ( $nextline = <IN> ); $nextline =~ s/[\\\r\n]+$//g; $_ .= "\\n" . $nextline; } @fields = split /\t/; $i = 0; print OUT "\nINSERT INTO webcal_entry\n" . " ( cal_id, cal_group_id, cal_create_by,\n" . " cal_date, cal_time, cal_mod_date, cal_mod_time, cal_duration,\n" . " cal_priority, cal_type, cal_access, cal_name,\n" . " cal_description )\n VALUES (\n "; print OUT &num_or_zero ( $fields[$i++] ) . ", "; #cal_id print OUT "NULL, "; #cal_group_id print OUT &string_or_null ( $fields[$i++] ) . ", "; #cal_create_by print OUT &date_to_int ( $fields[$i++] ) . ", "; #cal_date print OUT &time_to_int ( $fields[$i++] ) . ", "; #cal_time print OUT &date_to_int ( $fields[$i] ) . ", "; #cal_mod_date print OUT &time_to_int ( $fields[$i++] ) . ", "; #cal_mod_time print OUT &num_or_zero ( $fields[$i++] ) . ", "; #cal_duration print OUT &string_or_null ( $fields[$i++] ) . ", "; #cal_priority print OUT &string_or_null ( $fields[$i++] ) . ", "; #cal_type print OUT &string_or_null ( $fields[$i++] ) . ", "; #cal_access $i++; # skip over status since it was never used print OUT &string_or_null ( $fields[$i++] ) . ", "; #cal_name print OUT &string_or_null ( $fields[$i++] ) . ");\n"; #cal_description } close ( IN ); open ( IN, "$dir/cal_entry_user.txt" ); print OUT "\n\n\n"; while ( <IN> ) { chop; @fields = split /\t/; print OUT "INSERT INTO webcal_entry_user\n" . "( cal_id, cal_login, cal_status )\n" . "VALUES ( "; $i = 0; print OUT &num_or_zero ( $fields[$i++] ) . ", "; print OUT &string_or_null ( $fields[$i++] ) . ", "; print OUT &string_or_null ( $fields[$i++] ) . " );\n"; } close ( IN ); open ( IN, "$dir/cal_user_pref.txt" ); print OUT "\n\n\n"; while ( <IN> ) { chop; @fields = split /\t/; print OUT "INSERT INTO webcal_user_pref\n" . "( cal_login, cal_setting, cal_value )\n" . "VALUES ( "; $i = 0; print OUT &string_or_null ( $fields[$i++] ) . ", "; print OUT &string_or_null ( $fields[$i++] ) . ", "; print OUT &string_or_null ( $fields[$i++] ) . " );\n"; } close ( IN ); close ( OUT ); exit 0; PK �]�\Fbq� � tools/summary.txtnu �[��� Language file No. missing translations Afrikaans.txt: 1343 ( 4.1% complete) Albanian.txt: 1349 ( 3.7% complete) Arabic_utf8.txt: 1352 ( 3.5% complete) Bahasa_Indonesia.txt: 820 (41.5% complete) Basque.txt: 1001 (28.6% complete) Bulgarian.txt: 967 (31.0% complete) Catalan.txt: 848 (39.5% complete) Chinese-Big5.txt: 1198 (14.5% complete) Chinese-GB2312.txt: 950 (32.2% complete) Croatian_utf8.txt: 1370 ( 2.2% complete) Czech.txt: 851 (39.3% complete) Czech_utf8.txt: 823 (41.3% complete) Danish.txt: 783 (44.1% complete) Dutch.txt: 238 (83.0% complete) Elven.txt: 1317 ( 6.0% complete) English-US.txt: 15 (98.9% complete) Estonian.txt: 972 (30.6% complete) Finnish.txt: 855 (39.0% complete) French-UTF8.txt: 786 (43.9% complete) French.txt: 51 (96.4% complete) Galician.txt: 1151 (17.8% complete) German.txt: 13 (99.1% complete) German_utf8.txt: 13 (99.1% complete) Greek.txt: 113 (91.9% complete) Hebrew_utf8.txt: 394 (71.9% complete) Holo-Big5.txt: 1120 (20.1% complete) Hungarian.txt: 507 (63.8% complete) Icelandic.txt: 1183 (15.6% complete) Italian.txt: 47 (96.6% complete) Japanese-eucjp.txt: 317 (77.4% complete) Japanese-sjis.txt: 329 (76.5% complete) Japanese.txt: 358 (74.4% complete) Korean.txt: 1229 (12.3% complete) Lithuanian.txt: 1351 ( 3.6% complete) Norwegian.txt: 436 (68.9% complete) Polish-utf8.txt: 144 (89.7% complete) Polish.txt: 128 (90.9% complete) Portuguese.txt: 855 (39.0% complete) Portuguese_BR.txt: 804 (42.6% complete) Portuguese_BR_utf8.txt: 136 (90.3% complete) Romanian.txt: 796 (43.2% complete) Russian.txt: 314 (77.6% complete) Russian_utf8.txt: 316 (77.4% complete) Serbian_utf8.txt: 1350 ( 3.6% complete) Slovak_utf8.txt: 1352 ( 3.5% complete) Slovenian.txt: 1349 ( 3.7% complete) Spanish.txt: 791 (43.5% complete) Swedish.txt: 813 (42.0% complete) Turkish.txt: 1185 (15.4% complete) Welsh.txt: 1015 (27.6% complete) PK �]�\ �g� � tools/translation_summary.plnu ȯ�� #!/usr/bin/perl # # Examine all translation files to create a report that shows how # many translations are missing from each translation file. # # Usage: # perl translation_summary.pl # ####################################################################### $transdir = '../translations'; opendir ( DIR, $transdir ) || die 'Error opening ' . "$transdir: $!"; # We only want *.txt files, sorted. @files = grep ( /txt$/i, sort readdir ( DIR ) ); closedir ( DIR ); # header printf "%-25s %s\n", 'Language file', 'No. missing translations'; foreach $f ( @files ) { $out = `perl check_translation.pl $transdir/$f`; if ( $out =~ / missing./ ) { # missing some translations @lines = split ( /\n/, $out ); ( $l ) = grep ( / translation.s. missing/, @lines ); if ( $l =~ /^(\d+).*\((\d\S+)% complete/ ) { printf "%-25s %4d (%4.1f%% complete)\n", $f . ':', $1, $2; } } else { # all translations found :-) printf "%-25s %s\n", $f . ':', 'Complete'; } } PK �]�\l�*�M M tools/check_translation.plnu ȯ�� #!/usr/bin/perl # $Id: check_translation.pl,v 1.21 2007/04/09 14:52:30 bbannon Exp $ # # This tool helps with the translation into other languages by indicating # whether all text specified in translate() and tooltip() within the application # has a corresponding entry in the translation data file. # # Usage: # check_translation.pl languagefile # ... or to check the most recently modified translation file # check_translation.pl # # Example: # check_translation.pl ../translations/English-US.txt # # Note: this utility should be run from this directory (tools). # ########################################################################### use File::Find; sub find_pgm_files { # Skipping non WebCalendar plugins, # if the filename ends in .class or .php, add it to @files. push( @files, "$File::Find::name" ) if ( $_ =~ /\.(class|php)$/i && $File::Find::dir !~ /(fckeditor|htmlarea|phpmailer)/i ); } $trans_dir = '../translations'; $infile = $ARGV[0]; if ( $infile eq '' ) { opendir( DIR, $trans_dir ) || die 'error opening ' . $trans_dir; @files = grep ( /\.txt$/, readdir(DIR) ); closedir(DIR); $last_mtime = 0; foreach $f (@files) { ($mtime) = ( stat("$trans_dir/$f") )[9]; if ( $mtime > $last_mtime ) { $last_mtime = $mtime; $infile = "$trans_dir/$f"; } } } if ( $infile ne '' && !-f $infile ) { if ( -f "$trans_dir/$infile" ) { $infile = "$trans_dir/$infile"; } else { $infile = "$trans_dir/$infile.txt"; } } @files = (); # First get the list of .class and .php files. find \&find_pgm_files, '..'; foreach $f (@files) { open( F, $f ) || die 'Error reading ' . $f; #print "Checking $f for text.\n"; while (<F>) { $data = $_; while ( $data =~ /(translate|tooltip)\s*\(\s*['"]/ ) { $data = $'; if ( $data =~ /['"]\s*[,\)]/ ) { $text = $`; $text{$text} = 1; $data = $'; } } } close(F); } #print "Found the following entries:\n"; #foreach $text ( sort { uc($a) cmp uc($b) } keys ( %text ) ) { # print "$text\n"; #} # Now load the translation file if ( !-f $infile ) { die "Usage: $0 translation-file\n"; } open( F, $infile ) || die 'Error opening ' . $infile; while (<F>) { chop; next if (/^#/); if (/\s*:/) { $abbrev = $`; $trans{$abbrev} = $'; } } $notfound = $total = 0; foreach $text ( sort { uc($a) cmp uc($b) } keys(%text) ) { if ( !defined( $trans{$text} ) ) { # if ( !$notfound ) { # print "The following text did not have a translation in $infile:\n\n"; # } # print "$text\n"; $notfound++; } $total++; } # Check for translations that are not used... $extra = 0; foreach $text ( sort { uc($a) cmp uc($b) } keys(%trans) ) { if ( !defined( $text{$text} ) ) { # if ( !$extra ) { # print "\nThe following translation text is not needed in $infile:\n\n"; # } # print "$text\n"; $extra++; } } if ( !$notfound ) { print "All text was found in $infile. Good job :-)\n"; } else { printf "\n$notfound of $total translation(s) missing. (%2.1f%% complete)\n", ( 100 * ( $total - $notfound ) / $total ); } exit 0; PK �]�\iWȾ� � tools/convert_passwords.phpnu �[��� #!/usr/local/bin/php -q <?php /** * This script will alter the webcal_user table to allow 32 character passwords * and convert user passwords to PHP md5 passwords. * * It is necessary to run this to upgrade to version 0.9.43 from any version. * * * ** NOTE: This script should only be run ONCE and then be deleted!! * */ /********************************************************************/ define ( '__WC_INCLUDEDIR', '../includes' ); require_once __WC_INCLUDEDIR . '/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include __WC_INCLUDEDIR . '/config.php'; include __WC_INCLUDEDIR . '/dbi4php.php'; $WebCalendar->initializeFirstPhase(); $WebCalendar->initializeSecondPhase(); $c = dbi_connect ( $db_host, $db_login, $db_password, $db_database ); if ( ! $c ) { echo "Error connecting to database: " . dbi_error(); exit; } // First, look at the passwords. If we find and md5 hash in there, // (it will have 32 chars instead of < 25 like in the old version), // then we know this script was already run. $sql = "SELECT cal_passwd FROM webcal_user"; $res = dbi_execute ( $sql ); $doneBefore = false; if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { if ( strlen ( $row[0] ) > 30 ) $doneBefore = true; } dbi_free_result ( $res ); } else { echo "Database error: " . dbi_error(); exit; } if ( $doneBefore ) { echo "Passwords were already converted to md5!\n<br />\n"; exit; } // See if webcal_user.cal_passwd will allow 32 characters $sql = "DESC webcal_user"; $res = dbi_execute ( $sql ); while ( $row = dbi_fetch_row ( $res ) ) { if ($row[Field] == 'cal_passwd') { preg_match ( "/([0-9]+)/", $row[Type], $match ); if ($match[1] < 32) { $sql = "ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR(32) NULL"; // Use the following on older MySQL versions //$sql = "ALTER TABLE webcal_user CHANGE cal_passwd cal_passwd VARCHAR(32) NULL"; $res = dbi_execute ( $sql ); if ($res) { echo "Table webcal_user altered to allow 32 character passwords.\n" . "<br />Converting passwords...\n<br /><br />\n"; } } } } dbi_free_result ( $res ); // Convert the passwords $sql = "SELECT cal_login, cal_passwd FROM webcal_user"; $res = dbi_execute ( $sql ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $sql2 = "UPDATE webcal_user SET cal_passwd = ? WHERE cal_login = ?"; $res2 = dbi_execute ( $sql2, [md5 ( $row[1] ), $row[0]] ); if ($res2) echo "Password updated for: ".$row[0]."<br />\n"; } dbi_free_result ( $res ); echo "Finished converting passwords\n<br />\n"; echo "<br /><br />\n<h1>DO NOT Run this script again!!!</h1>\n<br />\n"; echo '<h1>Delete this script if it ran successfully!!!</h1>'; } ?> PK �]�\���q9] 9] tools/send_reminders.phpnu �[��� #!/usr/local/bin/php -q <?php /** * Description: * This is a command-line script that will send out any email * reminders that are due. * * Usage: * php send_reminders.php * * Setup: * This script should be setup to run periodically on your system. You could run * it once every minute, but every 5-15 minutes should be sufficient. * * To set this up in cron, add a line like the following in your crontab * to run it every 10 minutes: * 1,11,21,31,41,51 * * * * php /some/path/here/send_reminders.php * Of course, change the path to where this script lives. If the php binary is * not in your $PATH, you may also need to provide the full path to "php". * On Linux, just type crontab -e to edit your crontab. * * If you're a Windows user, you'll either need to find a cron clone * for Windows (they're out there) or use the Windows Task Scheduler. * (See docs/WebCalendar-SysAdmin.html for instructions.) * * Comments: * You will need access to the PHP binary (command-line) rather than * the module-based version that is typically installed for use with * a web server.to build as a CGI (rather than an Apache module) for * * If running this script from the command line generates PHP * warnings, you can disable error_reporting by adding * "-d error_reporting=0" to the command line: * php -d error_reporting=0 /some/path/here/tools/send_reminders.php * *********************************************************************/ // How many days in advance can a reminder be sent (max)? // This will affect performance, but keep in mind that someone may enter // a reminder to be sent 60 days in advance or they may enter a specific // date for a reminder to be sent that is more than 30 days before the // event's date. If you're only running this once an hour or less often, // then you could certainly change this to look a whole 365 days ahead. $DAYS_IN_ADVANCE = 30; // $DAYS_IN_ADVANCE = 365; // Load include files. // If you have moved this script out of the WebCalendar directory, which you // probably should do since it would be better for security reasons, you would // need to change __WC_INCLUDEDIR to point to the webcalendar include directory. define( '__WC_BASEDIR', '../' ); // Points to the base WebCalendar directory // relative to current working directory. define( '__WC_INCLUDEDIR', __WC_BASEDIR . 'includes/' ); define( '__WC_CLASSDIR', __WC_INCLUDEDIR . 'classes/' ); $old_path = ini_get ( 'include_path' ); $delim = ( strstr ( $old_path, ';' ) ? ';' : ':' ); ini_set ( 'include_path', $old_path . $delim . __WC_INCLUDEDIR . $delim ); require_once __WC_CLASSDIR . 'WebCalendar.class'; require_once __WC_CLASSDIR . 'Event.class'; require_once __WC_CLASSDIR . 'RptEvent.class'; require_once __WC_CLASSDIR . 'WebCalMailer.class'; $WebCalendar = new WebCalendar( __FILE__ ); include __WC_INCLUDEDIR . 'translate.php'; include __WC_INCLUDEDIR . 'config.php'; include __WC_INCLUDEDIR . 'dbi4php.php'; include __WC_INCLUDEDIR . 'formvars.php'; include __WC_INCLUDEDIR . 'functions.php'; $WebCalendar->initializeFirstPhase(); include __WC_INCLUDEDIR . $user_inc; include __WC_INCLUDEDIR . 'site_extras.php'; $WebCalendar->initializeSecondPhase(); $debug = false;// Set to true to print debug info... $only_testing = false; // Just pretend to send -- for debugging. // Establish a database connection. $c = dbi_connect ( $db_host, $db_login, $db_password, $db_database, true ); if ( ! $c ) { echo translate( 'Error connecting to database' ) . ': ' . dbi_error(); exit; } load_global_settings(); $WebCalendar->setLanguage(); set_today(); if ( $debug ) echo '<br />Include Path=' . ini_get ( 'include_path' ) . "<br />\n"; // Get a list of the email users in the system. // They must also have an email address. // Otherwise, we can't send them mail, so what's the point? $allusers = user_get_users(); $allusercnt = count ( $allusers ); for ( $i = 0; $i < $allusercnt; $i++ ) { $names[$allusers[$i]['cal_login']] = $allusers[$i]['cal_fullname']; $emails[$allusers[$i]['cal_login']] = $allusers[$i]['cal_email']; } $attachics = $htmlmail = $languages = $noemail = $t_format = $tz = []; $res = dbi_execute ( 'SELECT cal_login, cal_value, cal_setting FROM webcal_user_pref WHERE ( cal_setting = \'EMAIL_HTML\' AND cal_value = \'Y\' ) OR ( cal_setting = \'EMAIL_REMINDER\' AND cal_value = \'N\' ) OR ( cal_setting = \'EMAIL_REMINDER_ATTACH_ICS\' AND cal_value = \'Y\') OR cal_setting = \'LANGUAGE\' OR cal_setting = \'TIME_FORMAT\' OR cal_setting = \'TIMEZONE\' ORDER BY cal_login, cal_setting' ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $user = $row[0]; switch ( $row[2] ) { case 'EMAIL_HTML': // Users who have asked for HTML (default is plain text). $htmlmail[$user] = true; if ( $debug ) echo "User $user wants HTML mail.<br />\n"; break; case 'EMAIL_REMINDER': // Users who have asked not to receive email. $noemail[$user] = 1; if ( $debug ) echo "User $user does not want email.<br />\n"; break; case 'EMAIL_REMINDER_ATTACH_ICS': // Users who have asked receive an ICS-attachment with their email. $attachics[$user] = 1; if ( $debug ) echo "User $user does want ICS-attachment with email.<br />\n"; break; case 'LANGUAGE': // Users language preference. $languages[$user] = $row[1]; if ( $debug ) { echo "Language for $user is $row[1].<br />\n"; #print_r ( $row ); } break; case 'TIME_FORMAT': // Users time format settings. $t_format[$user] = $row[1]; if ( $debug ) echo "Time Format for $user is $row[1].<br />\n"; break; case 'TIMEZONE': // Users TIMEZONE settings. $tz[$user] = $row[1]; if ( $debug ) echo "TIMEZONE for $user is $row[1].<br />\n"; break; } // switch } dbi_free_result ( $res ); } if ( empty ( $GENERAL_USE_GMT ) || $GENERAL_USE_GMT != 'Y' ) $def_tz = $SERVER_TIMEZONE; $startdateTS = time ( 0, 0, 0 ); $enddateTS = $startdateTS + ( $DAYS_IN_ADVANCE * 86400 ); $startdate = date ( 'Ymd', $startdateTS ); $enddate = date ( 'Ymd', $enddateTS ); // Now read all the repeating events (for all users). $repeated_events = query_events ( '', true, 'AND ( wer.cal_end >= ' . $startdate . ' OR wer.cal_end IS NULL )' ); $repcnt = count ( $repeated_events ); // Read non-repeating events (for all users). if ( $debug ) echo "Checking for events from date $startdate to date $enddate.<br />\n"; $events = read_events ( '', $startdateTS, $enddateTS ); $eventcnt = count ( $events ); if ( $debug ) echo "Checking for tasks from date $startdate to date $enddate.<br />\n"; $tasks = read_tasks ( '', $enddateTS ); $taskcnt = count ( $tasks ); if ( $debug ) echo 'Found ' . 0 + $eventcnt + $taskcnt + $repcnt . " events in time range.<br />\n"; $is_task = false; for ( $d = 0; $d < $DAYS_IN_ADVANCE; $d++ ) { $dateTS = time() + ( $d * 86400 ); $date = date ( 'Ymd', $dateTS ); // Get non-repeating events for this date. // An event will be included one time for each participant. $ev = get_entries ( $date ); // Keep track of duplicates. $completed_ids = []; $evcnt = count ( $ev ); for ( $i = 0; $i < $evcnt; $i++ ) { $id = $ev[$i]->getID(); if ( ! empty ( $completed_ids[$id] ) ) continue; $completed_ids[$id] = 1; process_event( $id, $ev[$i]->getName(), $ev[$i]->getDateTimeTS(), $ev[$i]->getEndDateTimeTS() ); } // Get tasks for this date. // A task will be included one time for each participant. $tks = get_tasks ( $date ); // Keep track of duplicates. $completed_ids = []; $tkscnt = count ( $tks ); for ( $i = 0; $i < $tkscnt; $i++ ) { $id = $tks[$i]->getID(); if ( ! empty ( $completed_ids[$id] ) ) continue; $completed_ids[$id] = 1; $is_task = true; process_event( $id, $tks[$i]->getName(), $tks[$i]->getDateTimeTS(), $tks[$i]->getDueDateTimeTS(), $dateTS ); } $is_task = false; // Get repeating events...tasks are not included at this time. if ( $debug ) echo "getting repeating events for $date<br />"; $rep = my_get_repeating_entries ( '', $date ); $repcnt = count ( $rep ); if ( $debug ) echo "found $repcnt repeating events for $date<br />"; for ( $i = 0; $i < $repcnt; $i++ ) { $id = $rep[$i]->getID(); if ( ! empty ( $completed_ids[$id] ) ) continue; $completed_ids[$id] = 1; process_event( $id, $rep[$i]->getName(), $rep[$i]->getDateTimeTS(), $rep[$i]->getEndDateTimeTS(), $date ); } } if ( $debug ) echo "Done.<br />\n"; // Send a reminder for a single event for a single day to all participants in // the event who have accepted as well as those who have not yet approved. // But, don't send to users who rejected (cal_status='R' ). function send_reminder ( $id, $event_date ) { global $ALLOW_EXTERNAL_USERS, $attachics, $debug, $def_tz, $emails, $EXTERNAL_REMINDERS, $htmlmail, $ignore_user_case, $is_task, $LANGUAGE, $languages, $names, $only_testing, $SERVER_URL, $site_extras, $tz, $t_format; $ext_participants = $participants = []; $num_ext_participants = $num_participants = 0; $pri[1] = translate ( 'High' ); $pri[2] = translate ( 'Medium' ); $pri[3] = translate ( 'Low' ); // Get participants first... $res = dbi_execute ( 'SELECT cal_login, cal_percent FROM webcal_entry_user WHERE cal_id = ? AND cal_status IN ( \'A\',\'W\' ) ORDER BY cal_login', [$id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $participants[$num_participants++] = $row[0]; $percentage[$row[0]] = $row[1]; } } $partcnt = count ( $participants ); // Get external participants. if ( ! empty ( $ALLOW_EXTERNAL_USERS ) && $ALLOW_EXTERNAL_USERS == 'Y' && ! empty ( $EXTERNAL_REMINDERS ) && $EXTERNAL_REMINDERS == 'Y' ) { $res = dbi_execute ( 'SELECT cal_fullname, cal_email FROM webcal_entry_ext_user WHERE cal_id = ? AND cal_email IS NOT NULL ORDER BY cal_fullname', [$id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $ext_participants[$num_ext_participants] = $row[0]; $ext_participants_email[$num_ext_participants++] = $row[1]; } } } $ext_partcnt = count ( $ext_participants ); if ( ! $num_participants && ! $num_ext_participants ) { if ( $debug ) echo 'No participants found for event id' . ": $id<br />\n"; return; } // Get event details. $res = dbi_execute ( 'SELECT cal_create_by, cal_date, cal_time, cal_mod_date, cal_mod_time, cal_duration, cal_priority, cal_type, cal_access, cal_name, cal_description, cal_due_date, cal_due_time FROM webcal_entry WHERE cal_id = ?', [$id] ); if ( ! $res ) { echo translate ( 'Database error' ) . ': ' . translate ( 'could not find event id' ) . " $id.\n"; return; } if ( ! ( $row = dbi_fetch_row ( $res ) ) ) { echo translate ( 'Error' ) . ': ' . str_replace ( 'XXX', $id, translate ( 'could not find event id XXX in database.' ) ) . "\n"; return; } // Send mail. We send one user at a time so that we can switch // languages between users if needed (as well as HTML vs plain text). $mailusers = $recipients = []; if ( isset ( $single_user ) && $single_user == 'Y' ) { $mailusers[] = $emails[$single_user_login]; $recipients[] = $single_user_login; } else { for ( $i = 0; $i < $partcnt; $i++ ) { if ( strlen ( $emails[$participants[$i]] ) ) { $mailusers[] = $emails[$participants[$i]]; $recipients[] = $participants[$i]; } else { if ( $debug ) echo "No email for user $participants[$i].<br />\n"; } } for ( $i = 0; $i < $ext_partcnt; $i++ ) { $mailusers[] = $ext_participants_email[$i]; $recipients[] = $ext_participants[$i]; } } $mailusercnt = count ( $mailusers ); if ( $debug ) echo 'Found ' . $mailusercnt . " with email addresses<br />\n"; for ( $j = 0; $j < $mailusercnt; $j++ ) { $recip = $mailusers[$j]; $user = $recipients[$j]; $isExt = ( ! in_array ( $user, $participants ) ); $userlang = ( empty ( $languages[$user] ) ? $LANGUAGE // System default. : $languages[$user] ); $userTformat = ( ! empty ( $t_format[$user] ) ? $t_format[$user] : 24 ); // Gotta pick something. if ( $userlang == 'none' ) $userlang = 'English-US'; // Gotta pick something. if ( $debug ) echo "Setting language to \"$userlang\".<br />\n"; reset_language ( $userlang ); $adminStr = translate ( 'Administrator' ); // Reset timezone setting for current user. if ( ! empty ( $tz[$user] ) ) { $display_tzid = 2; // Display TZ. $user_TIMEZONE = $tz[$user]; } else if ( ! empty ( $def_tz ) ) { $display_tzid = 2; $user_TIMEZONE = $def_tz; } else { $display_tzid = 3; // Do not use offset & display TZ. // I think this is the only real timezone set to UTC...since 1972 at least. $user_TIMEZONE = 'Africa/Monrovia'; } // This will allow date functions to use the proper TIMEZONE. set_env ( 'TZ', $user_TIMEZONE ); $useHtml = ( ! empty ( $htmlmail[$user] ) ? 'Y' : 'N' ); $padding = ( ! empty ( $htmlmail[$user] ) ? ' ' : ' ' ); $body = str_replace ( 'XXX', ( $is_task ? translate ( 'task' ) : translate ( 'event' ) ), translate ( 'This is a reminder for the XXX detailed below.' ) ) . "\n\n"; $create_by = $row[0]; $event_time = date_to_epoch ( $row[1] . ( $row[2] != -1 ? sprintf ( "%06d", $row[2] ): '' ) ); $name = $row[9]; $description = $row[10]; // Add trailing '/' if not found in server_url. // Don't include link for External users. if ( ! empty ( $SERVER_URL ) && ! $isExt ) { $eventURL = $SERVER_URL . ( substr ( $SERVER_URL, -1, 1 ) == '/' ? '' : '/' ) . 'view_entry.php?id=' . $id . '&em=1'; if ( $useHtml == 'Y' ) $eventURL = activate_urls ( $eventURL ); $body .= $eventURL . "\n\n"; } $body .= strtoupper ( $name ) . "\n\n" . translate ( 'Description' ) . ":\n" . $padding . $description . "\n" . ( $is_task ? translate ( 'Start Date' ) : translate ( 'Date' ) ) . ': ' . date_to_str ( ( $row[2] > 0? date ( 'Ymd', $event_date ) : gmdate ( 'Ymd', $event_date ) ) ) . "\n" . ( $row[2] > 0 ? ( $is_task ? translate ( 'Start Time' ) : translate ( 'Time' ) ) . ': ' . display_time ( '', $display_tzid, $event_time, $userTformat ) . "\n" : ( ( $row[2] == 0 && $row[5] == 1440) ? translate( 'Time' ) . ': ' . translate( 'All day event' ). "\n" : '' ) ) . ( $row[5] > 0 && ! $is_task ? translate ( 'Duration' ) . ': ' . $row[5] . ' ' . translate ( 'minutes' ) . "\n" : ( $is_task ? translate ( 'Due Date' ) . ': ' . date_to_str ( $row[11] ) . "\n" . translate ( 'Due Time' ) . ': ' . display_time ( $row[12], $display_tzid, '', $userTformat ) . "\n" : '' ) ) . ( $is_task && isset ( $percentage[$user] ) ? translate ( 'Pecentage Complete' ) . ': ' . $percentage[$user] . "%\n" : '' ) . ( empty ( $DISABLE_PRIORITY_FIELD ) || $DISABLE_PRIORITY_FIELD != 'Y' ? translate ( 'Priority' ) . ': ' . $row[6] . '-' . $pri[ceil( $row[6] / 3 )] . "\n" : '' ); if ( empty ( $DISABLE_ACCESS_FIELD ) || $DISABLE_ACCESS_FIELD != 'Y' ) { $body .= translate ( 'Access' ) . ': '; if ( $row[8] == 'C' ) $body .= translate ( 'Confidential' ) . "\n"; elseif ( $row[8] == 'P' ) $body .= translate ( 'Public' ) . "\n"; elseif ( $row[8] == 'R' ) $body .= translate ( 'Private' ) . "\n"; } $body .= ( ! empty ( $single_user_login ) && ! $single_user_login ? translate ( 'Created by' ) . ': ' . $row[0] . "\n" : '' ) . translate ( 'Updated' ) . ': ' . date_to_str ( $row[3] ) . ' ' . display_time ( $row[3] . sprintf ( "%06d", $row[4] ), $display_tzid, '', $userTformat ) . "\n"; // Site extra fields. $extras = get_site_extra_fields ( $id ); $site_extracnt = count ( $site_extras ); for ( $i = 0; $i < $site_extracnt; $i++ ) { if ( $site_extras[$i] == 'FIELDSET' ) continue; $extra_name = $site_extras[$i][0]; $extra_descr = $site_extras[$i][1]; $extra_type = $site_extras[$i][2]; $extra_arg1 = $site_extras[$i][3]; $extra_arg2 = $site_extras[$i][4]; if ( ! empty ( $site_extras[$i][5] ) ) $extra_view = $site_extras[$i][5] & EXTRA_DISPLAY_REMINDER; if ( ! empty ( $extras[$extra_name]['cal_name'] ) && $extras[$extra_name]['cal_name'] != '' && ! empty ( $extra_view ) ) { $val = ''; $body .= $extra_descr; if ( $extra_type == EXTRA_DATE ) $body .= ': ' . $extras[$extra_name]['cal_date'] . "\n"; elseif ( $extra_type == EXTRA_MULTILINETEXT ) $body .= "\n" . $padding . $extras[$extra_name]['cal_data'] . "\n"; elseif ( $extra_type == EXTRA_RADIO ) $body .= ': ' . $extra_arg1[$extras[$extra_name]['cal_data']] . "\n"; else // Default method for EXTRA_URL, EXTRA_TEXT, etc... $body .= ': ' . $extras[$extra_name]['cal_data'] . "\n"; } } if ( ( empty ( $single_user ) || $single_user != 'Y' ) && ( empty ( $DISABLE_PARTICIPANTS_FIELD ) || $DISABLE_PARTICIPANTS_FIELD != 'N' ) ) { $body .= translate ( 'Participants' ) . ":\n"; for ( $i = 0; $i < $partcnt; $i++ ) { $body .= $padding . $names[$participants[$i]] . "\n"; } for ( $i = 0; $i < $ext_partcnt; $i++ ) { $body .= $padding . $ext_participants[$i] . ' ( ' . translate ( 'External User' ) . ")\n"; } } $subject = translate ( 'Reminder' ) . ': ' . stripslashes ( $name ); if ( $debug ) echo "Sending mail to $recip (in $userlang).<br />\n"; if ( $only_testing ) { if ( $debug ) echo '<hr /> <pre> To: ' . $recip . ' Subject: ' . $subject . ' From:' . $adminStr . ' ' . $body . ' </pre> '; } else { $mail = new WebCalMailer; user_load_variables ( $user, 'temp' ); $recipName = ( $isExt ? $user : $GLOBALS ['tempfullname'] ); // Send ics attachment to External Users or // or users who explicitly chose to receive it. $attach = ( ($isExt || isset($attachics[$user])) ? $id : '' ); $mail->WC_Send ( $adminStr, $recip, $recipName, $subject, $body, $useHtml, $GLOBALS['EMAIL_FALLBACK_FROM'], $attach ); $cal_text = ( $isExt ? translate ( 'External User' ) : '' ) . $recipName; activity_log ( $id, 'system', $user, LOG_REMINDER, $cal_text ); } } } /** * Keep track of the fact that we sent the reminder, so we don't do it again. */ function log_reminder ( $id, $times_sent ) { global $debug, $only_testing; if ( ! $only_testing ) dbi_execute ( 'UPDATE webcal_reminders SET cal_last_sent = ?, cal_times_sent = ? WHERE cal_id = ?', [time(), $times_sent, $id] ); } /** * Process an event for a single day. Check to see if it has a reminder, * when it needs to be sent and when the last time it was sent. */ function process_event ( $id, $name, $start, $end, $new_date = '' ) { global $debug, $is_task, $only_testing; // Get reminders array. $reminder = getReminders ( $id ); if ( ! empty ( $reminder ) ) { if ( $debug ) echo " Reminder set for event.<br />\n"; $times_sent = $reminder['times_sent']; $repeats = $reminder['repeats']; $lastsent = $reminder['last_sent']; $related = $reminder['related']; // If we are working with a repeat or overdue task, and we have sent all the // reminders for the basic event, then reset the counter to 0. if ( ! empty ( $new_date ) ) { if ( $times_sent == $repeats + 1 ) { if ( ! $is_task || ( $related == 'E' && date( 'Ymd', $new_date ) != date ( 'Ymd', $end ) ) ) // Tasks only. $times_sent = 0; } $new_offset = date_to_epoch ( $new_date ) - ( $start - ( $start % 86400 ) ); $start += $new_offset; $end += $new_offset; } if ( $debug ) printf ( "Event %d: \"%s\" on %s at %s GMT<br />\n", $id, $name, gmdate ( 'Ymd', $start ), gmdate ( 'H:i:s', $start ) ); // It is pointless to send reminders after this time! $pointless = $end; $remB4 = ( $reminder['before'] == 'Y' ); if ( ! empty ( $reminder['date'] ) ) // We're using a date. $remind_time = $reminder['timestamp']; else { // We're using offsets. $offset = $reminder['offset'] * 60; // Convert to seconds. if ( $related == 'S' ) { // Relative to start. $offset_msg = ( $remB4 ? ' Mins Before Start: ' : ' Mins After Start: ' ) . $reminder['offset']; $remind_time = ( $remB4 ? $start - $offset : $start + $offset ); } else { // Relative to end/due. $offset_msg = ( $remB4 ? ' Mins Before End: ' : ' Mins After End: ' ) . $reminder['offset']; $remind_time = ( $remB4 ? $end - $offset : $end + $offset ); $pointless = ( $remB4 ? $end : $end + $offset ); } } // Factor in repeats if set. if ( $repeats > 0 && $times_sent <= $repeats ) $remind_time += ( $reminder['duration'] * 60 * $times_sent ); if ( $debug ) echo ( empty ( $offset_msg ) ? '' : $offset_msg . '<br />' ) . ' Event ' . ( $related == 'S' // Relative to start. ? 'start time is: ' . gmdate ( 'm/d/Y H:i', $start ) : 'end time is: ' . gmdate ( 'm/d/Y H:i', $end ) ) . ' GMT<br /> Remind time is: ' . gmdate ( 'm/d/Y H:i', $remind_time ) . ' GMT<br /> Effective delivery time is: ' . date ( 'm/d/Y H:i T', $remind_time ) . '<br /> Last sent on: ' . ( $lastsent == 0 ? 'NEVER' : date ( 'm/d/Y H:i T', $lastsent ) ) // No sense sending reminders if the event is over! // Unless the entry is a task. . '<br /><br /> times_sent = ' . $times_sent . ' repeats = ' . $repeats . ' time = ' . date( 'His', time() ) . ' remind_time = ' . date( 'His', $remind_time ) . ' lastsent = ' . ( $lastsent > 0 ? date( 'Ymd His', $lastsent ) : ' NEVER ' ) . ' pointless = ' . date( 'Ymd His', $pointless ) . ' is_task = ' . ( $is_task ? 'true' : 'false' ) . '<br />'; if( $times_sent < ( $repeats + 1 ) && time() >= $remind_time && $lastsent <= $remind_time && ( time() <= $pointless || $is_task ) ) { // Send a reminder. if ( $debug ) echo ' SENDING REMINDER!<br />' . "\n"; send_reminder ( $id, $start ); // Now update the db... if ( $debug ) echo '<br /> LOGGING REMINDER!<br /><br />' . "\n"; log_reminder ( $id, $times_sent + 1 ); } } } //end function process_event /** * my_get_repeating_entries (needs description) */ function my_get_repeating_entries ( $user, $dateYmd, $get_unapproved = true ) { global $debug, $repeated_events; $n = 0; $ret = []; if ( $debug ) echo "Getting repeating entries for $dateYmd<br />"; for ( $i = 0, $cnt = count ( $repeated_events ); $i < $cnt; $i++ ) { $list = $repeated_events[$i]->getRepeatAllDates(); for ( $j = 0, $cnt_j = count ( $list ); $j < $cnt_j; $j++ ) { if ( $debug ) { echo " checking $list[$j] aka " . date( 'Ymd', $list[$j]) . "<br />: " . ( $dateYmd == date ( 'Ymd', $list[$j] ) ? "Y" : "N" ) . "\n"; } if ( $dateYmd == date ( 'Ymd', $list[$j] ) ) { $ret[$n++] = $repeated_events[$i]; if ( $debug ) echo 'Added!<br />'; } } } return $ret; } ?> PK �]�\���m� � tools/reload_remotes.phpnu �[��� #!/usr/local/bin/php -q <?php /** * Description: * This is a command-line script that will reload all user's remote calendars. * * Usage: * php reload_remotes.php * * Setup: * This script should be setup to run periodically on your system. * You should not run this more a once per hour for performance reasons * * To set this up in cron, add a line like the following in your crontab * to run it every hour: * 1 * * * * php /some/path/here/reload_remotes.php * Of course, change the path to where this script lives. If the PHP binary is * not in your $PATH, you may also need to provide the full path to "php". * On Linux, just type crontab -e to edit your crontab. * * If you're a Windows user, you'll either need to find a cron clone * for Windows (they're out there) or use the Windows Task Scheduler. * (See docs/WebCalendar-SysAdmin.html for instructions.) * * Comments: * You will need access to the PHP binary (command-line) rather than the * module-based version that is typically installed for use with a web server. * * If running this script from the command line generates PHP warnings, * you can disable error_reporting by adding * "-d error_reporting=0" to the command line: * php -d error_reporting=0 /some/path/here/tools/reload_remotes.php * ******************************************************************** */ // Load include files. // If you have moved this script out of the WebCalendar directory, // which you probably should do since it would be better for security reasons, // you would need to change __WC_INCLUDEDIR to point to the // webcalendar include directory. define( '__WC_BASEDIR', '../' ); // Points to the base WebCalendar directory // relative to current working directory. define( '__WC_INCLUDEDIR', __WC_BASEDIR . 'includes/' ); define( '__WC_CLASSDIR', __WC_INCLUDEDIR . 'classes/' ); $old_path = ini_get ( 'include_path' ); $delim = ( strstr ( $old_path, ';' ) ? ';' : ':' ); ini_set ( 'include_path', $old_path . $delim . __WC_INCLUDEDIR . $delim ); include_once __WC_INCLUDEDIR . 'translate.php'; require_once __WC_CLASSDIR . 'WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include __WC_INCLUDEDIR . 'config.php'; include __WC_INCLUDEDIR . 'dbi4php.php'; include __WC_INCLUDEDIR . 'formvars.php'; include __WC_INCLUDEDIR . 'functions.php'; $WebCalendar->initializeFirstPhase(); include __WC_INCLUDEDIR . $user_inc; include __WC_INCLUDEDIR . 'xcal.php'; $WebCalendar->initializeSecondPhase(); // Used for hCal parsing. require_once __WC_CLASSDIR . 'hKit/hkit.class.php'; $debug = false; // Set to true to print debug info... // Establish a database connection. $c = dbi_connect ( $db_host, $db_login, $db_password, $db_database, true ); if ( ! $c ) { echo translate ( 'Error connecting to database' ) . ': ' . dbi_error(); exit; } load_global_settings(); $WebCalendar->setLanguage(); if ( $debug ) echo "<br />\n" . translate ( 'Include Path' ) . ' =' . ini_get ( 'include_path' ) . "<br />\n"; if ( $REMOTES_ENABLED == 'Y' ) { $res = dbi_execute ( 'SELECT cal_login, cal_url, cal_admin FROM webcal_nonuser_cals WHERE cal_url IS NOT NULL' ); $cnt = 0; if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $data = []; $cnt++; $calUser = $row[0]; $cal_url = $row[1]; $login = $row[2]; $overwrite = true; $type = 'remoteics'; $data = parse_ical ( $cal_url, $type ); // TODO it may be a vcs file // if ( count ( $data ) == 0 ) { // $data = parse_vcal ( $cal_url ); // } // we may be processing an hCalendar if ( count ( $data ) == 0 && function_exists ( 'simplexml_load_string' ) ) { $h = new hKit; $h->tidy_mode = 'proxy'; $result = $h->getByURL ( 'hcal', $cal_url ); $type = 'hcal'; $data = parse_hcal ( $result, $type ); } if ( count ( $data ) && empty ( $errormsg ) ) { // delete existing events if ( $debug ) echo "<br />\n" . translate ( 'Deleting events for' ) . ": $calUser<br />\n"; delete_events ( $calUser ); // import new events if ( $debug ) echo translate ( 'Importing events for' ) . ": $calUser<br />\n" . translate ( 'From' ) . ": $cal_url<br />\n"; import_data ( $data, $overwrite, $type ); if ( $debug ) echo translate ( 'Events successfully imported' ) . ": $count_suc<br /><br />\n"; } else { // we didn't receive any data and/or there was an error if ( ! empty ( $errormsg ) ) echo $errormsg . "<br />\n"; if ( count ( $data ) == 0 ) echo "<br />\n" . translate ( 'No data returned from' ) . ": $cal_url<br />\n" . translate ( 'for non-user calendar' ) . ": $calUser<br />\n"; } } dbi_free_result ( $res ); } if ( $cnt == 0 ) echo "<br />\n" . translate ( 'No Remote Calendars found' ); } else echo "<br />\n" . translate ( 'Remote Calendars not enabled' ); // just in case $login = ''; /** * delete_events (needs description) */ function delete_events ( $nid ) { // Get event ids for all events this user is a participant $events = get_users_event_ids ( $nid ); // Now count number of participants in each event... // If just 1, then save id to be deleted $delete_em = []; for ( $i = 0, $cnt = count ( $events ); $i < $cnt; $i++ ) { $res = dbi_execute ( 'SELECT COUNT( * ) FROM webcal_entry_user WHERE cal_id = ?', [$events[$i]] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { if ( $row[0] == 1 ) $delete_em[] = $events[$i]; } dbi_free_result ( $res ); } } // Now delete events that were just for this user for ( $i = 0, $cnt = count ( $delete_em ); $i < $cnt; $i++ ) { dbi_execute ( 'DELETE FROM webcal_entry_repeats WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_repeats_not WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_log WHERE cal_entry_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_import_data WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_site_extras WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_ext_user WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_reminders WHERE cal_id =? ', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_blob WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry WHERE cal_id = ?', [$delete_em[$i]] ); } // Delete user participation from events dbi_execute ( 'DELETE FROM webcal_entry_user WHERE cal_login = ?', [$nid] ); } ?> PK �]�\�6��B �B tools/palm_datebook.plnu ȯ�� #!/usr/bin/perl =head1 NAME palm_datebook.pl =head1 SYNOPSIS Reads the events from a Palm Desktop DateBook.dat =head1 DESCRIPTION This file reads a Palm Desktop DateBook file (datebook.dat) and prints all the non-expired entries (can return all, see below) to STDOUT. It prints a pipe separated value list by default. =head1 USAGE The script is set up to be used with the webcalendar and doesn't need to be altered. If you want to use it some other way, then change the variables in the config section to suit your needs and edit the main program (bottom of script). You can uncomment the $outfile config to print to a file. The default program will not include expired events and takes 2 arguments: 1. $DateBookFileName - The name/location of the datebook.dat 2. $exc_private - If a 1 is passed private records will be skipped The following data is available in $Entry: $Entry->{RecordID} = Record ID in the Palm $Entry->{Status} = Identifies new and deleted records (status in datebook) $Entry->{Position} = Position in list? $Entry->{StartTime} = In seconds since 1970 $Entry->{EndTime} = In seconds since 1970 $Entry->{Description} = Description of event (string) $Entry->{Duration} = How long the event lasts (in minutes) $Entry->{Note} = Note (string) $Entry->{Untimed} = 1 = true 0 = false $Entry->{Private} = 1 = true 0 = false $Entry->{Category} = Short description of category (PD Version > 4.1.1) $Entry->{AlarmSet} = 1 = true 0 = false $Entry->{AlarmAdvanceAmount} = How many units in AlarmAdvanceType (-1 means not set) $Entry->{AlarmAdvanceType} = Units: (0=minutes, 1=hours, 2=days) $Entry->{Location} = Location field (PD Version > 4.1.1) $Entry->{Repeat} = Array containing repeat information (if repeat) $Entry->{Repeat}->{Interval} = 1=daily,2=weekly,3=MonthlyByDay,4=MonthlyByDate,5=Yearly $Entry->{Repeat}->{Frequency} = How often event occurs. (1=every, 2=every other,etc.) $Entry->{Repeat}->{EndTime} = When the repeat ends (In seconds since 1970) $Entry->{Repeat}->{Exceptions} = An exception to the repeat (In seconds since 1970) $Entry->{Repeat}->{RepeatDays} = For Weekly: What days to repeat on (7 characters...y or n for each day) $Entry->{Repeat}->{DayNum} = For MonthlyByDay: Day of week (1=sun,2=mon,3=tue,4=wed,5=thu,6=fri,7=sat) $Entry->{Repeat}->{WeekNum} = For MonthlyByDay: Week number (1=first,2=second,3=third,4=fourth,5=last) =head1 AUTHOR Jeff Hoover =head1 CONTRIBUTERS Eduard Martinescu - Provided patch to parse category list. =head1 NOTE Palm changed the format of the datebook.dat file in Palm Desktop 4.1.1. I _finally_ reversed engineered the file format using a hex editor. I don't know what all the new fields are for, but the script works so who cares. =cut use CGI qw (:standard); my $q = new CGI; my ($Year, $Month, $Day); my ($DATA, @Categories); # ----------------------- Config if necessary ---------------------------- my $DateBookFileName = $ARGV[0]; # The name of the file my $exc_private = $ARGV[1]; # Do we want private entries? (1 = skip private) my $inc_expired = 0; # Do we want expired entries? (1 = include expired) my $sep = "|"; # what to separate the output with #my $outfile = "/tmp/datebook_dump.txt"; # uncomment to print to file #--------------------------------------------------------------------------- #================= sub ReadDateBook { #================= # ReadDateBook opens the file we passed (datebook.dat) and reads the entries. my ($FileName, $Filter) = @_; my (@Fields, @Entries, $FieldCount, $NumberOfEntries); my ($Entry, $i, $Header, $Tag); my ($NextFree, $CategoryCount, $Category, $ResourceID); my ($FieldsPerRow, $RecordIdPos, $RecordStatusPos, $RecordPlacementPos); my ($TestField, $NewFormat, $Trash); open DATEBOOK, "<".$FileName; binmode DATEBOOK; local $/ = undef; $_ = <DATEBOOK>; $GlobalPos = 0; close DATEBOOK; # First, check the initial 4 byte "tag" field. $Tag = ReadLong(); # Next, figure out what version of datebook.dat we are using. # - prior to 4.1.1 the next field was the FileName # - after 4.1.1 it is a header that says "PalmSG Database" $TestField = ReadPilotString(); $NewFormat = ($TestField eq 'PalmSG Database') ? 1 : 0; if ($NewFormat eq 1) { $Header = $TestField; $Trash = ReadLong(); $Trash = ReadLong(); $Trash = ReadByteString(12); $Trash = ReadByte(); # Number of entries ? $Trash = ReadByte(); $Trash = ReadByteString(10); $FileName = ReadPilotString(); $Trash = ReadByteString(47); } else { $FileName = $TestField; $Header = ReadPilotString(); $NextFree = ReadLong(); } # Read the category information $CategoryCount = ReadLong(); for ($i=0; $i<$CategoryCount; $i++) { $Category = ReadCategory(); $Categories[$Category->{Index}] = $Category->{ShortName} if ($Category ne 0); } $ResourceID = ReadLong(); $FieldsPerRow = ReadLong(); $RecordIdPos = ReadLong(); $RecordStatusPos = ReadLong(); $RecordPlacementPos = ReadLong(); # Read the field list. $FieldCount = ReadShort(); for ($i=0; $i<$FieldCount; $i++) {push @Fields, ReadShort();} # Figure out how many entries to read $NumberOfEntries = ReadLong() / $FieldCount; # Read the entries. for ($i=0; $i<$NumberOfEntries; $i++) { $Entry = ReadEntry($NewFormat); if ($Entry ne 0){ if (!$Filter or &$Filter($Entry)){push @Entries, $Entry;} } } return @Entries; } #============== sub ReadEntry { #============== # ReadPalmEntry reads a single entry from the datebook, stores it in a local # hash, and returns a reference to that hash. The reference can safely # be stored in an array for later use. my ($NewFormat) = @_; my (%Entry, $Trash); if ($NewFormat eq 1) { $Entry{RecordID} = ReadPilotField(); $Entry{Position} = ReadPilotField(); $Entry{Status} = ReadPilotField(); $Trash = ReadPilotField(); # field counter $Trash = ReadPilotField(); $Entry{Category} = ReadPilotField(); $Entry{Private} = ReadPilotField(); $Trash = ReadPilotField(); $Trash = ReadPilotField(); $Trash = ReadPilotField(); $Trash = ReadPilotField(); $Trash = ReadPilotField(); $Trash = ReadPilotField(); $Entry{StartTime} = ReadPilotField(); $Entry{EndTime} = ReadPilotField(); $Entry{Description} = ReadPilotField(); $Trash = ReadPilotField(); $Entry{Note} = ReadPilotField(); $Entry{Untimed} = ReadPilotField(); $Entry{AlarmSet} = ReadPilotField(); $Entry{AlarmAdvanceAmount} = ReadPilotField(); $Entry{AlarmAdvanceType} = ReadPilotField(); $Entry{Repeat} = ReadPilotField(); $Entry{Location} = ReadPilotField(); # new location field $Trash = ReadPilotField(); $Trash = ReadPilotField(); $Trash = ReadPilotField(); } else { $Entry{RecordID} = ReadPilotField(); $Entry{Status} = ReadPilotField(); $Entry{Position} = ReadPilotField(); $Entry{StartTime} = ReadPilotField(); $Entry{EndTime} = ReadPilotField(); $Entry{Description} = ReadPilotField(); $Entry{Duration} = ReadPilotField(); $Entry{Note} = ReadPilotField(); $Entry{Untimed} = ReadPilotField(); $Entry{Private} = ReadPilotField(); $Entry{Category} = ReadPilotField(); $Entry{AlarmSet} = ReadPilotField(); $Entry{AlarmAdvanceAmount} = ReadPilotField(); $Entry{AlarmAdvanceType} = ReadPilotField(); $Entry{Repeat} = ReadPilotField(); } #Should return as -1 if not set, but is returning as 4294967295 $Entry{AlarmAdvanceAmount} = "-1" if ($Entry{AlarmAdvanceAmount} eq '4294967295'); # Remove Crap from the DateBook5 Application $Entry{Note} = '' if ($Entry{Note} =~ /^\#\#[fcdxX\@]/); # Filter single quotes, \n\r $Entry{Description} = &filter_quotes($Entry{Description}); $Entry{Note} = &filter_quotes($Entry{Note}); # Calculate duration in minutes $Entry{Duration} = ($Entry{EndTime} - $Entry{StartTime}) / 60; # Get category text $Entry{Category} = $Categories[$Entry{Category}] if ($Entry{Category} > 0); # Skip private records if $exc_private if (($exc_private) && ($Entry{Private} == 1)) { return 0; # Skip Record if not in Palm (no RecordID) } elsif ($Entry{RecordID} == 0){ return 0; # Skip Record if marked for deletion (4=delete, 128=sync'd:delete+archive, 129=Not sync'd:delete+archive) } elsif (($Entry{Status} == 128) || ($Entry{Status} == 129) || ($Entry{Status} == 4)){ return 0; # Skip events that are past endtime (except repeats that aren't expired) unless $inc_expired } elsif (($Entry{EndTime} < time()) && (!$Entry{Repeat}) && (!$inc_expired)){ return 0; } elsif (($Entry{Repeat}) && ($Entry{Repeat}{EndTime} < time())&& ($Entry{Repeat}{EndTime} != 0) && (!$inc_expired)){ return 0; } else { #print $Entry{RecordID} . "\n"; return \%Entry; } } #=================== sub ReadPilotField { #=================== # ReadPilotField returns a single field from the datebook file. my ($Type, $N, $sun, $mon, $tue, $wed, $thu, $fri, $sat); my ($i, $DatesToSkip, $Repeat, $Interval, $Frequency, $Duration, $Position, $EndTime, $exceptions, @E); my (%RA); $Type = ReadLong(); if ($Type == 1 or $Type == 3 or $Type == 6) { return ReadLong(); } elsif ($Type == 5) { ReadLong(); # Skip the long of all zeroes return ReadPilotString(); } elsif ($Type == 8) { $DatesToSkip = ReadShort(); for ($i=1; $i<=$DatesToSkip; $i++) {$exceptions .= ReadLong().":";} chop $exceptions; $Repeat = ReadShort(); if ($Repeat == 0xFFFF) { ReadShort(); $Skip = ReadShort(); SkipBytes($Skip); } elsif ($Repeat and $Repeat != 0x8001) { #($Repeat == 0x1a40 or $Repeat == 0xb3c0 or $Repeat == 0xe750) # print " DEBUG: Repeat is $Repeat\n"; # ReadLong(); } if ($Repeat) { $Interval = ReadLong(); $Frequency = ReadLong(); $EndTime = ReadLong(); if ($EndTime eq 1956542399) { # No EndTime $EndTime = ''; } ReadLong(); $DayNum = ReadLong(); if ($Interval == 2) { $Position = ReadByte(); } elsif ($Interval == 3) { $Position = ReadLong(); } elsif ($Interval == 5) { $Position = ReadLong(); } else { $Position == 0; } # Build the Repeat array to return $RA{Interval} = $Interval; $RA{Frequency} = $Frequency; $RA{EndTime} = $EndTime; if ($exceptions){ $RA{Exceptions} = $exceptions;} if ($Interval == 2) { # Weekly repeat # $Position is an integer that tells what days of the week # to repeat on. (sun=1,mon=2,tue=4,wed=8,thu=16,fri=32,sat=64) # The numbers are added together to give a unique integer. # We will break it down since the WebCalendar doesn't use this format. $N = $Position; # Check for Saturday if ($N - 64 >= 0) { $sat = 'y'; $N -= 64; } else { $sat = 'n'; } # Check for Friday if ($N - 32 >= 0) { $fri = 'y'; $N -= 32; } else { $fri = 'n'; } # Check for Thursday if ($N - 16 >= 0) { $thu = 'y'; $N -= 16; } else { $thu = 'n'; } # Check for Wednesday if ($N - 8 >= 0) { $wed = 'y'; $N -= 8; } else { $wed = 'n'; } # Check for Tuesday if ($N - 4 >= 0) { $tue = 'y'; $N -= 4; } else { $tue = 'n'; } # Check for Monday if ($N - 2 >= 0) { $mon = 'y'; $N -= 2; } else { $mon = 'n'; } # Check for Sunday if ($N - 1 >= 0) { $sun = 'y'; $N -= 1; } else { $sun = 'n'; } $RA{RepeatDays} = $sun.$mon.$tue.$wed.$thu.$fri.$sat; } elsif ($Interval == 3) { # Monthlybyday repeat $RA{DayNum} = $DayNum + 1; # Day of week (1=sun,2=mon,3=tue,4=wed,5=thu,6=fri,7=sat) $RA{WeekNum} = $Position + 1; # Week number (1=first,2=second,3=third,4=fourth,5=last) } return \%RA; } else { return 0; # No repeat } } elsif ($Type == 64 or $Type == 65 or $Type == 66) { # 0x4000 0x4100 0x4200 return ReadLong(); } else { print STDERR "There's a problem with this pilot field of type $Type\n"; exit; #return undef; } } #=================== sub ReadByteString { #=================== # ReadByteString reads the number of bytes passed to it as a parameter # and returns it as a character string. my ($Count) = @_; $GlobalPos += $Count; return substr ($_, $GlobalPos-$Count, $Count); } #==================== sub ReadPilotString { #==================== # ReadPilotString reads a pilot formatted string, which is a size (one # byte, unless the byte is 0xFF, then it's the two bytes after the 0xFF), # followed by that many bytes, and returns a Perl string. my ($String) = ""; my ($Length, $i); $Length = unpack ('C', substr ($_, $GlobalPos, 1)); $GlobalPos++; if ($Length == 255) { $Length = ReadShort(); } $GlobalPos += $Length; return substr ($_, $GlobalPos-$Length, $Length); } #============== sub SkipBytes { #============== # SkipBytes is just like ReadByteString, except it throws away the data, # rather than returning it. my ($Count) = @_; $GlobalPos += $Count; } #============= sub ReadByte { #============= # ReadByte reads a single byte, and returns it as an integer. $GlobalPos++; return unpack ('C', substr($_, $GlobalPos-1, 1)); } #============== sub ReadShort { #============== # ReadShort reads two bytes, and returns them as an integer (low order # byte is the first one read). $GlobalPos+=2; return unpack ('S', substr($_, $GlobalPos-2, 2)); } #============= sub ReadLong { #============= # ReadLong reads four bytes, and returns them as an integer (low order # byte is the first one read). $GlobalPos+=4; return unpack ('L', substr($_, $GlobalPos-4, 4)); } #==================== sub ByDateAscending { #==================== # Sort records by StartTime return $a->{StartTime} <=> $b->{StartTime}; } #================== sub filter_quotes { #================== # Filter newline/return my $temp = $_[0]; # $temp =~ s/'/\\'/g; $temp =~ s/\n|\r/ /g; # Remove newline return ($temp); } #================= sub ReadCategory { #================= # ReadCategory reads a single category entry from the datebook, # stores it in a local hash, and returns a reference to that hash. # The reference can safely be stored in an array for later use. my (%Entry); $Entry{Index} = ReadLong(); $Entry{CategoryID} = ReadLong(); $Entry{DirtyFlag} = ReadLong(); $Entry{LongName} = ReadPilotString(); $Entry{ShortName} = filter_quotes(ReadPilotString()); return \%Entry; } #----------------------------- Main Program ------------------------------- foreach $Entry (sort ByDateAscending ReadDateBook($DateBookFileName)) { $DATA .= $Entry->{RecordID}. $sep; $DATA .= $Entry->{StartTime}. $sep; $DATA .= $Entry->{EndTime}. $sep; $DATA .= $Entry->{Description}. $sep; $DATA .= $Entry->{Duration}. $sep; $DATA .= $Entry->{Note}. $sep; $DATA .= $Entry->{Untimed}. $sep; $DATA .= $Entry->{Private}. $sep; $DATA .= $Entry->{Category}. $sep; $DATA .= $Entry->{AlarmSet}. $sep; $DATA .= $Entry->{AlarmAdvanceAmount}. $sep; $DATA .= $Entry->{AlarmAdvanceType}. $sep; $DATA .= $Entry->{Repeat}->{Interval}. $sep; $DATA .= $Entry->{Repeat}->{Frequency}. $sep; $DATA .= $Entry->{Repeat}->{EndTime}. $sep; $DATA .= $Entry->{Repeat}->{Exceptions}. $sep; $DATA .= $Entry->{Repeat}->{RepeatDays}. $sep; # $DATA .= $Entry->{Repeat}->{DayNum}. $sep; $DATA .= $Entry->{Repeat}->{WeekNum}. $sep; $DATA .= "\n"; } if ($outfile) { die "Couldn't open $outfile: $!" if ((open OUT, ">$outfile") eq undef); flock (OUT, 2);print OUT $DATA;flock (OUT, 8);close OUT; } else { print STDOUT $DATA; } exit;PK �]�\��J#( #( tools/update_translation.plnu ȯ�� #!/usr/bin/perl # $Id: update_translation.pl,v 1.41 2008/10/14 01:16:22 bbannon Exp $ # # This tool will update a translation file by doing the following: # - Phrases are organized by the page on which they first appear. # - When a missing translation is found, the phrase can optionally have # << MISSING >> # right above it. And, when the "phrase" is an abbreviation of the # full English text, show the English text (in a comment) below. # # Example: # << MISSING >> # custom-script-help: # English text: Allows entry of custom Javascript or stylesheet text that will be inserted into the HTML "head" section of every page. # # Note: you will lose any comments you put in the translation file # when using this tool (except for the comments at the very beginning). # # Note #2: This will overwrite the existing translation file, so a backup # of the original can optionally be saved with a timestamp file extension. # # Usage: # update_translation.pl [-p plugin] languagefile # # Example for main WebCalendar translation: # update_translation.pl French.txt # or # update_translation.pl French # # Example for plugin "tnn" translation: # update_translation.pl -p tnn French.txt # or # update_translation.pl -p tnn French # # Note: this utility should be run from this directory (tools). # Note #2: you can use perltidy to format this perl script nicely: # http://perltidy.sourceforge.net/ # Usage: # perltidy -i=2 update_translation.pl # (which will create update_translation.pl.tdy, the new version) # #################################################################### use File::Copy; use File::Find; sub find_pgm_files { # Skipping non WebCalendar plugins, # if the filename ends in .class or .php, add it to @files. push( @files, "$File::Find::name" ) if ( $_ =~ /\.(class|php)$/i && $File::Find::dir !~ /(fckeditor|htmlarea|phpmailer)/i ); } $base_dir = '..'; $trans_dir = '../translations'; $base_trans_file = "$trans_dir/English-US.txt"; $plugin = ''; $save_backup = 0; # set to 1 to create backups $show_dups = 0; # set to 0 to minimize translation file. $show_missing = 1; # set to 0 to minimize translation file. $verbose = 0; ( $this ) = reverse split( /\//, $0 ); for ( $i = 0; $i < @ARGV; $i++ ) { if ( $ARGV[ $i ] eq '-p' ) { $plugin = $ARGV[ ++$i ]; } elsif ( $ARGV[ $i ] eq '-b' ) { $save_backup++; } elsif ( $ARGV[ $i ] eq '-d' ) { $show_dups++; } elsif ( $ARGV[ $i ] eq '-m' ) { $show_missing--; } elsif ( $ARGV[ $i ] eq '-v' ) { $verbose++; } else { $infile = $ARGV[ $i ]; } } die "Usage: $this [-p plugin] language\n" if ( $infile eq '' ); if ( $plugin ne '' ) { $p_trans_dir = "$base_dir/$plugin/translations"; $p_base_trans_file = "$p_trans_dir/English-US.txt"; $p_base_dir = "$base_dir/$plugin"; } else { $p_trans_dir = $trans_dir; $p_base_trans_file = $base_trans_file; $p_base_dir = $base_dir; } $infile .= '.txt' if ( $infile !~ /txt$/ ); if ( -f "$trans_dir/$infile" || -f "$p_trans_dir/$infile" ) { $b_infile = "$trans_dir/$infile"; $infile = "$p_trans_dir/$infile"; } #print "infile: $infile\nb_infile: $b_infile\ntrans_dir: $trans_dir\n"; die "Usage: $this [-p plugin] language\n" if ( !-f $infile ); print "Translation file: $infile\n" if ( $verbose ); # # Save a backup copy of old translation file before we mess with it. # if ( $save_backup ) { $bak = $infile; $bak =~ s/txt$//; print "Attempting to backup file $infile. "; if ( copy( $infile, $bak . ( stat( $infile ) )[9] ) ) { print "Success!\n"; } else { warn "Failure!:\n$! "; } } # Read in the plugin base translation file. if ( $plugin ne '' ) { print "Reading plugin base translation file: $p_base_trans_file\n" if ( $verbose ); open( F, $p_base_trans_file ) || die "Error opening $p_base_trans_file"; while ( <F> ) { chop; s/\r*$//g; # remove annoying CR next if ( /^#/ ); if ( /\s*:\s*/ ) { $abbrev = $`; $base_trans{ $abbrev } = $' if ( $abbrev ne 'charset' ); } } close( F ); } # Now load the base translation file (English) so that we can include # the English text, below the untranslated phrase, in a comment. open( F, $base_trans_file ) || die "Error opening $base_trans_file"; print "Reading base translation file: $base_trans_file\n" if ( $verbose ); while ( <F> ) { chop; s/\r*$//g; # remove annoying CR next if ( /^#/ ); if ( /\s*:\s*/ ) { $abbrev = $`; $base_trans{ $abbrev } = $'; } } close( F ); # # Now load the translation file we are going to update. # if ( -f $infile ) { print "Reading current translations from $infile\n" if ( $verbose ); open( F, $infile ) || die "Error opening $infile"; $in_header = 1; while ( <F> ) { chop; s/\r*$//g; # remove annoying CR if ( $in_header && /^#/ ) { if ( /Translation last (pagified|updated)/ ) { # Ignore since we will replace this with current date below. } else { $header .= $_ . "\n"; } } next if ( /^#/ ); $in_header = 0; if ( /\s*:\s*/ ) { $abbrev = $`; $temp = $'; $temp = '=' if ( $infile !~ /english-us/i && $base_trans{ $abbrev } eq $temp ); $trans{ $abbrev } = $temp; } } } $trans{ 'charset' } = '=' if ( !defined( $trans{ 'charset' } ) ); $trans{ 'direction' } = '=' if ( !defined( $trans{ 'direction' } ) ); $trans{ '__mm__/__dd__/__yyyy__' } = '=' if ( !defined( $trans{ '__mm__/__dd__/__yyyy__' } ) ); $trans{ '__month__ __dd__' } = '=' if ( !defined( $trans{ '__month__ __dd__' } ) ); $trans{ '__month__ __dd__, __yyyy__' } = '=' if ( !defined( $trans{ '__month__ __dd__, __yyyy__' } ) ); $trans{ '__month__ __yyyy__' } = '=' if ( !defined( $trans{ '__month__ __yyyy__' } ) ); if ( $plugin ne '' ) { print "Reading current WebCalendar translations from $b_infile\n" if ( $verbose ); open( F, $b_infile ) || die "Error opening $b_infile"; $in_header = 1; while ( <F> ) { chop; s/\r*$//g; # remove annoying CR if ( /\s*:\s*/ ) { $abbrev = $`; $webcaltrans{ $abbrev } = $'; } } } ( $day, $mon, $year ) = ( localtime( time() ) )[ 3, 4, 5 ]; $header .= '# Translation last updated on ' . sprintf( "%02d-%02d-%04d", $mon + 1, $day, $year + 1900 ) . "\n"; print "\nFinding WebCalendar class and php files.\n\n" if ( $verbose ); find \&find_pgm_files, $base_dir; # # Write new translation file. # $notfound = 0; open( OUT, ">$infile" ) || die "Error writing $infile: "; print OUT $header; if ( $plugin eq '' ) { $foundin{ 'charset' } = $foundin{ 'direction' } = $foundin{ '__mm__/__dd__/__yyyy__' } = $foundin{ '__month__ __dd__' } = $foundin{ '__month__ __dd__, __yyyy__' } = $foundin{ '__month__ __yyyy__' } = ' top of this file'; $text{ 'charset' } = $text{ 'direction' } = $text{ '__mm__/__dd__/__yyyy__' } = $text{ '__month__ __dd__' } = $text{ '__month__ __dd__, __yyyy__' } = $text{ '__month__ __yyyy__' } = 1; print OUT ( $infile !~ /english-us/i ? ' ' . ( '#' x 80 ) . ' # DO NOT "TRANSLATE" THIS SECTION # ' . ( '#' x 80 ) . ' # A lone equal sign "=" to the right of the colon, such as "charset: =", # indicates that the "translation" is identical to the English text. # Specify a charset (will be sent within meta tag for each page). ' : '' ) . ' charset: ' . $trans{ 'charset' } . ( $infile !~ /english-us/i ? ' # "direction" need only be changed if using a right to left language. # Options are: ltr (left to right, default) or rtl (right to left). ' : '' ) . ' direction: ' . $trans{ 'direction' } . ( $infile !~ /english-us/i ? ' # In the date formats, change only the format of the terms. # For example in German.txt the proper "translation" would be # __month__ __dd__, __yyyy__: __dd__. __month__ __yyyy__ # Select elements for date specification. # ex)2008-10-13 # __yyyy__ ... 2008, __mm__ ... 10, __month__ ... October, __dd__ ... 13 ' : '' ) . ' __mm__/__dd__/__yyyy__: ' . $trans{ '__mm__/__dd__/__yyyy__' } . ' __month__ __dd__: ' . $trans{ '__month__ __dd__' } . ' __month__ __dd__, __yyyy__: ' . $trans{ '__month__ __dd__, __yyyy__' } . ' __month__ __yyyy__: ' . $trans{ '__month__ __yyyy__' } . ' ' . ( $infile !~ /english-us/i ? ' ' . ('#' x 80).' ' . ('#' x 80).' ' : '' ); } foreach $f ( @files ) { open( F, $f ) || die "Error reading $f"; $f =~ s,^\.\.\/,,; $pageHeader = "\n" . ( '#' x 40 ) . "\n# Page: $f\n#\n"; print "Searching $f\n" if ( $verbose ); %thispage = (); while ( <F> ) { $data = $_; while ( $data =~ /(translate|tooltip)\s*\(\s*['"]/ ) { $data = $'; if ( $data =~ /['"]\s*[,\)]/ ) { $text = $`; if ( defined( $thispage{ $text } ) || $text eq 'charset' ) { # already found } elsif ( defined( $text{ $text } ) ) { if ( $show_dups ) { print OUT $pageHeader . "# \"$text\" previously defined (in $foundin{$text})\n"; $pageHeader = ''; } $thispage{ $text } = 1; } else { if ( !length( $trans{ $text } ) ) { if ( $show_missing ) { print OUT $pageHeader; $pageHeader = ''; if ( length( $webcaltrans{ $text } ) ) { print OUT "# \"$text\" defined in WebCalendar translation\n"; } else { print OUT "#\n# << MISSING >>\n# $text:\n"; print OUT "# English text: $base_trans{$text}\n#\n" if ( length( $base_trans{ $text } ) && $base_trans{ $text } ne $text ); } } $notfound++ if ( !length( $webcaltrans{ $text } ) ); } else { print OUT $pageHeader; $pageHeader = ''; printf OUT ( "%s: %s\n", $text, $trans{ $text } ); } $foundin{ $text } = $f; $text{ $text } = $thispage{ $text } = 1; } $data = $'; } } } close( F ); } print STDERR ( !$notfound ? "All text was found in $infile. Good job :-)\n" : "$notfound translation(s) missing.\n" ); exit 0; PK �]�\|]� � tools/update_all.plnu ȯ�� #!/usr/bin/perl # # Update each translation file using update_translation.pl. # ####################################################################### $transdir = "../translations"; opendir ( DIR, $transdir ) || die "Error opening $transdir: $!"; @files = readdir ( DIR ); closedir ( DIR ); # ignore everything except .txt files @files = grep ( /.txt$/, @files ); foreach $f ( @files ) { printf "%-25s", $f; print `perl update_translation.pl -b -m $f`; } print "\nDone.\n"; exit 0; PK �]�\ծW> > UPGRADING.htmlnu �[��� <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>WebCalendar Upgrading Notes</title> <link href="includes/css/docs.css" rel="stylesheet"> </head> <body id="upgrading"> <h1>WebCalendar Upgrading Notes</h1> <table> <tr> <th>WebCalendar Version:</th> <td>1.3.0 </td> </tr> </table> <p><span class="note">Important News:</span> A major improvement beginning with Version 1.1 is the addition of an automated installation script. This script will guide you through the installation process and help identify any problem areas that might prevent successful installation or operation of WebCalendar.</p> <ul> <li>If upgrading, the script will attempt to determine your current installation version and bring your database up to date.</li> <li>If this is a new installation, the installation script will create your database and setup the required tables for you. It can then create a default Administrator account and add the basic configuration data to get you up and running.</li> </ul> <p>This installation script was tested primarily using MySQL and Apache on a dedicated server. If using an ISP or a CPANEL installer, your mileage may vary. If problems arise, you can always follow the instruction below as in previous versions and setup your database manually. As with any upgrade, it's always a good idea to <span style="color: #F00">backup your data prior to installation</span>.</p> <p>Another major upgrade to WebCalendar for v1.1 is the implementation of full timezone support. In olders versions, all date/time data was stored based on server time and users set their 'time offset' relative to server time. Now, all date/time data will be stored in the database as Greenwich Mean Time (GMT) and users will be able to select a timezone based on their geographical location.</p> <p>Having true timezone information available within WebCalendar enables the system to correct for Daylight Savings Time (DST) even if users are in different timezones. The database houses timezone information from 1970 to 2038 and can calculate the appropriate GMT offset required to allow users to see events in their true 'local time'.</p> <p>The installation script will perform the initial import of the timezone data and guide you through the one-time conversion required to get your existing data converted to GMT.</p> <p><a href="install/index.php">Launch the Automatic Installation Script</a></p> <h2>Upgrading Steps</h2> <p>With the install wizard, you will no longer be troubled with uploading SQL files to phpMyAdmin or executing SQL commands yourself. (For the most part. There are one or two database types that have not been fully implemented, as yet. If you are able to set them up, we'd appreciate the help.) Your database will be upgraded automatically from your current WebCalendar installation. Follow the steps below to upgrade to WebCalendar 1.3.0 from an older version of WebCalendar. </p><p><b>NOTE:</b> You should use the <a href="install/index.php">Launch the Automatic Installation Script</a> instead of doing this manually, but the information below is provided as documentation for those who are interested... All users (including those using the Automatic Installation Script) should create a backup of their database before performing the upgrade. </p> <ol> <li>Make a backup of your current WebCalendar database. This can be done a couple of different ways. <ul> <li>If you have access to phpMyAdmin, you can use the export function: <ul> <li>Startup phpMyAdmin </li> <li>Select the database from the pulldown on the left under the label "Databases". (This will be the same database name used in your <span class="tt">includes/settings.php</span> file in your current WebCalendar installation.)</li> <li>Click on the "Export" tab.</li> <li>Select the radio button for "Custom - display all possible options"</li> <li>It's best to use "SQL" for the "Format:" so it can be easily imported again.</li> <li>Under "Tables:" Make sure all the tables are checked as well as both the "structure" and "data" checkboxes for all of them.</li> <li>Under "Output:" Select "Save output to a file".</li> <li>Under "Data creation options" you'll want at least "Function to use when dumping data: INSERT" and "both of the above" radio button.</li> <li>Experiment with the other options to find out what works best for your situation.</li> <li>Click on the "Go" button at the bottom of the page and save the file to your computer. Preferably somewhere you can find it again; like the desktop.</li> </ul> </li> <li>If you have access to a MySQL command line (typically via shell access on a Linux server), you can use the mysqldump command:<br> <span class="tt">mysqldump -u<b>USERNAME</b> -p<b>PASSWORD DATABASE</b> > dumpfile.sql</span> <br>Of course, replace USERNAME, PASSWORD and DATABASE from the values in your <span class="tt">includes/settings.php</span> file from your current WebCalendar installation. </li> </ul></li> </li> <li>Make a backup of your current WebCalendar files on the server. You would typically do this with an FTP client (like <a href="https://filezilla-project.org/">FileZilla</a>). </li> <li>Install the new WebCalendar files in a <b>new</b> directory on your server. How you do this will depend on what type of access you have to your server. It is best to not overwrite your old WebCalendar install. The unpacked/unzipped files will create a directory with the current WebCalendar version name in it. </li> <li><b>Optional:</b> If you prefer to use a simple name (like "webcalendar" rather than "WebCalendar-1.2.7"), then you can rename the directory after you've installed the files. A good way to do this might be to rename your old webcalendar install to something like "webcalendar-oldinstall" and rename the new install to be the same name as your old one. <br><b>Note:</b> If you are planning on renaming the directory, it is best to do this <i>before</i> you proceed to the automated install. </li> <li>Change the permissions of the <span class="tt">includes</span> directory. If you are doing this from FTP, change directories to the new webcalendar directory and use the following command:<br> <span class="tt">chmod 777 includes</span> <li>Change the permissions of the <span class="tt">icons</span> directory. If you are doing this from FTP, change directories to the new webcalendar directory and use the following command:<br> <span class="tt">chmod 777 icons</span> <li>Download a copy of your old <span class="tt">includes/settings.php</span> file from your current WebCalendar install and have it handy so you can enter the same values in your upgrade process. </li> <li>Download all files in your old <span class="tt">icons</span> directory from your old WebCalendar and copy the files into the <span class="tt">icons</span> directory in the new install directory. </li> <li>You're now ready to start the install/upgrade wizard. Point your browser to the web server where you have installed the files. You only need to specify the webcalendar directory to get to the wizard. Since there is no <span class="tt">includes/settings.php</span> file in the new install, you will be redirected to the install/upgrade wizard.</li> <li>Once the wizard is complete, it's a good idea to change your <span class="tt">includes</span> permissions back to what they were originally for better security. </li> </ol> <hr> <h2>Manual Upgrade Instructions</h2> <p>Below are the steps needed to manually upgrade from a previous version. <b>You can ignore everything below if you use the Automated Installation Script.</b> Select the version of your existing install from the list below. If you are more than one version behind (i.e. the new version is v1.2.7, and you're using 1.1.1), you'll need to perform each upgrade in sequence from your current version on up. Don't skip any.</p> <p><span class="note">Note:</span> Due to large number of database types that WebCalendar can support, it would be impractical to list all the SQL variations here. All SQL listed is taken from the <a href="install/sql/upgrade-mysql.sql" target="_blank">upgrade-mysq.sql</a> file used during the automatic installation process. If you are using a database other then MySQL, you may want refer to the appropriate upgrade-xxxxx.sql file in the install/sql folder.</p> <h2>My currently installed version is...</h2> <ul> <li><a href="UPGRADING.html#from_1.1.3">1.1.3</a></li> <li><a href="UPGRADING.html#from_1.1.2">1.1.2</a></li> <li><a href="UPGRADING.html#from_1.1.1">1.1.1</a></li> <li><a href="UPGRADING.html#from_1.1.0e-CVS">1.1.0e-CVS</a></li> <li><a href="UPGRADING.html#from_1.1.0d-CVS">1.1.0d-CVS</a></li> <li><a href="UPGRADING.html#from_1.1.0c-CVS">1.1.0c-CVS</a></li> <li><a href="UPGRADING.html#from_1.1.0b-CVS">1.1.0b-CVS</a></li> <li><a href="UPGRADING.html#from_1.1.0a-CVS">1.1.0-CVS or 1.1.0a-CVS</a></li> <li><a href="UPGRADING.html#from_1.0.0">1.0RC3 or 1.0.0</a></li> <li><a href="UPGRADING.html#from_1_0RC3">0.9.42 or 1.0RC1</a></li> <li><a href="UPGRADING.html#dot942">0.9.42</a></li> <li><a href="UPGRADING.html#dot941">0.9.41</a></li> <li><a href="UPGRADING.html#dot940">0.9.40</a></li> <li><a href="UPGRADING.html#dot939">0.9.39</a></li> <li><a href="UPGRADING.html#dot938">0.9.38</a></li> <li><a href="UPGRADING.html#dot937">0.9.37</a></li> <li><a href="UPGRADING.html#dot936">0.9.35 - 0.9.36</a></li> <li><a href="UPGRADING.html#dot934">0.9.27 - 0.9.34</a></li> <li><a href="UPGRADING.html#dot926">0.9.22 - 0.9.26</a></li> <li><a href="UPGRADING.html#dot921">0.9.14 - 0.9.21</a></li> <li><a href="UPGRADING.html#dot913">0.9.12 - 0.9.13</a></li> <li><a href="UPGRADING.html#dot911">0.9.07 - 0.9.11</a></li> <li><a href="UPGRADING.html#dot906">0.9.01 - 0.9.06</a></li> <li><a href="UPGRADING.html#dot9">0.9</a></li> </ul> <hr> <h2><a id="dot9">To upgrade from v0.9</a></h2> <p>You need to create the table cal_user_pref in tables.sql. You need to create the table cal_entry_user in tables.sql that was mistakenly created as "cal_event_user" in the 0.9 release.</p> <a href="UPGRADING.html#dot906">next...</a> <hr> <h2><a id="dot906">To upgrade from v0.9.01</a></h2> <p>Entirely new tables are used. Use the following commands to convert your existing MySQL tables to the new tables:</p> <pre> cd tools ./upgrade_to_0.9.7.pl mysql intranet < commands.sql </pre> <p>where "intranet" is the name of the MySQL database that contains your WebCalendar tables.</p> <a href="UPGRADING.html#dot911">next...</a> <hr> <h2><a id="dot911">To upgrade from v0.9.07 - v0.9.11</a></h2> <p>To fix a bug in the handing of events at midnight, all the entries with NULL for cal_time are changed to -1. Use the following SQL command:</p> <pre>UPDATE webcal_entry SET cal_time = -1 WHERE cal_time is null;</pre> <a href="UPGRADING.html#dot913">next...</a> <hr> <h2><a id="dot913">To upgrade from v0.9.12 or v0.9.13</a></h2> <p>A new table was added to support repeating events. Use the following SQL command:</p> <pre> CREATE TABLE webcal_entry_repeats ( cal_id INT DEFAULT '0' NOT NULL, cal_days CHAR(7), cal_end INT, cal_frequency INT DEFAULT '1', cal_type VARCHAR(20), PRIMARY KEY (cal_id) ); </pre> <a href="UPGRADING.html#dot921">next...</a> <hr> <h2><a id="dot921">To upgrade from v0.9.14 - v0.9.21</a></h2> <p>A new table was added to support layering. For MySQL, the SQL is:</p> <pre> CREATE TABLE webcal_user_layers ( cal_login varchar(25) NOT NULL, cal_layeruser varchar(25) NOT NULL, cal_color varchar(25) NULL, cal_dups CHAR(1) DEFAULT 'N', cal_layerid INT DEFAULT '0' NOT NULL, PRIMARY KEY ( cal_login, cal_layeruser ) ); </pre> <a href="UPGRADING.html#dot926">next...</a> <hr> <h2><a id="dot926">To upgrade from v0.9.22 - v0.9.26</a></h2> <p>Two new tables were added for custom event fields and reminders. For MySQL the SQL is:</p> <pre> CREATE TABLE webcal_site_extras ( cal_id INT DEFAULT '0' NOT NULL, cal_name VARCHAR(25) NOT NULL, cal_type INT NOT NULL, cal_date INT DEFAULT '0', cal_remind INT DEFAULT '0', cal_data TEXT, PRIMARY KEY ( cal_id, cal_name, cal_type ) ); CREATE TABLE webcal_reminder_log ( cal_id INT DEFAULT '0' NOT NULL, cal_name VARCHAR(25) NOT NULL, cal_event_date INT NOT NULL DEFAULT 0, cal_last_sent INT NOT NULL DEFAULT 0, PRIMARY KEY ( cal_id, cal_name, cal_event_date ) ); </pre> <p>You will also need to setup the tools/send_reminders.php script to be run periodically. I would recommend once an hour. For Linux/UNIX, this is simple. Just use cron and add a line to your crontab file that looks like:</p> <pre>1 * * * * cd /some/directory/webcalendar/tools; ./send_reminders.php</pre> <p>This will tell cron to run the script at one minute after the hour. Windows users will have to find another way to run the script. There are ports/look-a-likes of cron for Windows, so look around.</p> <a href="UPGRADING.html#dot934">next...</a> <hr> <h2><a id="dot934">To upgrade from v0.9.27 - v0.9.34</a></h2> <p>Six new tables were added for group support, views, system settings and activity logs. For MySQL the SQL is:</p> <pre> CREATE TABLE webcal_group ( cal_group_id INT NOT NULL, cal_last_update INT NOT NULL, cal_name VARCHAR(50) NOT NULL, cal_owner VARCHAR(25) NULL, PRIMARY KEY ( cal_group_id ) ); CREATE TABLE webcal_group_user ( cal_group_id INT NOT NULL, cal_login VARCHAR(25) NOT NULL, PRIMARY KEY ( cal_group_id, cal_login ) ); CREATE TABLE webcal_view ( cal_view_id INT NOT NULL, cal_name VARCHAR(50) NOT NULL, cal_owner VARCHAR(25) NOT NULL, cal_view_type CHAR(1), PRIMARY KEY ( cal_view_id ) ); CREATE TABLE webcal_view_user ( cal_view_id INT NOT NULL, cal_login VARCHAR(25) NOT NULL, PRIMARY KEY ( cal_view_id, cal_login ) ); CREATE TABLE webcal_config ( cal_setting VARCHAR(50) NOT NULL, cal_value VARCHAR(50) NULL, PRIMARY KEY ( cal_setting ) ); CREATE TABLE webcal_entry_log ( cal_log_id INT NOT NULL, cal_date INT NOT NULL, cal_entry_id INT NOT NULL, cal_login VARCHAR(25) NOT NULL, cal_time INT NULL, cal_type CHAR(1) NOT NULL, cal_text TEXT, PRIMARY KEY ( cal_log_id ) ); </pre> <a href="UPGRADING.html#dot936">next...</a> <hr> <h2><a id="dot936">To upgrade from v0.9.35 or v0.9.36</a></h2> <p>The webcal_entry_log table was modified, and a new table webcal_entry_repeats_not was created. Use the following SQL for MySQL:</p> <pre> ALTER TABLE webcal_entry_log ADD cal_user_cal VARCHAR(25); CREATE TABLE webcal_entry_repeats_not ( cal_id INT NOT NULL, cal_date INT NOT NULL, PRIMARY KEY ( cal_id, cal_date ) ); </pre> <a href="UPGRADING.html#dot937">next...</a> <hr> <h2><a id="dot937">To upgrade from v0.9.37</a></h2> <p>The webcal_entry_user table was modified, and a new table webcal_categories was created. Use the following SQL for MySQL:</p> <pre> ALTER TABLE webcal_entry_user ADD cal_category INT DEFAULT NULL; CREATE TABLE webcal_categories ( cat_id INT NOT NULL, cat_name VARCHAR(80) NOT NULL, cat_owner VARCHAR(25), PRIMARY KEY ( cat_id ) ); </pre> <a href="UPGRADING.html#dot938">next...</a> <hr> <h2><a id="dot938">To upgrade from v0.9.38</a></h2> <p>The names of the date settings in the database were modified. All old data settings need to be removed from the database.</p> <pre> DELETE FROM webcal_config WHERE cal_setting LIKE 'DATE_FORMAT%'; DELETE FROM webcal_user_pref WHERE cal_setting LIKE 'DATE_FORMAT%'; </pre> <a href="UPGRADING.html#dot939">next...</a> <hr> <h2><a id="dot939">To upgrade from v0.9.39</a></h2> <p>Two new tables were created: webcal_asst and webcal_entry_ext_user. And the column cal_ext_for_id was added to the webcal_entry table. Use the following SQL for MySQL:</p> <pre> CREATE TABLE webcal_asst ( cal_boss VARCHAR(25) NOT NULL, cal_assistant VARCHAR(25) NOT NULL, PRIMARY KEY ( cal_boss, cal_assistant ) ); CREATE TABLE webcal_entry_ext_user ( cal_id INT DEFAULT 0 NOT NULL, cal_fullname VARCHAR(50) NOT NULL, cal_email VARCHAR(75) NULL, PRIMARY KEY ( cal_id, cal_fullname ) ); ALTER TABLE webcal_entry ADD cal_ext_for_id INT NULL; </pre> <a href="UPGRADING.html#dot940">next...</a> <hr> <h2><a id="dot940">To upgrade from v0.9.40</a></h2> <p>One new table was added: webcal_nonuser_cals. Use the following SQL for MySQL:</p> <pre> CREATE TABLE webcal_nonuser_cals ( cal_login VARCHAR(25) NOT NULL, cal_admin VARCHAR(25) NOT NULL, cal_firstname VARCHAR(25), cal_lastname VARCHAR(25), PRIMARY KEY ( cal_login ) ); </pre> <a href="UPGRADING.html#dot941">next...</a> <hr> <h2><a id="dot941">To upgrade from v0.9.41</a></h2> <p>Three new tables were added: webcal_report, webcal_report_template, and webcal_import_data. Use the following SQL for MySQL:</p> <pre> CREATE TABLE webcal_report ( cal_report_id INT NOT NULL, cal_allow_nav CHAR(1) DEFAULT 'Y', cal_cat_id INT NULL, cal_include_empty CHAR(1) DEFAULT 'N', cal_include_header CHAR(1) DEFAULT 'Y' NOT NULL, cal_is_global CHAR(1) DEFAULT 'N' NOT NULL, cal_login VARCHAR(25) NOT NULL, cal_report_name VARCHAR(50) NOT NULL, cal_report_type VARCHAR(20) NOT NULL, cal_show_in_trailer CHAR(1) DEFAULT 'N', cal_time_range INT NOT NULL, cal_update_date INT NOT NULL, cal_user VARCHAR(25) NULL, PRIMARY KEY ( cal_report_id ) ); CREATE TABLE webcal_report_template ( cal_report_id INT NOT NULL, cal_template_type CHAR(1) NOT NULL, cal_template_text TEXT, PRIMARY KEY ( cal_report_id, cal_template_type ) ); CREATE TABLE webcal_import_data ( cal_id int NOT NULL, cal_login VARCHAR(25) NOT NULL, cal_external_id VARCHAR(200) NULL, cal_import_type VARCHAR(15) NOT NULL, PRIMARY KEY ( cal_id, cal_login ) ); </pre> <a href="UPGRADING.html#dot942">next...</a> <hr> <h2><a id="dot942">To upgrade from v0.9.42</a></h2> <p>User passwords are now stored using md5 and require the webcal_user table to be altered to accommodate larger password data. Use the following SQL for MySQL:</p> <pre> ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR(32) NULL; DROP TABLE webcal_import_data; CREATE TABLE webcal_import ( cal_import_id INT NOT NULL, cal_date INT NOT NULL, cal_login VARCHAR(25) NULL, cal_name VARCHAR(50) NULL, cal_type VARCHAR(10) NOT NULL, PRIMARY KEY ( cal_import_id ) ); CREATE TABLE webcal_import_data ( cal_id INT NOT NULL, cal_login VARCHAR(25) NOT NULL, cal_external_id VARCHAR(200) NULL, cal_import_id INT NOT NULL, cal_import_type VARCHAR(15) NOT NULL, PRIMARY KEY ( cal_id, cal_login ) ); </pre> <p>Next, you will need to run the script found in the <span class="tt">tools</span> subdirectory. This will convert all your passwords from plain text to md5. You can run this from the command line (if you have a standalone version of PHP compiled):</p> <pre> cd tools php convert_passwords.php </pre> <p>Or, if you do not have a standalone version of PHP, you can just type in the URL to access the script in your browser:</p> <pre>http://yourcalendarurl/tools/convert_passwords.php</pre> <p>You may safely delete the file <span class="tt">/tools/convert_passwords.php</span> after successfully performing this step.</p> <p>Delete all webcalendar_login browser cookies. Details should be available on your local browser help section.</p> <a href="UPGRADING.html#from_1_0RC3">next...</a> <hr> <h2><a id="from_1_0RC3">To upgrade from v0.9.43 - v1.0RC3</a></h2> <p>The <span class="tt">webcal_view</span> table was modified. Execute the following SQL to update your database:</p> <pre> UPDATE webcal_config SET cal_value = 'week.php' WHERE cal_setting = 'STARTVIEW'; UPDATE webcal_user_pref SET cal_value = 'day.php' WHERE cal_value = 'day' AND cal_setting = 'STARTVIEW'; UPDATE webcal_user_pref SET cal_value = 'month.php' WHERE cal_value = 'month' AND cal_setting = 'STARTVIEW'; UPDATE webcal_user_pref SET cal_value = 'week.php' WHERE cal_value = 'week' AND cal_setting = 'STARTVIEW'; UPDATE webcal_user_pref SET cal_value = 'year.php' WHERE cal_value = 'year' AND cal_setting = 'STARTVIEW'; ALTER TABLE webcal_view ADD cal_is_global CHAR(1) NOT NULL DEFAULT 'N'; UPDATE webcal_view SET cal_is_global = 'N'; </pre> <a href="UPGRADING.html#from_1.0.0">next...</a> <hr> <h2><a id="from_1.0.0">To upgrade from v1.0RC3 - v1.0.0</a></h2> <p>Two new tables need to be created to support advanced user access control. One new table is needed to store custom user header/footer template information. Execute the following SQL to update your database:</p> <pre> CREATE TABLE webcal_access_user ( cal_login VARCHAR(25) NOT NULL, cal_other_user VARCHAR(25) NOT NULL, cal_can_approve CHAR(1) NOT NULL DEFAULT 'N', cal_can_delete CHAR(1) NOT NULL DEFAULT 'N', cal_can_edit CHAR(1) NOT NULL DEFAULT 'N', cal_can_view CHAR(1) NOT NULL DEFAULT 'N', PRIMARY KEY ( cal_login, cal_other_user ) ); CREATE TABLE webcal_access_function ( cal_login VARCHAR(25) NOT NULL, cal_permissions VARCHAR(64) NOT NULL, PRIMARY KEY ( cal_login ) ); ALTER TABLE webcal_nonuser_cals ADD cal_is_public CHAR(1) NOT NULL DEFAULT 'N'; CREATE TABLE webcal_user_template ( cal_login VARCHAR(25) NOT NULL, cal_type CHAR(1) NOT NULL, cal_template_text TEXT, PRIMARY KEY ( cal_login, cal_type ) ); </pre> <a href="UPGRADING.html#from_1.1.0a-CVS">next...</a> <hr> <h2><a id="from_1.1.0a-CVS">To upgrade from 1.1.0-CVS or 1.1.0a-CVS</a></h2> <p>A new table is needed to support multiple categories. In addition, several new columns have been added to webcal_entry and one column added to webcal_entry_user to support VTODO tasks, and to webcal_repeats to support the much improved ical support. A new column was added to webcal_entry_repeats_not to differentiate between exclusion and inclusions. Use the following SQL to update your MySQL database:</p> <pre> ALTER TABLE webcal_entry ADD cal_due_date int(11) default NULL; ALTER TABLE webcal_entry ADD cal_due_time int(11) default NULL; ALTER TABLE webcal_entry ADD cal_location varchar(50) default NULL; ALTER TABLE webcal_entry ADD cal_url varchar(100) default NULL; ALTER TABLE webcal_entry ADD cal_completed int(11) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_endtime int(11) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_byday varchar(100) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_bymonth varchar(50) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_bymonthday varchar(100) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_bysetpos varchar(50) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_byweekno varchar(50) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_byyearday varchar(50) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_count int(11) default NULL; ALTER TABLE webcal_entry_repeats ADD cal_wkst char(2) default 'MO'; ALTER TABLE webcal_entry_repeats_not ADD cal_exdate int(1) NOT NULL DEFAULT '1'; ALTER TABLE webcal_entry_user ADD cal_percent int(11) NOT NULL DEFAULT '0'; CREATE TABLE webcal_entry_categories ( cal_id int(11) NOT NULL default '0', cat_id int(11) NOT NULL default '0', cat_order int(11) NOT NULL default '0', cat_owner varchar(25) default NULL ); </pre> <a href="UPGRADING.html#from_1.1.0b-CVS">next...</a> <hr> <h2><a id="from_1.1.0b-CVS">To upgrade from 1.1.0b-CVS</a></h2> <p>We need a new table to handle event attachments and comments. This is the SQL.</p> <pre> CREATE TABLE webcal_blob ( cal_blob_id INT NOT NULL, cal_description VARCHAR(128) NULL, cal_id INT NULL, cal_login VARCHAR(25) NULL, cal_mime_type VARCHAR(50) NULL, cal_mod_date INT NOT NULL, cal_mod_time INT NOT NULL, cal_name VARCHAR(30) NULL, cal_size INT NULL, cal_type CHAR(1) NOT NULL, cal_blob LONGBLOB, PRIMARY KEY (cal_blob_id) ); </pre> <a href="UPGRADING.html#from_1.1.0c-CVS">next...</a> <hr> <h2><a id="from_1.1.0c-CVS">upgrading from 1.1.0cCVS</a></h2> <p>We're recreating table webcal_access_user to add several fields.</p> <pre> DROP TABLE IF EXISTS webcal_access_user; CREATE TABLE webcal_access_user ( cal_login VARCHAR(25) NOT NULL, cal_other_user VARCHAR(25) NOT NULL, cal_can_approve INT NOT NULL DEFAULT '0', cal_can_edit INT NOT NULL DEFAULT '0', cal_can_email CHAR(1) DEFAULT 'Y', cal_can_invite CHAR(1) DEFAULT 'Y', cal_can_view INT NOT NULL DEFAULT '0', cal_see_time_only CHAR(1) DEFAULT 'N', PRIMARY KEY (cal_login, cal_other_user) ); </pre> <a href="UPGRADING.html#from_1.1.0d-CVS">next...</a> <hr> <h2><a id="from_1.1.0d-CVS">upgrading from 1.1.0d-CVS</a></h2> <p>A new table to track reminders. When are they due? Have they been sent?</p> <pre> CREATE TABLE webcal_reminders ( cal_id INT NOT NULL DEFAULT '0', cal_action VARCHAR(12) NOT NULL DEFAULT 'EMAIL', cal_before CHAR(1) NOT NULL DEFAULT 'Y', cal_date INT NOT NULL DEFAULT '0', cal_duration INT NOT NULL DEFAULT '0', cal_last_sent INT NOT NULL DEFAULT '0', cal_offset INT NOT NULL DEFAULT '0', cal_related CHAR(1) NOT NULL DEFAULT 'S', cal_repeats INT NOT NULL DEFAULT '0', cal_times_sent INT NOT NULL DEFAULT '0', PRIMARY KEY (cal_id) ); </pre> <a href="UPGRADING.html#from_1.1.0e-CVS">next...</a> <hr> <h2><a id="from_1.1.0e-CVS">Upgrade from 1.1.0e-CVS</a></h2> <p>A new field indicating the URL of a public, or at least a non-user, calendar event.</p> <pre> ALTER TABLE webcal_nonuser_cals ADD cal_url VARCHAR(255) DEFAULT NULL; </pre> <a href="UPGRADING.html#from_1.1.1">next...</a> <hr> <h2><a id="from_1.1.1">Upgrade from 1.1.1</a></h2> <p>Add a color for each user category. We are also considering tracking more user data; birthday, phone, etc. As a contact reference as well as an event calendar.</p> <pre> ALTER TABLE webcal_categories ADD cat_color VARCHAR(8) DEFAULT NULL; ALTER TABLE webcal_user ADD cal_address VARCHAR(75) DEFAULT NULL; ALTER TABLE webcal_user ADD cal_birthday INT NULL; ALTER TABLE webcal_user ADD cal_enabled CHAR(1) DEFAULT 'Y'; ALTER TABLE webcal_user ADD cal_last_login INT NULL; ALTER TABLE webcal_user ADD cal_telephone VARCHAR(50) DEFAULT NULL; ALTER TABLE webcal_user ADD cal_title VARCHAR(75) DEFAULT NULL; </pre> <a href="UPGRADING.html#from_1.1.2">next...</a> <hr> <h2><a id="from_1.1.2">Upgrade from 1.1.2</a></h2> <p>A new table to hold the various timezones of the world. How far from Greenich Mean Time? When does Daylight Savings start / end, if applicable.</p> <pre> CREATE TABLE webcal_timezones ( tzid varchar(100) NOT NULL default '', dtstart varchar(25) default NULL, dtend varchar(25) default NULL, vtimezone text, PRIMARY KEY (tzid) ); </pre> <a href="UPGRADING.html#from_1.1.3">next...</a> <hr> <h2><a id="from_1.1.3">Upgrade from 1.1.3</a></h2> <p>// Craig. This LOOKS like an extensive upgrade. However, mostly it's just putting the table / field /*comments*/ from "install/sql/tables-mysql.sql" in the actual database to make maintaining it easier. Also, phpMyAdmin can use the "COMMENT"s to create a replacement for "docs/WebCalendar-Database.html" without the need for "docs/sql2html.pl". Mostly. It isn't quite as clean:<ul><li>there is some unnecessary javascript.</li><li>all the "rowspan='1' is kind of silly.</li><li>It needs to be run through html_entity_decode().</li><li>It doesn't have the list of tables at the top.</li></ul>But, it looks the same otherwise.<br><br>phpMyAdmin "export" puts the "ENGINE" and "CHARSET" in the file, so I included them, too.<br>I am also utilizing MySQL / MariaDB field types such as enum, tinyint, etc. to better show what the field is about.<br><br>Converting from MySQL / Maria to all the other dababase types supported by WebCalendar only takes about 50 lines total, mostly preg_replace() with arrays, in a switch construct. We would only need a single "tables.sql" and a single "upgrade.sql" instead of all the variants. (Work in progress.)<br><br>The new table, "webcal_translations" (not yet used) to hold the various language translations. Eventually would eliminate all the various "translations/*.txt" files. "tools/update_translation.pl" could create the sql files to load it, while creating the *.txt files for the translators.<br><br>I'm also looking at consolidating some fields / tables into webcal_user_pref. Only takes about 100 lines of code changes. Not counting the "/*Consolodate some fields*/" section below. What do you think? bb </p> <pre> ALTER TABLE webcal_access_user ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Specifies which users can access another user''s calendar.'; ALTER TABLE webcal_access_user MODIFY cal_see_time_only ENUM('N','Y') NOT NULL DEFAULT 'N' COMMENT 'Can current user can only see time of other user?'; ALTER TABLE webcal_access_user MODIFY cal_can_view smallint UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Can current user view events on the other user''s calendar?' FIRST; ALTER TABLE webcal_access_user MODIFY cal_can_invite ENUM('N','Y') NOT NULL DEFAULT 'Y' COMMENT 'Can current user see other user in Participant lists?' FIRST; ALTER TABLE webcal_access_user MODIFY cal_can_email ENUM('N','Y') DEFAULT 'Y' COMMENT 'Can current user send emails to other user?' FIRST; ALTER TABLE webcal_access_user MODIFY cal_can_edit smallint UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Can current user edit events on the other user''s calendar?' FIRST; ALTER TABLE webcal_access_user MODIFY cal_can_approve smallint UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Can current user approve events on the other user''s calendar?' FIRST; ALTER TABLE webcal_access_user MODIFY cal_other_user varchar(25) NOT NULL COMMENT 'The login of the other user whose calendar the current user wants to access. Also, from <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_access_user MODIFY cal_login varchar(25) NOT NULL COMMENT 'The current user who is attempting to look at another user''s calendar. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_access_function ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Specifies what WebCalendar functions a user can access. Each function has a corresponding numeric value (specified in the file includes/access.php). For example, view event is 0, so the very first character in the cal_permissions column is either a "Y" if this user can view events or a "N" if they cannot.'; ALTER TABLE webcal_access_function MODIFY cal_login varchar(25) NOT NULL COMMENT 'User login. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_access_function MODIFY cal_permissions varchar(64) NOT NULL COMMENT 'A string of "Y"s and/or "N"s for the various functions.'; ALTER TABLE webcal_asst ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Define assistant/boss relationship.'; ALTER TABLE webcal_asst MODIFY cal_assistant varchar(25) NOT NULL COMMENT 'Assistant login. Also from <a href="#webcal_user">webcal_user</a> table.'; ALTER TABLE webcal_asst MODIFY cal_boss varchar(25) NOT NULL COMMENT 'Boss login. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_blob ENGINE MyISAM CHARACTER SET utf8 COMMENT 'This table stores event attachments and comments.'; ALTER TABLE webcal_blob MODIFY cal_type ENUM('A','C') NOT NULL DEFAULT 'C' COMMENT 'Type of object: C=Comment, A=Attachment.' FIRST; ALTER TABLE webcal_blob MODIFY cal_size int UNSIGNED DEFAULT NULL COMMENT 'Size of object (not used for comments).' FIRST; ALTER TABLE webcal_blob MODIFY cal_name varchar(30) DEFAULT NULL COMMENT 'Filename of object (not used for comments).' FIRST; ALTER TABLE webcal_blob MODIFY cal_mod_time time NOT NULL COMMENT 'Time added.' FIRST; ALTER TABLE webcal_blob ADD cal_mod TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'When was this added / changed?' FIRST; ALTER TABLE webcal_blob MODIFY cal_mod TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'When was this added / changed?' FIRST; ALTER TABLE webcal_blob MODIFY cal_mime_type varchar(50) DEFAULT NULL COMMENT 'MIME type of object (as specified by browser during upload (not used for comment).' FIRST; ALTER TABLE webcal_blob MODIFY cal_login varchar(25) DEFAULT NULL COMMENT 'Login of user who created. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_blob MODIFY cal_id int UNSIGNED DEFAULT NULL COMMENT 'Event id (if applicable). From <a href="#webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_blob MODIFY cal_description varchar(128) DEFAULT NULL COMMENT 'Description of what the object is (subject for comment).' FIRST; ALTER TABLE webcal_blob MODIFY cal_blob_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique identifier for this object.' FIRST; ALTER TABLE webcal_blob MODIFY cal_blob longblob COMMENT 'Binary data for object.'; ALTER TABLE webcal_blob ADD UNIQUE KEY wb_cl_cd (cal_login,cal_description); ALTER TABLE webcal_categories ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Defines user categories. Categories can be specific to a user or global. When a category is global, the cat_owner field will be NULL. (Only an admin user can create a global category.)'; ALTER TABLE webcal_categories MODIFY cat_name varchar(80) NOT NULL COMMENT 'Category name.' FIRST; ALTER TABLE webcal_categories MODIFY cat_color varchar(7) DEFAULT NULL COMMENT 'RGB color for category.' FIRST; ALTER TABLE webcal_categories MODIFY cat_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique category id.' FIRST; ALTER TABLE webcal_categories MODIFY cat_owner varchar(25) DEFAULT NULL COMMENT 'User login of category owner. From <a href="#webcal_user">webcal_user</a> table, if applicable. If this is NULL, then it is a global category.'; ALTER TABLE webcal_config ENGINE MyISAM CHARACTER SET utf8 COMMENT 'System settings (set by the admin interface in admin.php).'; ALTER TABLE webcal_config MODIFY cal_setting varchar(50) NOT NULL COMMENT 'System setting.' FIRST; ALTER TABLE webcal_config MODIFY cal_value varchar(100) NULL COMMENT 'System setting value.'; ALTER TABLE webcal_entry ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Defines a calendar event. Each event in the system has one entry in this table unless the event starts before midnight and ends after midnight. In that case a secondary event will be created with cal_ext_for_id set to the cal_id of the original entry. The following tables contain additional information about each event:<ul><li><a href="#webcal_entry_user">webcal_entry_user</a> table - lists participants in the event and specifies the status (accepted, rejected) and category of each participant.</li><li><a href="#webcal_entry_repeats">webcal_entry_repeats</a> table - contains information if the event repeats.</li><li><a href="#webcal_entry_repeats_not">webcal_entry_repeats_not</a> table - specifies which dates the repeating event does not repeat (because they were deleted or modified for just that date by the user.)</li><li><a href="#webcal_entry_log">webcal_entry_log</a> table - provides a history of changes to this event.</li><li><a href="#webcal_site_extras">webcal_site_extras</a> table - stores event data as defined in site_extras.php (such as reminders and other custom event fields).</li></ul>'; ALTER TABLE webcal_entry MODIFY cal_url varchar(100) DEFAULT NULL COMMENT 'URL of event.'; ALTER TABLE webcal_entry MODIFY cal_type ENUM('E','M','T') DEFAULT 'E' COMMENT '"E" = Event, "M" = Repeating event, "T" = Task.' FIRST; ALTER TABLE webcal_entry MODIFY cal_time time DEFAULT NULL COMMENT 'Event start time.' FIRST; ALTER TABLE webcal_entry MODIFY cal_priority tinyint UNSIGNED DEFAULT '5' COMMENT 'Event priority: 1=High, 9=Low.' FIRST; ALTER TABLE webcal_entry MODIFY cal_name varchar(80) NOT NULL COMMENT 'Brief description of event.' FIRST; ALTER TABLE webcal_entry MODIFY cal_mod_time time DEFAULT NULL COMMENT 'Time the event was last modified.' FIRST; ALTER TABLE webcal_entry ADD cal_mod TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'When was this added / changed?' FIRST; ALTER TABLE webcal_entry MODIFY cal_mod TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'When was this added / changed?' FIRST; ALTER TABLE webcal_entry MODIFY cal_location varchar(100) DEFAULT NULL COMMENT 'Location of event.' FIRST; ALTER TABLE webcal_entry MODIFY cal_group_id int UNSIGNED DEFAULT NULL COMMENT 'The parent event id if this event is overriding an occurrence of a repeating event. From this table.' FIRST; ALTER TABLE webcal_entry MODIFY cal_ext_for_id int UNSIGNED DEFAULT NULL COMMENT 'Used when an event goes past midnight into the next day, in which case an additional entry in this table will use this field to indicate the original event cal_id.' FIRST; ALTER TABLE webcal_entry MODIFY cal_duration int UNSIGNED NOT NULL COMMENT 'Duration of event in minutes.' FIRST; ALTER TABLE webcal_entry MODIFY cal_due_time time DEFAULT NULL COMMENT 'Task due time.' FIRST; ALTER TABLE webcal_entry ADD cal_due datetime DEFAULT NULL COMMENT 'When is this task due?' FIRST; ALTER TABLE webcal_entry MODIFY cal_due datetime DEFAULT NULL COMMENT 'When is this task due?' FIRST; ALTER TABLE webcal_entry ADD cal_datetime datetime NOT NULL COMMENT 'When is this event scheduled to start?' FIRST; ALTER TABLE webcal_entry MODIFY cal_datetime datetime NOT NULL COMMENT 'When is this event scheduled to start?' FIRST; ALTER TABLE webcal_entry MODIFY cal_date date NOT NULL COMMENT 'Date of event.' FIRST; ALTER TABLE webcal_entry MODIFY cal_create_by varchar(25) NOT NULL COMMENT 'Login of user that created the event. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_entry MODIFY cal_completed date DEFAULT NULL COMMENT 'Date task completed.' FIRST; ALTER TABLE webcal_entry MODIFY cal_access ENUM('C','P','R') DEFAULT 'P' COMMENT '"P" = Public, "R" = Private (others cannot see the event), "C" = Confidential (others can see time allocated but not what it is).' FIRST; ALTER TABLE webcal_entry MODIFY cal_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique integer id for event.' FIRST; UPDATE webcal_entry SET cal_datetime = CONCAT(cal_date,cal_time); UPDATE webcal_entry SET cal_due = CONCAT(cal_due_date,cal_due_time); ALTER TABLE webcal_entry_categories ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Contains category foreign keys to enable multiple categories for each event or task.'; ALTER TABLE webcal_entry_categories MODIFY cat_owner varchar(25) DEFAULT NULL COMMENT 'User that owns this record. Global categories will be NULL. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_entry_categories MODIFY cat_order int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Order that user requests their categories appear. Globals are always last.'; ALTER TABLE webcal_entry_categories MODIFY cat_id int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Id of category from <a href="webcal_categories">webcal_categories</a> table.' FIRST; ALTER TABLE webcal_entry_categories MODIFY cal_id int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Id of event from <a href="webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_entry_ext_user ENGINE MyISAM CHARACTER SET utf8 COMMENT 'External user (no login) for an event.'; ALTER TABLE webcal_entry_ext_user MODIFY cal_fullname varchar(50) NOT NULL COMMENT 'external user full name'; ALTER TABLE webcal_entry_ext_user MODIFY cal_email varchar(75) NULL COMMENT 'external user email (for sending a reminder)' FIRST; ALTER TABLE webcal_entry_ext_user MODIFY cal_id int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'From <a href="webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_entry_log ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Activity log for an event.'; ALTER TABLE webcal_entry_log MODIFY cal_user_cal varchar(25) DEFAULT NULL COMMENT 'User of calendar affected. Also from <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_entry_log MODIFY cal_type ENUM('A','C','E','M','R','U') NOT NULL DEFAULT 'C' COMMENT 'Log types:<ul><li>C: Created</li><li>A: Approved/Confirmed by user</li><li>R: Rejected by user</li><li>U: Updated by user</li><li>M: Mail Notification sent</li><li>E: Reminder sent</li></ul>' FIRST; ALTER TABLE webcal_entry_log MODIFY cal_time time DEFAULT NULL FIRST; ALTER TABLE webcal_entry_log MODIFY cal_text text COMMENT 'Optional text.'; ALTER TABLE webcal_entry_log ADD cal_mod TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'When was this added / changed?' FIRST; ALTER TABLE webcal_entry_log MODIFY cal_login varchar(25) NOT NULL COMMENT 'User who performed this action. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_entry_log MODIFY cal_entry_id int UNSIGNED NOT NULL COMMENT 'Event id. From <a href="#webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_entry_log MODIFY cal_date date NOT NULL FIRST; ALTER TABLE webcal_entry_log MODIFY cal_log_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique id of this log entry.' FIRST; ALTER TABLE webcal_entry_repeats ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Defines repeating info about an event. The event is defined in <a href="#webcal_entry">webcal_entry</a> table.'; ALTER TABLE webcal_entry_repeats MODIFY cal_type varchar(20) DEFAULT NULL COMMENT 'Type of repeating:<ul><li>daily - repeats daily</li><li>monthlyByDate - repeats on same day of the month</li><li>monthlyBySetPos - repeats based on position within other ByXXX values</li><li>monthlyByDay - repeats on specified weekday, (2nd Monday, for example)</li><li>weekly - repeats every week</li><li>yearly - repeats on same date every year</li></ul>' FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_frequency int UNSIGNED DEFAULT '1' COMMENT 'Frequency of repeat: 1 = every, 2 = every other, 3 = every 3rd, etc.' FIRST; ALTER TABLE webcal_entry_repeats ADD cal_enddt datetime DEFAULT NULL COMMENT 'End date and time for repeating event.' FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_enddt datetime DEFAULT NULL COMMENT 'End date and time for repeating event.' FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_end date DEFAULT NULL COMMENT 'End date for repeating event.' FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_wkst ENUM('MO','TU','WE','TH','FR','SA','SU') DEFAULT 'MO' COMMENT 'Week starts on...'; ALTER TABLE webcal_entry_repeats MODIFY cal_days ENUM('N','Y') DEFAULT NULL COMMENT 'NO LONGER USED. We''ll leave it in for now.' FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_count int UNSIGNED DEFAULT NULL FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_byyearday varchar(50) DEFAULT NULL FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_byweekno varchar(50) DEFAULT NULL FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_bysetpos varchar(50) DEFAULT NULL FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_bymonthday varchar(100) DEFAULT NULL FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_bymonth varchar(50) DEFAULT NULL FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_byday varchar(100) DEFAULT NULL COMMENT 'The following columns are values as specified in RFC2445.' FIRST; ALTER TABLE webcal_entry_repeats MODIFY cal_id int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Event id. From <a href="#webcal_entry">webcal_entry</a> table.' FIRST; UPDATE webcal_entry_repeats SET cal_enddt = CONCAT(cal_end,cal_endtime); ALTER TABLE webcal_entry_repeats_not ENGINE MyISAM CHARACTER SET utf8 COMMENT 'This table specifies which dates in a repeating event have either been deleted, included, or replaced with another event for that day. When replaced, the cal_group_id (I know... not the best name, but it was not being used) column will be set to the original event. That way the user can delete the original event and (at the same time) delete any exception events.'; ALTER TABLE webcal_entry_repeats_not MODIFY cal_date DATE NOT NULL COMMENT 'Date event should not repeat.' FIRST; ALTER TABLE webcal_entry_repeats_not MODIFY cal_id int UNSIGNED NOT NULL COMMENT 'Event id of repeating event. From <a href="#webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_entry_repeats_not MODIFY cal_exdate tinyint UNSIGNED NOT NULL DEFAULT '1' COMMENT 'Indicates whether this record is an exclusion1) or inclusion0).'; ALTER TABLE webcal_entry_user ENGINE MyISAM CHARACTER SET utf8 COMMENT 'This table associates one or more users with an event by the event id. The event can be found in <a href="#webcal_entry">webcal_entry</a> table.'; ALTER TABLE webcal_entry_user MODIFY cal_status ENUM('A','C','D','P','R','W') DEFAULT 'A' COMMENT 'Status of event for this user:<ul><li>A=Accepted</li><li>C=Completed</li><li>D=Deleted</li><li>P=In-Progress</li><li>R=Rejected/Declined</li><li>W=Waiting</li></ul>'; ALTER TABLE webcal_entry_user MODIFY cal_percent tinyint UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Task percentage of completion for this user''s task.' FIRST; ALTER TABLE webcal_entry_user MODIFY cal_category int UNSIGNED DEFAULT NULL COMMENT 'Category of the event for this user.' FIRST; ALTER TABLE webcal_entry_user MODIFY cal_login varchar(25) NOT NULL COMMENT 'Participant in the event. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_entry_user MODIFY cal_id int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Event id. From <a href="#webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_group ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Define a group. Group members can be found in <a href="#webcal_group_user">webcal_group_user</a> table.'; ALTER TABLE webcal_group MODIFY cal_owner varchar(25) DEFAULT NULL COMMENT 'User login of user that created this group. From <a href="#webcal_user">webcal_user</a> table.'; ALTER TABLE webcal_group MODIFY cal_name varchar(50) NOT NULL COMMENT 'Name of the group.' FIRST; ALTER TABLE webcal_group MODIFY cal_last_update TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Date last updated.' FIRST; ALTER TABLE webcal_group MODIFY cal_group_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique group id.' FIRST; ALTER TABLE webcal_group_user ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Group members.'; ALTER TABLE webcal_group_user MODIFY cal_login varchar(25) NOT NULL COMMENT 'From <a href="webcal_user">webcal_user</a>'; ALTER TABLE webcal_group_user MODIFY cal_group_id int UNSIGNED NOT NULL COMMENT 'From <a href="webcal_group">webcal_group</a>' FIRST; ALTER TABLE webcal_import ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Used to track import data (one row per import).'; ALTER TABLE webcal_import MODIFY cal_type varchar(10) NOT NULL COMMENT 'Type of import (ical, vcal, palm, outlookcsv).'; ALTER TABLE webcal_import MODIFY cal_name varchar(50) DEFAULT NULL COMMENT 'Name of import (optional).' FIRST; ALTER TABLE webcal_import MODIFY cal_login varchar(25) DEFAULT NULL COMMENT 'User who performed the import.' FIRST; ALTER TABLE webcal_import MODIFY cal_date TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Datetime of import.' FIRST; ALTER TABLE webcal_import MODIFY cal_import_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique id for import.' FIRST; ALTER TABLE webcal_import_data ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Used to track import data (one row per event).'; ALTER TABLE webcal_import_data MODIFY cal_import_type varchar(15) NOT NULL COMMENT 'Type of import: "palm", "vcal", "ical" or "outlookcsv".'; ALTER TABLE webcal_import_data MODIFY cal_import_id int UNSIGNED NOT NULL COMMENT 'Import id (From <a href="#webcal_import">webcal_import</a> table.' FIRST; ALTER TABLE webcal_import_data MODIFY cal_external_id varchar(200) DEFAULT NULL COMMENT 'External id used in external calendar system (for example, UID in iCal).' FIRST; ALTER TABLE webcal_import_data MODIFY cal_login varchar(25) NOT NULL COMMENT 'User login. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_import_data MODIFY cal_id int UNSIGNED NOT NULL COMMENT 'Event id in WebCalendar. From <a href="#webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_nonuser_cals ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Defines non-user calendars.'; ALTER TABLE webcal_nonuser_cals MODIFY cal_url varchar(255) DEFAULT NULL COMMENT 'URL of the remote calendar.'; ALTER TABLE webcal_nonuser_cals MODIFY cal_lastname varchar(25) DEFAULT NULL COMMENT 'Calendar''s last name.' FIRST; ALTER TABLE webcal_nonuser_cals MODIFY cal_is_public ENUM('N','Y') NOT NULL DEFAULT 'N' COMMENT 'Can this nonuser calendar be a public calendar (no login required)?' FIRST; ALTER TABLE webcal_nonuser_cals MODIFY cal_firstname varchar(25) DEFAULT NULL COMMENT 'Calendar'' first name.' FIRST; ALTER TABLE webcal_nonuser_cals ADD cal_displayname varchar(50) DEFAULT NULL COMMENT 'Name to diplay on public or other user''s calendars.' FIRST; ALTER TABLE webcal_nonuser_cals MODIFY cal_admin varchar(25) NOT NULL COMMENT 'The calendar administrator. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_nonuser_cals MODIFY cal_login varchar(25) NOT NULL COMMENT 'Unique id for the calendar.' FIRST; UPDATE webcal_nonuser_cals SET cal_displayname = CONCAT_WS(' ',cal_firstname,cal_lastname); ALTER TABLE webcal_reminders ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Stores information about reminders.'; ALTER TABLE webcal_reminders MODIFY cal_times_sent int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Number of times this reminder has been sent.'; ALTER TABLE webcal_reminders MODIFY cal_repeats int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Number of times to repeat in addition to original occurrence.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_related ENUM('E','S') NOT NULL DEFAULT 'S' COMMENT 'S=Start, E=End. Specifies which edge of entry this reminder applies to.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_offset int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Offset in minutes from the selected edge.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_last_sent datetime NOT NULL COMMENT 'Timestamp of last sent reminder.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_duration int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Time in ISO 8601 format that specifies time between repeated reminders.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_date datetime NOT NULL COMMENT 'When to send? Use this or cal_offset, but not both.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_before ENUM('N','Y') NOT NULL DEFAULT 'Y' COMMENT 'Specifies whether reminder is sent before or after selected edge.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_action varchar(12) NOT NULL DEFAULT 'EMAIL' COMMENT 'Action as imported, may be used in the future.' FIRST; ALTER TABLE webcal_reminders MODIFY cal_id int UNSIGNED NOT NULL DEFAULT '0' FIRST; ALTER TABLE webcal_report ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Defines a custom report created by a user.'; ALTER TABLE webcal_report MODIFY cal_user varchar(25) DEFAULT NULL COMMENT 'User calendar to display (NULL indicates current user).'; ALTER TABLE webcal_report MODIFY cal_update_date date NOT NULL COMMENT 'Date created or last updated.' FIRST; ALTER TABLE webcal_report MODIFY cal_time_range int UNSIGNED NOT NULL COMMENT 'Time range for report:<ul><li>0 = tomorrow</li><li>1 = today</li><li>2 = yesterday</li><li>3 = day before yesterday</li><li>10 = next week</li><li>11 = current week</li><li>12 = last week</li><li>13 = week before last</li><li>20 = next week and week after</li><li>21 = current week and next week</li><li>22 = last week and this week</li><li>23 = last two weeks</li><li>30 = next month</li><li>31 = current month</li><li>32 = last month</li><li>33 = month before last</li><li>40 = next year</li><li>41 = current year</li><li>42 = last year</li><li>43 = year before last</li></ul>' FIRST; ALTER TABLE webcal_report MODIFY cal_show_in_trailer ENUM('N','Y') DEFAULT 'N' COMMENT 'Include a link for this report in the "Go to" section of the navigation in the page trailer? ("Y" or "N")' FIRST; ALTER TABLE webcal_report MODIFY cal_report_type varchar(20) NOT NULL COMMENT 'Format of report (html, plain or csv).' FIRST; ALTER TABLE webcal_report MODIFY cal_report_name varchar(50) NOT NULL COMMENT 'Name of the report.' FIRST; ALTER TABLE webcal_report ADD cal_mod TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Created or last updated.' FIRST; ALTER TABLE webcal_report MODIFY cal_login varchar(25) NOT NULL COMMENT 'Creator of report.' FIRST; ALTER TABLE webcal_report MODIFY cal_is_global ENUM('N','Y') NOT NULL DEFAULT 'N' COMMENT 'Is this a global report (can it be accessed by other users - "Y" or "N")' FIRST; ALTER TABLE webcal_report MODIFY cal_include_header ENUM('N','Y') NOT NULL DEFAULT 'Y' COMMENT 'If cal_report_type is "html", should the default HTML header and trailer be included? ("Y" or "N")' FIRST; ALTER TABLE webcal_report MODIFY cal_include_empty ENUM('N','Y') DEFAULT 'N' COMMENT 'Include empty dates in report ("Y" or "N").' FIRST; ALTER TABLE webcal_report MODIFY cal_cat_id int UNSIGNED DEFAULT NULL COMMENT 'Category to filter on (optional).' FIRST; ALTER TABLE webcal_report MODIFY cal_allow_nav ENUM('N','Y') DEFAULT 'Y' COMMENT 'Allow user to navigate to different dates with next/previous? ("Y" or "N")' FIRST; ALTER TABLE webcal_report MODIFY cal_report_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique id of this report.' FIRST; ALTER TABLE webcal_report_template ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Defines one of the templates used for a report. Each report has three templates: <ol><li>Page template - Defines the entire page (except for header and footer). The following variables can be defined:<ul><li>${days}<sup>*</sup> - the HTML of all dates (generated from the Date template)</li></ul></li><li>Date template - Defines events for one day. If the report is for a week or month, then the results of each day will be concatenated and used as the ${days} variable in the Page template. The following variables can be defined:<ul><li>${events}<sup>*</sup> - the HTML of all events for the data (generated from the Event template)</li><li>${date} - the date</li><li>${fulldate} - date (includes weekday)</li></ul></li><li>Event template - Defines a single event. The following variables can be defined: <ul><li>${name}<sup>*</sup> - Brief Description of event</li><li>${description} - Full Description of event</li><li>${date} - Date of event</li><li>${fulldate} - Date of event (includes weekday)</li><li>${time} - Time of event (4:00pm - 4:30pm)</li><li>${starttime} - Start time of event</li><li>${endtime} - End time of event</li><li>${duration} - Duration of event (in minutes)</li><li>${priority} - Priority of event</li><li>${href} - URL to view event details</li></ul></li></ol><sup>*</sup> denotes a required template variable.'; ALTER TABLE webcal_report_template MODIFY cal_template_type ENUM('D','E','P') NOT NULL DEFAULT "P" COMMENT 'Type of template:<ul><li>"P": page template represents entire document</li><li>"D": date template represents a single day of events</li><li>"E": event template represents a single event</li></ul>' FIRST; ALTER TABLE webcal_report_template MODIFY cal_template_text text COMMENT 'Text of template.'; ALTER TABLE webcal_report_template MODIFY cal_report_id int UNSIGNED NOT NULL COMMENT 'Report id from <a href="webcal_report table">webcal_report</a> table.' FIRST; ALTER TABLE webcal_site_extras ENGINE MyISAM CHARACTER SET utf8 COMMENT 'This table holds data for site extra fields (customized in site_extra.php).'; ALTER TABLE webcal_site_extras MODIFY cal_type int UNSIGNED NOT NULL COMMENT 'EXTRA_URL, EXTRA_DATE, etc.' FIRST; ALTER TABLE webcal_site_extras MODIFY cal_remind int UNSIGNED DEFAULT '0' COMMENT 'How many minutes before event should a reminder be sent.' FIRST; ALTER TABLE webcal_site_extras MODIFY cal_name varchar(25) NOT NULL COMMENT 'The brief name of this type (first field in $site_extra array).' FIRST; ALTER TABLE webcal_site_extras MODIFY cal_id int UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Event id from <a href="webcal_entry">webcal_entry</a> table.' FIRST; ALTER TABLE webcal_site_extras MODIFY cal_date DATE NULL DEFAULT NULL COMMENT 'Only used for EXTRA_DATE type fields.' FIRST; ALTER TABLE webcal_site_extras MODIFY cal_data text COMMENT 'Used to store text data.'; ALTER TABLE webcal_timezones ENGINE MyISAM CHARACTER SET utf8 COMMENT 'This table stores timezones of the world.'; ALTER TABLE webcal_timezones MODIFY vtimezone text COMMENT 'Complete VTIMEZONE text gleaned from imported ics files.'; ALTER TABLE webcal_timezones MODIFY tzid varchar(100) NOT NULL DEFAULT '' COMMENT 'Unique name of timezone, try to use Olsen naming conventions.' FIRST; ALTER TABLE webcal_timezones MODIFY dtstart varchar(16) DEFAULT NULL COMMENT 'Earliest date this timezone represents in YYYYMMDDTHHMMSSZ format.' FIRST; ALTER TABLE webcal_timezones MODIFY dtend varchar(16) DEFAULT NULL COMMENT 'Last date this timezone represents in YYYYMMDDTHHMMSSZ format.' FIRST; DROP TABLE IF EXISTS webcal_translations; CREATE TABLE IF NOT EXISTS webcal_translations ( phrase varchar(300) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL COMMENT 'The translate / tooltip (phrases) from the code. And the __phrase__ from version 2.0.0. ("latin1" is currently the only choice that is case sensitive.)', on_page varchar(50) NOT NULL COMMENT 'which code page (sorted alphabetically) has the first occurance of the above phrase.', English_US varchar(300) NOT NULL COMMENT 'The full English text.', Afrikaans varchar(300) NOT NULL, Albanian varchar(300) NOT NULL, Arabic varchar(300) NOT NULL, Armenian varchar(300) NOT NULL, Azerbaijan varchar(300) NOT NULL, Basque varchar(300) NOT NULL, Belarusian varchar(300) NOT NULL, Bulgarian varchar(300) NOT NULL, Catalan varchar(300) NOT NULL, Chamorro varchar(300) NOT NULL, Chinese_Big5 varchar(300) NOT NULL, Chinese_GB2312 varchar(300) NOT NULL, Croatian varchar(300) CHARACTER SET utf8 COLLATE utf8_croatian_ci NOT NULL, Czech varchar(300) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL, Danish varchar(300) CHARACTER SET utf8 COLLATE utf8_danish_ci NOT NULL, Dutch varchar(300) NOT NULL, Elven varchar(300) NOT NULL COMMENT 'From JRR Tolkien "Hobbit" and "Lord of the Rings".', Esperanto varchar(300) CHARACTER SET utf8 COLLATE utf8_esperanto_ci NOT NULL, Estonian varchar(300) CHARACTER SET utf8 COLLATE utf8_estonian_ci NOT NULL, Faroese varchar(300) NOT NULL, Farsi varchar(300) NOT NULL, Finnish varchar(300) NOT NULL, French varchar(300) NOT NULL, Galician varchar(300) NOT NULL, Georgian varchar(300) NOT NULL, German varchar(300) CHARACTER SET utf8 COLLATE utf8_german2_ci NOT NULL, Greek varchar(300) NOT NULL, Hebrew varchar(300) NOT NULL, Hungarian varchar(300) CHARACTER SET utf8 COLLATE utf8_hungarian_ci NOT NULL, Icelandic varchar(300) CHARACTER SET utf8 COLLATE utf8_icelandic_ci NOT NULL, Indonesian varchar(300) NOT NULL, Italian varchar(300) NOT NULL, Japanese varchar(300) NOT NULL, Klingon varchar(300) NOT NULL, Korean varchar(300) NOT NULL, Latvian varchar(300) CHARACTER SET utf8 COLLATE utf8_latvian_ci NOT NULL, Lithuanian varchar(300) CHARACTER SET utf8 COLLATE utf8_lithuanian_ci NOT NULL, Malaysian varchar(300) NOT NULL, Myanmar varchar(300) CHARACTER SET utf8 COLLATE utf8_myanmar_ci NOT NULL, Norwegian varchar(300) NOT NULL, Persian varchar(300) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL, Polish varchar(300) CHARACTER SET utf8 COLLATE utf8_polish_ci NOT NULL, Portuguese varchar(300) NOT NULL, Portuguese_BR varchar(300) NOT NULL, Romanian varchar(300) CHARACTER SET utf8 COLLATE utf8_romanian_ci NOT NULL, Russian varchar(300) NOT NULL, Serbian varchar(300) NOT NULL, Sinhala varchar(300) CHARACTER SET utf8 COLLATE utf8_sinhala_ci NOT NULL, Slovakian varchar(300) CHARACTER SET utf8 COLLATE utf8_slovak_ci NOT NULL, Slovenian varchar(300) CHARACTER SET utf8 COLLATE utf8_slovenian_ci NOT NULL, Spanish varchar(300) CHARACTER SET utf8 COLLATE utf8_spanish_ci NOT NULL, Swedish varchar(300) NOT NULL, Taiwanese varchar(300) NOT NULL, Turkish varchar(300) CHARACTER SET utf8 COLLATE utf8_turkish_ci NOT NULL, Ukrainian varchar(300) NOT NULL, Vietnamese varchar(300) CHARACTER SET utf8 COLLATE utf8_vietnamese_ci NOT NULL, Welsh varchar(300) NOT NULL, PRIMARY KEY (phrase), KEY wt_op (on_page) ) ENGINE MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Various language translations.'; ALTER TABLE webcal_user ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Defines a WebCalendar user.'; ALTER TABLE webcal_user ADD cal_type ENUM('A','N','S','U') DEFAULT 'U' COMMENT 'Is this an A)dmin, N)on_user, S)ystem, or ordinary U)ser? Will evevtually replace is_admin.'; ALTER TABLE webcal_user MODIFY cal_passwd varchar(32) DEFAULT NULL COMMENT 'The user''s password (not used for http.)' FIRST; ALTER TABLE webcal_user ADD cal_mod TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'User''s last log in.' FIRST; ALTER TABLE webcal_user MODIFY cal_last_login timestamp on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Date user last logged in.' FIRST; ALTER TABLE webcal_user MODIFY cal_is_admin ENUM('N','Y') DEFAULT 'N' COMMENT 'Is the user a WebCalendar administrator? (Y or N)' FIRST; ALTER TABLE webcal_user MODIFY cal_enabled ENUM('N','Y') DEFAULT 'Y' COMMENT 'Allow admin to disable account? (Y or N)' FIRST; ALTER TABLE webcal_user MODIFY cal_login varchar(25) NOT NULL COMMENT 'Unique user login.' FIRST; UPDATE webcal_user SET cal_type = 'U' WHERE cal_is_admin = 'N'; UPDATE webcal_user SET cal_type = 'A' WHERE cal_is_admin = 'Y'; ALTER TABLE webcal_user_layers ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Define layers for a user.'; ALTER TABLE webcal_user_layers MODIFY cal_layerid int UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE COMMENT 'Unique layer id.' FIRST; ALTER TABLE webcal_user_layers MODIFY cal_dups ENUM('N','Y') DEFAULT 'N' COMMENT 'Show duplicates? (Y or N)'; ALTER TABLE webcal_user_layers MODIFY cal_color varchar(25) DEFAULT NULL COMMENT 'Color (preferably in hex) of this layer.' FIRST; ALTER TABLE webcal_user_layers MODIFY cal_layeruser varchar(25) NOT NULL COMMENT 'Login name of user that this layer represents. Also from <a href="webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_user_layers MODIFY cal_login varchar(25) NOT NULL COMMENT 'Login of owner of this layer from <a href="webcal_user">webcal_user</a> table.' FIRST; /*Consolodate some fields / tables into webcal_user_pref.*/ DELETE FROM webcal_config WHERE cal_value IS NULL; DELETE FROM webcal_user_pref WHERE cal_value IS NULL; ALTER TABLE webcal_user_pref DROP PRIMARY KEY; ALTER TABLE webcal_user_pref ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Specify preferences for a user. Most preferences are set via pref.php. Values in this table are loaded after system settings found in <a href="#webcal_config">webcal_config</a> table.'; ALTER TABLE webcal_user_pref MODIFY cal_value varchar(100) NOT NULL COMMENT 'Value of setting.'; ALTER TABLE webcal_user_pref ADD PRIMARY KEY (cal_login,cal_setting,cal_value); ALTER TABLE webcal_user_pref MODIFY cal_login varchar(25) DEFAULT '__webcal__sys__'; INSERT INTO webcal_user_pref (cal_setting, cal_value) SELECT cal_setting, cal_value FROM webcal_config; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'ACCESS_FUNCTIONS' FIRST; ALTER TABLE webcal_user_pref MODIFY cal_login varchar(25) NOT NULL COMMENT 'User login from <a href="#webcal_user">webcal_user</a> table.' FIRST; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_permissions FROM webcal_access_function; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'ASSISTANT'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_boss, cal_assistant FROM webcal_asst; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'GROUP_ID'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_group_id FROM webcal_group_user; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'ADDRESS'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_address FROM webcal_user WHERE cal_address IS NOT NULL; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'BIRTHDAY'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_birthday FROM webcal_user WHERE cal_birthday IS NOT NULL; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'DISPLAY_NAME'; UPDATE webcal_user_pref SET cal_firstname = '' WHERE cal_firstname IS NULL; UPDATE webcal_user_pref SET cal_lastname = '' WHERE cal_lastname IS NULL; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, TRIM( CONCAT_WS( ' ',cal_firstname,cal_lastname ) ) FROM webcal_user; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'EMAIL'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_email FROM webcal_user WHERE cal_email IS NOT NULL; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'FIRSTNAME'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_firstname FROM webcal_user; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'LASTNAME'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_lastname FROM webcal_user; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'PHONE'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_telephone FROM webcal_user WHERE cal_telephone IS NOT NULL; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'TITLE'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_title FROM webcal_user WHERE cal_title IS NOT NULL; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) DEFAULT 'VIEW_ID'; INSERT INTO webcal_user_pref (cal_login, cal_value) SELECT cal_login, cal_view_id FROM webcal_view_user; ALTER TABLE webcal_user_pref MODIFY cal_setting varchar(50) NOT NULL COMMENT 'Setting name.'; /* Once the code gets updated, drop the obsolete fields / tables. */ /* End consolidating webcal_user_pref */ UPDATE webcal_user_template SET cal_login = '__webcal__sys__' WHERE cal_login = '__system_'; ALTER TABLE webcal_user_template ENGINE MyISAM CHARACTER SET utf8 COMMENT 'This table stores the custom header/stylesheet/trailer. If configured properly, each user (or nonuser cal) can have their own custom header/trailer.'; ALTER TABLE webcal_user_template MODIFY cal_type ENUM('H','S','T') NOT NULL COMMENT 'H)eader, S)tylesheet/script, T)railer.' FIRST; ALTER TABLE webcal_user_template MODIFY cal_template_text text COMMENT 'Text of template.'; ALTER TABLE webcal_user_template MODIFY cal_login varchar(25) NOT NULL COMMENT 'User login (or nonuser cal name), the default for all users is stored with the username "__webcal__sys__".' FIRST; ALTER TABLE webcal_view ENGINE MyISAM CHARACTER SET utf8 COMMENT 'A "view" allows a user to put the calendars of multiple users all on one page. A "view" is valid only for the owner (cal_owner) of the view. Users for the view are in <a href="#webcal_view_user">webcal_view_user</a> table.'; ALTER TABLE webcal_view MODIFY cal_view_type ENUM('D','M','W') DEFAULT NULL COMMENT '"W" for week view, "D" for day view, "M" for month view.'; ALTER TABLE webcal_view MODIFY cal_owner varchar(25) NOT NULL COMMENT 'Login name of owner of this view. From <a href="#webcal_user">webcal_user</a> table.' FIRST; ALTER TABLE webcal_view MODIFY cal_name varchar(50) NOT NULL COMMENT 'Name of view.' FIRST; ALTER TABLE webcal_view MODIFY cal_is_global ENUM('N','Y') NOT NULL DEFAULT 'N' COMMENT 'Is this a global view? (can it be accessed by other users - "Y" or "N")' FIRST; ALTER TABLE webcal_view MODIFY cal_view_id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Unique view id.' FIRST; ALTER TABLE webcal_view_user ENGINE MyISAM CHARACTER SET utf8 COMMENT 'Specify users in a view.'; ALTER TABLE webcal_view_user MODIFY cal_login varchar(25) NOT NULL COMMENT 'A user in the view. From <a href="#webcal_user">webcal_user</a> table.'; ALTER TABLE webcal_view_user MODIFY cal_view_id int UNSIGNED NOT NULL COMMENT 'view id from <a href="#webcal_view">webcal_view</a> table.' FIRST; </pre> <hr><br> <p>After you complete manually updating your database, you will still need to run the <a href="install/index.php">installation script</a> to perform any necessary data changes needed to convert existing data. Although, I've tried to do that for you in upgrading from 1.1.3, I may have missed something.</p><br> <p><a href="http://validator.w3.org/check?uri=referer"> <img src="../images/HTML5_Logo.png" alt="Valid HTML5!"></a></p><br> </body> </html> PK �]�\��p� � view_m.phpnu �[��� <?php // $Id: view_m.php,v 1.88 2009/11/22 22:26:18 bbannon Exp $ /** * Page Description: * Display a month view with users side by side. * * Input Parameters: * id (*) - specify view id in webcal_view table * date - specify the starting date of the view. * If not specified, current date will be used. * friendly - if set to 1, then page does not include links or trailer navigation. * (*) required field * * Security: * Must have "allow view others" enabled ($ALLOW_VIEW_OTHER) in System Settings * unless the user is an admin user ($is_admin). If the view is not global, the * user must be owner of the view. If the view is global, then and * user_sees_only_his_groups is enabled, then we remove users not in this user's * groups (except for nonuser calendars... which we allow regardless of group). */ include_once 'includes/init.php'; include_once 'includes/views.php'; $error = ''; $USERS_PER_TABLE = 6; $printerStr = generate_printer_friendly ( 'view_m.php' ); set_today ( $date ); view_init ( $id ); $next = mktime ( 0, 0, 0, $thismonth + 1, 1, $thisyear ); $nextyear = date ( 'Y', $next ); $nextmonth = date ( 'm', $next ); $nextdate = sprintf ( "%04d%02d01", $nextyear, $nextmonth ); $prev = mktime ( 0, 0, 0, $thismonth - 1, 1, $thisyear ); $prevyear = date ( 'Y', $prev ); $prevmonth = date ( 'm', $prev ); $prevdate = sprintf ( "%04d%02d01", $prevyear, $prevmonth ); $startdate = mktime ( 0, 0, 0, $thismonth, 1, $thisyear ); $enddate = mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear ); $thisdate = date ( 'Ymd', $startdate ); $nextStr = translate ( 'Next' ); $prevStr = translate ( 'Previous' ); print_header( array( 'js/popups.js/true', 'js/dblclick_add.js/true' ) ); echo ' <div style="width:99%;"> <a title="' . $prevStr . '" class="prev" href="view_m.php?id=' . $id . '&date=' . $prevdate . '"><img src="images/leftarrow.gif" alt="' . $prevStr . '" /></a> <a title="' . $nextStr . '" class="next" href="view_m.php?id=' . $id . '&date=' . $nextdate . '"><img src="images/rightarrow.gif" alt="' . $nextStr . '" /></a> <div class="title"> <span class="date">'; printf ( "%s %d", month_name ( $thismonth - 1 ), $thisyear ); echo '</span><br /> <span class="viewname">' . htmlspecialchars ( $view_name ) . '</span> </div> </div><br />'; // The table has names across the top and dates for rows. Since we need to spit // out an entire row before we can move to the next date, we'll save up all the // HTML for each cell and then print it out when we're done.... // Additionally, we only want to put at most 6 users in one table // since any more than that doesn't really fit in the page. // Get users in this view. $viewusers = view_get_user_list ( $id ); if ( count ( $viewusers ) == 0 ) // This could happen if user_sees_only_his_groups = Y and // this user is not a member of any group assigned to this view. $error = translate( 'No users for this view.' ); if ( ! empty ( $error ) ) { echo print_error ( $error ) . print_trailer(); exit; } $can_add = ( empty ( $ADD_LINK_IN_VIEWS ) || $ADD_LINK_IN_VIEWS != 'N' ); $e_save = $re_save = array(); $viewusercnt = count ( $viewusers ); for ( $i = 0; $i < $viewusercnt; $i++ ) { /* Pre-Load the repeated events for quckier access */ $repeated_events = read_repeated_events ( $viewusers[$i], $startdate, $enddate, '' ); $re_save[$i] = $repeated_events; /* Pre-load the non-repeating events for quicker access */ $events = read_events ( $viewusers[$i], $startdate, $enddate ); $e_save[$i] = $events; } for ( $j = 0; $j < $viewusercnt; $j += $USERS_PER_TABLE ) { // Since print_date_entries is rather stupid, we can swap the event data // around for users by changing what $events points to. // Calculate width of columns in this table. $num_left = count ( $viewusers ) - $j; if ( $num_left > $USERS_PER_TABLE ) $num_left = $USERS_PER_TABLE; $tdw = ( $num_left > 0 ? intval( 90 / ( $num_left < $USERS_PER_TABLE ? $num_left : $USERS_PER_TABLE ) ) : 5 ); echo ' <br /><br /> <table class="main"'; if ( $can_add ) echo ' title="' . translate ( 'Double-click on empty cell to add new entry' ) . '"'; echo '> <tr> <th class="empty"> </th>'; // $j points to start of this table/row. // $k is counter starting at 0. // $i starts at table start and goes until end of this table/row. for ( $i = $j, $k = 0; $i < $viewusercnt && $k < $USERS_PER_TABLE; $i++, $k++ ) { $user = $viewusers[$i]; user_load_variables ( $user, 'temp' ); echo ' <th style="width:' . $tdw . '%;">' . $tempfullname . '</th>'; } //end for echo ' </tr>'; for ( $date = $startdate; $date <= $enddate; $date += 86400 ) { $dateYmd = date ( 'Ymd', $date ); $todayYmd = date ( 'Ymd', $today ); $is_weekend = is_weekend ( $date ); if ( $is_weekend && $DISPLAY_WEEKENDS == 'N' ) continue; $weekday = weekday_name ( date ( 'w', $date ), $DISPLAY_LONG_DAYS ); $class = 'class="' . ( $dateYmd == $todayYmd ? 'today"' : ( $is_weekend ? 'weekend"' : 'row"' ) ); // Non-breaking space below keeps event from wrapping prematurely. echo ' <tr> <th ' . $class . '>' . $weekday . ' ' . date ( 'd', $date ) . '</th>'; for ( $i = $j, $k = 0; $i < $viewusercnt && $k < $USERS_PER_TABLE; $i++, $k++ ) { $events = $e_save[$i]; $repeated_events = $re_save[$i]; $user = $viewusers[$i]; $entryStr = print_date_entries ( $dateYmd, $user, true ); // Unset class from above if needed. if ( $class == 'class="row"' || $class == 'class="hasevents"' ) $class = ''; if ( ! empty ( $entryStr ) && $entryStr != ' ' ) $class = 'class="hasevents"'; else if ( $dateYmd == $todayYmd ) $class = 'class="today"'; else if ( $is_weekend ) $class = 'class="weekend"'; echo '<td ' . $class . ' style="width:' . $tdw . '%;"'; if ( $can_add ) echo " ondblclick=\"dblclick_add( '$dateYmd', '$user', 0, 0 )\""; echo '>' . $entryStr . '</td>'; } //end for echo ' </tr>'; } echo ' </table>'; } $user = ''; // reset echo ( empty ( $eventinfo ) ? '' : $eventinfo ) . $printerStr . print_trailer(); ?> PK �]�\;g� view_l.phpnu �[��� <?php // $Id: view_l.php,v 1.76 2009/11/22 22:26:18 bbannon Exp $ /** * Page Description: * This page will display the month "view" with all users's events on the same * calendar. (The other month "view" displays each user calendar in a separate * column, side-by-side.) This view gives you the same effect as enabling layers, * but with layers you can only have one configuration of users. * * Input Parameters: * id (*) - specify view id in webcal_view table * date - specify the starting date of the view. * If not specified, current date will be used. * friendly - if set to 1, then page does not include links or trailer navigation. * (*) required field * * Security: * Must have "allow view others" enabled ($ALLOW_VIEW_OTHER) in System Settings * unless the user is an admin user ($is_admin). If the view is not global, the * user must be owner of the view. If the view is global, then and * user_sees_only_his_groups is enabled, then we remove users not in this user's * groups (except for nonuser calendars... which we allow regardless of group). */ include_once 'includes/init.php'; include_once 'includes/views.php'; view_init ( $id ); $error = $printerStr = $unapprovedStr = ''; if ( empty ( $friendly ) ) { $unapprovedStr = display_unapproved_events( $is_assistant || $is_nonuser_admin ? $user : $login ); $printerStr = generate_printer_friendly ( 'month.php' ); } set_today ( $date ); print_header( array( 'js/popups.php/true' ), '<script type="text/javascript" src="includes/js/weekHover.js?' . filemtime( 'includes/js/weekHover.js' ) . '"></script>' ); $trailerStr = print_trailer(); $next = mktime ( 3, 0, 0, $thismonth + 1, 1, $thisyear ); $nextyear = date ( 'Y', $next ); $nextmonth = date ( 'm', $next ); $nextdate = sprintf ( "%04d%02d01", $nextyear, $nextmonth ); $nextYmd = date ( 'Ymd', $next ); $prev = mktime ( 3, 0, 0, $thismonth - 1, 1, $thisyear ); $prevyear = date ( 'Y', $prev ); $prevmonth = date ( 'm', $prev ); $prevdate = sprintf ( "%04d%02d01", $prevyear, $prevmonth ); $prevYmd = date ( 'Ymd', $prev ); if ( ! empty ( $BOLD_DAYS_IN_YEAR ) && $BOLD_DAYS_IN_YEAR == 'Y' ) { $boldDays = true; $startdate = mktime ( 0, 0, 0, $thismonth - 1, 1, $thisyear ); $enddate = mktime ( 23, 59, 59, $thismonth + 2, 0, $thisyear ); } else { $boldDays = false; $startdate = mktime ( 0, 0, 0, $thismonth, 1, $thisyear ); $enddate = mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear ); } $thisdate = date ( 'Ymd', $startdate ); // Get users in this view. $viewusers = view_get_user_list ( $id ); if ( count ( $viewusers ) == 0 ) // This could happen if user_sees_only_his_groups = Y and // this user is not a member of any group assigned to this view. $error = translate( 'No users for this view.' ); if ( ! empty ( $error ) ) { echo print_error ( $error ) . print_trailer(); exit; } $e_save = $re_save = array(); for ( $i = 0, $cnt = count ( $viewusers ); $i < $cnt; $i++ ) { /* Pre-Load the repeated events for quckier access */ $repeated_events = read_repeated_events ( $viewusers[$i], $startdate, $enddate, '' ); $re_save = array_merge ( $re_save, $repeated_events ); /* Pre-load the non-repeating events for quicker access */ $events = read_events ( $viewusers[$i], $startdate, $enddate ); $e_save = array_merge ( $e_save, $events ); } $events = $repeated_events = array(); for ( $i = 0, $cnt = count ( $e_save ); $i < $cnt; $i++ ) { $should_add = 1; for ( $j = 0, $cnt_j = count ( $events ); $j < $cnt_j && $should_add; $j++ ) { if ( ! $e_save[$i]->getClone() && $e_save[$i]->getID() == $events[$j]->getID() ) $should_add = 0; } if ( $should_add ) array_push ( $events, $e_save[$i] ); } for ( $i = 0, $cnt = count ( $re_save ); $i < $cnt; $i++ ) { $should_add = 1; for ( $j = 0, $cnt_j = count ( $repeated_events ); $j < $cnt_j && $should_add; $j++ ) { if( ! $re_save[$i]->getClone() && $re_save[$i]->getID() == $repeated_events[$j]->getID() ) $should_add = 0; } if ( $should_add ) array_push ( $repeated_events, $re_save[$i] ); } if ( $DISPLAY_SM_MONTH != 'N' ) { $prevMonth = display_small_month ( $prevmonth, $prevyear, true, true, 'prevmonth', 'view_l.php?id=' . $id . '&' ); $nextMonth = display_small_month ( $nextmonth, $nextyear, true, true, 'nextmonth', 'view_l.php?id=' . $id . '&' ); $navStr = display_navigation ( 'view_l', false, false ); } else $navStr = display_navigation ( 'view_l', true, false ); $monthStr = display_month ( $thismonth, $thisyear ); $eventinfo = ( empty ( $eventinfo ) ? '' : $eventinfo ); echo <<<EOT <div class="title"> <div class="minical"> {$prevMonth}{$nextMonth} </div> {$navStr} <span class="viewname"><br />{$view_name}</span> </div> <br /> {$monthStr} {$eventinfo} {$unapprovedStr} {$printerStr} {$trailerStr} EOT; PK �]�\g��� edit_template.phpnu �[��� <?php /** * Page Description: * This page will present the HTML form to edit an entry in the cal_report table, * and this page will also process the form. * This is only used for editing the custom header/trailer. * The report_id is always 0. * * Input Parameters: * type - "header" or "trailer" * * Security: * Admin permissions are checked by the WebCalendar class. */ include_once 'includes/init.php'; require_valid_referring_url (); $cur = $error = ''; $found = $foundOld = false; $report_id = 0; $type = getValue ( 'type', 'H|S|T', true ); $user = '__system__'; if ( ! empty ( $ALLOW_USER_HEADER ) && $ALLOW_USER_HEADER == 'Y' ) { $user = getValue ( 'user' ); if ( empty ( $user ) ) $user = '__system__'; } if ( $user == '__system__' ) assert ( '($is_admin && ! access_is_enabled() ) || access_can_access_function ( ACCESS_SYSTEM_SETTINGS )' ); // Get existing value. $res = dbi_execute ( 'SELECT cal_template_text FROM webcal_user_template WHERE cal_type = ? AND cal_login = ?', [$type, $user] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { $cur = $row[0]; $found = true; } dbi_free_result ( $res ); } // Check the cal_template_text table // since that is where we stored it in 1.0 and before. if ( ! $found ) { $res = dbi_execute ( 'SELECT cal_template_text FROM webcal_report_template WHERE cal_template_type = ? AND cal_report_id = 0', [$type] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { $cur = $row[0]; $foundOld = true; } dbi_free_result ( $res ); } } if ( empty ( $REQUEST_METHOD ) ) $REQUEST_METHOD = $_SERVER['REQUEST_METHOD']; // Handle form submission. if ( $REQUEST_METHOD == 'POST' ) { // Was this a delete request? $delete = getPostValue ( 'delete' ); if ( $user != '__system__' && ! empty ( $delete ) ) { dbi_execute ( 'DELETE FROM webcal_user_template WHERE cal_type = ? AND cal_login = ?', [$type, $user] ); echo '<html><body onload="window.close();"></body></html>'; exit; } $query_params = [getPostValue ( 'template' ), $type, $user]; if ( $found ) $sql = 'UPDATE webcal_user_template SET cal_template_text = ? WHERE cal_type = ? AND cal_login = ?'; else { $sql = 'INSERT INTO webcal_user_template ( cal_template_text, cal_type, cal_login ) VALUES ( ?, ?, ? )'; if ( $foundOld && $user == '__system__' ) // User is upgrading from WebCalendar 1.0 to 1.1. // Delete from the webcal_report_template table and move the info // to the new webcal_user_template table. dbi_execute ( 'DELETE FROM webcal_report_template WHERE cal_template_type = ? AND cal_report_id = 0 ', [$type] ); } if ( ! dbi_execute ( $sql, $query_params ) ) $error = db_error(); else { echo '<html> <head></head> <body onload="window.close();"> Done </body> </html>'; exit; } } print_header ( '', '', '', true ); /* echo 'report_id: ' . $report_id . '<br /> report_name: ' . $report_name . '<br /> report_user: ' . $report_user . '<br /> '; */ echo ' <h2>'; if ( $type == 'H' ) etranslate ( 'Edit Custom Header' ); elseif ( $type == 'S' ) etranslate ( 'Edit Custom Script/Stylesheet' ); else etranslate ( 'Edit Custom Trailer' ); if ( $user != '__system__' ) { user_load_variables ( $user, 'temp_' ); echo ' [' . $temp_fullname . ']'; } echo '</h2>' . ( ! empty ( $error ) ? print_error ( $error ) : ' <form action="edit_template.php" method="post" name="reportform"> <input type="hidden" name="type" value="' . $type . '" />' . ( ! empty ( $ALLOW_USER_HEADER ) && $ALLOW_USER_HEADER == 'Y' && ! empty ( $user ) && $user != '__system__' ? ' <input type="hidden" name="user" value="' . $user . '" />' : '' ) . ' <textarea rows="15" cols="60" name="template">' . htmlspecialchars ( $cur ) . '</textarea><br /> <input type="button" value="' . translate ( 'Cancel' ) . '" onclick="window.close();" /> <input name="action" type="submit" value="' . translate ( 'Save' ) . '" />' . ( ! empty ( $user ) ? ' <input name="delete" type="submit" value="' . translate ( 'Delete' ) . '" onclick="return confirm( \'' . translate( 'Are you sure you want to delete this entry?' ) . '\');" />' : '' ) . ' </form>' ) . "\n" . print_trailer ( false, true, true ); ?> PK �]�\2Һh� � search.phpnu �[��� <?php // $Id: search.php,v 1.58.2.1 2013/01/24 21:15:09 cknudsen Exp $ include_once 'includes/init.php'; // Is this user allowed to search the calendars of other users? $show_others = false; // show "Advanced Search" if( $single_user == 'Y' ) $show_others = false; if( $is_admin ) $show_others = true; elseif( access_is_enabled() ) $show_others = access_can_access_function( ACCESS_ADVANCED_SEARCH ); elseif( $login != '__public__' && ! $is_nonuser && ! empty( $ALLOW_VIEW_OTHER ) && $ALLOW_VIEW_OTHER == 'Y' ) $show_others = true; elseif( $login == '__public__' && ! empty( $PUBLIC_ACCESS_OTHERS ) && $PUBLIC_ACCESS_OTHERS == 'Y' ) $show_others = true; $show_advanced = getValue( 'adv', '[01]' ); $show_advanced = $show_advanced == '1' ? '1' : '0'; $avdStyle = array( 'hidden', 'visible' ); if( access_is_enabled() && ! access_can_access_function( ACCESS_ADVANCED_SEARCH ) ) $show_advanced = false; load_user_categories(); $selected = ' selected="selected" '; $advSearchStr = translate( 'Advanced Search' ); $searchStr = translate( 'Search' ); $INC = array(); $INC[] = 'js/autocomplete.js'; if( $show_advanced ) { $INC[] = 'js/translate.js.php'; $INC[] = 'js/visible.js/true'; $INC[] = 'js/datesel.php'; } if( $show_others ) $INC[] = 'js/search.js/true'; print_header( $INC ); echo ' <h2>' . ( $show_advanced ? $advSearchStr : $searchStr ) . '</h2> <form action="search_handler.php" method="GET" id="searchformentry" ' . 'name="searchformentry" style="margin-left: 13px;"> <input type="hidden" name="advanced" value="' . $show_advanced . '" /> <table><tr><td><label for="keywordsadv">' . translate ( 'Keywords' ) . ': </label></td> <td><input type="text" name="keywords" id="keywordsadv" size="30" /> <input type="submit" value="' . $searchStr . '" /></td></tr>'; echo '<tr height="30px"><td> </td><td class="aligntop">(' . translate( 'Enter % for all entries' ) . ')</td></tr>'; if( is_array( $categories ) && $show_advanced ) { echo ' <tr id="catfilter" style="visibility:' . $avdStyle[$show_advanced] . ';"> <td><label for="cat_filter" class="colon">' . translate( 'Categories' ) . '</label></td> <td> <select name="cat_filter" id="cat_filter"> <option value=""' . $selected . '>' . translate( 'All' ) . '</option>'; foreach( $categories as $K => $V ) { if( $K > 0 ) echo ' <option value="' . $K . '">' . htmlentities ( $V['cat_name'] ) . '</option>'; } echo ' </select> </td> </tr>'; } if( count( $site_extras ) > 0 ) { echo ' <tr id="extrafilter" style="visibility:' . $avdStyle[$show_advanced] . ';"> <td><label for="extra_filter" class="colon">' . translate( 'Include' ) . '<br />' . translate( 'Site Extras' ) . '</label></td> <td><input type="checkbox" name="extra_filter" value="Y" /> </td></tr>'; } if( $show_advanced ) { $dateYmd = date( 'Ymd' ); echo ' <tr id="datefilter" style="visibility:' . $avdStyle[$show_advanced] . ';"> <td><label for="date_filter" class="colon">' . translate('Filter by Date') . '</label></td> <td> <select name="date_filter" id="date_filter" onchange="toggleDateRange()"> <option value="0"' . $selected . '>' . translate( 'All Dates' ) . '</option> <option value="1">' . translate( 'Past' ) . '</option> <option value="2">' . translate( 'Upcoming' ) . '</option> <option value="3">' . translate( 'Range' ) . '</option> </select> </td> </tr> <tr id="startDate" style="visibility:hidden"> <td> <label class="colon">' . translate( 'Start date' ) . '</label></td> <td>' . datesel_Print( 'from_', $dateYmd ) . ' </td> </tr> <tr id="endDate" style="visibility:hidden"> <td> <label class="colon">' . translate( 'End date' ) . '</label></td> <td>' . datesel_Print( 'until_', $dateYmd ) . ' </td> </tr>'; } if( $show_others ) { $users = get_my_users( '', 'view' ); // Get non-user calendars (if enabled) if( ! empty( $NONUSER_ENABLED ) && $NONUSER_ENABLED == 'Y' ) { $nonusers = get_my_nonusers( $login, true, 'view' ); $users = ( ! empty( $NONUSER_AT_TOP ) && $NONUSER_AT_TOP == 'Y' ? array_merge( $nonusers, $users ) : array_merge( $users, $nonusers ) ); } $cnt = count( $users ); if( $cnt > 50 ) $size = 15; elseif( $cnt > 10 ) $size = 10; else $size = $cnt; echo ' <tr id="advlink" style="visibility:' . $avdStyle[!$show_advanced] . ';"><td colspan="2"><a title="' . $advSearchStr . '" href="search.php?adv=1">' . $advSearchStr . '</a></td></tr> <tr id="adv" style="visibility:' . $avdStyle[$show_advanced] . ';"> <td class="aligntop"><label for="usersadv">' . translate( 'Users' ) . ': </label></td> <td> <select name="users[]" id="usersadv" size="' . $size . '" multiple="multiple">'; for( $i = 0; $i < $cnt; $i++ ) { echo ' <option value="' . $users[$i]['cal_login'] . '"' . ( $users[$i]['cal_login'] == $login ? ' selected="selected"' : '' ) . '>' . $users[$i]['cal_fullname'] . '</option>'; } echo ' </select>' . ( $GROUPS_ENABLED == 'Y' ? '<input type="button" onclick="selectUsers()" value="' . translate( 'Select' ) . '..." />' : '' ) . ' </td> </tr>'; } echo '</table></form>'; ?> <script language="JavaScript"> <!-- <![CDATA[ new Autocomplete('keywordsadv', { serviceUrl:'autocomplete_ajax.php' }); //]]> --> </script> <?php print_trailer (); ?> PK �]�\j��M M approve_entry.phpnu �[��� <?php include_once 'includes/init.php'; require_valid_referring_url (); require ( 'includes/classes/WebCalMailer.class' ); $error = ''; if ( $readonly == 'Y' ) $error = print_not_auth(); // Give user a chance to add comments to approval email. if ( getPostValue( 'comments' ) !== null ) { $comments = getPostValue ( 'comments' ); $cancel = getPostValue ( 'cancel' ); } else if ( empty ( $ret ) ) { $q_string = ( ! empty ( $_SERVER['QUERY_STRING'] ) ? '?' . $_SERVER['QUERY_STRING'] : '' ); print_header(); echo ' <form action="approve_entry.php' . $q_string . '" method="post" name="add_comments"> <table cellspacing="5"> <tr> <td class="aligncenter alignbottom"><h3>' . translate ( 'Additional Comments (optional)' ) . '</h3></td> <tr> <tr> <td class="aligncenter"><textarea name="comments" rows="5" ' . 'cols="60"></textarea></td> </tr> <tr> <td class="aligncenter"> <input type="submit" value="' . translate ( 'Approve and Send' ) . '" /> <input type="submit" id="cancel" name="cancel" value="' . translate( 'Approve and Exit' ) . '" /> </td> </tr> <tr> <td>' . translate ( '(Your comments will be emailed to the event creator.)' ) . '</td> </tr> </table> </form> </body> </html> '; exit; } $user = getValue ( 'user' ); $type = getValue ( 'type' ); $id = getValue ( 'id' ); // Allow administrators to approve public events. $app_user = ( $PUBLIC_ACCESS == 'Y' && ! empty ( $public ) && $is_admin ? '__public__' : ( $is_assistant || $is_nonuser_admin ? $user : $login ) ); // If User Access Control is enabled, we check to see if they are // allowed to approve for the specified user. if ( access_is_enabled() && ! empty ( $user ) && $user != $login && access_user_calendar ( 'approve', $user ) ) $app_user = $user; if ( empty ( $error ) && $id > 0 ) update_status ( 'A', $app_user, $id, $type ); if ( ! empty ( $comments ) && empty ( $cancel ) ) { $mail = new WebCalMailer; // Email event creator to notify that it was approved with comments. // Get the name of the event. $res = dbi_execute ( 'SELECT cal_name, cal_description, cal_date, cal_time, cal_create_by FROM webcal_entry WHERE cal_id = ?', [$id] ); if ( $res ) { $row = dbi_fetch_row ( $res ); $name = $row[0]; $description = $row[1]; $fmtdate = $row[2]; $time = sprintf ( "%06d", $row[3] ); $creator = $row[4]; dbi_free_result ( $res ); } $eventstart = date_to_epoch ( $fmtdate . $time ); // TODO figure out if creator wants approved comment email. // Check UAC. $send_user_mail = ( access_is_enabled() ? access_user_calendar ( 'email', $creator, $login ) : 'Y' ); $htmlmail = get_pref_setting ( $creator, 'EMAIL_HTML' ); user_load_variables ( $creator, 'temp' ); $user_TIMEZONE = get_pref_setting ( $creator, 'TIMEZONE' ); set_env ( 'TZ', $user_TIMEZONE ); $user_language = get_pref_setting ( $creator, 'LANGUAGE' ); if ( $send_user_mail == 'Y' && strlen ( $tempemail ) && $SEND_EMAIL != 'N' ) { reset_language ( empty ( $user_language ) || ( $user_language == 'none' ) ? $LANGUAGE : $user_language ); $msg = str_replace ( 'XXX', $tempfullname, translate ( 'Hello, XXX.' ) ) . "\n\n" . str_replace ( 'XXX', $login_fullname, translate ( 'XXX has approved an appointment and added comments.' ) ) . "\n\n" . str_replace ( 'XXX', $name, translate ( 'Subject XXX' ) ) . "\n" . str_replace ( 'XXX', $description, translate ( 'Description XXX' ) ) . "\n" . str_replace ( 'XXX', date_to_str ( $fmtdate ), translate ( 'Date XXX' ) ) . ' ' . ( empty ( $hour ) && empty ( $minute ) ? '' : str_replace ( 'XXX', // Display using user's GMT offset and display TZID. display_time ( '', 2, $eventstart, get_pref_setting ( $creator, 'TIME_FORMAT' ) ), translate ( 'Time XXX' ) ) ) . "\n"; if ( ! empty ( $SERVER_URL ) ) { // DON'T change & to & here. email will handle it $url = $SERVER_URL . 'view_entry.php?id=' . $id . '&em=1'; if ( $htmlmail == 'Y' ) $url = activate_urls ( $url ); $msg .= "\n" . $url; } if ( ! empty ( $comments ) ) $msg .= "\n\n" . str_replace ( 'XXX', $comments, translate ( 'Comments XXX' ) ); $from = ( strlen ( $login_email ) ? $login_email : $EMAIL_FALLBACK_FROM ); // Send mail. $mail->WC_Send ( $login_fullname, $tempemail, $tempfullname, $name, $msg, $htmlmail, $from ); activity_log ( $id, $login, $creator, LOG_NOTIFICATION, str_replace ( 'XXX', $app_user, translate ( 'Approved w/Comments by XXX.' ) ) ); } } // Return to login TIMEZONE. set_env ( 'TZ', $TIMEZONE ); if ( empty ( $error ) && empty ( $mailerError ) ) { do_redirect ( ! empty ( $ret ) && $ret == 'listall' ? 'list_unapproved.php' : ( ( ! empty ( $ret ) && $ret == 'list' ? 'list_unapproved.php?' : 'view_entry.php?id=' . $id . '&' ) . 'user=' . $app_user ) ); exit; } // Process errors. $mail->MailError ( $mailerError, $error ); ?> PK �]�\���G G views.phpnu �[��� <?php // $Id: views.php,v 1.29 2010/01/24 10:51:02 bbannon Exp $ include_once 'includes/init.php'; if ( ! $is_admin ) $user = $login; print_header( array( 'js/visible.php' ) ); echo display_admin_link() . ' <!-- TABS --> <div id="tabs"> <span class="tabfor" id="tab_views"><a href="#tabviews" onclick="return ' . 'showTab( \'views\' )">' . translate ( 'Views' ) . '</a></span> </div> <!-- TABS BODY --> <div id="tabscontent"> <!-- VIEWS --> <a name="tabviews"></a> <div id="tabscontent_views"> <a title="' . translate ( 'Add New View' ) . '" href="views_edit.php" target="viewiframe" onclick="showFrame' . '( \'viewiframe\' );">' . translate ( 'Add New View' ) . '</a> <ul>'; $global_found = false; for ( $i = 0, $cnt = count ( $views ); $i < $cnt; $i++ ) { if ( $views[$i]['cal_is_global'] != 'Y' || $is_admin ) { echo ' <li><a title="' . htmlspecialchars ( $views[$i]['cal_name'] ) . '" href="views_edit.php?id=' . $views[$i]['cal_view_id'] . '" target="viewiframe" onclick="showFrame( \'viewiframe\' );">' . htmlspecialchars ( $views[$i]['cal_name'] ) . '</a>'; if ( $views[$i]['cal_is_global'] == 'Y' ) { echo ' <abbr title="' . translate ( 'Global' ) . '">*</abbr>'; $global_found = true; } echo '</li>'; } } echo ' </ul>' . ( $global_found ? '<br /> * ' . translate ( 'Global' ) : '' ) . '<br /> <iframe name="viewiframe" id="viewiframe" style="width: 90%; border: 0;' . ' height: 343px;"></iframe> </div> </div> ' . print_trailer(); ?> PK �]�\�� � � day.phpnu �[��� <?php // $Id: day.php,v 1.85 2010/02/21 08:27:48 bbannon Exp $ include_once 'includes/init.php'; //check UAC if( ! access_can_access_function( ACCESS_DAY ) || ( ! empty( $user ) && ! access_user_calendar( 'view', $user ) ) ) send_to_preferred_view(); load_user_layers ( $user != $login && $is_nonuser_admin ? $user : '' ); load_user_categories(); $wday = strftime ( '%w', mktime ( 0, 0, 0, $thismonth, $thisday, $thisyear ) ); $now = mktime ( 23, 59, 59, $thismonth, $thisday, $thisyear ); $nowYmd = date ( 'Ymd', $now ); $next = mktime ( 0, 0, 0, $thismonth, $thisday + 1, $thisyear ); $nextday = date ( 'd', $next ); $nextmonth = date ( 'm', $next ); $nextyear = date ( 'Y', $next ); $nextYmd = date ( 'Ymd', $next ); $prev = mktime ( 0, 0, 0, $thismonth, $thisday - 1, $thisyear ); $prevday = date ( 'd', $prev ); $prevmonth = date ( 'm', $prev ); $prevyear = date ( 'Y', $prev ); $prevYmd = date ( 'Ymd', $prev ); if ( empty ( $TIME_SLOTS ) ) $TIME_SLOTS = 24; $boldDays = ( $BOLD_DAYS_IN_YEAR == 'Y' ); $startdate = mktime ( 0, 0, 0, $thismonth, 0, $thisyear ); $enddate = mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear ); $printerStr = $unapprovedStr = ''; /* Pre-Load the repeated events for quckier access */ $repeated_events = read_repeated_events ( empty ( $user ) ? $login : $user, $startdate, $enddate, $cat_id ); /* Pre-load the non-repeating events for quicker access */ $events = read_events ( empty ( $user ) ? $login : $user, $startdate, $enddate, $cat_id ); if ( empty ( $DISPLAY_TASKS_IN_GRID ) || $DISPLAY_TASKS_IN_GRID == 'Y' ) /* Pre-load tasks for quicker access */ $tasks = read_tasks ( ! empty ( $user ) && strlen ( $user ) && $is_assistant ? $user : $login, $now, $cat_id ); $smallTasks = ( $DISPLAY_TASKS == 'Y' ? '<div id="minitask"> ' . display_small_tasks ( $cat_id ) . ' </div>' : '' ); $dayStr = print_day_at_a_glance ( $nowYmd, ( empty ( $user ) ? $login : $user ), $can_add ); $navStr = display_navigation ( 'day' ); $smallMonthStr = display_small_month ( $thismonth, $thisyear, true ); if ( empty ( $friendly ) ) { $unapprovedStr = display_unapproved_events ( $is_assistant || $is_nonuser_admin ? $user : $login ); $printerStr = generate_printer_friendly ( 'day.php' ); } $eventinfo = ( empty ( $eventinfo ) ? '' : $eventinfo ); $trailerStr = print_trailer(); print_header( array( 'js/popups.js/true', 'js/dblclick_add.js/true' ), generate_refresh_meta(), '', false, false, false, false ); echo <<<EOT <table cellpadding="1"> <tr> <td width="80%"> {$navStr} </td> <td class="aligntop" rowspan="2"> <!-- START MINICAL --> <div class="minicalcontainer"> {$smallMonthStr} </div> {$smallTasks} </td> </tr> <tr> <td> {$dayStr} </td> </tr> </table> {$eventinfo} {$unapprovedStr} {$printerStr} {$trailerStr} EOT; ?> PK �]�\N��B�� �� docs/WebCalendar-SysAdmin.htmlnu �[��� <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>WebCalendar System Administrator's Guide</title> <link href="../includes/css/docs.css" rel="stylesheet"> </head> <body id="sysadmin"> <h1>WebCalendar System Administrator's Guide</h1> <p><strong>WebCalendar Version: 1.3.0</strong></p> <h2>Table of Contents</h2> <ul> <li><a href="#intro">Introduction</a></li> <li><a href="#requirements">System Requirements</a></li> <li><a href="#fileunpacking">File Unpacking</a></li> <li><a href="#appsetup">Application Installation</a></li> <li><a href="#eventcal">Configuring as Event Calendar</a></li> <li><a href="#users">Creating Users</a></li> <li><a href="#reminders">Setting Up Email Reminders</a></li> <li><a href="#systemsettings">System Settings</a></li> <li><a href="#siteextras">Custom Event Fields</a></li> <li><a href="#faq">FAQ</a></li> <li><a href="#trouble">Troubleshooting</a></li> <li><a href="#help">Getting Help</a></li> <li><a href="#license">Licensing</a></li> <li><a href="#glossary">Glossary</a></li> <li><a href="#appendixA">Appendix A: Database Setup with phpMyAdmin</a></li> <li><a href="#appendixB">Appendix B: Database Setup</a></li> <li><a href="#appendixC">Appendix C: Setting Up Reminders on Windows</a></li> <li><a href="#appendixD">Appendix D: Displaying Upcoming Events on Your Site</a></li> <li><a href="#appendixE">Appendix E: How To Configure for LDAP</a></li> <li><a href="#appendixF">Appendix F: Manual Installation</a></li> </ul> <hr> <a name="intro"></a> <h2>Introduction</h2> <p>WebCalender is an open source PHP-based multi-user calendar.</p> <p><strong>Features:</strong></p> <ul> <li>Multi-user support</li> <li>Group support</li> <li>View day-at-glance</li> <li>View month-at-glance</li> <li>View week-at-glance</li> <li>View year-at-glance</li> <li>View another user's calendar</li> <li>View multiple users' calendars at the same time</li> <li>View one or more users' calendar via layers on top of your own calendar</li> <li>Public calendar (that requires no login) where anonymous users submit events that are approved by an administrator</li> <li>Add/Edit/Delete users</li> <li>Add/Edit/Delete events/todos</li> <li>Repeating events</li> <li>Custom event fields</li> <li>Search interface for calendar entries</li> <li>User-configurable preferences for colors, 12/24 time format, Week start on Sun or Mon, default work hours</li> <li>Online help</li> <li>Checks for scheduling conflicts</li> <li>Support for multiple timezones</li> <li>Users can accept or reject events added by another user to their calendar</li> <li>Email reminders</li> <li>Email notifications for new events</li> <li>Support, at least partially, for more than 40 different languages: <ul> <li>Afrikaans</li> <li>Albanian</li> <li>Arabic</li> <li>Basque</li> <li>Bulgarian</li> <li>Catalan</li> <li>繁體中文(Big5)</li> <li>简体中文(GB2312)</li> <li>Croatian</li> <li>Czech</li> <li>Danish</li> <li>Deutsche (German)</li> <li>Elven (JRR Tolkien's "<i>Lord of the Rings</i>") Requires a special font.</li> <li>English</li> <li>Español (Spanish)</li> <li>Estonian</li> <li>Français (French)</li> <li>Galician</li> <li>Greek</li> <li>Hebrew</li> <li>Hollands (Dutch)</li> <li>Holo (Taiwanese)</li> <li>Hungarian</li> <li>Icelandic</li> <li>Italiano (Italian)</li> <li>Japanese (EUCJP, SJIS)</li> <li>Korean</li> <li>Lithuanian</li> <li>Norsk (Norwegian)</li> <li>Polish</li> <li>Portuguese</li> <li>Portuguese/Brazil</li> <li>Romanian</li> <li>Русско (Russian)</li> <li>Serbian</li> <li>Slovak</li> <li>Slovenian</li> <li>Suomalainen (Finnish)</li> <li>Svensk (Swedish)</li> <li>Turkish</li> <li>Welsh</li> </ul> </li> <li>Exporting to and importing from: <ul> <li>Palm Pilot</li> <li>iCalendar</li> <li>vCalendar</li> <li>hCalendar (import only, requires PHP5)</li> </ul> </li> <li>Authentication using: <ul> <li>web-based</li> <li>HTTP authentication</li> <li>LDAP</li> <li>NIS</li> <li>IMAP</li> <li>support for external application authentication ( Postnuke, Joomla ) </li> </ul> </li> <li>Activity log that tracks: <ul> <li>event creation</li> <li>event updates</li> <li>event acceptance</li> <li>event rejection</li> <li>email notifications</li> <li>email reminders</li> </ul> </li> <li>Synchronization and Syndication: <ul> <li>Two-way authenticated iCalendar (ics) sync </li> <li>Anonymous iCalendar (ics) publishing</li> <li>RSS 2.0 feed </li> </ul> </li> </ul> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="requirements"></a> <h2>System Requirements</h2> <ul> <li>PHP 4.1 - PHP 5: some features specific version: <ul> <li>two-way iCalendar sync: PHP 4.3+ </li> <li>hCalendar importing: PHP 5+ </li> </ul> </li> <li>Database (see <a href="#database">below</a>)</li> <li>CSS-enabled browser: <ul> <li>Microsoft Internet Explorer </li> <li>Mozilla Firefox </li> <li>Opera </li> <li>Apple Safari </li> </ul> </li> <li>JavaScript-enabled browser</li> <li>If not using HTTP-based authentication, then browser cookies are required</li> </ul> <p><strong>Recommended:</strong></p> <ul> <li>pilot-link (if exporting to Palm): <a href="http://sourceforge.net/project/?group_id=2158">http://sourceforge.net/project/?group_id=2158</a> <a href="http://sourceforge.net/project/?group_id=2158" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> </ul> <p><a name="database">You must have one of the following databases installed</a>:</p> <ul> <li>MySQL</li> <li>Oracle 8+</li> <li>PostgreSQL</li> <li>Interbase</li> <li>MS SQL Server</li> <li>SQLLite (PHP5)</li> <li>IBM DB2 </li> <li>ODBC</li> </ul> <p class="ptip"><span class="tip">TIP</span>PHP ODBC includes support for Adabas D, Solid and Sybase SQL Anywhere as well as ODBC. PHP5 comes bundled with SQLite support. SQLite is an embedded file-based database. If your hosting service supports PHP5, you should be able to create as many SQLite databases as you like (since each database is just a file).</p> <p>For the database you choose, you must have its drivers built into PHP. For example, to use MySQL, PHP must be compiled with MySQL support (which is the default setting when installing PHP). See the PHP pages (<a href="http://www.php.net">www.php.net</a> <a href="http://www.php.net" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>) for more information on setting up PHP.</p> <p>No optional PHP packages (other than MySQL) are required for this application. However, PHP should be compiled with <tt>--enable-track-vars</tt> on some systems.</p> <p class="ptip"><span class="tip">TIP</span>If you want to use gradient background images, PHP must be compiled with the GD library. </p> <p>You can run PHP either as a CGI or an Apache module. You'll get better performance with PHP setup as a module. Not only will you not have to deal with the CGI performance hit, but you'll be able to use PHP's database connection pooling. Additionally, this application can use a form/cookie-based authentication or traditional HTTP authentication. For traditional HTTP authentication, PHP must be built as an Apache module.</p> <p>If you are planning on using email reminders, you will need to build PHP as a CGI in order to run the <tt>send_reminders.php</tt> script. I would strongly recommend building a module-based PHP for your web server and then a second PHP build to create the CGI version.</p> <p class="ptip"><span class="tip">TIP</span> Some Linux distributions come with both a module-based PHP with Apache and a standalone PHP binary. Check for <tt>/usr/bin/php</tt> to see if you already have the PHP standalone executable. If it's there, you can use the following command to see what version of PHP you have: <br><br> <tt style="margin-left: 50px;">/usr/bin/php -v</tt> </p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="fileunpacking"></a> <h2>File Unpacking</h2> <p>Unpack the calendar software in its own directory somewhere where your web server will find it. (See your web server documentation for information.)</p> <p>By default, unpacking WebCalendar will create its own directory when you unpack it. The new directory name will typically contain the version name (such as <tt>WebCalendar-1.3.0</tt>). You can rename this directory after unpacking the files if you prefer a directory name like <tt>calendar</tt> or <tt>webcalendar</tt>. Keep in mind that unless you remap the directory (via your web server's configuration settings), it will be part of the URL for the calendar.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="appsetup"></a> <h2>Application Installation</h2> <p>WebCalendar now includes an installation script that will guide you through the entire installation process. It should run automatically when first accessing a new installation or when a major version upgrade has been performed. The installation script can always be rerun if needed by adding <tt>install/index.php</tt> to your base WebCalendar URL. </p> <h3>WebCalendar Installation Wizard: Step 1</h3> <p>When first run, the installation script will prompt you for a <em>Configuration Wizard Password</em> that will protect against unauthorized tampering. Until this password is set, your WebCalendar installation and possibly your database are vulnerable to attack. Once, you've set your password, be sure to write it down. If forgotten, the only way to recover is to manually edit the <tt>install/settings.php</tt> file.</p> <p>The installation script will now check several prerequisites and report the results. Any item that appears in <font color="#FF0000">RED</font> should be corrected before continuing.</p> <table cellpadding="2"> <tr><th>Prerequisite Failed</th><th>Recommended Solution</th></tr> <tr> <td>PHP 4.1.0 or greater</td> <td>Upgrade your PHP installation</td> </tr> <tr> <td>Safe Mode* = Off</td> <td>If possible, change this setting in your <tt>php.ini</tt> file to <tt>Off</tt>.</td> </tr> <tr> <td>Safe Mode Allowed Vars*</td> <td>If unable to to set Safe Mode Off, then set safe_mode_allowed_vars to contain <tt>TZ</tt> in your <tt>php.ini</tt> file. </td> </tr> <tr><td colspan="2">* NOTE: If neither of the these settings pass testing, then your WebCalendar installation will be restricted to using the server's timezone setting only.</td> </tr> <tr> <td>File Uploads</td> <td>If disabled, then some features of WebCalendar will not function. This setting is configurable in your <tt>php.ini</tt> or <tt>httpd.conf</tt> files as <tt>file_uploads</tt></td> </tr> <tr> <td>CRYPT_STD_DES</td> <td>This setting should be able to be ignored. We now support multiple <tt>crypt</tt> algorithms. If this setting is not enabled and you experience difficulties logging in, please notify the WebCalendar development team.</td> </tr> <tr> <td>GD</td> <td>This library is required only if gradient background images are desired. Normally, PHP must be compiled with this option. Some installations only require it be enabled in your <tt>php.ini</tt> file.</td> </tr> <tr> <td>Session Check</td> <td>PHP Sessions are used during the installation process and are required for proper operation. Sessions can be configured in your <tt>php.ini</tt> file. If it's not possible to enable sessions, then you must manually install WebCalendar. Details are available in <a href="#appendixF">Appendix F</a></td> </tr> <tr> <td>Settings.php Status</td> <td>The installation script was either unable to create, or unable to write to your settings.php file. You will need to modify the permissions of the <tt>includes</tt> directory. On Linux/UNIX, you should change this directory to be read/write for all users (<tt>chmod 777 includes</tt>). On Windows, change this directory to have full access for all users using Windows Explorer.</td> </tr> </table> <h3>WebCalendar Installation Wizard: STEP 2</h3> <p>The installation script can create your WebCalendar database as well as create all the required tables and pre-populate them with the basic configuration data. These features are only available when using fully supported database types. See <a href="#appendixB">Appendix B</a> to manually create your database if needed.</p> <p><strong>Database Status</strong></p> <p>Displays the current status of your database settings as well the supported databases for your PHP installation.</p> <p><strong>Database Settings</strong></p> <p>To configure your database access. Set the values for:</p> <table class="distinguish"> <tr><th>Displayed Value</th><th>settings.php value</th><th>Comments</th></tr> <tr><td> Database Type</td><td>db_type</td> <td> One of "mysql", "oracle", "postgresql", "odbc", "mssql", sqllite, db2, or "ibase" </td> </tr> <tr><td> Server</td><td>db_host</td><td> The hostname that database is running on. (Use localhost if it's the same machine as the web server.) (This variable is not used with ODBC, enter 'none') (Use 'none' if your db server does not use a TCP socket to connect) (If using a special PORT, you can specify it as HOST:PORT) </td></tr> <tr><td> Login</td><td>db_login</td><td> The database login (Not used for SQLite.) </td></tr> <tr><td> Database Name</td><td>db_password</td><td> The database password for the above login<br> (Use 'none' if your db server does not use a TCP socket to connect.) (Not used for SQLite.) </td></tr> <tr><td> Database Name</td><td>db_database</td><td> The name of the database that the calendar tables reside in. ("intranet" in the <a href="#dbsetup">examples above</a>.) For ODBC, this should be the DSN. For SQLite, this is the filename that will be used. </td></tr> <tr><td> Connection Persistence</td><td>db_persistent</td><td> Enable use of persistent (pooled) database connections. This should typically be enabled. This setting may be disabled for CGI installations. </td></tr> <tr><td> Database Cache Directory</td><td>db_cachedir</td> <td> To enable caching of database query results, enter a writable directory. This directory should NOT be in the webserver document path to prevent unauthorized access to cached sensitive data such as passwords hashes and private event details. To disable this feature, leave this field blank. However, this feature is recommended to enhance your system's performance. </td> </tr> </table> <p>Click the <font color="#FF0000">Test Settings</font> button to perform the test your settings.</p> <p>Click the <font color="#FF0000">Create</font> button to have the installation script create your database. This option will only be available for fully supported database types. Retest your database settings if prompted to do so.</p> <p class="ptip"><span class="tip">TIP</span>If this step does not complete properly, then you will have to manually create your database. Detailed instructions can be found in <a href="#appendixB">Appendix B</a>. Then rerun the installation script to continue the installation.</p> <h3>WebCalendar Installation Wizard: STEP 3</h3> <p>In this section we will perform the required database changes to bring your database up to the required level If you are using a fully supported database, this step will be performed automatically for you If not, the required SQL can be displayed and you should be able to cut & paste it into your database server query window.</p> <p><strong>Database Status</strong></p> <p>This should display the current installed version of WebCalendar as well as the version being installed.</p> <p><font color="#FF0000"><strong>The following database actions are required</strong> </font></p> <p>If using a fully supported database type, clicking the <strong>Update Database</strong> button will create any tables required for this installation or upgrade. If this feature is not supported, then this button will not be available.</p> <p>The <strong>Display Required SQL</strong> button will always be available and if clicked will display the required SQL text that can then be cut & pasted into the SQL query window of your database program. If using the approach, please rerun the installation script after completing your required database updates.</p> <p class="ptip"><span class="tip">TIP</span>If this step does not complete properly, then you will have to manually create your database tables. Detailed instructions can be found in <a href="#appendixF">Appendix F</a>. Then rerun the installation script to continue the installation.</p> <h3>WebCalendar Installation Wizard: STEP 4</h3> <p><strong>Timezone Conversion</strong></p> <p>If upgrading WebCalendar from a previous version, you may be prompted to perform a Timezone Conversion. WebCalendar version 1.0.4 and earlier stored event date and time in the server's timezone. As of v1.1.0, all event date and time information is stored as UTC time. So, a one-time conversion of existing events will required to prevent event displayed times from appearing incorrectly.</p> <p><strong>Application Settings</strong></p> <p>Create Default Admin Account: If checked, a DEFAULT ADMINISTRATOR account will be created with username:admin password:admin</p> <p>Application Name: The default value <strong>Title</strong> will be translated into <strong>WebCalendar</strong> into the user's language. Any other entry will not be translated unless entries are made into the appropriate language.txt files.</p> <p>Server URL: This should be the full URL to access your WebCalendar installation.The trailing "/" is required for proper operation. If this field is left blank, WebCalendar will calculate the proper value and store it in the database.</p> <p>User Authentication: You can configure the calendar to run in single-user<a href="#g_singleuser">*</a> mode or multi-user<a href="#g_multiuser">*</a> mode. If this is your first time using the calendar, it's easier to try single-user. You can always switch to multi-user later. Leave <tt>single_user</tt> set to "false" (the default) for multi-user or set it to "true" and set the value of <tt>single_user_login</tt> to a login name of your liking to set the system to single-user mode. (And be sure to set the value of <tt>single_user_login</tt> to the login that you would choose if you decide to switch to multi-user mode some day.)</p> <p><span class="note">Note:</span> If you do decide to switch from single-user mode to multi-user mode, make sure you add in a user to the system for the login you set the <tt>single_user_login</tt> variable to. You will need to do this via the database (mysql, sqlplus, etc.) Look in the <tt>tables-mysql.sql</tt> (or <tt>tables-oracle.sql</tt>, etc.) to see the example of adding in the "admin" user.</p> <p>If you are setting up a multi-user calendar, you will need to choose how your users are authenticated. You must change the settings of <tt>use_http_auth</tt> and <tt>user_inc</tt> to setup which authentication method to use.</p> <p>You currently have five choices:</p> <ol> <li>Web-based authentication (login/passwords verified in the WebCalendar database):<br> <tt>use_http_auth = false</tt><br> <tt>user_inc = user.php</tt> </li> <li>HTTP-based authentication (login/passwords verified by the web server):<br> <tt>use_http_auth = true</tt><br> <tt>user_inc = user.php</tt><br> ... and don't forget to setup your web server to handle user authentication.<br> <span class="note">Note:</span> In order to use HTTP-based authentication, PHP must be setup as a module for your server rather than a CGI. </li> <li>NIS-based authentication (login/passwords verified by NIS):<br> <tt>use_http_auth = false</tt><br> <tt>user_inc = user-nis.php</tt><br> Additional configuration settings will need to be set in <tt>includes/user-nis.php</tt>. </li> <li>LDAP-based authentication (login/passwords verified by LDAP server):<br> <tt>use_http_auth = false</tt><br> <tt>user_inc = user-ldap.php</tt><br> Additional configuration settings will need to be set in <tt>includes/user-ldap.php</tt>. </li> <li>IMAP-based authentication (login/passwords verified by IMAP server):<br> <tt>use_http_auth = false</tt><br> <tt>user_inc = user-imap.php</tt><br> Additional configuration settings will need to be set in <tt>includes/user-imap.php</tt>. </li> </ol> <p>Read-Only: Determines whether events can be added to your WebCalendar.</p> <p>Environment: Normally set this <strong>Production</strong>. Development will allow more verbose sql logging and should not be used unless needed.</p> <p>After saving your settings, you should be provided with a <strong>Launch WebCalendar</strong> button that will open WebCalendar in a separate browser window.</p> <p><strong>Congratulations! You have successfully installed WebCalendar on your system.</strong></p> <p>Keep in mind that if you want to use reminders, you will need to setup the <tt>send_reminders.php</tt> script (see below) and keep your admin setting for "Email enabled" set to "Yes" on the admin settings page.</p> <p>At this point, your WebCalendar installation should be up and running. To access WebCalendar open up your favorite web browser and type in the URL. The URL will depend on where you installed WebCalendar.</p> <p class="ptip"><span class="tip">TIP</span> On a multi-user system, the only user account created during installation has the username of "admin" and a password of "admin". You should create a new admin account and delete this one for security reasons.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="eventcal"></a> <h2>Configuring as Event Calendar</h2> <p> If you intend to use WebCalendar as an event calendar, you will need to enable "Public Access" in the System Settings with the following steps:</p> <ul> <li>Login to WebCalendar as an administrator (the default username is 'admin' and password 'admin'). </li> <li>Click on the "Admin" link at the bottom of any page.</li> <li>Click on the "System Settings" button.</li> <li>Click on the "Public Access" tab.</li> <li>Select "Yes" for "Allow public access".</li> </ul> <p>This will allow users to access WebCalendar without a username and password. Only events that are created with the "Public User" as an event participant will show up in your event calendar for users who have not logged in. If events are not showing up on your public calendar, make sure the events have the "Public User" as a participant and the event has been approved. </p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="users"></a> <h2>Creating Users</h2> <p>After logging in as an admin user (the initial username is "admin" with password "admin"), you will see a common set of links at the bottom of each page. Follow these steps to create a new user:</p> <ol> <li>Login to WebCalendar as an admin user</li> <li>Click on the "Admin" link at the bottom of any WebCalendar page</li> <li>Click on the "Users" button</li> <li>Click on the "Add New User" link</li> <li>Fill out the form with details for the new user (email address is optional)</li> <li>Click on the "Save" button</li> </ol> <p class="ptip"><span class="tip">TIP</span> On a single-user system, you do not need to create any users.</p> <p class="ptip"><span class="tip">TIP</span> For an event calendar, you do not need to create a user for the "public user".</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="reminders"></a> <h2>Setting Up Email Reminders</h2> <p>PHP does not come with a utility for executing time-based jobs. So, in order to check periodically for email reminders, a shell script was written in PHP. You will need two things to get this working:</p> <ol> <li>You should have a version of PHP built as a CGI (so that you can run php from the command line). This does not mean you must build all of PHP as a CGI. You can still build PHP as a module for your web server and then build the CGI-based PHP later.<br> <span class="note">Note:</span> Many Linux distributions and some Windows LAMP packages come with the PHP built for CGI.</li> <li>You must setup cron (on Linux/UNIX) or something like cron for Windows to run the <tt>send_reminders.php</tt> script periodically.</li> </ol> <p>Building PHP as a CGI is outside the scope of these instructions. But, if you read the PHP instructions, you'll see that the default build settings will build the CGI-based PHP. If you really can't do this (perhaps you don't have permission to install anything new on the system), skip down a couple of paragraphs to an alternate solution that does not require PHP CGI.</p> <p>For Linux/UNIX users, add the following line to the crontab entry of a user. (This would be the same user that the web server process runs as.)</p> <pre><tt>1 * * * * cd /some/directory/webcalendar/tools; ./send_reminders.php</tt></pre> <p>Of course, replace the directory location to wherever the <tt>send_reminders.php</tt> file can be found. If you moved this out of the tools directory (which is recommended for security reasons), be sure to update <tt>send_reminders.php</tt> since it needs to know where to find other WebCalendar files.</p> <p>If you cannot setup PHP as a CGI or have no idea how, you can leave <tt>send_reminders.php</tt> in its current location and access it via a URL. IMHO, this is not the best choice, but it still works. Setup a cron job to access the URL. For Linux/UNIX users, add the following line to the crontab entry of a user.</p> <pre><tt>1 * * * * wget http://yourserverhere/webcalendardirectoryhere/tools/send_reminders.php > /dev/null</tt></pre> <p>Some users have reported the following works better for their configuration.</p> <pre><tt>1 * * * * wget -q -O /dev/null http://yourserverhere/webcalendardirectoryhere/tools/send_reminders.php</tt> </pre> <p>You should test this from the command line first to make sure your setup is correct. If you do not have <tt>wget</tt> installed on your system, you can use any tool (lynx, perl script, etc.) that is capable of making an HTTP request for this.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="systemsettings"></a> <h2>System Settings</h2> <p>System Settings allows the administrator to control what features are available to users as well as default values for certain features.</p> <p>Many of these settings can be overridden by users in their Preferences (such as color). These user configurable settings are identified by <strong><em>Italics</em></strong>.</p> <h3>Settings</h3> <dl> <dt>Application Name</dt> <dd>Specifies the document title (typically displayed in the window title bar of most browsers)</dd> <dt>Server URL</dt> <dd>Specifies the base URL of the calendar. This information is needed to accurately include URLs in email messages (Notifications and Reminders).</dd> <dt>Home URL</dt> <dd>Specifies the URL to return to when exiting WebCalendar. If set, a new menu option will become visible in the menu.</dd> <dt><em>Language</em></dt> <dd>Specifies the default language setting for all users.</dd> <dt>Server Timezone Selection</dt> <dd>Allows you to manually set your server's WebCalendar timezone selection. This has no effect on the OS Timezone settings.</dd> <dt>Allow user to use themes</dt> <dd>Allows users to have access to pre-defined themes that can set color or user preference settings. There are a few examples available in the <tt>themes</tt> folder.</dd> <dt><em>Themes</em></dt> <dd>The default theme that will be applied to all users unless they make their own changes.</dd> <dt>Allow top menu</dt> <dd>Turns on the NEW menu system for all users.</dd> <dt>Date Selectors position</dt> <dd>Determines position of Date Pulldown Selectors. Either inside the NEW menu or in their original location at the bottom of the calendar.</dd> <dt><em>Menu theme</em></dt> <dd>Theme to be used with NEW menu.</dd> <dt><em>Fonts</em></dt> <dd>Specifies your preferred font. Multiple font names should be comma-separated.</dd> <dt><em>Custom script/stylesheet</em></dt> <dd>Place any custom stylesheet information or JavaScript that will be included on all WebCalendar pages.</dd> <dt><em>Custom header</em></dt> <dd>The custom header allows you to specify HTML to be placed after the <body> tag but before any WebCalendar content and included on all WebCalendar pages.</dd> <dt><em>Custom trailer</em></dt> <dd>The custom trailer allows you to specify HTML to be placed after the WebCalendar content but before the </body> tag and included on all WebCalendar pages.</dd> <dt>Allow external file for header/script/trailer</dt> <dd>If enabled, then the Custom header and Custom trailer settings can specify a filename on the server rather than HTML.</dd> <dt>Allow user to override header/trailer</dt> <dd>If enabled, then users can add their own custom HTML for both the header (top of the page) and trailer (bottom of the page) to customize the appearance of all pages.</dd> <dt><em>Preferred View</em></dt> <dd>Specify if users should see the day, week, month, or year after logging in.</dd> <dt><em>Display small months</em></dt> <dd>Specifies whether small months are included in month, week, day views.</dd> <dt><em>Display weekends</em></dt> <dd>Specifies whether weekends are included in month, week, day, and views.</dd> <dt><em>Display all days in month view</em></dt> <dd>Specifies whether the complete month grid is filled with days from previous and next month.</dd> <dt>Display days with events in bold in month and year views</dt> <dd>Highlights and bolds the text for days containing events in the mini-calendars used in day, month and year calendars.</dd> <dt><em>Display description in printer day view</em></dt> <dd>If enabled, then the "printer friendly" view of the day view will include full event descriptions rather than just the event name.</dd> <dt>Display Common Use Date/Times as GMT</dt> <dd>Sets the timezone to used for General Purpose dates. Either GMT of the Server timezone will be selected.</dd> <dt><em>Date format</em></dt> <dd>Specifies the default format for displaying dates. These are defined in file <tt>includes/date_formats.php</tt> and if <strong>LANGUAGE DEFINED</strong> is selected then the format will be adjusted based on the format in the user's language.txt file.</dd> <dt><em>Time format</em></dt> <dd>Specifies the default time format as either 12-hour (3:45pm) or 24-hour (15:14)</dd> <dt><em>Display 00 minutes always</em></dt> <dd>Specifies whether times on the hour ( 10:00 ) are displayed with trailing 00.</dd> <dt><em>Entry interval</em></dt> <dd>Specify the default options for entry start and stop times. This values will also determine the display resolution of timebar views as well as user availability.</dd> <dt><em>Time interval</em></dt> <dd>Specify the default number of minutes each time block represents in the day and week display</dd> <dt><em>Auto-refresh calendars</em></dt> <dd>If set to "yes," the day, week, and month pages will automatically reload after a specified duration</dd> <dt><em>Auto-refresh time</em></dt> <dd>Specifies how long to wait before the auto-refresh should force a page to be reloaded</dd> <dt>Require event approvals</dt> <dd>If enabled, then events added to one user's calendar by another user will require approval.</dd> <dt><em>Display unapproved</em></dt> <dd>Specifies whether events that have been added to a calendar but not yet approved should display on the calendar (in a different color)</dd> <dt><em>Display week number</em></dt> <dd>Specifies whether the week number should be displayed in month and week views</dd> <dt><em>Week starts on</em></dt> <dd>Specifies if week start on Sunday or Monday</dd> <dt><em>Work hours</em></dt> <dd>Specifies the default time range to display in day and week views</dd> <dt>Disable Pop-Ups</dt> <dd>Determines whether event pop-ups are displayed.</dd> <dt>Disable Location field</dt> <dd>Determines whether to use the Location field for events.</dd> <dt>Disable Priority field</dt> <dd>If enabled, the Priority field will not be used</dd> <dt>Disable Access field</dt> <dd>If enabled, the Access field will not be used</dd> <dt>Disable Participants field</dt> <dd>If enabled, the Participants field will not be used, and users will not be able to add events to any calendar other than their own.</dd> <dt>Disable Repeating field</dt> <dd>If enabled, users will not be able to create repeating events</dd> <dt>Display Site Extras in popup</dt> <dd>If enabled, custom event fields configured in <tt>site_extras.php</tt> will appear in the mouse-over popups containing additional event information.</dd> <dt>Display Participants in popup</dt> <dd>If enabled, event participants will be included in popup details.</dd> <dt>Allow HTML in Description</dt> <dd>Allow the use of HTML in the description field when creating events. In addition, with the addition of either of two optional packages (HTMLArea or FCKEditor), you can have a WYSIWYG interface. These packages are available on <a href="http://www.k5n.us/webcalendar.php?topic=Add-Ons">WebCalendar's Home Page</a></dd> <dt>Allow viewing other user's calendars</dt> <dd>If enabled, users will be able to view the calendar of another user</dd> <dt>Include add event link in views</dt> <dd>If enabled, Views will include a link to quickly add events to the specified user's calendar.</dd> <dt>Remember last login</dt> <dd>If enabled, when a returning calendar user reaches the login page, their login name will be pre-filled with the last login username that they entered. (The password field will still be blank.)</dd> <dt>Check for event conflicts</dt> <dd>Specifies if the system should check for scheduling conflicts when a user adds or updates an event.</dd> <dt>Conflict checking months</dt> <dd>If conflict checking is enabled, this specifies how many months past the initial date the system will check for conflicts when a user adds or updates a repeating event.</dd> <dt>Allow users to override conflicts</dt> <dd>If enabled, users will be warned when there is an event conflict and be presented with the option of scheduling the event anyhow.</dd> <dt>Limit number of timed events per day</dt> <dd>If enabled, users can be limited to a specific number of timed events per day</dd> <dt>Maximum timed events per day</dt> <dd>Specifies that maximum number of events that can be scheduled in one day of any one user.</dd> <dt>Specify timed event length by</dt> <dd>Allows you to configure event lengths to be specified by either duration or end time.</dd> <dt>Brief Description Length</dt> <dd>Specifies the maximum numbers of characters to display in calendar views.</dd> <dt><em>Display Lunar Phases in month view</em></dt> <dd>Show Lunar Calendar icons in month view. This will not use existing event space.</dd> <dt><em>Disable Cross-Day Events</em></dt> <dd>Determines whether to display events that cross user's day boundary as multiple events.</dd> </dl> <h3>Public Access</h3> <dl> <dt>Allow public access</dt> <dd>If enabled, anonymous users will be able to view the public access calendar without logging in.</dd> <dt>Public access visible by default</dt> <dd>If enabled, user's can go to the public access page without having to select it.</dd> <dt>Public access is default participant</dt> <dd>If enabled, public access will be added to every event created.</dd> <dt>Public access can view other users</dt> <dd>If enabled, public access user's will be able to see the calendar of other WebCalendar users. <font color="#FF0000">Use with caution!</font></dd> <dt>Public access can add events</dt> <dd>If enabled, anonymous users will be able to submit new events</dd> <dt>Public access new events require approval</dt> <dd>If enabled, events submitted to the public access calendar (by anonymous users) will require approval by an admin user. If not enabled, then new events will appear on the public access calendar as soon as they are submitted.</dd> <dt> Public access can view participants</dt> <dd>If enabled, public access users can view the names of other participants for any event that public access is a participant. <font color="#FF0000">Use with caution!</font></dd> <dt>Override event name/description for public access</dt> <dd>If enabled, the value of the following setting will be used to mask the name and description of events.</dd> <dt>Text to display to public access</dt> <dd>Text to display as explained above.</dd> </dl> <h3>User Access Control</h3> <dl> <dt> User Access Control enabled</dt> <dd>User Access Control provides more advanced control of user access permissions. If enabled, a "User Access Control" button will appear on the main Admin page and/or on the Settings menu of the NEW top menu. This page will allow you to configure: </dd> <dd> <ul> <li>which functions in the system each user can access </li> <li>which user calendars each user can access (user A can edit events on user B's calendar, etc.)</li> </ul> </dd> </dl> <h3>Groups</h3> <dl> <dt>Groups enabled</dt> <dd>Specifies if group features should be enabled</dd> <dt>User sees only his group</dt> <dd>If enabled, users will be unaware of any users that are not in the same group as the user.</dd> </dl> <h3>NonUser Calendars</h3> <dl> <dt>Nonuser Calendars Enabled</dt> <dd>If enabled, you may create "nonuser calendars" in WebCalendar. A nonuser calendar is a calendar without a user login. It can be used to manage a resource like a conference room's availability. Or it can be used to place common events (like holidays) that multiple users may want to access as a layer. You will need to enable nonuser calendars in order to subscribe to remote iCalendar URLs from within WebCalendar (allowing the events from an iCalendar or hCalendar file elsewhere on the net to appear in your WebCalendar calendar.) </dd> <dt>Display in participants list at</dt> <dd>If enabled, then nonuser calendars can be selected as participants to events.</dd> </dl> <h3>Other</h3> <dl> <dt>Reports enabled</dt> <dd>If enabled, user's will be able to create and generate reports.</dd> <dt><em>Allow remote subscriptions</em></dt> <dd>If enabled, user's will be able enable their own subscription settings. There are currently two main ways to publish events with WebCalendar.</dd> <dd> <ul style="margin-left:70px;"><li ><strong>publish.php</strong> will provide outbound publishing to a calendar client</li> <li><strong>icalclient.php</strong> will provide two-way full synchronization between WebCalendar and another calendar client such as Sunbird, Apple iCal. (PHP 4.3+ required)</li> </ul></dd> <dt>Allow remote calendars</dt> <dd>If enabled, user's will be able to add a special type Non-User Calendar that includes a URL that point to the remote location. The user can manually synchronize the remote calendars if desired. In addition, <tt>tool/reload_remotes.php</tt> can be set up as a cron job to automatically reload all remote calendars as desired. Currently both iCalendar and hCalendar calendars can be consumed by WebCalendar. The calendar type should be automatically detected based on the URL and calendar content. Users will need to create a layer to make a remote calendar visible on their calendars, just like regular Non-User Calendars.</dd> <dt>Enable RSS feed</dt> <dd>If enabled, a link is added to all pages that permits some browsers to create a persistent RSS feed to that page. Currently, only Firefox and IE 7.0 supports this functionality. Also, the setting will enable the use of the rss.php script generate RSS feeds to RSS clients. User's will also be required to enable this feature in their respective preference settings.</dd> <dt>Categories enabled</dt> <dd>Specifies if category features should be enabled</dd> <dt>Category Icon Upload enabled</dt> <dd>Specifies if category icons can be uploaded by users. This requires that a folder named <tt>icons</tt> exist in the WebCalendar directory.</dd> <dt><em>Display small task list</em></dt> <dd>If enabled, a small task window will be displayed in the month and day calendars. These tasks are compatible with the VTODO component of RFC2445 (iCalendar)</dd> <dt><em>Display tasks in Calendars</em></dt> <dd>If enabled, tasks are displayed along with events in calendars. The date they appear is the due date but if the due date has passed without the task being completed, the task will shift to the current day.</dd> <!-- <dt>Export VTIMEZONE in iCalendar (ics) files</dt> <dd>If enabled, a complete VTIMEZONE component will be exported with iCalendar (ics) files as necessary. This function requires considerable processing time, so it should not be enabled unless needed.</dd> --> <dt>Allow external users</dt> <dd>If enabled, the create/edit event page will contain a text area to include the names (and optional email address) of event participants that are not calendar users.</dd> <dt>External users can receive email notifications</dt> <dd>If enabled, event participants entered into the External Participants area will receive email notifications at the same time as calendar users (if an email address was specified for the External Participant).</dd> <dt>External users can receive email reminders</dt> <dd>If enabled, event participants entered into the External Participants area will receive email reminders at the same time as calendar users (if an email address was specified for the External Participant).</dd> <dt>Allow self-registration</dt> <dd>If enabled, new users are permitted to setup their own accounts and log into WebCalendar without admin intervention. <font color="#FF0000">Use with caution!</font></dd> <dt>Restrict self-registration to blacklist</dt> <dd>If enabled, admin can configure the includes/blacklist.php to restrict or permit self-registration based on the user's IP. This will restrict access to existing users or new user's set up by admin. Details and examples are available in the top of the file.</dd> <dt>Generate passwords and send to new users</dt> <dd>If enabled, self-registration user's will be emailed a randomly generated password that they can then use to access WebCalendar normally. Hopefully, this will prevent some spammers and hackers from misusing the self-registration process.</dd> <dt>Allow file attachments to events</dt> <dd>If enabled, attachments can be uploaded and associated with events. The attachments are stored in the database, so care should be taken if performance is an issue. Additionally, permission may extended to participants and/or anyone.</dd> <dt>Allow comments to events</dt> <dd>If enabled, comments can be associated with events. Additionally, permission may extended to participants and/or anyone. </dd> </dl> <h3>Email</h3> <dl> <dt>Email enabled</dt> <dd>Specifies if email functionality should be enabled. If set to "No," then no email messages will be sent at any time.</dd> <dt>Default sender address</dt> <dd>Specifies the email originator to use when the system sends out email Notifications and Reminders</dd> <dt>Email Mailer</dt> <dd>Specifies the email program to use. (PHP mail, SMTP, or sendmail)</dd> <dt>SMTP Host name(s)</dt> <dd>Specifies the SMTP server name(s) or IP(s) if SMTP is selected above.</dd> <dt>SMTP Port Number</dt> <dd>Specifies the SMTP port number if SMTP is selected above. Default is 25.</dd> <dt>SMTP Authentication</dt> <dd>Specifies whether authentication is required if SMTP is selected above. Additionally, <strong>SMTP Username</strong> and <strong>SMTP Password</strong> will be required.</dd> <dt>Event reminders</dt> <dd>Specifies if email reminders for events that include a reminder should be sent</dd> <dt>Events added to my calendar</dt> <dd>Specifies if the system should send email when an event is added</dd> <dt>Events updated on my calendar</dt> <dd>Specifies if the system should send email when an event is updated</dd> <dt>Events removed from my calendar</dt> <dd>Specifies if the system should send email when an event is deleted</dd> <dt>Event rejected by participant</dt> <dd>Specifies if the system should send email when a participant to an event rejects the event</dd> </dl> <h3>Colors</h3> <dl> <dt>Allow user to customize colors</dt> <dd>Specifies whether color settings should be available to users in their Preferences</dd> <dt> Enable gradient images for background colors</dt> <dd>If enabled, the background of calendar table cells will be rendered with a gradient image based on the background color selected for that cell type. This option requires that php be compiled with the <strong>gd module</strong>.</dd> <dt>Document background</dt> <dd>Specifies the background color of all pages</dd> <dt>Document title</dt> <dd>Specifies the color of page title on each page</dd> <dt>Document text</dt> <dd>Specifies the default text color on each page</dd> <dt>My event text</dt> <dd>Specifies the default text color for the user's events</dd> <dt>Table grid color</dt> <dd>Specifies color of the lines that make HTML table grids on each page</dd> <dt>Table header background</dt> <dd>Specifies the default background for the heading of any HTML table</dd> <dt>Table header text</dt> <dd>Specifies the default text color for the heading of any HTML table</dd> <dt>Table cell background</dt> <dd>Specifies the background color for table cells</dd> <dt>Table cell background for current day</dt> <dd>Specifies the background color for the table cell containing the current date (<strong>today</strong>) </dd> <dt>Table cell background for days with events</dt> <dd>Specifies the background color of table cells containing events. This setting will not override the <strong>today</strong> setting and if identical to <strong>today</strong>, will be ignored. </dd> <dt>Table cell background for weekend</dt> <dd>Specifies the background color for table cells that represent a Saturday or Sunday</dd> <dt>Table cell background for other month</dt> <dd>Specifies the background color for table cells of other month days.</dd> <dt>Week number color</dt> <dd>Specifies the text color for week numbers (if enabled)</dd> <dt>Event popup background</dt> <dd>Specifies the background color of event popup areas</dd> <dt>Event popup text</dt> <dd>Specifies the text color of event popup areas</dd> </dl> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="siteextras"></a> <h2>Custom Event Fields</h2> <p>You may want to customize the event-specific fields found in the <tt>includes/site_extras.php</tt> field. If this is your first time using the calendar, you can skip this step and come back later since this step is <em>optional</em>.</p> <p>You can use this feature to add extra fields to your calendar events. For example, you can add a URL, a contact email address, or a pulldown containing predefined attributes.</p> <p>When defining a new custom field, the following types listed below are available. "Arg 1" and "Arg 2" have different meaning depending on the type of field. In some cases, "Arg 1" and "Arg 2" are not used.</p> <center> <table style="width: 100%;"> <tr><th> Type</th><th> Description</th><th> Arg 1</th><th> Arg 2 </th></tr> <tr><td> <tt>EXTRA_TEXT</tt></td><td> Allows the user to enter a single line of text</td><td> Specifies the size of the text form element as it would appear in the following ("NN" would be replaced with Arg 1):<br> <tt><input size="NN" ...</tt></td><td> N/A </td></tr> <tr><td> <tt>EXTRA_MULTILINETEXT</tt></td><td> Allows the user to enter multiple lines of text</td><td> Specifies how many characters wide the textform element should be as it would appear in the following ("NN" would be replaced with Arg 1):<br> <tt><textarea cols="NN" ...</tt></td><td> Specifies how many lines long the textform element should be as it would appear in the following ("NN" would be replaced with Arg 1):<br> <tt><textarea rows="NN" ...</tt> </td></tr> <tr><td> <tt>EXTRA_URL</tt></td><td> Allows the user to enter a single line of text and will be displayed as a link when viewed</td><td> N/A</td><td> N/A </td></tr> <tr><td> <tt>EXTRA_DATE</tt></td><td> Allows the user to select a date using the standard date selection form elements</td><td> N/A</td><td> N/A </td></tr> <tr><td> <tt>EXTRA_EMAIL</tt></td><td> Allows the user to enter a single line of text and will be displayed as a mailto URL link</td><td> N/A</td><td> N/A </td></tr> <tr><td> <tt>EXTRA_USER</tt></td><td> Allows selection of a WebCalendar user from a pulldown list</td><td> N/A</td><td> N/A </td></tr> <tr><td> <tt>EXTRA_RADIO</tt></td><td> Allows selection of a single item from a group of radio buttons</td><td> Specifies the list of available options using the PHP <tt>array</tt></td><td> The default item that will be selected (from list above) </td></tr> <tr><td> <tt>EXTRA_SELECTION_LIST</tt></td><td> Presents the user with a selection list (single selection) to choose from</td><td> Specifies the list of available options using the PHP <tt>array</tt> function</td><td> 0 indicates single selection, 1 indicates multiple selection and also the maximum size </td></tr> <tr><td> <tt>EXTRA_CHECKBOX</tt></td><td> Will display a checkbox control</td><td> N/A</td><td> N/A </td></tr> </table> </center> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="faq"></a> <h2>Frequently Asked Questions</h2> <dl> <!-- cek: leave these comments here... extractfaqs.pl looks for them --> <!-- START FAQ: Installation/Setup --> <dt>How do I setup PHP, MySQL and Apache on Windows?</dt> <dd>The easiest way to do this is to try one of the prepackaged bundles that will install all of these for you: <ul> <li><a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a> <a href="http://www.apachefriends.org/en/xampp.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> <li><a href="http://www.foxserv.net/">FoxServ</a> <a href="http://www.foxserv.net" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> <li><a href="http://www.sokkit.net/">Sokkit</a> <a href="http://www.sokkit.net" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a> (formerly PHPTriad)</li> </ul> </dd> <dt>How do I setup PHP, MySQL and Apache on Mac OS X?</dt> <dd>You can use the built-in Apache/PHP installed on Mac OS X. However, this does not inlude MySQL. An easier way to setup WebCalendar would be to use one of the following packages: <ul> <li><a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a> <a href="http://www.apachefriends.org/en/xampp.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> </ul> </dd> <dt>How do I setup PHP, MySQL and Apache on UNIX/Linux?</dt> <dd>There are many online instructions on how to do this. Here are a few: <ul> <li><a href="http://www.onlamp.com/pub/a/php/2000/11/17/php_admin.html">ONLamp.com: Basic Installation of PHP on a Unix System</a> <a href="http://www.onlamp.com/pub/a/php/2000/11/17/php_admin.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> <li><a href="http://www.devshed.com/Server_Side/PHP/SoothinglySeamless/">Developer Shed: The Soothingly Seamless Setup of Apache, SSL, MySQL and PHP</a> <a href="http://www.devshed.com/Server_Side/PHP/SoothinglySeamless/" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> <li><a href="http://www.linuxhelp.net/guides/lamp/">Linux Help: LAMP Guide</a> <a href="http://www.linuxhelp.net/guides/lamp/" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> <li><a href="http://www.php.net/manual/en/installation.php">PHP.net</a> <a href="http://www.php.net/manual/en/installation.php" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></li> </ul> </dd> <dt>I've finished the install. What is the login to WebCalendar?</dt> <dd>After the initial creation of the database tables, there will be a single user account created with the username "admin" and the password set to "admin" as well. <br><span class="note">Note:</span> This account is intended to get your started. You should create a new admin account and delete this one.</dd> <dt><a name="samplepublic">I want to use WebCalendar as an events calendar for my organization. How do I set it up to do this?</a></dt> <dd>You will want to setup WebCalendar to use public access. <ol> <li>Setup your <tt>settings.php</tt> file as a multi-user system (see <a href="#appsetup">instructions</a>).</li> <li>In System Settings, set "Allow public access" to "Yes."</li> <li>If you want people to be able to submit new events through public access, set "Public access can add events" to "Yes."</li> <li>If you set "Public access can add events" to "Yes", set the setting for "Public access new events require approval" to your liking. If you set this to "Yes," an admin user will need to approve any new events before they will appear on the public access calendar.</li> <li>Login using one of the accounts you have setup. Add a new event, and select "Public User" as one of the participants.</li> <li>If you have enabled "Require event approvals" in your System Settings, then you will need to approve the new event. Choose the "Unapproved Events" at the bottom of any page (you must be an admin user to access this). You will be presented with a list of unapproved events (for both the current user and for the Public User account). Approve the new event for the Public User.</li> <li>Go to the Login page. You will see a "Access public calendar" link that will bring you to the calendar for public access.</li> <li>By default, the index.php page should send users to the public calendar.</li> </ol> </dd> <dt>How can I add holidays to the calendar?</dt> <dd>There is no built-in support for holidays because it is not necessary. You can add holidays into WebCalendar by importing one of the many iCalendar holiday files that are freely available. A good resource for free iCalendar files is <a href="http://www.icalshare.com">iCalShare <img src="newwin.gif" alt="new" class="newwin"></a>. For example, the U.S. holiday iCalendar file can be downloaded from: <blockquote> <a href="http://icalshare.com/article.php?story=20020912105939521">http://icalshare.com/article.php?story=20020912105939521 <img src="newwin.gif" alt="new" class="newwin"></a> </blockquote> If you don't want each individual user to have to import the holiday calendar, you can use nonuser calendars. First, make sure nonuser calendars are enabled in your system settings. Then, from Admin->Users, you can access nonuser calendars. Create a new nonuser calendar (such as "usholidays"). Then, notify your users that they can add this nonuser calendar as a layer to their own calendar in order to see the holidays. </dd> <dt>Why are deleted events still present in the database?</dt> <dd>When you delete an event from your calendar, it is not deleted from the database. Instead, it is marked as deleted. This allows the system administrator access to information even after it is deleted.</dd> <dt>Can I setup more than one public calendar?</dt> <dd>You cannot directly setup two public calendars. However, there are two options for emulating this type of functionality: <ul> <li>You can <a href="WebCalendar-UserManual.html#categories">create global categories</a> and point users to the calendar with only a certain category displayed.</li> <li>You can setup multiple NonUser calendars and enable public access viewing of other users' calendars. You can then link directly to the calendar of one of the NonUser calendars, or you can <a href="WebCalendar-UserManual.html#views">setup a view</a> that contains the calendar of one or more of the NonUser calendars.</li> </ul> </dd> <dt>How do I change the title "Public Access" at the top of the calendar?</dt> <dd>In the file <tt>translations/English-US.txt</tt>, change the line that says "Public Access" to what you want it to say on the right side.<br><br>Example: <pre>Public Access: Foobar Event Calendar</pre> </dd> <dt>Can I embed WebCalendar as a component on another web page?</dt> <dd>WebCalendar is meant to be run as a standalone web application. You can customize the appearance of WebCalendar to match your existing site. To do this, In System Settings, set both "Custom header" and "Custom trailer" to "Yes" and press the "Edit" button to enter the header and trailer content. <br> If you are looking to just include a list of upcoming events in one of your web pages, you can use the <tt>upcoming.php</tt> page in WebCalendar to do this. Edit the top of this file to configure options. (These settings will likely move into System Settings in subsequent release.) You can then use an <tt>iframe</tt> elsewhere on your web site as in the example below: <pre><iframe height="250" width="300" scrolling="yes" src="upcoming.php"></iframe></pre> Include this HTML anywhere on any of your pages. By default, the events from the public calendar will be loaded (so you must have "Public Access" enabled in System Settings). You can override this with another user's calendar. (See <tt>upcoming.php</tt> for instructions on this.) <br><br> If you would like to display a small calendar (like the ones on the month view), you can add the following example. There are some configuration options available in the top of this file as well. You can then use an <tt>iframe</tt> elsewhere on your web site as in the example below: <pre><iframe height="200" width="180" scrolling="yes" src="minical.php"></iframe></pre> </dd> <dt>How do I customize the appearance of WebCalendar so that it matches the rest of my site?</dt> <dd>You can customize the appearance of WebCalendar to match your existing site. To do this, In System Settings, set both "Custom header" and "Custom trailer" to "Yes", and press the "Save" button. Then click on the "Edit" button to enter your site content. The custom header will be included after the document's HTML <code><body></code> tag but before any WebCalendar content. The custom trailer will be included after the WebCalendar content and before the document's HTML <code></body></code> tag. If you want to add JavaScript or Stylesheet data, you can use the "Custom script/stylesheet" option on the same System Settings page. Any content entered will be included within the document's HTML <code><head></code> section. </dd> <dt>How do I add a new translation?</dt> <dd> It's a fairly simple process. If you've ever translated a C-based app that used GNU's gettext tool, then you'll have no problem. The I18N support was based on GNU's <a href="http://www.gnu.org/software/gettext/gettext.html">gettext</a> <a href="http://www.gnu.org/software/gettext/gettext.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>. Here's what you need to do. <ol> <li>look in the "translations" directory</li> <li>copy the <tt>English-US.txt</tt> file into what you'd like to call your language data file. (e.g. <tt>cp English-US.txt French.txt</tt>)</li> <li>Now translate all the text to the _right_ of the ": " into the new language. Do <em>not</em> alter the text to the left of the ": ".</li> <li>When you're done making changes, move into the "tools" directory. Run the <tt>check_translation.pl</tt> script on your new data file to make sure you have all the needed translations. (e.g. <tt>perl check_translation.pl French</tt>)</li> <li>Add the new language to both the $languages array and the $browser_languages arrays defined in <tt>includes/translate.php</tt>.</li> <li>Test it out... </li> <li>Post a copy of your translation (along with your changes to <tt>includes/translate.php</tt>) to the <a href="http://sourceforge.net/tracker/?group_id=3870&atid=303870">SourceForge Patches</a> <a href="http://sourceforge.net/tracker/?group_id=3870&atid=303870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a> for WebCalendar.</li> </ol> </dd> <dt>How do I update an existing translation?</dt> <dd>Just open up the translation file in the <tt>translations</tt> directory with your favorite text editor (like vi, vim, emacs, pico, Notepad, etc.). In particular look for places where missing translations are indicated. All missing translations should be marked with a "<< MISSING >>" note. and typically the English version of the translation will also be included on the following line (as in the example below): <pre># << MISSING >> # Edit: #</pre><br> For some text, an abbreviation may be used rather than the English text. In those cases, the full text will be noted as in the following example: <pre># << MISSING >> # custom-script-help: # English text: Allows entry of custom Javascript or stylesheet text that # will be inserted into the HTML "head" section of every page. #</pre><br> When you're done making changes, move into the <tt>tools</tt> directory. Run the <tt>check_translation.pl</tt> script on your new data file to make sure you have all the needed translations: <pre><tt>perl check_translation.pl French</tt></pre> Post a copy of your translation to the <a href="http://sourceforge.net/tracker/?group_id=3870&atid=303870">SourceForge Patches</a> <a href="http://sourceforge.net/tracker/?group_id=3870&atid=303870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a> for WebCalendar.</dd> <dt>During Import, I receive this error: Unknown Timezone: XXXXX defaulting to GMT.</dt> <dd>This is a notice that your import file contained unknown timezone information. WebCalendar will simply save the event or task as GMT. You are encouraged to submit these notices as <a href="https://sourceforge.net/projects/webcalendar/">Bug Reports to SourceForge</a>, so that WebCalendar can improve its TZID support.</dd> <!-- END FAQ --> </dl> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="trouble"></a> <h2>Troubleshooting</h2> <dl> <!-- cek: leave these comments here... extractfaqs.pl looks for them --> <!-- START FAQ: Troubleshooting --> <dt>I get error messages about undefined variables when I try to view any page.</dt> <dd>On newer versions of PHP, the default setting of PHP is to display messages when an undefined variable is referenced. To prevent these messages from being displayed, change the setting of <tt>error_reporting</tt> in your <tt>php.ini</tt> file to be: <pre>error_reporting = E_ALL & ~E_NOTICE</pre> Alternately, you can disable any error messages from being displayed in the browser and have them logged to a file. (See the comments included in the <tt>php.ini</tt> file for instructions on how to do this.)</dd> <dt><a name="dbCacheError">I receive an error message saying "Error removing temporary file" or "Cache error".</a></dt> <dd>This indicates that a file in your database cache directory could not be deleted or created. The quickest solution to this problem is to not use the database cache. Simply remote the <tt>db_cachedir</tt> line from <tt>includes/settings.php</tt> with a simple text editor. This error is most common when the <tt>send_reminders.php</tt> script is run from a cron job under a different system account than the PHP application server is running under. This causes files created by the <tt>send_reminders.php</tt> script to be owned by a different user than normal, preventing the PHP application from being able to remove the files when needed. </dd> <dt>I receive an error message saying "Failed opening 'includes/...' for inclusion ..."</dt> <dd>You may have to modify the <tt>include_path</tt> setting in your <tt>php.ini</tt> file. Most users do not need to do this, but some PHP installs seem to require it. You will need to add the WebCalendar directory to the list of directories for <tt>include_path</tt>.</dd> <dt>I get an error message from PHP saying "Call to undefined function: ..."</dt> <dd>This tells you that your version of PHP is missing something that WebCalendar needs. If the function mentioned is a database login function (<em>ociplogin</em>, <em>mysql_pconnect</em>, <em>ibase_connect</em>, <em>pg_pconnect</em>), then you probably do not have the needed support for your database compiled into PHP. If the function is not a database connect call, then check the <a href="http://www.php.net/manual/en/">PHP manual</a> <a href="http://www.php.net/manual/en/" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a> to see if the function requires a specific version of PHP. You may have an out-dated version of PHP that requires upgrading.</dd> <dt>When I try and view certain pages, nothing happens for 30 seconds, then I get a time-out error.</dt> <dd>On slower or very busy servers, it can take some time for the server to get all the events. Most PHP installations have a built-in timeout out of 30 seconds and will interrupt any request that takes longer than that. This is most likely to happen on the year-long custom report or on the month view when layers are being used. If you have access, you can increase the time-out value for PHP in the <tt>php.ini</tt> file by changing the setting of the <tt>max_execution_time</tt> setting.</dd> <dt>I get an error message that says "Can't connect to local MySQL server through socket '/tmp/mysql.sock'."</dt> <dd>This is a PHP/MySQL configuration issue. The value of <tt>mysql.default_socket</tt> in your <tt>php.ini</tt> file must match the value of <tt>socket</tt> in your <tt>my.cnf</tt> file. Edit the <tt>php.ini</tt> file to fix this problem.</dd> <dt>I am not receiving any email messages from WebCalendar.</dt> <dd>WebCalendar sends two types of email messages: Notifications<a href="#g_notification">*</a> and Reminders<a href="#g_reminder">*</a>. Check the following if you are not receiving any email: <ol> <li>You have defined a valid SMTP server in your PHP configuration file <tt>php.ini</tt>. (The setting is "SMTP" in the "mail_function" section.)</li> <li>In WebCalendar's System Settings, you have set the "Email Enabled" setting to "Yes".</li> <li>In WebCalendar's System Settings, make sure you have the "Default sender address" to something. <br><span class="note">Note:</span> Some mail system will reject mail that has a "From" address that is a different domain from the originating SMTP server. So, if your SMTP server is smtp.mydomain.com and your "Default sender address" is calendar@someotherdomain.com, some mail systems may bounce the mail back.</li> <li>For a Notification, make sure you have the type of Notification set to "Yes" in the user's Preferences.</li> <li>For a Reminder: <ul> <li>Make sure you have "Event reminders" set to "Yes" in the user's Preferences.</li> <li>Make sure you have <a href="#reminders">setup a cron job</a> to periodically run the <tt>send_reminders.php</tt> script.</li> </ul> </li> </ol> </dd> <dt>Some of the pages are displaying text in English rather than <insert your language here></dt> <dd>The translations have been submitted at various points of WebCalendar development. Some have not been updated to include newer features.</dd> <dt>The text that I entered in the <a href="#siteextras">Custom Event Fields</a> is not being translated to different languages.</dt> <dd>You will need to add an entry in each of the translation files for any text you add into the Custom Event Fields.</dd> <dt>How do I get the most recent version of WebCalendar?</dt> <dd>You can download the latest public release from SourceForge's <a href="http://sourceforge.net/project/showfiles.php?group_id=3870">file list for WebCalendar</a> <a href="http://sourceforge.net/project/showfiles.php?group_id=3870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>. <br> You can download the latest development code from the CVS server using the <a href="http://sourceforge.net/cvs/?group_id=3870">instructions provided by SourceForge</a> <a href="http://sourceforge.net/cvs/?group_id=3870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>. (You will need a CVS client to do this.)</dd> <dt>How do I install a patch file listed on SourceForge's <a href="http://sourceforge.net/tracker?group_id=3870&atid=303870">list of WebCalendar patches</a> <a href="http://sourceforge.net/tracker?group_id=3870&atid=303870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>?</dt> <dd>Most patches are distributed as context diffs. That means they were produced using the UNIX <tt>diff</tt> command with the <tt>-C</tt> option. The patches are intended to be used with the <a href="http://www.fsf.org/software/patch/patch.html">GNU patch</a> <a href="http://www.fsf.org/software/patch/patch.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a> program. This program is standard on most Linux systems and can be obtained as part of the <a href="http://www.cygwin.com">Cygwin</a> <a href="http://www.cygwin.com" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a> package for Windows. Mac OS X will have the patch program installed if they install the developer tools CD.</dd> <dt>I forgot/lost my admin password. How can I reset it?</dt> <dd>The easiest way is to admin a new admin user and then use that new user to reset the password for your old admin account. Assuming you have deleted the original 'admin' login, you can use the following SQL to insert a new admin user into the database: <pre>INSERT INTO webcal_user ( cal_login, cal_passwd, cal_lastname, cal_firstname, cal_is_admin ) VALUES ( 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'Default', 'Y' );</pre> This will add a user with login 'admin' and password 'admin' to the database. If you still have a user named 'admin', then replace 'admin' in the above SQL with a different username. </dd> <dt>I get a database error indicating table <tt>webcal_config</tt> does not exist.</dt> <dd>This is the first table that WebCalendar tries to access, so it typically means one of the following: <ul> <li>You have not created the database tables as described in the instructions</li> <li>You have the wrong database name specified in your <tt>includes/settings.php</tt> file</li> </ul> </dd> <dt>I get a database error from MySQL that says "Client does not support authentication protocol."</dt> <dd>From the MySQL 5.0 Reference Manual: <blockquote>MySQL 5.0 uses an authentication protocol based on a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients. If you upgrade the server from 4.0, attempts to connect to it with an older client may fail with the following message: <br><br> Client does not support authentication protocol requested by server; consider upgrading MySQL client </blockquote> The <a href="http://dev.mysql.com/doc/refman/5.0/en/old-client.html">MySQL Reference Manual</a> has solutions for this problem. </dd> <!-- END FAQ --> </dl> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="help"></a> <h2>Getting Help</h2> <p>Try the Help/Troubleshooting forum for WebCalendar, hosted at SourceForge.net:</p> <pre><a href="https://sourceforge.net/forum/forum.php?forum_id=11588">https://sourceforge.net/forum/forum.php?forum_id=11588</a> <a href="http://sourceforge.net/forum/forum.php?forum_id=11588" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a></pre> <p>If you encounter a bug, please check the <a href="http://sourceforge.net/tracker/?group_id=3870&atid=103870">list of open and pending bugs</a> <a href="http://sourceforge.net/tracker/?group_id=3870&atid=103870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>. If you do <strong>not</strong> see anything similar, submit a new bug.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="license"></a> <h2>Licensing</h2> <p>WebCalendar is distributed under the open source <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public License</a> <a href="http://www.gnu.org/licenses/gpl.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>. If you have questions about this license, please read their <a href="http://www.gnu.org/licenses/gpl-faq.html">GPL FAQ</a> <a href="http://www.gnu.org/licenses/gpl-faq.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin"></a>.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="glossary"></a> <h2>Glossary</h2> <dl> <dt><a name="g_activitylog">Activity Log</a></dt> <dd>A summary of recent updates to calendar data</dd> <dt><a name="g_assistant">Assistant</a></dt> <dd>A calendar user that has been designated by another calendar user (the Boss) to help manage their calendar</dd> <dt><a name="g_boss">Boss</a></dt> <dd>A calendar user that has designated another calendar user (the Assistant) to help manage his calendar</dd> <dt><a name="g_externaluser">External User</a></dt> <dd>A calendar participant that does not have a calendar user account</dd> <dt><a name="g_group">Group</a></dt> <dd>A mechanism of dividing up a large set of users into smaller sets of users</dd> <dt><a name="g_imap">IMAP</a></dt> <dd>Internet Message Access Protocol, an optional method of user authentication.</dd> <dt><a name="g_layer">Layer</a></dt> <dd>A function that allows a user to overlay another user's calendar on top of his own calendar so that the standard day, week and month pages show both his own and the layered user's events</dd> <dt><a name="g_ldap">LDAP</a></dt> <dd>LDAP (Lightweight Directory Access Protocol) is an Internet protocol used to maintain user directories</dd> <dt><a name="g_mulituser">Multi-User Mode</a></dt> <dd>When WebCalendar is configured in Multi-User Mode, there can be multiple user accounts, each with his own calendar. Unless Public Access is enabled, all users will be required to login before they can access the system.</dd> <dt><a name="g_nis">NIS</a></dt> <dd>NIS (Network Information Service) is a UNIX-based user authentication system for managing user directories in a network</dd> <dt><a name="g_nonuser">NonUser Calendar</a></dt> <dd>A participant to a calendar event that is not a calendar user. This is typically used either as a resource (conference room, laptop computer) that needs to be shared or as a shared calendar that other users overlay onto their own calendar using layers (company-wide calendar, holiday calendar, etc.)</dd> <dt><a name="g_notification">Notification</a></dt> <dd>An email message that is sent when an event is added, removed or updated in the user's calendar by another user</dd> <dt><a name="g_preferredview">Preferred View</a></dt> <dd>The standard page (day, week, month or year) that will be presented to the user after logging in (set in user <a href="#pref">Preferences</a>)</dd> <dt><a name="g_preferredview">Public Access</a></dt> <dd>A <a href="#systemsettings">System Setting</a> that will allow anonymous users to access the calendar. See the <a href="#samplepublic">simple instructions</a> for setting this up in the <a href="#faq">FAQ section</a>. (Requires WebCalendar to be configured in Multi-User Mode).</dd> <dt><a name="g_reminder">Reminder</a></dt> <dd>An email message that is sent before an event to remind the participant</dd> <dt><a name="g_singleuser">Single-User Mode</a></dt> <dd>When WebCalendar is configured in Single-User Mode, there is no concept of users. You will be managing a single calendar and no login will be required. Anyone accessing this calendar will have full privileges to view, add, edit and delete all events.</dd> <dt><a name="g_timeinterval">Time Interval</a></dt> <dd>The amount of time each "block" will represent in either the day or week view (set in user <a href="#pref">Preferences</a>)</dd> <dt><a name="g_uac">User Access Control (UAC)</a></dt> <dd>The fully configurable feature to allow extremely granular access control to user. This control applies to system options and features as well as other user's calendars.</dd> <dt><a name="g_view">View</a></dt> <dd>A customized page that presents the events of selected users</dd> <dt><a name="g_workhours">Work Hours</a></dt> <dd>The default hours to show in the week and day view where events are displayed in blocks of time (set in user <a href="#pref">Preferences</a>)</dd> </dl> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="appendixA"></a> <h2>Appendix A: Using phpMyAdmin</h2> <p> If you have <a href="http://www.phpmyadmin.net">phpMyAdmin</a> installed and configured to manage your MySQL database, use the following steps to setup WebCalendar. (The following information is based on phpMyAdmin version 2.6.1.)</p> <ol> <li>On the initial phpMyAdmin page, under the "MySQL" heading, the first option should be "Create new database." Enter the name you have chosen for the database and press the "Create" button. (The default database name used by WebCalendar is "intranet".) After pressing the "Create" button, it should say: "Database <your database name here> has been created." </li> <li>Click on the home icon (the small house) in the left-side navigation. This will bring you back to your phpMyAdmin home page.</li> <li>(Optional) Create new MySQL user. If you already have a MySQL login that you would like to use, you can skip this step.</li> <li><ul> <li>Click on the "Privileges" link under the "MySQL" heading.</li> <li>Below any existing users listed, click on the link "Add a new User."</li> <li>Fill in the details of your new database user. The default username for WebCalendar is "webcalendar" with a password of "webcal01". Leave the "Host" field set to "Any host".</li> <li>From the list of "Global privileges", be sure to select: SELECT, INSERT, UPDATE, DELETE, FILE, CREATE, ALTER, INDEX, DROP </li> <li>Click on the "Go" button.</li> <li>You should see a page that says "You have added a new user."</li> </ul></li> <li>Click on the "Databases" tab at the top of the page.</li> <li>From the list of databases on the page, click on the name of the database that you created.</li> <li>Click on the "SQL" tab at the top of the page.</li> <li>At the bottom of the page, there is an area to upload a SQL file. Click on the "Browse" button and select the <tt>tables-mysql.sql</tt> file in the WebCalendar toplevel directory. Then, press the "Go" button.</li> <li>The top of the page should say "Your SQL-query has been executed successfully."</li> <li>You have now finished creating the WebCalendar database tables.</li> </ol> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="appendixB"></a> <h2>Appendix B: Database Setup</h2> <p>There are three steps in setting up the database:</p> <ol> <li>Creating the database</li> <li>Creating the user</li> <li>Creating the required tables</li> </ol> <p>Follow the steps outlined below for the database you are using. When complete, a single user account will be created with the <strong>login "admin" and password "admin"</strong>, which you are encouraged to use to create your own account.</p> <p><span class="note">Note:</span> In the examples below, text in <strong>bold</strong> represents text that you must type in.</p> <p><span class="note">Security:</span> The default values for database, login, and password (<strong>intranet</strong>, <strong>webcalendar</strong>, and <strong>webcal01</strong>) are for demonstration purposes only and should never be used in a production environment.</p> <h3 class="colorheader">MySQL</h3> <p>The following will create a database named "intranet".</p> <pre><strong>mysqladmin create intranet</strong></pre> <p>Next, create the database user account that will be used to access the database.</p> <pre><strong>mysql --user=root mysql</strong> mysql> <strong>GRANT ALL PRIVILEGES ON *.* TO webcalendar@localhost IDENTIFIED BY 'webcal01' WITH GRANT OPTION;</strong> mysql> <strong>FLUSH PRIVILEGES;</strong> mysql> <strong>QUIT</strong></pre> <p>If you will be accessing MySQL from a different machine than the one running the web server, repeat the command above and replace 'localhost' with the hostname of the other machine.</p> <p>Create the calendar tables using the supplied <tt>tables-mysql.sql</tt> file:</p> <pre><strong>mysql intranet < tables-mysql.sql</strong></pre> <p>In the above example, "intranet" is the name of your database.</p> <p><span class="note">Note:</span> If you are using <a href="http://www.phpmyadmin.net">phpMyAdmin</a> to manage your MySQL database, follow the instructions in <a href="#appendixA">Appendix A</a>.</p> <h3 class="colorheader">Oracle</h3> <p>The following will create a tablespace named "webcalendar". From the command line, startup sqlplus and issue the following command:</p> <pre><strong>sqlplus</strong> SQL> <strong>CREATE TABLESPACE webcalendar DATAFILE 'webcalendar.dat' SIZE 10M AUTOEXTEND ON NEXT 10M MAXSIZE 40M;</strong></pre> <p>Next, create the database user account that will be used to access the database.</p> <pre><strong>sqlplus</strong> SQL> <strong>CREATE USER webcalendar IDENTIFIED BY webcal01 DEFAULT TABLESPACE webcalendar;</strong> SQL> <strong>GRANT dba TO webcalendar;</strong> SQL> <strong>quit</strong></pre> <p>Create the calendar tables using the supplied <tt>tables-oracle.sql</tt> file:</p> <pre><strong>sqlplus webcalendar/webcal01</strong> SQL> <strong>@tables-oracle;</strong> SQL> <strong>quit</strong></pre> <h3 class="colorheader">PostgreSQL</h3> <p>The following will create a database named "webcalendar". From the command line as the psql user: issue the following commands:</p> <pre>$ <strong>su postgres</strong> # <strong>createdb webcalendar</strong> # <strong>createuser --no-createdb --no-adduser -P webcalendar</strong> # <strong>psql webcalendar webcalendar</strong> <strong>\i tables-postgres.sql</strong> <strong>\q</strong></pre> <h3 class="colorheader">Interbase</h3> <p>The following will create a database named "WEBCAL.gdb". From the command line, startup usql and issue the following command:</p> <pre><strong>CREATE DATABASE 'WEBCAL.gdb';</strong></pre> <p>Create the calendar tables using the supplied <tt>tables-ibase.sql</tt> file:</p> <pre><strong>isql connect /path/WEBCAL.gdb; input path/table-ibase.sql;</strong></pre> <h3 class="colorheader">ODBC</h3> <p>Setup will depend on which database you are using. When it comes time to create the tables, the <tt>tables-postgres.sql</tt> file should work for most databases.</p> <h3 class="colorheader">MSSQL</h3> <p>Create a database, <strong>intranet,</strong> and add a user, <strong>webcalendar</strong>, to access this database. The user should be granted public, db_datareader, and db_datawriter privileges. Open SQL Query Analyzer then open the file <tt>tables-postgres.sql</tt>. Make sure you have identified <strong>intranet</strong> as the target database and Execute the contents of the sql file.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <a name="appendixC"></a> <h2>Appendix C: Setting Up Reminders on Windows</h2> <p>You have two options to choose from when setting up email reminders on a Windows platform. You can either install a cron package for Windows, or you can use the Windows Task Scheduler.</p> <h3>Installing a Cron Package</h3> <p> If you install a cron package for Windows, you will need to setup to setup a cron job. (UNIX cron is a tool for used to run tasks as specified times anywhere from every minute to once a year.)</p> <p> First, you should create a <tt>sendreminders.bat</tt> file that contains a single line:</p> <pre>C:\your\path\to\php.exe C:\your\path\to\webcalendar\tools\send_reminders.php</pre> <p>You can place this <tt>sendreminders.bat</tt> file anywhere on your file system.</p> <p>Next, you need to setup the cron job. The crontab entry should look like the following (replace with the correct path to your newly created <tt>sendreminders.bat</tt> file):</p> <pre>1 * * * * C:\your\path\to\sendreminders.bat</pre> <p>The "1 * * * *" will tell the cron schedule to run this task at 1 after the hour all day long (12:01am, 1:01am, 2:01am, etc.) If you only want to run it once per day, you could use:</p> <pre>1 4 * * * C:\your\path\to\sendreminders.bat</pre> <p>This would tell the cron scheduler to run the task at 4:01am every day. For more information about the syntax of cron, check the documentation for the package you have installed or view the UNIX man page for crontab (like <a href="http://www.rt.com/man/crontab.5.html" target="_blank">this one</a>).</p> <p>There are many cron packages for Windows available. Below is a list of packages to choose from. (Note: use at your own risk. These links are provided for information only.)</p> <ul> <li><a href="http://cronw.sourceforge.net/" target="_blank">CRONw</a> (open source) </li> <li><a href="http://www.gold-software.com/VisualCron-review11507.htm" target="_blank">VisualCron</a> (freeware)</li> <li><a href="http://www.nncron.ru" target="_blank">nnCron</a> (freeware and commercial versions)</li> <li><a href="http://surguy.net/articles/icron.xml" target="_blank">iCron</a> </li> <li><a href="http://p.clark.home.mindspring.com/jcron/index.html" target="_blank">jCron</a> (freeware) </li> </ul> <h3>Using the Windows Task Schedule</h3> <p>Follow the steps listed below to setup a new task in the Windows Task Scheduler. (These instructions were created with Windows XP Professional. Other versions of Windows might be different.)</p> <ol> <li>Create a new batch file called <tt>sendreminders.bat</tt>. The contents of this file should be a single line: <pre>C:\your\path\to\php.exe C:\your\path\to\webcalendar\tools\send_reminders.php</pre> </li> <li>On Windows XP, go to Control Panel</li> <li>Double-click on "Scheduled Tasks." This brings up a window that says "Scheduled Task Wizard" </li> <li>Click on "Browse..." </li> <li>Select the location of your newly created <tt>sendreminders.bat</tt> file.</li> <li>Click on "Open" </li> <li>Change the name of the task. "WebCalendar Reminders" is a good name. </li> <li>Select how often to perform this task. Select "Daily." </li> <li>Click on "Next" </li> <li>Select the start time, then click "Next". If you are planning on sending out reminders throughout the day, pick a time shortly after midnight. </li> <li> Enter your user password as required. Click on "Next." </li> <li> Select the checkbox "Open advanced properties". </li> <li> Click on "Finish." </li> <li> Under the "Schedule" tab, click on "Advanced." </li> <li> Click on "Repeat Task" and fill in the details of how often the job should run. For example, you can set it to run "every 15 minutes", then click on "until" and set that time to 11:30pm. </li> </ol> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="appendixD"></a> <h2>Appendix D: Displaying Upcoming Events on Your Site</h2> <p> If you would like to list upcoming events somewhere on a page on your site (someplace other than the WebCalendar pages), you can use the <tt>upcoming.php</tt> page to do this. This page is intended to be included in other pages using the <tt>iframe</tt> tag.</p> <p>You may need to modify some of the variables near the top of <tt>upcoming.php</tt> with a text editor:</p> <table border="0" style="margin-left: 20px; margin-right: 20px;"> <tr><td valign="top">$public_must_be_enabled</td> <td> Specifies if Public Access must be enabled in System Settings for this page to be viewed. <br>Default setting: false </td></tr> <tr><td valign="top">$display_link</td> <td> Specifies if events should have a link to the URL within WebCalendar to view the event. <br>Default setting: true </td></tr> <tr><td valign="top">$link_target</td> <td> Specifies the name of the window that be used for the link target. <br>Default setting: _top </td></tr> <tr><td valign="top">$numDays</td> <td> Specifies how many days of events should be listed. <br>Can override this by passing "num" in within the URL with "upcoming.php?num=60" <br>Default setting: 30 </td></tr> <tr><td valign="top">$maxEvents</td> <td> Specifies the maximum number of events to list. <br>Default setting: 10 </td></tr> <tr><td valign="top">$username</td> <td> The login of the calendar to display upcoming events for. If you want to see upcoming events for user login "joe", then you would change this to "joe". <br>Default setting: __public__ (The public calendar) </td></tr> <tr><td valign="top">$allow_user_override</td> <td> Specifies whether the calendar user can be specified in the URL (in which case the $username setting will be ignored) using a URL like "upcoming.php?user=joe". <br>Default setting: true </td></tr> <tr><td valign="top">$load_layers</td> <td> Specifies if the calendar user's layers should also be included in the upcoming events. <br>Note: Layers must be enabled in the user's preferences. <br>Default setting: true </td></tr> <tr><td valign="top">$cat_id</td> <td> Specifies a category id to filter events on. <br>Note: Categories must be enabled in System Settings. <br>Default setting: (empty) </td></tr> </table> <p>Below is an example of how you would include <tt>upcoming.php</tt> in a simple HTML page.</p> <pre> <html><head><title>ACME Home Page</title></head> <body> <h1>Welcome to the ACME Home Page</h1> <h2>News</h2> <p>No news....</p> <h2>Upcoming Events</h2> <iframe src="upcoming.php" width="400" height="400" name="califrame"></iframe> </body> </html> </pre> <p><span class="tip">TIP</span> The <a href="http://www.w3schools.com/tags/tag_iframe.asp" target="_blank">W3 Schools</a> site provides documentation about the different options that you can use with the <tt>iframe</tt> tag.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="appendixE"></a> <h2>Appendix E: How To Configure for LDAP</h2> <p>Configuring WebCalendar to use an existing LDAP directory is fairly simple. It is know to work with OpenLDAP and Novell Edirectory and should work with other systems as well. <br> <span class="note">Note:</span> If you use LDAP, the group functionality of WebCalendar does not yet work.</p> <p>To configure WebCalendar to use LDAP, do the following:</p> <ol> <li>Verify that your PHP install supports LDAP.</li> <li>Configure <tt>settings.php</tt></li> <li>Configure <tt>includes/user-ldap.php</tt></li> </ol> <p>The first step is to verify that your install of PHP supports LDAP. The simplest way to do this is to view the output of <code>phpinfo()</code>. If you can't easily call phpinfo() from another page, consider pasting the following into a new page (e.g. <tt>phpinfo.php</tt>):</p> <pre> <html><head><title>PHP Info page</title></head> <body> <?php phpinfo() ?> </body> </html> </pre> <p>When you load the page in your browser, the resulting output will begin with general PHP information and then include an alphabetical list of enabled PHP modules. If you aren't sure where to put the file so you can load it via your web server, place it in the webcalendar directory and add "phpinfo.php" to the URL for your webcalendar install. If your PHP supports LDAP, it will be listed as a module and version information will be given. If "ldap" is not listed anywhere in the output of <tt>phpinfo()</tt>, then your PHP install does not support LDAP. You may need to install additional packages, depending on your OS and version; under Debian Linux, for example, the "php4" package does not include support but, "php4-ldap" does.</p> <p>The second step is to set WebCalendar to use LDAP authentication in <tt>settings.php</tt>. Instructions on to do this can be found in the <a href="#appsetup">Application Installation</a> section above. In summary, the following should be set:<br> <tt>use_http_auth = false</tt><br> <tt>user_inc = user-ldap.php</tt><br></p> <p>The next step is a little more work and involves editing the <tt>includes/user-ldap.php</tt> file with a text editor. You will have to set several configuration variables. If you don't know what to set the variables to, consult your LDAP system administrator. Documentation exists for all variables in the file. Finally, users have gotten LDAP working with OpenLDAP and Novell Edirectory by just changing the following:</p> <table border="0" style="margin-left: 20px; margin-right: 20px;"> <tr><td valign="top">$ldap_server</td> <td> FQDN or IP address of the LDAP server (or localhost). <br>ex. 'ldapserver.company.com' </td></tr> <tr><td valign="top">$ldap_base_dn</td> <td> Specifies the base DN used to search for users <br>ex. 'ou=people,dc=company,dc=com' or 'o=context,ou=subcontext' </td></tr> <tr><td valign="top">$ldap_admin_group_name</td> <td> Specifies a group (complete DN) with admin rights for WebCalendar <br>You might have to create one in LDAP <br>ex. 'cn=it,ou=group,dc=company,dc=com' </td></tr> </table> <h3>Using SSL with LDAP</h3> <p>If the LDAP server will accept connections over SSL, simply add 'ldaps://' to the beginning of <tt>$ldap_server</tt>.<br>Example: ldaps://ldapserver.company.com</p> <h3>Using TLS with LDAP</h3> <p>If the LDAP server is set up to use TLS, set <tt>$ldap_start_tls = true</tt>.</p> <h3>Using LDAPv3</h3> <p>If the LDAP server uses protocol version 3, set <tt>$set_ldap_version = true</tt> and <tt>$ldap_version = '3'</tt>.</p> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <a name="appendixF"></a> <h2>Appendix F: Manual Installation</h2> <div class="top"><a href="#" target="_top">↑ top</a></div> <hr> <h3>TODO</h3> <p> <a href="http://validator.w3.org/check?uri=referer"><img src="../images/HTML5_Logo.png" alt="Valid HTML5!"></a></p> </body> </html> PK �]�\��7�� � docs/newwin.gifnu �[��� GIF89a � ������ E� U� Q�a� Y�]�aε������������������������������������� !� , @T���`�'@�@�<NC4] �a�A8�H����K��b- Bd��d,I��Y���[n�[�� (�x�$�2&���r:�1��j�5,! ;PK �]�\�K��W W icalclient.phpnu �[��� <?php // $Id: icalclient.php,v 1.42 2010/02/21 08:27:48 bbannon Exp $ /** * WARNING * WARNING * WARNING * WARNING * WARNING * This script is still considered alpha level. * Please backup your database before using it. * WARNING * WARNING * WARNING * WARNING * WARNING * * Description: * Creates the iCal output for a single user's calendar so that remote users can * "subscribe" to a WebCalendar calendar. Both Apple iCal and Mozilla's calendar * (Sunbird) support subscribing to remote calendars and publishing events back * to the server (WebCalendar in this case). * * This file was based on publish.php * and may replace it when it is found to be stable. * * Note that unlike the export to iCal, this page does not include * attendee info. This improves the performance considerably, BTW. * * ERROR !!!!! * There seems to be a bug in certain versions of PHP where the fgets() returns * a blank string when reading stdin. I found this to be a problem with * PHP 4.1.2 on Linux. If this is true for your PHP, you will not be able to * import the events back from the ical client. * It did work correctly with PHP 5.0.2. * * The script sends an error message back to the iCal client, * but Mozilla Calendar does not seem to display the message. * (Strange, since it did display a PHP compile error message...) * * Usage Requirements: * For this work, at least on some Apache intallations, * the following may need to be added to the httpd.conf file: * <Directory "/var/www/html/webcalendar"> * Script PUT /icalclient.php * </Directory> * Of course, replace "/var/www/html/webcalendar" with the * directory where you installed WebCalendar. * * Input parameters: * None * * Security: * If $PUBLISH_ENABLED is not 'Y' (set in Admin System Settings), do not allow. * If $USER_PUBLISH_RW_ENABLED is not 'Y' (set in each user's Preferences), do not allow. * * Change List: * 06-Jan-2005 Ray Jones * Added logic to publish calendars to remote iCal clients. * The clients I've tested use METHOD:PUT to upload their data to the server. * This file does not use WEBDAV, but the client doesn't know or seem to care. * * Notes: * Because data is being written back to WebCalendar, the user is prompted * for username and password via the 401 HEADER. * SEE TO DO for needed work. * * To Delete an event from the iCal client, mark it as 'Cancelled'. * This will translate into a 'D' in webcal_entry_user.cal_status. * * TODO: * Security! If an event update comes back from an iCal client, we need to make * sure that the remote user has the authority to modify the event. (If they are * only a participant and not the creator of the event or an admin, then they * should not be able to update an event.) * * MAYBE add logic to loop through webcal_import_data and delete any records that * don't come back from the iCal client. This would indicate events were deleted * from the client instead of being marked 'Cancelled'. * * HTML in cal_description gets escaped when coming back from iCal client. * Some formatting is getting deleted. I added a couple lines to modify these * and it seems to work. However....you never know what it might break. * * Testing needs to be done with various RRULE options on import. * * Better support for event reminders. Reminders for past events are not sent * currently. This is because Mozilla Calendar may popup all reminders (even * ones that are years old) when the calendar is loaded. Ideally, we should * check the webcal_reminders table to see if an event reminder was already sent. * Also, not sure if reminders for repeated events are handled properly yet. */ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include_once 'includes/validate.php'; include 'includes/site_extras.php'; include_once 'includes/xcal.php'; $WebCalendar->initializeSecondPhase(); $appStr = generate_application_name(); // If WebCalendar is using http auth, then $login will be set in validate.php. /* If running as CGI, the following instructions should set the PHP_AUTH_xxxx variables. This has only been tested with apache2, so far. If using php as CGI, you'll need to include this in your httpd.conf file or possibly in an .htaccess file. Method 1: If this method fails, try method 2 <IfModule mod_rewrite.c> RewriteEngine on RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L] </IfModule> Method 2: <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{QUERY_STRING} ^$ RewriteRule ([^\s]+).php$ $1.php?BAD_HOSTING=%{HTTP:Authorization} RewriteCond %{QUERY_STRING} ^(.+)$ RewriteRule ([^\s]+).php $1.php?%1&BAD_HOSTING=%{HTTP:Authorization} </IfModule> */ //Method 1 if ( empty( $_SERVER['PHP_AUTH_USER'] ) && ! empty( $_ENV['REMOTE_USER'] ) ) { list( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) = explode( ':', base64_decode( substr( $_ENV['REMOTE_USER'], 6 ) ) ); $_SERVER['PHP_AUTH_USER'] = trim ( $_SERVER['PHP_AUTH_USER'] ); $_SERVER['PHP_AUTH_PW'] = trim ( $_SERVER['PHP_AUTH_PW'] ); } //Method 2 if ( ( empty( $_SERVER['PHP_AUTH_USER'] ) or empty( $_SERVER['PHP_AUTH_PW'] ) ) and isset( $_REQUEST['BAD_HOSTING'] ) and preg_match( '/Basic\s+(.*)$/i', $_REQUEST['BAD_HOSTING'], $matc ) ) list( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) = explode( ':', base64_decode( $matc[1] ) ); unset( $_ENV['REMOTE_USER'] ); if ( empty ( $login ) ) { if ( isset ( $_SERVER['PHP_AUTH_USER'] ) && user_valid_login ( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], true ) ) $login = $_SERVER['PHP_AUTH_USER']; if ( empty ( $login ) || $login != $_SERVER['PHP_AUTH_USER'] ) { $_SERVER['PHP_AUTH_PW'] = $_SERVER['PHP_AUTH_USER'] = ''; unset ( $_SERVER['PHP_AUTH_USER'] ); unset ( $_SERVER['PHP_AUTH_PW'] ); header ( 'WWW-Authenticate: Basic realm="' . $appStr . '"' ); header ( 'HTTP/1.0 401 Unauthorized' ); exit; } } load_global_settings(); load_user_preferences(); $WebCalendar->setLanguage(); if ( empty ( $PUBLISH_ENABLED ) || $PUBLISH_ENABLED != 'Y' ) { header ( 'Content-Type: text/plain' ); // Mozilla Calendar does not bother showing errors, so they won't see this // error message anyhow... Not sure about Apple iCal or other clients. etranslate ( 'Publishing Disabled (Admin)' ); exit; } if ( empty ( $USER_PUBLISH_RW_ENABLED ) || $USER_PUBLISH_RW_ENABLED != 'Y' ) { header ( 'Content-Type: text/plain' ); etranslate ( 'Publishing Disabled (User)' ); exit; } $prodid = 'Unnamed iCal client'; // Load user name, etc. user_load_variables ( $login, 'publish_' ); function dump_globals() { foreach ( $GLOBALS as $K => $V ) { do_debug ( "GLOBALS[$K] => " . ( strlen ( $V ) < 70 ? $V : '(too long)' ) ); } foreach ( $GLOBALS['HTTP_POST_VARS'] as $K => $V ) { do_debug ( "GLOBALS[$_POST[$K]] => " . ( strlen ( $V ) < 70 ? $V : '(too long)' ) ); } } switch ( $_SERVER['REQUEST_METHOD'] ) { case 'PUT': // do_debug ( "Importing updated remote calendar" ); $calUser = $login; $overwrite = true; $type = 'icalclient'; $data = parse_ical ( '', $type ); import_data ( $data, $overwrite, $type ); break; case 'GET': // do_debug ( "Exporting updated remote calendar" ); header ( 'Content-Type: text/calendar' ); header ( 'Content-Disposition: attachment; filename="' . $login . '.ics"' ); $use_all_dates = true; echo export_ical(); break; case 'OPTIONS'; header ( 'Allow: GET, PUT, OPTIONS' ); break; default: header ( 'Allow: GET, PUT, OPTIONS' ); header( 'HTTP/1.0 405 Method Not Allowed' ); break; } ?> PK �]�\8mcJ J help_import.phpnu �[��� <?php // $Id: help_import.php,v 1.27 2009/11/22 16:47:45 bbannon Exp $ include_once 'includes/init.php'; include_once 'includes/help_list.php'; print_header ( '', '', '', true ); echo $helpListStr . ' <h2>' . translate ( 'Help' ) . ': ' . translate ( 'Import' ) . '</h2> <h3>' . translate ( 'Palm Desktop' ) . '</h3> <p>' . translate ( 'allow you to import entries from the Palm...' ) . '</p> <p>' . translate ( 'The following entries will not be imported' ) . '</p> <ul> <li>' . translate ( 'Entries older than the current date' ) . '</li> <li>' . translate ( 'Entries created in the Palm Desktop...' ) . '</li> </ul> <p>' . translate ( 'Anything imported from Palm...' ) . '</p> <h3>' . translate ( 'vCal' ) . '</h3> <p>' . translate ( 'This form will import vCalendar (.vcs) 1.0 events.' ) . '</p> <p>' . translate ( 'The following formats have been tested' ) . '</p> <ul> <li>Palm Desktop 4</li> <li>Lotus Organizer 6</li> <li>Microsoft Outlook 2002</li> </ul> <h3>iCalendar</h3> <p>' . translate ( 'This form will import iCalendar (.ics) events.' ) . ' ' . translate ( 'Enabling' ) . ' <b>' . translate ( 'Overwrite Prior Import' ) . '</b>, ' . translate ( 'will cause events imported previously...' ) . '</p>'; echo print_trailer ( false, true, true ); ?> PK �]�\ �`l� � README.mdnu �[��� WebCalendar README ------------------ Project Home Page: http://www.k5n.us/webcalendar.php Project Owner: Craig Knudsen, craig@k5n.us Documentation: - [System Administrator's Guide](http://htmlpreview.github.io/?https://github.com/craigk5n/webcalendar/blob/master/docs/WebCalendar-SysAdmin.html) (Installation instructions, FAQ) - [Upgrading Instructions](http://htmlpreview.github.io/?https://github.com/craigk5n/webcalendar/blob/master/UPGRADING.html) - License: [GPLv2](https://github.com/craigk5n/webcalendar/blob/master/LICENSE) - [Online Demo at SF](http://webcalendar.sourceforge.net/demo/) Developer Resources: - [WebCalendar-Database.html](http://htmlpreview.github.io/?https://github.com/craigk5n/webcalendar/blob/master/docs/WebCalendar-Database.html) - [WebCalendar-DeveloperGuide.html](http://htmlpreview.github.io/?https://github.com/craigk5n/webcalendar/blob/master/docs/WebCalendar-DeveloperGuide.html) PK �]�\>em�N N security_audit.phpnu �[��� <?php // $Id: security_audit.php,v 1.13 2010/01/24 10:07:07 bbannon Exp $ /** * Description: * This page will take look for possible security issues with * this installation of WebCalendar. * * Input Parameters: * None * * Security: * User must be an admin user * AND, if user access control is enabled, they must have access to * 'Security Audit'. */ include_once 'includes/init.php'; if ( ! $is_admin || ( access_is_enabled() && ! access_can_access_function( ACCESS_SECURITY_AUDIT ) ) ) die_miserable_death( print_not_auth() ); $phpinfo = getGetValue( 'phpinfo' ); if ( $phpinfo == '1' ) { print_header( '', '', '', true ); phpinfo(); print_trailer( false, true, true ); exit; } clearstatcache(); print_header(); echo ' <h2>' . translate( 'Security Audit' ) . '</h2> <ul id="securityAuditNotes"> <li>' . translate( 'list potential security issues') . '</li> <li>' . translate( 'For questions about WebCalendar security see the forums' ) . '<a href="https://sourceforge.net/forum/?group_id=3870" target="_blank">' . '<img src="docs/newwin.gif" alt="SourceForge.net"></a></li> <li><a href="#" onclick="window.open( \'security_audit.php?phpinfo=1\', ' . '\'phpinfo\', \'dependent,menubar,scrollbars,height=500,width=600,' . 'innerHeight=520,outerWidth=620\' );" />' . translate( 'View your current PHP settings' ) . '</a></li> </ul> <table id="securityAudit" cellpadding="4"> <tr> <th>' . translate( 'Security Issue' ) . '</th> <th>' . translate( 'Status' ) . '</th> <th>' . translate( 'Details' ) . '</th> </tr>'; // Make sure they aren't still using the default admin username/password. print_issue( translate( 'Default admin user password' ), ( user_valid_login( 'admin', 'admin' ) == false ), translate( 'You should change the password of the default admin user.' ) ); // Is the main directory still writable? // Just see if we get an error trying to append to it. $wcDir = '.'; $wcName = 'WebCalendar toplevel director'; if ( preg_match( '/(.*).security_audit.php/', __FILE__, $matches ) ) { $wcDir = $matches[1] . '\\'; $wcName = basename( $wcDir ); } $filePerms = translate( 'File permissions XXX' ); $noWriteItem = translate( 'item XXX should not be writable' ); print_issue( str_replace( 'XXX', $wcName, $filePerms ), ( ! is__writable( $wcDir ) ), str_replace( 'XXX', htmlentities( $wcDir ), $noWriteItem ) ); // Is the includes directory still writable? // Just see if we get an error trying to append to it. print_issue( str_replace( 'XXX', 'includes', $filePerms ), ( ! is__writable( 'includes' ) ), str_replace( 'XXX', get_wc_path( 'includes' ), $noWriteItem ) ); // Is the includes/settings.php file still writable? // Unfortunately, some of the PHP file permissions calls have bugs, // so just see if we get an error trying to append to it. $fd = @fopen( 'includes/settings.php', 'a+b' ); $isOk = true; if ( $fd > 0 ) { // Error: should not be allowed to write! fclose( $fd ); $isOk = false; } print_issue( str_replace( 'XXX', 'includes/settings.php', $filePerms ), $isOk, str_replace( 'XXX', get_wc_path( 'includes/settings.php' ), $noWriteItem ) ); // If email or reminders are not enabled, tell them to remove the file. $isOk = ( ! file_exists( 'tools/send_reminders.php' ) ); if ( $SEND_EMAIL != 'Y' ) { // Reminders are disabled! print_issue( str_replace( 'XXX', 'tools/send_reminders.php', translate( 'File exists XXX' ) ), $isOk, translate( 'Because you have email disabled, you should remove this file.' ) ); } else { // Is tools/send_reminders.php in the 'standard' location? print_issue( str_replace( 'XXX', 'tools/send_reminders.php', translate( 'File location XXX' ) ), $isOk, str_replace( 'XXX', get_wc_path( 'tools/send_reminders.php' ), translate( 'remove XXX if not using' ) ) ); } $sysSettingsXXX = translate( 'System Settings XXX' ); // Is UAC enabled? print_issue( str_replace( 'XXX', translate( 'User Access Control' ), $sysSettingsXXX ), access_is_enabled(), translate( 'consider enabling UAC' ) ); // If Public Access enabled, make sure approvals are on if ( $PUBLIC_ACCESS == 'Y' ) { print_issue( str_replace( 'XXX', translate( 'Public access new events require approval' ), $sysSettingsXXX ), ( $PUBLIC_ACCESS_CAN_ADD != 'Y' || $PUBLIC_ACCESS_ADD_NEEDS_APPROVAL == 'Y' ), translate( 'recommend approving new public events' ) ); print_issue( str_replace( 'XXX', translate( 'Require CAPTCHA validation for public access new events' ), $sysSettingsXXX ), ( $ENABLE_CAPTCHA == 'Y' ), translate( 'recommend using CAPTCHA' ) ); } // Is db cache directory a subdirectory of WebCalendar? $isOk = true; if ( ! empty( $settings['db_cachedir'] ) && $wcDir != '.' ) { $cache = str_replace( '\\', '/', $settings['db_cachedir'] ); $wcDir = str_replace( '\\', '/', $wcDir ); if ( strncmp( $cache, $wcDir, strlen( $wcDir ) ) == 0 && strlen( $wcDir ) < strlen( $cache ) ) { // Using a webcalendar subdirectory for db cache. $isOk = false; } } print_issue( translate( 'Database cache directory location' ), $isOk, translate( 'db cache should be inaccessable' ) ); $phpSettingsXXX = translate( 'PHP Settings XXX' ); $recommendXXXOff = translate( 'recommend setting XXX Off' ); // Check for magic quotes. // See: http://us.php.net/manual/en/security.magicquotes.php print_issue( str_replace( 'XXX', 'magic_quotes_gpc', $phpSettingsXXX ), ( get_magic_quotes_gpc() == 0 ), str_replace( 'XXX', 'magic quotes', $recommendXXXOff ) ); // Check for register globals. print_issue( str_replace( 'XXX', 'register_globals', $phpSettingsXXX ), ( ini_get( 'register_globals' ) == 0 ), str_replace( 'XXX', 'register_globals', $recommendXXXOff ) ); // Check for allow_url_fopen. // Recommended setting is off when remote calendars are not enabled. print_issue( str_replace( 'XXX', 'allow_url_fopen', $phpSettingsXXX ), ( ini_get( 'allow_url_fopen' ) == 0 || $REMOTES_ENABLED == 'Y' ), translate( 'recommend setting allow_url_fopen Off' ) ); // Check for allow_url_include. print_issue( str_replace( 'XXX', 'allow_url_include', $phpSettingsXXX ), ( ini_get( 'allow_url_include' ) == 0 ), str_replace( 'XXX', 'allow_url_include', $recommendXXXOff ) ); echo ' </table> ' . print_trailer() . ' <!-- done -->'; exit; /* functions ... */ /** * print_issue (needs description) */ function print_issue( $description, $isOk, $help ) { global $count; if ( empty( $count ) ) $count = 0; if ( $isOk ) { $img = 'ok.gif" alt="OK"'; $help = ' '; } else $img = 'error.gif" alt="Warning"'; echo ' <tr' . ( $count++ % 2 > 0 ? ' class="odd"' : '' ) . '> <td>' . $description . '</td> <td><img src="images/' . $img . ' width="16" height="16" /></td> <td>' . $help . '</td> </tr>'; } /** * Get the full path to a file located in the webcalendar directory. */ function get_wc_path( $filename ) { if ( preg_match( '/(.*)security_audit.php/', __FILE__, $matches ) ) return $matches[1] . $filename; else // Oops. This file is not named security_audit.php die_miserable_death( 'Crap! Someone renamed security_audit.php' ); } /** * Determine if a directory or file is writable */ function is__writable( $path ) { //Will work despite Windows ACLs bug. //NOTE: use a trailing slash for folders!!! //see http://bugs.php.net/bug.php?id=27609 //see http://bugs.php.net/bug.php?id=30931 if ( $path{ strlen( $path ) - 1 } == '/' ) // recursively return a temporary file path return is__writable( $path . uniqid( mt_rand() ) . '.tmp' ); else if ( @is_dir( $path ) ) return is__writable( $path . '/' . uniqid( mt_rand() ) . '.tmp' ); // Check tmp file for read/write capabilities. $rm = @file_exists( $path ); $f = @fopen( $path, 'a' ); if ( $f === false ) return false; @fclose( $f ); if ( ! $rm ) @unlink( $path ); return true; } ?> PK �]�\cn�R5 5 nonusers.phpnu �[��� <?php // $Id: nonusers.php,v 1.35 2009/11/22 16:47:45 bbannon Exp $ defined ( '_ISVALID' ) or die ( 'You cannot access this file directly!' ); if ( ! $is_admin ) { echo print_not_auth ( true ) . ' </body> </html>'; exit; } if ( ! $NONUSER_PREFIX ) { echo print_error_header() . translate ( 'NONUSER_PREFIX not set' ) . ' </body> </html>'; exit; } $add = getValue ( 'add' ); $newNonUserStr = translate ( 'Add New NonUser Calendar' ); $targetStr = 'target="nonusersiframe" onclick="showFrame( \'nonusersiframe\' );">'; echo ' <a name="tabnonusers"></a> <div id="tabscontent_nonusers">'; if ( empty ( $error ) ) { echo ' <a title="' . $newNonUserStr . '" href="edit_nonusers.php?add=1"' . $targetStr . $newNonUserStr . '</a><br />'; // Displaying NonUser Calendars $userlist = get_nonuser_cals(); if ( ! empty ( $userlist ) ) { echo ' <ul>'; for ( $i = 0, $cnt = count ( $userlist ); $i < $cnt; $i++ ) { echo ' <li><a title="' . $userlist[$i]['cal_fullname'] . '" href="edit_nonusers.php?nid=' . $userlist[$i]['cal_login'] . '"' . $targetStr . $userlist[$i]['cal_fullname'] . '</a></li>'; } echo ' </ul>'; } } echo ' <iframe name="nonusersiframe" id="nonusersiframe" style="width: 90%; ' . 'border: 0; height: 250px;"></iframe> </div>'; ?> PK �]�\c� . . set_entry_cat.phpnu �[��� <?php /** * Allows the setting of categories by each participant of an event. * * Multiple categories can be added by each participant and stored separately * for that user. Global categories will be visible by all participants, * but can only be added/removed by the owner or an admin in the edit-entry form. */ include_once 'includes/init.php'; load_user_categories(); $error = ''; if ( empty ( $id ) ) $error = translate ( 'Invalid entry id.' ); else if ( $CATEGORIES_ENABLED != 'Y' ) $error = print_not_auth(); else if ( empty ( $categories ) ) $error = translate ( 'You have not added any categories.' ); // Make sure user is a participant. $res = dbi_execute ( 'SELECT cal_status FROM webcal_entry_user WHERE cal_id = ? AND cal_login = ?', [$id, $login] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { if ( $row[0] == 'D' ) // User deleted themself. $error = print_not_auth(); } else // Not a participant for this event. $error = print_not_auth(); dbi_free_result ( $res ); } else $error = db_error(); $cat_id = getValue ( 'cat_id', '-?[0-9,\-]*', true ); $cat_ids = $cat_name = []; $catNames = ''; // Get user's categories for this event. $globals_found = false; $categories = get_categories_by_id ( $id, $login, true ); if ( ! empty ( $categories ) ) { $catNames = htmlentities ( implode ( ', ', $categories ) ); $keys = array_keys ( $categories ); $catList = implode ( ',', $keys ); sort ( $keys ); if ( $keys[0] < 0 ) $globals_found = true; } // Get event name and make sure event exists. $event_name = ''; $res = dbi_execute ( 'SELECT cal_name FROM webcal_entry WHERE cal_id = ?', [$id] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) $event_name = $row[0]; else // No such event $error = translate ( 'Invalid entry id.' ); dbi_free_result ( $res ); } else $error = db_error(); // If this is the form handler, then save now if ( ! empty ( $cat_id ) && empty ( $error ) ) { dbi_execute ( 'DELETE FROM webcal_entry_categories WHERE cal_id = ? AND ( cat_owner = ? )', [$id, $login] ); $categories = explode ( ',', $cat_id ); $names = $sql_params = $values = []; for ( $i = 0, $cnt = count ( $categories ); $i < $cnt; $i++ ) { // Don't process Global Categories. if ( $categories[$i] > 0 ) { $names[] = 'cal_id'; $names[] = 'cat_id'; $names[] = 'cat_order'; $names[] = 'cat_owner'; $values[] = '?'; $values[] = '?'; $values[] = '?'; $values[] = '?'; $sql_params[] = $id; $sql_params[] = abs ( $categories[$i] ); $sql_params[] = ( $i + 1 ); $sql_params[] = $login; } } if ( ! dbi_execute ( 'INSERT INTO webcal_entry_categories ( ' . implode ( ', ', $names ) . ' ) VALUES ( ' . implode ( ', ', $values ) . ' )', $sql_params ) ) $error = db_error(); else do_redirect ( 'view_entry.php?id=' . $id . ( empty ( $date ) ? '' : '&date=' . $date ) ); } // Set up variables for inclusion later. $setCatStr = translate ( 'Set Category' ); $briefStr = translate ( 'Brief Description' ); $catHelpStr = tooltip ( 'category-help' ); $catStr = translate ( 'Category' ); $editStr = translate ( 'Edit' ); $globalNoteStr = ( $globals_found ? translate ( 'Global Categories cannot be changed.' ) : '' ); $saveStr = translate ( 'Save' ); print_header ( array ( 'js/set_entry_cat.php/true' ) ); if ( ! empty ( $error ) ) echo print_error ( $error ); else { echo <<<EOT <h2>{$setCatStr}</h2> <form action="set_entry_cat.php" method="post" name="selectcategory"> <input type="hidden" name="date" value="{$date}" /> <input type="hidden" name="id" value="{$id}" /> <table cellpadding="5"> <tr class="aligntop"> <td class="bold colon">{$briefStr}</td> <td>{$event_name}</td> </tr> <tr> <td class="tooltip aligntop" title="{$catHelpStr}"> <label for="entry_categories" class="colon">{$catStr}<br /></label> <input type="button" value="{$editStr}" onclick="editCats( event )" /> </td> <td class="aligntop"> <input readonly="readonly" type="text" name="catnames" value="{$catNames}" size="75" onclick="editCats( event )" /><br /> {$globalNoteStr} <input type="hidden" name="cat_id" id="entry_categories" value="{$catList}" /> </td> </tr> <tr class="aligntop"> <td colspan="2"><br /><input type="submit" value="{$saveStr}" /></td> </tr> </table> </form> EOT; } echo print_trailer(); ?> PK �]�\[�SP� � activity_log.phpnu �[��� <?php // $Id: activity_log.php,v 1.55 2009/11/22 16:47:44 bbannon Exp $ /** * Description: * Display either the "Activity Log" (for events/tasks) or the * "System Log" (entries not associated with an event). * * Input Parameters: * startid - specified the id of the first log entry to display * system - if specified, then view the system log (entries with no * event id associated with them) rather than the event log. * * Security: * User must be an admin user * AND, if user access control is enabled, they must have access to * activity logs. (This is because users may see event details * for other groups that they are not supposed to have access to.) */ include_once 'includes/init.php'; if ( ! $is_admin || ( access_is_enabled() && ! access_can_access_function( ACCESS_ACTIVITY_LOG ) ) ) die_miserable_death ( print_not_auth() ); $eventsStr = translate ( 'Events' ); $nextStr = translate ( 'Next' ); $prevStr = translate ( 'Previous' ); $PAGE_SIZE = 25; // Number of entries to show at once. $startid = getValue ( 'startid', '-?[0-9]+', true ); $sys = ( $is_admin && getGetValue ( 'system' ) != '' ); print_header(); echo generate_activity_log( '', $sys, $startid ) . ' <div class="navigation">' // Go BACK in time. . ( ! empty ( $nextpage ) ? ' <a title="' . $prevStr . ' ' . $PAGE_SIZE . ' ' . $eventsStr . '" class="prev" href="activity_log.php?startid=' . $nextpage . ( $sys ? '&system=1' : '' ) . '">' . $prevStr . ' ' . $PAGE_SIZE . ' ' . $eventsStr . '</a>' : '' ); if ( ! empty ( $startid ) ) { $previd = $startid + $PAGE_SIZE; $res = dbi_execute ( 'SELECT MAX( cal_log_id ) FROM webcal_entry_log' ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) // Go FORWARD in time. echo ' <a title="' . $nextStr . ' ' . $PAGE_SIZE . ' ' . $eventsStr . '" class="next" href="activity_log.php' . ( $row[0] <= $previd ? ( $sys ? '?system=1' : '' ) : '?startid=' . $previd . ( $sys ? '&system=1' : '' ) ) . '">' . $nextStr . ' ' . $PAGE_SIZE . ' ' . $eventsStr . '</a><br />'; dbi_free_result ( $res ); } } echo ' </div>' . print_trailer(); ?> PK �]�\[*�� � minical.phpnu �[��� <?php // $Id: minical.php,v 1.23 2009/11/22 16:47:45 bbannon Exp $ /** * Description: * This script is intended to be used inside an IFRAME on another website * It can be embedded like so * <iframe name="minical" frameborder="0" height="190" width="250" * src="http://cal/minical.php";> * * You must have public access enabled in System Settings to use this page * (unless you modify the $public_must_be_enabled setting below in this file). * * By default (if you do not edit this file), * events for the public calendar will be used. * * Input parameters: * You can override settings by changing the URL parameters: * - cat_id: specify a category id to filter on * - user: login name of calendar to display (instead of public user), * if allowed by System Settings. * Only NUC Calendar that are marked PUBLIC can be specified. * * Security: * $PUBLISH_ENABLED must be set true */ include_once 'includes/init.php'; load_global_settings(); // These values will be used by styles.php to customize the size of this calendar. $DISPLAY_WEEKENDS = true; $MINICALFONT = '11px'; $MINICALWIDTH = '160px'; if ( empty ( $PUBLISH_ENABLED ) || $PUBLISH_ENABLED != 'Y' ) { header ( 'Content-Type: text/plain' ); echo print_not_auth(); exit; } /* Configurable settings for this file. You may change the settings below to * change the default settings. These settings will likely move into the * System Settings in the web admin interface in a future release. */ // The HTML target window to use when clicking on the minical. You should be // able to set this to the desired frame or window to receive the results. $MINI_TARGET = '_blank'; // Change this to false if you still want to access this page // even though you do not have public access enabled. $public_must_be_enabled = true; // Login of calendar user to use. // '__public__' is the login name for the public user. $user = ( empty ( $user ) ? '__public__' : $user ); // Allow the URL to override the user setting such as // "minical.php?user=_NUC_training". // If false, __public_ will always be used. $allow_user_override = false; // Load just a specified category (by its id). // Leave blank to not filter on category (unless specified in URL). // Can override in URL with "minical.php?cat_id=4" $cat_id = ( empty ( $cat_id ) ? '' : $cat_id ); // End configurable settings... // Set for use elsewhere as a global. $login = $user; if ( $public_must_be_enabled && $PUBLIC_ACCESS != 'Y' ) $error = print_not_auth(); if ( $allow_user_override ) { $u = getValue ( 'user', '[A-Za-z0-9_\.=@,\-]+', true ); if ( ! empty ( $u ) ) $login = $user = $u; // We also set $login since some functions assume that it is set. } load_user_preferences(); user_load_variables ( $login, 'minical_' ); if ( $user != '__public__' && ! nonuser_load_variables ( $login, 'minica_' ) ) die_miserable_death ( str_replace ( 'XXX', $login, translate ( 'No such nonuser calendar XXX.' ) ) ); if ( $user != '__public__' && ( empty ( $minical_is_public ) || $minical_is_public != 'Y' ) ) die_miserable_death ( translate ( 'This Calendar is not Public.' ) ); $next = mktime ( 0, 0, 0, $thismonth + 1, 1, $thisyear ); $nextmonth = date ( 'm', $next ); $nextyear = date ( 'Y', $next ); $prev = mktime ( 0, 0, 0, $thismonth - 1, 1, $thisyear ); $prevmonth = date ( 'm', $prev ); $prevyear = date ( 'Y', $prev ); $boldDays = true; $startdate = mktime ( 0, 0, 0, $thismonth, 1, $thisyear ); $enddate = mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear ); // Don't display custom header. print_header ( '', generate_refresh_meta(), '', true ); /* Pre-Load the repeated events for quicker access. */ $repeated_events = read_repeated_events ( $user, $startdate, $enddate, $cat_id ); /* Pre-load the non-repeating events for quicker access. */ $events = read_events ( $user, $startdate, $enddate, $cat_id ); echo display_small_month ( $thismonth, $thisyear, true, false ); // Reset...just in case. $login = ''; ?> </body> </html> PK �]�\SJ�Q� � import_outlookcsv.phpnu �[��� <?php /** * File Description: * This file incudes functions for parsing CSV files generated from MS Outlook. * * It will be included by import_handler.php. * * Limitations: * This only works when the user does not "Map Custom Fields" * during the export from Outlook. */ /** * Parse the Outlook CSV file and return the data hash. */ function parse_outlookcsv ( $cal_file ) { global $errormsg, $tz; $outlookcsv_data = []; if ( ! $fd = @fopen ( $cal_file, 'r' ) ) { $errormsg .= 'Cannot read temporary file: ' . "$cal_file\n"; exit(); } else { # Burn First Row of Headers $data = fgetcsv ( $fd, filesize ( $cal_file ), ',' ); while ( $data = fgetcsv ( $fd, filesize ( $cal_file ) ) ) { $subject = addslashes ( $data[0] ); $start = icaldate_to_timestamp ( date ( 'Ymd\THis', strtotime ( $data[1] . ' ' . $data[2] ) ) ); $end = icaldate_to_timestamp ( date ( 'Ymd\THis', strtotime ( $data[3] . ' ' . $data[4] ) ) ); $all_day_event = ( int ) toBoolean ( $data[5] ); $remind_on_off = ( int ) toBoolean ( $data[6] ); $reminder = icaldate_to_timestamp ( date ( 'Ymd\THis', strtotime ( $data[7] . ' ' . $data[8] ) ) ); $meeting_organizer = $data[9]; $required_attendies = $data[10]; $optional_attendies = $data[11]; $meeting_resources = $data[12]; $billing_information = $data[13]; $categories = addslashes ( str_replace ( ';', ',', $data[14] ) ); $description = addslashes ( $data[15] ); $location = addslashes ( $data[16] ); $mileage = $data[17]; $priority = $data[18]; $class = ( int ) toBoolean ( $data[19] ); $sensitivity = $data[20]; $show_time_as = $data[21]; /* * Start New Section For Outlook CSV */ // $tmp_data['RecordID'] = ; $tmp_data['StartTime'] = $start; // In seconds since 1970 (Unix Epoch) $tmp_data['EndTime'] = $end; // In seconds since 1970 (Unix Epoch) $tmp_data['Summary'] = $subject; // Summary of event (string) $tmp_data['Duration'] = dateDifference ( $start, $end, 1 ); // How long the event lasts (in minutes) $tmp_data['Description'] = $description; // Full Description (string) $tmp_data['Location'] = $location; // Location (string) $tmp_data['AllDay'] = $all_day_event; // 1 = true 0 = false $tmp_data['Class'] = ( $class == 1 ? 'R': 'P' ); $tmp_data['Categories'] = get_categories_id_byname ( $categories ); $tmp_data['AlarmSet'] = $remind_on_off; // 1 = true 0 = false $tmp_data['ADate'] = $reminder; // Date/Time of Alarm $tmp_data['AAction'] = 'EMAIL'; // The default action $tmp_data['CalendarType'] = 'VEVENT'; // The default type $outlookcsv_data[] = $tmp_data; } // End while fclose ( $fd ); } return $outlookcsv_data; } function dateDifference ( $start_timestamp, $end_timestamp, $unit = 0 ) { $days_seconds_star = ( 23 * 56 * 60 ) + 4.091; // Star Day $days_seconds_sun = 86400; // Sun Day $difference_seconds = $end_timestamp - $start_timestamp; switch ( $unit ) { case 3: // Days $difference_days = round ( ( $difference_seconds / $days_seconds_sun ), 2 ); return 'approx. ' . $difference_hours . ' Days'; case 2: // Hours $difference_hours = round ( ( $difference_seconds / 3600 ), 2 ); return 'approx. ' . $difference_hours . ' Hours'; break; case 1: // Minutes $difference_minutes = round ( ( $difference_seconds / 60 ), 2 ); return $difference_minutes; break; default: // Seconds return $difference_seconds . ' Second' . ( $difference_seconds != 1 ? 's' : '' ); } } function toBoolean ( $string ) { return in_array ( strtoupper ( $string ), ['TRUE', 'T', '1', 'TR'] ); } ?> PK �]�\pU��% �% login.phpnu �[��� <?php @session_start(); foreach ( $_SESSION as $key => $value ) { $dummy[$key] = $value; // Copy to a dummy array. } if ( ! empty ( $dummy ) ) { foreach ( $dummy as $key => $value ) { if ( substr ( $key, 0, 6 ) == 'webcal' ) unset ( $_SESSION[$key] ); } } // PHP 4.1.0 may have issues with the above code. unset ( $_SESSION['webcal_login'] ); unset ( $_SESSION['webcalendar_session'] ); include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include_once 'includes/access.php'; include 'includes/gradient.php'; $WebCalendar->initializeSecondPhase(); load_global_settings(); // Set this true to show "no such user" or "invalid password" on login failures. $showLoginFailureReason = false; if ( ! empty ( $last_login ) ) $login = ''; if ( empty ( $webcalendar_login ) ) $webcalendar_login = ''; if ( $REMEMBER_LAST_LOGIN == 'Y' && empty ( $login ) ) $last_login = $login = $webcalendar_login; load_user_preferences ( 'guest' ); $WebCalendar->setLanguage(); // Look for action=logout. $logout = false; $action = getGetValue ( 'action' ); if ( ! empty ( $action ) && $action == 'logout' ) { $logout = true; $return_path = ''; SetCookie ( 'webcalendar_login', '', 0 ); SetCookie ( 'webcalendar_last_view', '', 0 ); } else if ( empty ( $return_path ) ) { // See if a return path was set. $return_path = get_last_view ( false ); } if ( ! empty ( $return_path ) ) $url = $return_path = clean_whitespace ( $return_path ); else $url = 'index.php'; // If Application Name is set to "Title" then get translation. // If not, use the Admin defined Application Name. $appStr = generate_application_name(); $login = getPostValue ( 'login' ); $password = getPostValue ( 'password' ); $remember = getPostValue ( 'remember' ); // Calculate path for cookie. if ( empty ( $PHP_SELF ) ) $PHP_SELF = $_SERVER['PHP_SELF']; $cookie_path = str_replace ( 'login.php', '', $PHP_SELF ); if ( $single_user == 'Y' || $use_http_auth ) // No login for single-user mode or when using HTTP authorization. do_redirect ( 'index.php' ); else { if ( ! empty ( $login ) && ! empty ( $password ) && ! $logout ) { if ( get_magic_quotes_gpc() ) { $login = stripslashes ( $login ); $password = stripslashes ( $password ); } $login = trim ( $login ); $badLoginStr = translate ( 'Illegal characters in login XXX.' ); if ( $login != addslashes ( $login ) ) die_miserable_death ( str_replace ( 'XXX', htmlentities ( $login ), $badLoginStr ) ); if ( user_valid_login ( $login, $password ) ) { user_load_variables ( $login, '' ); $encoded_login = encode_string ( $login . '|' . crypt( $password ) ); // If $remember, set login to expire in 365 days. $timeStr = ( ! empty ( $remember ) && $remember == 'yes' ? time() + 31536000 : 0 ); SetCookie ( 'webcalendar_session', $encoded_login, $timeStr, $cookie_path ); // The cookie "webcalendar_login" is provided as a convenience to other // apps that may wish to know what was the last calendar login, // so they can use week_ssi.php as a server-side include. // As such, it's not a security risk to have it un-encoded since it is not // used to allow logins within this app. It is used to load user // preferences on the login page (before anyone has logged in) // if $REMEMBER_LAST_LOGIN is set to "Y" (in admin.php). SetCookie ( 'webcalendar_login', $login, $timeStr, $cookie_path ); if ( ! empty ( $GLOBALS['newUserUrl'] ) ) $url = $GLOBALS['newUserUrl']; do_redirect ( $url ); } else { // Invalid login. if ( empty ( $error ) || ! $showLoginFailureReason ) $error = translate ( 'Invalid login', true ); activity_log ( 0, 'system', '', LOG_LOGIN_FAILURE, str_replace ( ['XXX', 'YYY'], [$login, $_SERVER['REMOTE_ADDR']], translate ( 'Activity login failure' ) ) ); } } else { // No login info... just present empty login page. // $error = "Start"; } // Delete current user. SetCookie ( 'webcalendar_session', '', 0, $cookie_path ); // In older versions, the cookie path had no trailing slash and NS 4.78 // thinks "path/" and "path" are different, so the line above does not // delete the "old" cookie. This prohibits the login. So we also delete the // cookie with the trailing slash removed. if ( substr ( $cookie_path, -1 ) == '/' ) SetCookie ( 'webcalendar_session', '', 0, substr ( $cookie_path, 0, -1 ) ); } echo send_doctype ( $appStr ) . ( $logout ? '' : ' <script> // Error check login/password. function valid_form ( form ) { if ( form.login.value.length == 0 || form.password.value.length == 0 ) { alert ( \'' . translate ( 'You must enter a login and password.', true ) . '\' ); return false; } return true; } function myOnLoad() { document.login_form.login.focus();' . ( empty ( $login ) ? '' : ' document.login_form.login.select();' ) . ( empty ( $error ) ? '' : ' alert ( \'' . $error . '\' );' ) . ' } </script>' ) . ' <link href="css_cacher.php?login=__public__" rel="stylesheet" /> <link href="includes/css/styles.css" rel="stylesheet" />' // Print custom header (since we do not call print_header function). . ( ! empty ( $CUSTOM_SCRIPT ) && $CUSTOM_SCRIPT == 'Y' ? load_template ( $login, 'S' ) : '' ) . ' </head> <body id="login"' . ( $logout ? '' : ' onload="myOnLoad();"' ) . '>' // Print custom header (since we do not call print_header function). . ( ! empty ( $CUSTOM_HEADER ) && $CUSTOM_HEADER == 'Y' ? load_template ( $login, 'H' ) : '' ) . ' <h2>' . $appStr . '</h2>' . ( empty ( $error ) ? '' : ' <span style="color:#f00; font-weight:bold;">' . str_replace ( 'XXX', $error, translate ( 'Error XXX' ) ) . '</span>' ) . '<br />' . ( $logout ? ' <p>' . translate ( 'You have been logged out.' ) . '</p><br /><br /> <a class="nav" href="login.php' . ( empty ( $return_path ) ? '' : '?return_path=' . htmlentities ( $return_path ) ) . '">' . translate ( 'Login' ) . '</a><br /><br /><br />' : ' <form name="login_form" id="login" action="login.php" method="post" ' . ' onsubmit="return valid_form( this )">' . ( empty ( $return_path ) ? '' : ' <input type="hidden" name="return_path" value="' . htmlentities ( $return_path ) . '" />' ) . ' <table class="aligncenter" id="logintable" cellspacing="10" cellpadding="10"> <tr> <td rowspan="2"><img src="images/login.gif" alt="Login" /></td> <td class="alignright"><label for="user">' . translate ( 'Username' ) . ':</label></td> <td><input name="login" id="user" size="15" maxlength="25" value="' . ( empty ( $last_login ) ? '' : $last_login ) . '" tabindex="1" /></td> </tr> <tr> <td class="alignright"><label for="password">' . translate ( 'Password' ) . ':</label></td> <td><input name="password" id="password" type="password" size="15" ' . 'maxlength="30" tabindex="2" /></td> </tr> <tr> <td colspan="3" style="font-size:10px;"> <input type="checkbox" name="remember" id="remember" tabindex="3" ' . 'value="yes"' . ( ! empty ( $remember ) && $remember == 'yes' ? 'checked="checked"' : '' ) . ' /> <label id="save-cookies" for="remember"> ' . translate ( 'Save login via cookies so I dont have to login next time.' ) . ' </label> </td> </tr> <tr> <td colspan="4" class="aligncenter"><input type="submit" value="' . translate ( 'Login' ) . '" tabindex="4" /></td> </tr> </table> </form>' ) . ( ! empty ( $PUBLIC_ACCESS ) && $PUBLIC_ACCESS == 'Y' ? '<br /><br /> <a class="nav" href="index.php">' . translate ( 'Access public calendar' ) . '</a><br />' : '' ); $nulist = get_nonuser_cals(); $accessStr = translate ( 'Access XXX calendar' ); for ( $i = 0, $cnt = count ( $nulist ); $i < $cnt; $i++ ) { if ( $nulist[$i]['cal_is_public'] == 'Y' ) echo ' <a class="nav" href="nulogin.php?login=' . $nulist[$i]['cal_login'] . '">' . str_replace ( 'XXX', $nulist[$i]['cal_fullname'], $accessStr ) . '</a><br />'; } echo ( $DEMO_MODE == 'Y' // This is used on the sourceforge demo page. ? ' Demo login: user = "demo", password = "demo"<br />' : '' ) . '<br /><br />'; if ( ! empty ( $ALLOW_SELF_REGISTRATION ) && $ALLOW_SELF_REGISTRATION == 'Y' ) { // We can limit what domain is allowed to self register. // $self_registration_domain should have this format "192.168.220.0:255.255.240.0"; $valid_ip = validate_domain(); if ( ! empty ( $valid_ip ) ) echo ' <b><a href="register.php">' . translate ( 'Not yet registered? Register here!' ) . '</a></b><br />'; } echo ' <span class="cookies">' . translate ( 'cookies-note' ) . '</span><br /> <hr /> <br /> <a href="' . $PROGRAM_URL . '" target="_blank" id="programname">' . $PROGRAM_NAME . '</a> <br /> <br />' // Print custom trailer (since we do not call print_trailer function). . ( ! empty ( $CUSTOM_TRAILER ) && $CUSTOM_TRAILER == 'Y' ? load_template ( $login, 'T' ) : '' ) . ' </body> </html>'; ?> PK �]�\6��� � help_index.phpnu �[��� <?php // $Id: help_index.php,v 1.29 2009/11/22 16:47:45 bbannon Exp $ include_once 'includes/init.php'; include_once 'includes/help_list.php'; print_header ( '', '', '', true ); echo ' <h2>' . translate ( 'Help Index' ) . '</h2> <ul>'; $page = 0; //display About WebCalendar link only on index page $aboutStr = translate ( 'About WebCalendar' ); echo ' <li><a title="' . $aboutStr . '" href="" onclick="javascript:openAbout()">' . $aboutStr . '</a></li>'; foreach ( $help_list as $key => $val ) { $page++; $transStr = translate ( $key ); echo ' <li><a title="' . $transStr . '" href="' . $val . '?thispage=' . $page . '">' . $transStr . '</a></li>'; } echo ' </ul> ' . print_trailer ( false, true, true ); ?> PK �]�\��j j icons.phpnu �[��� <?php include_once 'includes/init.php'; $icon_path = 'icons/'; $can_edit = ( is_dir ( $icon_path ) && ( $ENABLE_ICON_UPLOADS == 'Y' || $is_admin ) ); if ( ! $can_edit ) do_redirect ( 'category.php' ); print_header ( array ( 'js/visible.php' ), '', '', true ); $icons = []; if ( $d = dir ( $icon_path ) ) { while ( false !== ( $entry = $d->read() ) ) { if ( substr ( $entry, -3, 3 ) == 'gif' ) { $data = ''; // We''ll compare the files to eliminate duplicates. $fd = @fopen ( $icon_path . $entry, 'rb' ); if ( $fd ) { // We only need to compare the first 1kb. $data .= fgets ( $fd, 1024 ); $icons[md5 ( $data )] = $entry; } fclose ( $fd ); } } $d->close(); // Remove duplicates and replace keys with 0...n. $icons = array_unique ( $icons ); //Convert associative array into numeric array $icons = array_values ( $icons ); $title_str = translate ( 'Click to Select' ); ?> <script> <!-- <![CDATA[ function sendURL ( url ) { var thisInput = window.opener.document.catform.urlname, thisPic = window.opener.document.images.urlpic, thistr1 = window.opener.document.getElementById ('cat_icon'), thistr2 = window.opener.document.getElementById ('remove_icon'); thisInput.value = url.substring (6); thisPic.src = url; thistr1.style.visibility = thistr2.style.visibility = "visible"; window.close(); } //]]> --> </script> <?php echo ' <table class="aligncenter"> <tr> <td colspan="8" class="aligncenter"><h2>' . translate ( 'Current Icons on Server' ) . '</h2></td> </tr> <tr>'; for ( $i = 0, $cnt = count ( $icons ); $i < $cnt; $i++ ) { echo ' <td><a href="#" onclick="sendURL( \'' . $icon_path . $icons[$i] . '\' )" ><img src="' . $icon_path . $icons[$i] . '" title="' . $title_str . '" alt="' . $title_str . '" /></a></td>' . ( $i > 0 && $i % 8 == 0 ? ' </tr> <tr>' : '' ); } echo ' </tr> <tr> <td colspan="8" class="aligncenter">' . $title_str . '</td> </tr> </table> </body> </html>'; } ?> PK �]�\�g� � select_user.phpnu �[��� <?php // $Id: select_user.php,v 1.36 2009/11/22 16:47:45 bbannon Exp $ include_once 'includes/init.php'; print_header(); echo ' <h2>' . translate ( 'View Another Users Calendar' ) . '</h2>'; if ( ( $ALLOW_VIEW_OTHER != 'Y' && ! $is_admin ) || ( $PUBLIC_ACCESS == 'Y' && $login == '__public__' && $PUBLIC_ACCESS_OTHERS != 'Y' ) ) { $error = print_not_auth(); echo ' <blockquote>' . $error . '</blockquote>'; } else { $userlist = get_my_users ( '', 'view' ); if ( $NONUSER_ENABLED == 'Y' ) { $nonusers = get_my_nonusers ( $login, true ); $userlist = ( $NONUSER_AT_TOP == 'Y' ? array_merge ( $nonusers, $userlist ) : array_merge ( $userlist, $nonusers ) ); } if ( strstr ( $STARTVIEW, 'view' ) ) $url = 'month.php'; else { $url = $STARTVIEW; if ( $url == 'month' || $url == 'day' || $url == 'week' || $url == 'year' ) $url .= '.php'; } echo ' <form action="' . $url . '" method="get" name="SelectUser"> <select name="user" onchange="document.SelectUser.submit()">'; for ( $i = 0, $cnt = count ( $userlist ); $i < $cnt; $i++ ) { // Don't list current user if ( $login == $userlist[$i]['cal_login'] ) continue; echo ' <option value="' . $userlist[$i]['cal_login'] . '">' . $userlist[$i]['cal_fullname'] . '</option>'; } echo ' </select> <input type="submit" value="' . translate ( 'Go' ) . '" /> </form>'; } echo '<br /><br /> ' . print_trailer(); ?> PK �]�\Xw �l l publish.phpnu �[��� <?php // $Id: publish.php,v 1.37 2009/11/22 16:47:45 bbannon Exp $ /** * Description: * Creates the iCal output for a single user's calendar so that remote users can * "subscribe" to a WebCalendar calendar. Both Apple iCal and Mozilla's calendar * support subscribing to remote calendars. * * Note that unlike the export to iCal, this page does not include * attendee info. This improves the performance considerably, BTW. * * Notes: * Does anyone know when a client (iCal, for example) refreshes its * data, does it delete all old data and reload? Just wondering * if we need to somehow send a delete notification on updates... * * Input parameters: * URL should be the form of /xxx/publish.php/username.ics * or /xxx/publish.php?user=username * * Security: * DO NOT ALLOW if either; * $PUBLISH_ENABLED is not 'Y' (set in Admin System Settings). * $USER_PUBLISH_ENABLED is not 'Y' (set in each user's Preferences). */ include_once 'includes/translate.php'; require_once 'includes/classes/WebCalendar.class'; $WebCalendar = new WebCalendar( __FILE__ ); include 'includes/config.php'; include 'includes/dbi4php.php'; include 'includes/formvars.php'; include 'includes/functions.php'; $WebCalendar->initializeFirstPhase(); include 'includes/' . $user_inc; include 'includes/validate.php'; include 'includes/site_extras.php'; include_once 'includes/xcal.php'; $WebCalendar->initializeSecondPhase(); // Calculate username. // If using http_auth, use those credentials. if ( $use_http_auth && empty ( $user ) ) $user = $login; if ( empty ( $user ) ) { $arr = explode ( '/', $PHP_SELF ); $user = $arr[count ( $arr )-1]; # remove any trailing ".ics" in user name $user = preg_replace ( "/\.[iI][cC][sS]$/", '', $user ); } if ( $user == 'publish.php' ) $user = ''; if ( $user == 'public' ) $user = '__public__'; load_global_settings(); $WebCalendar->setLanguage(); if ( empty ( $PUBLISH_ENABLED ) || $PUBLISH_ENABLED != 'Y' ) { header ( 'Content-Type: text/plain' ); echo print_not_auth(); exit; } $errorStr = translate ( 'Error' ); $nouser = translate( 'No user specified.' ); // Make sure they specified a username. if ( empty ( $user ) ) { echo send_doctype ( $errorStr ); echo <<<EOT </head> <body> <h2>{$errorStr}</h2> {$nouser}. </body> </html> EOT; exit; } // Load user preferences (to get the USER_PUBLISH_ENABLED and // DISPLAY_UNAPPROVED setting for this user). $login = $user; load_user_preferences(); if ( empty ( $USER_PUBLISH_ENABLED ) || $USER_PUBLISH_ENABLED != 'Y' ) { header ( 'Content-Type: text/plain' ); echo print_not_auth(); exit; } // Load user name, etc. user_load_variables ( $user, 'publish_' ); // header ( 'Content-Type: text/plain' ); header ( 'Content-Type: text/calendar' ); header ( 'Content-Disposition: attachment; filename="' . $user . '.ics"' ); $use_all_dates = true; $type = 'publish'; export_ical(); ?> PK �]�\��QK�# �# week.phpnu �[��� <?php // $Id: week.php,v 1.144 2010/02/21 08:27:48 bbannon Exp $ include_once 'includes/init.php'; //check UAC if( ! access_can_access_function( ACCESS_WEEK ) || ( ! empty( $user ) && ! access_user_calendar( 'view', $user ) ) ) send_to_preferred_view(); load_user_layers ( ( $user != $login ) && $is_nonuser_admin ? $user : '' ); load_user_categories(); $nextYmd = date ( 'Ymd', mktime ( 0, 0, 0, $thismonth, $thisday + 7, $thisyear ) ); $prevYmd = date ( 'Ymd', mktime ( 0, 0, 0, $thismonth, $thisday - 7, $thisyear ) ); $boldDays = ( ! empty ( $BOLD_DAYS_IN_YEAR ) && $BOLD_DAYS_IN_YEAR == 'Y' ); $wkstart = get_weekday_before ( $thisyear, $thismonth, $thisday + 1 ); $wkend = $wkstart + ( 86400 * ( $DISPLAY_WEEKENDS == 'N' ? 5 : 7 ) ); $startdate = date ( 'Ymd', $wkstart ); $enddate = date ( 'Ymd', $wkend ); $start_ind = 0; if ( $DISPLAY_WEEKENDS == 'N' ) { $end_ind = 4; $WEEK_START = 1; //Set to Monday. } else $end_ind = 6; if ( empty ( $TIME_SLOTS ) ) $TIME_SLOTS = 24; $interval = 1440 / $TIME_SLOTS; $first_slot = intval ( ( $WORK_DAY_START_HOUR * 60 ) / $interval ); $last_slot = intval ( ( $WORK_DAY_END_HOUR * 60 ) / $interval ); $untimed_found = false; $get_unapproved = ( $DISPLAY_UNAPPROVED == 'Y' ); // Make sure all days with events are bold if mini cal is displayed. if ( $DISPLAY_SM_MONTH == 'Y' && $BOLD_DAYS_IN_YEAR == 'Y' ) { $evStart = get_weekday_before ( $thisyear, $thismonth ); $evEnd = mktime ( 23, 59, 59, $thismonth + 2, 0, $thisyear ); } else { $evStart = $wkstart; $evEnd = $wkend; } /* Pre-Load the repeated events for quickier access. */ $repeated_events = read_repeated_events ( ( strlen ( $user ) ? $user : $login ), $evStart - 604800, $evEnd, $cat_id ); /* Pre-load the non-repeating events for quicker access. */ // Start the search ONE_WEEK early to account for cross-day events. $events = read_events ( ( strlen ( $user ) ? $user : $login ), $evStart - 604800, $evEnd, $cat_id ); if ( empty ( $DISPLAY_TASKS_IN_GRID ) || $DISPLAY_TASKS_IN_GRID == 'Y' ) /* Pre-load tasks for quicker access. */ $tasks = read_tasks ( ! empty ( $user ) && strlen ( $user ) && $is_assistant ? $user : $login, $wkend, $cat_id ); if ( $can_add ) { $help = ' title="' . translate ( 'Double-click on empty cell to add new entry' ) . '"'; } else { $help = ''; } $eventsStr = $filler = $headerStr = $minical_tasks = $untimedStr = ''; $navStr = display_navigation ( 'week' ); for ( $i = $start_ind; $i <= $end_ind; $i++ ) { $days[$i] = ( $wkstart + ( 86400 * $i ) ) + 43200; $weekdays[$i] = weekday_name ( ( $i + $WEEK_START ) % 7, $DISPLAY_LONG_DAYS ); $dateYmd = date ( 'Ymd', $days[$i] ); $header[$i] = $weekdays[$i] . '<br />' . date_to_str ( $dateYmd, $DATE_FORMAT_MD, false, true ); // Generate header row. $class = ( $dateYmd == date ( 'Ymd', $today ) ? ' class="today"' : ( is_weekend ( $days[$i] ) ? ' class="weekend"' : '' ) ); $headerStr .= '<th ' . $class . ( $can_add ? " ondblclick=\"dblclick_add('$dateYmd','$user',0,0)\"" : '' ) . ">"; $headerStr .= '<p style="margin:.75em 0 0 0"><a href="day.php?' . $u_url . 'date=' . $dateYmd . $caturl . '">' . $header[$i] . '</a></p></th>'; $date = date ( 'Ymd', $days[$i] ); $hour_arr = $rowspan_arr = $tk = array(); // Get, combine and sort, static and repeating events for this date. $ev = combine_and_sort_events ( get_entries ( $date, $get_unapproved ), get_repeating_entries ( $user, $date ) ); // Then sort in any tasks due for this day and before. $ev = combine_and_sort_events ( $ev, ( $date >= date ( 'Ymd' ) ? get_tasks ( $date, $get_unapproved ) : $tk ) ); for ( $j = 0, $cnt = count ( $ev ); $j < $cnt; $j++ ) { if ( $get_unapproved || $ev[$j]->getStatus() == 'A' ) html_for_event_week_at_a_glance ( $ev[$j], $date ); } // Squish events that use the same cell into the same cell. // For example, an event from 8:00-9:15 and another from 9:30-9:45 // both want to show up in the 8:00-9:59 cell. $last_row = -1; $rowspan = 0; for ( $j = 0; $j < $TIME_SLOTS; $j++ ) { if ( $rowspan > 1 ) { if ( ! empty ( $hour_arr[$j] ) ) { $diff_start_time = $j - $last_row; if ( $rowspan_arr[$j] > 1 ) { if ( $rowspan_arr[$j] + ( $diff_start_time ) > $rowspan_arr[$last_row] ) $rowspan_arr[$last_row] = ( $rowspan_arr[$j] + ( $diff_start_time ) ); $rowspan += ( $rowspan_arr[$j] - 1 ); } else $rowspan_arr[$last_row] += $rowspan_arr[$j]; // This will move entries apart that appear in one field, // yet start on different hours. for ( $u = $diff_start_time; $u > 0; $u-- ) { $hour_arr[$last_row] .= '<br />' . "\n"; } $hour_arr[$last_row] .= $hour_arr[$j]; $hour_arr[$j] = ''; $rowspan_arr[$j] = 0; } $rowspan--; } else if ( ! empty ( $rowspan_arr[$j] ) && $rowspan_arr[$j] > 1 ) { $last_row = $j; $rowspan = $rowspan_arr[$j]; } } // Now save the output... if ( ! empty ( $hour_arr[9999] ) && strlen ( $hour_arr[9999] ) ) { $untimed[$i] = $hour_arr[9999]; $untimed_found = true; } $untimedStr .= '<td'; if ( $can_add ) $untimedStr .= " ondblclick=\"dblclick_add('$dateYmd','$user',0,0)\""; // Use the class 'hasevents' for any hour block that has events in it. $untimedStr .= ( ! empty ( $untimed[$i] ) && strlen ( $untimed[$i] ) ? ' class="hasevents"' : $class ) . '>' . ( ! empty ( $untimed[$i] ) && strlen ( $untimed[$i] ) ? $untimed[$i] : ' ' ) . '</td>'; $save_hour_arr[$i] = $hour_arr; $save_rowspan_arr[$i] = $rowspan_arr; $rowspan_day[$i] = 0; } $untimedStr = ( $untimed_found ? ' <tr> <th class="empty"> </th>' . $untimedStr . ' </tr>' : '' ); for ( $i = $first_slot; $i <= $last_slot; $i++ ) { $time_h = intval ( ( $i * $interval ) / 60 ); $time_m = ( $i * $interval ) % 60; // Do not apply TZ offset. $eventsStr .= '<tr><th class="row">' . display_time ( ( $time_h * 100 + $time_m ) * 100, 1 ) . '</th>'; for ( $d = $start_ind; $d <= $end_ind; $d++ ) { $dateYmd = date ( 'Ymd', $days[$d] ); // Class "hasevents" overrides both "today" and "weekend". // And class "today" overrides "weekend". // So, no need to list them all. $class = ( ! empty ( $save_hour_arr[$d][$i] ) && strlen ( $save_hour_arr[$d][$i] ) ? ' class="hasevents"' : ( $dateYmd == date ( 'Ymd', $today ) ? ' class="today"' : ( is_weekend ( $days[$d] ) ? ' class="weekend"' : '' ) ) ); if ( $rowspan_day[$d] > 1 ) { // This might mean there's an overlap, // or it could mean one event ends at 11:15 and another starts at 11:30. if ( ! empty ( $save_hour_arr[$d][$i] ) ) { $eventsStr .= ' <td' . $class; if ( $can_add ) $eventsStr .= " ondblclick=\"dblclick_add('$dateYmd','$user',$time_h,$time_m)\""; $eventsStr .= '>' . $save_hour_arr[$d][$i] . '</td>'; } $rowspan_day[$d]--; } else { $eventsStr .= '<td' . $class; if ( $can_add ) $eventsStr .= " ondblclick=\"dblclick_add('$dateYmd','$user',$time_h,$time_m)\""; if ( empty ( $save_hour_arr[$d][$i] ) ) { $eventsStr .= '>' . ' '; } else { $rowspan_day[$d] = $save_rowspan_arr[$d][$i]; $eventsStr .= ( $rowspan_day[$d] > 1 ? ' rowspan="' . $rowspan_day[$d] .'"': '' ) . '>' . $save_hour_arr[$d][$i]; } $eventsStr .= '</td>'; } } $eventsStr .= ' </tr>'; } $eventinfo = ( empty ( $eventinfo ) ? '' : $eventinfo ); $tableWidth = '100%'; $unapprovedStr = $printerStr = ''; if ( empty ( $friendly ) ) { $unapprovedStr = display_unapproved_events ( $is_assistant || $is_nonuser_admin ? $user : $login ); $printerStr = generate_printer_friendly ( 'month.php' ); } $trailerStr = print_trailer(); if ( $DISPLAY_TASKS == 'Y' ) { $tableWidth = '80%'; $filler = '<td></td>'; $minical_tasks .= ' <td id="minicolumn" rowspan="2" class="aligntop"> <!-- START MINICAL --> <div class="minicontainer">' . ( $DISPLAY_SM_MONTH == 'Y' ? ' <div class="minicalcontainer">' . display_small_month ( $thismonth, $thisyear, true ) . '</div>' : '' ) . ' <div id="minitask">' . display_small_tasks ( $cat_id ) . '</div> </div> </td>'; } print_header( array( 'js/popups.js/true', 'js/dblclick_add.js/true' ), generate_refresh_meta(), '', false, false, false, false ); echo <<<EOT <table cellpadding="1"> <tr> <td id="printarea" style="vertical-align:top; width:{$tableWidth};"> {$navStr} </td> {$filler} </tr> <tr> <td> <table class="main"{$help}> <tr> <th class="empty"> </th>{$headerStr} </tr>{$untimedStr}{$eventsStr} </table> </td>{$minical_tasks} </tr> </table> {$eventinfo} {$unapprovedStr} {$printerStr} {$trailerStr} EOT; ?> PK �]�\�e�6g g view_v.phpnu �[��� <?php // $Id: view_v.php,v 1.85 2009/11/22 22:26:18 bbannon Exp $ /** * Page Description: * This page will display the month "view" with all users's events on the same * calendar. (The other month "view" displays each user calendar in a separate * column, side-by-side.) This view gives you the same effect as enabling layers, * but with layers you can only have one configuration of users. * * Input Parameters: * id (*) - specify view id in webcal_view table * date - specify the starting date of the view. * If not specified, current date will be used. * friendly - if set to 1, then page does not include links or trailer navigation. * (*) required field * * Security: * Must have "allow view others" enabled ($ALLOW_VIEW_OTHER) in System Settings * unless the user is an admin user ($is_admin). If the view is not global, the * user must be owner of the view. If the view is global, then and * user_sees_only_his_groups is enabled, then we remove users not in this user's * groups (except for nonuser calendars... which we allow regardless of group). */ include_once 'includes/init.php'; include_once 'includes/views.php'; $DAYS_PER_TABLE = 7; $error = ''; view_init ( $id ); $printerStr = generate_printer_friendly ( 'view_v.php' ); set_today ( $date ); $nextdate = date ( 'Ymd', mktime ( 0, 0, 0, $thismonth, $thisday + 7, $thisyear ) ); $prevdate = date ( 'Ymd', mktime ( 0, 0, 0, $thismonth, $thisday - 7, $thisyear ) ); $wkstart = get_weekday_before( $thisyear, $thismonth, $thisday + 1 ); $wkend = bump_local_timestamp( $wkstart, 0, 0, 0, 0, ( $DISPLAY_WEEKENDS == 'N' ? 5 : 7 ), 0 ) - 1; $thisdate = date( 'Ymd', $wkstart ); $nextStr = translate ( 'Next' ); $prevStr = translate ( 'Previous' ); $can_add = ( empty ( $ADD_LINK_IN_VIEWS ) || $ADD_LINK_IN_VIEWS != 'N' ); print_header( array( 'js/popups.js/true', 'js/dblclick_add.js/true' ) ); echo ' <div style="width:99%;"> <a title="' . $prevStr . '" class="prev" href="view_v.php?id=' . $id . '&date=' . $prevdate . '"><img src="images/leftarrow.gif" alt="' . $prevStr . '" /></a> <a title="' . $nextStr . '" class="next" href="view_v.php?id=' . $id . '&date=' . $nextdate . '"><img src="images/rightarrow.gif" alt="' . $nextStr . '" /></a> <div class="title"> <span class="date">' . date_to_str ( $thisdate, '', false ) . ' - ' . date_to_str ( date ( 'Ymd', $wkend ), '', false ) . '</span><br /> <span class="viewname">' . htmlspecialchars ( $view_name ) . '</span> </div> </div><br />'; // The table has names across the top and dates for rows. Since we need to spit // out an entire row before we can move to the next date, we'll save up all the // HTML for each cell and then print it out when we're done.. // Additionally, we only want to put at most 6 users in one table since // any more than that doesn't really fit in the page. // Get users in this view. $viewusers = view_get_user_list ( $id ); $viewusercnt = count ( $viewusers ); if ( $viewusercnt == 0 ) // This could happen if user_sees_only_his_groups = Y and // this user is not a member of any group assigned to this view. $error = translate( 'No users for this view.' ); if ( ! empty( $error ) ) { echo print_error( $error ) . print_trailer(); exit; } $e_save = $re_save = array(); for ( $i = 0; $i < $viewusercnt; $i++ ) { /* Pre-Load the repeated events for quicker access */ $re_save[$i] = read_repeated_events ( $viewusers[$i], $wkstart, $wkend, '' ); /* Pre-load the non-repeating events for quicker access subtracting ONE_WEEK to allow cross-day events to display. */ $e_save[$i] = read_events ( $viewusers[$i], $wkstart - 604800, $wkend ); } for ( $j = 0; $j < 7; $j += $DAYS_PER_TABLE ) { // Since print_date_entries is rather stupid, we can swap the event data // around for users by changing what $events points to. $tdw = 12; // Column width percent. echo ' <table class="main"'; if ( $can_add ) echo 'title="' . translate ( 'Double-click on empty cell to add new entry' ) . '"'; echo '> <tr> <th class="empty"> </th>'; $body = $header = ''; $todayYmd = date ( 'Ymd', $today ); for ( $i = 0; $i < $viewusercnt; $i++ ) { $events = $e_save[$i]; $repeated_events = $re_save[$i]; $user = $viewusers[$i]; user_load_variables ( $user, 'temp' ); $body .= ' <tr> <th class="row" style="width:' . $tdw . '%;">' . $tempfullname . '</th>'; for ( $date = $wkstart; $date <= $wkend; $date = bump_local_timestamp( $date, 0, 0, 0, 0, 1, 0 ) ) { $is_weekend = is_weekend( $date ); if ( $is_weekend && $DISPLAY_WEEKENDS == 'N' ) continue; $dateYmd = date ( 'Ymd', $date ); $entryStr = print_date_entries ( $dateYmd, $user, true ); $class = ( $dateYmd == $todayYmd ? ' class="today"' : ( ! empty ( $entryStr ) && $entryStr != ' ' ? ' class="hasevents"' : ( $is_weekend ? ' class="weekend"' : '' ) ) ) . ' style="width:' . $tdw . '%;"'; // Build header row. if ( $i == 0 ) { $header .= '<th' . $class . '>' . weekday_name ( date ( 'w', $date ), $DISPLAY_LONG_DAYS ) . ' ' . date ( 'd', $date ) . '</th>'; } $body .= '<td' . $class; if ( $can_add ) $body .= " ondblclick=\"dblclick_add( '$dateYmd', '$user' )\""; $body .= '>' . $entryStr . ' </td>'; } $body .= ' </tr>'; } // Output all. echo $header . ' </tr>' . $body . ' </table>'; } $user = ''; // reset echo ( empty ( $eventinfo ) ? '' : $eventinfo ) .$printerStr . print_trailer(); ?> PK �]�\��H�� � import_gitlog.phpnu �[��� <?php /** * File Description: * This file incudes functions for parsing output from the 'git log' command. * * It will be included by import_handler.php. * Note that the code here is really just parsing the git log data. The * actual import into the database happens in import_data which is in * includes/xcal.php. It was originally intended for VCAL and ICAL, so * the array names of the parsed data will reflect that. */ /** * Parse the git log file and return the data hash. * Tested with: * - git log * - git log --stat */ function parse_gitlog ( $cal_file ) { global $errormsg, $tz; $import_data = []; if ( ! $fd = @fopen ( $cal_file, 'r' ) ) { $errormsg .= 'Cannot read temporary file: ' . "$cal_file\n"; exit(); } else { $commitId = $author = $date = $message = ''; $inMessage = false; $matches = []; while ( ( $line = fgets ( $fd ) ) != false ) { $line = rtrim ( $line ); if ( preg_match ( "/^commit\s+(\S+)/", $line, $matches ) ) { if ( $inMessage ) { // Add previous commit $obj = create_event_object ( $commitId, $author, $date, $message ); $import_data[] = $obj; $inMessage = false; $commitId = $author = $date = $message = ''; } $commitId = $matches[1]; } else if ( preg_match ( "/^Author:\s+(\S.*)/", $line, $matches ) ) { $author = $matches[1]; } else if ( preg_match ( "/^Date:\s+(\S.*)/", $line, $matches ) ) { $date = parseGitDate ( $matches[1] ); } else { // Everything else is the commit message $inMessage = true; // skip any leading blank lines if ( strlen ( $message ) > 0 || strlen ( trim ( $line ) ) > 0 ) { if ( strlen ( $message ) > 0 ) $message .= "\n"; $message .= $line; } } } if ( strlen ( $commitId ) > 0 ) { $obj = create_event_object ( $commitId, $author, $date, $message ); $import_data[] = $obj; } } return $import_data; } // Convert the date from a git log into unix timestamp. function parseGitDate ( $dateStr ) { // This is where PHP shines :-) return strtotime ( $dateStr ); } function create_event_object ( $commitId, $author, $date, $message ) { $obj = []; $obj['UID'] = $commitId; $obj['CalendarType'] = 'VEVENT'; // The default type $obj['StartTime'] = $date; // In seconds since 1970 (Unix Epoch) $obj['EndTime'] = $date; // In seconds since 1970 (Unix Epoch) // Summary should be first 6 chars of commit id and first line of // commit message. $messageLines = explode ( "\n", $message ); $summary = substr ( $commitId, 0, 6 ) . ' ' . $messageLines[0]; $obj['Summary'] = $summary; // Summary of event (string) $obj['Description'] = nl2br ( $message ); // Full Description (string) $obj['AlarmSet'] = 0; // 1 = true 0 = false $obj['Duration'] = 0; $obj['AllDay'] = 0; // 1 = true 0 = false return $obj; } ?> PK �]�\�Y�Ǝ2 �2 view_t.phpnu �[��� <?php // $Id: view_t.php,v 1.93 2011/07/12 19:42:25 rjones6061 Exp $ /** * Page Description: * This page will display a timebar for a week or month as specified by timeb. * * Input Parameters: * id (*) - specify view id in webcal_view table * date - specify the starting date of the view. * If not specified, current date will be used. * friendly - if set to 1, then page does not include links or trailer navigation. * timeb - 1 = week, else month * (*) required field * * Security: * Must have "allow view others" enabled ($ALLOW_VIEW_OTHER) in System Settings * unless the user is an admin user ($is_admin). * If the view is not global, the user must be owner of the view. * If the view is global, then and user_sees_only_his_groups is enabled, * then we remove users not in this user's groups * (except for nonuser calendars... which we allow regardless of group). */ include_once 'includes/init.php'; include_once 'includes/views.php'; $error = ''; $USERS_PER_TABLE = 6; view_init ( $id ); $can_add = ( empty ( $ADD_LINK_IN_VIEWS ) || $ADD_LINK_IN_VIEWS != 'N' ); $entrySlots = ( $ENTRY_SLOTS > 144 ? 144 : $ENTRY_SLOTS ); $yardSlots = ( int ) 60 / ( 1440 / $entrySlots ); //Number of divisions per hour. $slotValue = 60 / $yardSlots; //Minutes per division. $totalHours = $WORK_DAY_END_HOUR - $WORK_DAY_START_HOUR; $width = ( 100 / $totalHours ); $yardWidth = round ( $width / $yardSlots, 3 ); //Percentage width of each division. $totalSlots = ( $totalHours * $yardSlots ); //Number of divisions full page. /** * Prints all the entries in a time bar format for the specified user for the * specified date. * * If we are displaying data from someone other than the logged in user, * then check the access permission of the entry. * * @param string $date Date in YYYYMMDD format * @param string $user Username * @param bool $ssi Should we not include links to add new events? */ function print_date_entries_timebar ( $date, $user, $ssi ) { global $DISPLAY_UNAPPROVED, $events, $is_admin, $PUBLIC_ACCESS, $PUBLIC_ACCESS_CAN_ADD, $readonly, $totalSlots; $ret = ''; $cnt = 0; $get_unapproved = ( $DISPLAY_UNAPPROVED == 'Y' ); $year = substr ( $date, 0, 4 ); $month = substr ( $date, 4, 2 ); $day = substr ( $date, 6, 2 ); $can_add = ( $readonly == 'N' || $is_admin ); if ( $PUBLIC_ACCESS == 'Y' && $PUBLIC_ACCESS_CAN_ADD != 'Y' && $GLOBALS['login'] == '__public__' ) $can_add = false; $cur_rep = 0; // Combine and sort the event arrays. $ev = combine_and_sort_events ( get_entries ( $date, $get_unapproved ), get_repeating_entries ( $user, $date ) ); $evcnt = count ( $ev ); for ( $i = 0; $i < $evcnt; $i++ ) { if( $get_unapproved || $ev[$i]->getStatus() == 'A' ) { $ret .= print_entry_timebar ( $ev[$i], $date ); $cnt++; } } return $ret . ( $cnt == 0 ? ' <tr> <td colspan="' . $totalSlots . '"> </td> </tr>' // So the table cell has at least something. : '' ); } /** * Prints the HTML for an event with a timebar. * * @param Event $event The event * @param string $date Date for which we're printing in YYYYMMDD format * * @staticvar int Used to ensure all event popups have a unique id */ function print_entry_timebar ( $event, $date ) { global $ENTRY_SLOTS, $entrySlots, $eventinfo, $login, $PHP_SELF, $PUBLIC_ACCESS_FULLNAME, $slotValue, $totalHours, $totalSlots, $user, $width, $WORK_DAY_END_HOUR, $WORK_DAY_START_HOUR, $yardSlots, $yardWidth; static $key = 0; $insidespan = false; $ret = ''; if( access_is_enabled() ) { $temp = $event->getLogin(); $can_access = access_user_calendar ( 'view', $temp, '', $event->getCalType(), $event->getAccess() ); $time_only = access_user_calendar ( 'time', $temp ); } else { $can_access = CAN_DOALL; $time_only = 'N'; } $id = $event->getID(); $name = $event->getName(); $linkid = "pop$id-$key"; $key++; $day_start = $WORK_DAY_START_HOUR * 60; $day_end = $WORK_DAY_END_HOUR * 60; if ( $day_end <= $day_start ) $day_end = $day_start + 60; //Avoid exceptions. $time = date( 'His', $event->getDateTimeTS() ); $startminutes = time_to_minutes ( $time ); $endminutes = time_to_minutes( date( 'His', $event->getEndDateTimeTS() ) ); $duration = $event->getDuration(); if( $event->isAllDay() ) { // All day event. $ev_duration = $totalSlots; $start_padding = 0; } elseif( $event->isUntimed() ) $ev_duration = $start_padding = 0; else { // Must be timed. $start_padding = round ( ( $startminutes - $day_start ) / $slotValue ); if ( $start_padding < 0 ) $start_padding = 0; if ( $startminutes > $day_end || $endminutes < $day_start ) $ev_duration = 1; else if ( $duration > 0 ) { $ev_duration = intval ( $duration / $slotValue ); // Event starts before workday. if ( $startminutes < $day_start ) $ev_duration = $ev_duration - ( ( int )( $day_start - $startminutes ) / $slotValue ); // Event ends after workday. if ( $endminutes > $day_end ) $ev_duration = $ev_duration - ( ( int )( $endminutes - $day_end ) / $slotValue ); } } $end_padding = $totalSlots - $start_padding - $ev_duration + 1; // If event is past viewing area. if ( $start_padding >= $totalSlots ) { $ev_duration = 1; $start_padding = $totalSlots -1; } // Choose where to position the text (pos=0->before,pos=1->on,pos=2->after). if ( $ev_duration / $totalSlots >= .3 ) $pos = 1; elseif ( $end_padding / $totalSlots >= .3 ) $pos = 2; else $pos = 0; $ret .= ' <!-- ENTRY BAR --> <tr class="entrycont">' . ( $start_padding > 0 ? ' <td class="alignright" colspan="' . $start_padding . '">' : '' ); if ( $pos > 0 ) { if( ! $event->isUntimed() ) { $ret .= ( $start_padding > 0 ? ' </td>': '' ) . ' <td class="entry" colspan="' . $ev_duration . '">' . ( $pos > 1 ? ' </td> <td class="alignleft" colspan="' . $end_padding . '">' : '' ); } else // Untimed, just display text. $ret .= ' <td colspan="' . $totalSlots . '">'; } $tempClone = $event->getClone(); $tempPri = ( $event->getPriority() < 4 ); user_load_variables ( $event->getLogin (), 'temp' ); return $ret . ( $tempPri ? '<strong>' : '' ) // Make sure clones have parents URL date. . ( $can_access != 0 && $time_only != 'Y' ? ' <a class="entry" id="' . $linkid . '" href="view_entry.php?id=' . $id . '&date=' . ( $tempClone ? $tempClone: $date ) . ( strlen ( $user ) > 0 ? '&user=' . $user : '' ) . '">' : '' ) . '[' . $GLOBALS['tempfullname'] . '] ' . build_entry_label ( $event, 'eventinfo-' . $linkid, $can_access, ( $event->isAllDay() ? translate( 'All day event' ) : ( ! $event->isUntimed() ? display_time( $event->getDatetime() ) . ( $event->getDuration() > 0 ? ' - ' . display_time( $event->getEndDateTime(), 2 ) : '' ) : '' ) ), $time_only ) . ( $insidespan ? '</span>' : '' ) // end color span . '</a>' . ( $tempPri ? '</strong>' : '' ) // end font-weight span . '</td>' . ( $pos < 2 ? ( $pos < 1 ? ' <td class="entry" colspan="' . $ev_duration . '"> </td>' : '' ) . ( $end_padding > 1 ? ' <td class="alignleft" colspan="' . $end_padding . '"> </td>' : '' ) : '' ) // We'll close the table later. . ' </tr>'; } /** * Prints the header for the timebar. */ function print_header_timebar() { global $ENTRY_SLOTS, $entrySlots, $TIME_FORMAT, $totalHours, $totalSlots, $width, $WORK_DAY_END_HOUR, $WORK_DAY_START_HOUR, $yardSlots, $yardWidth; // sh ... eh // +------+----....----+------+ // | | | | // Print hours. $ret = ' <!-- TIMEBAR --> <table class="timebar"> <tr>'; for ( $i = $WORK_DAY_START_HOUR; $i < $WORK_DAY_END_HOUR; $i++ ) { $hour = ( $i < 13 || $TIME_FORMAT == 24 ? $i : $i % 12 ); if ( $hour == 0 ) $hour = 12; $ret .= ' <td colspan="' . "$yardSlots\">$hour" . '</td>'; } $ret .= ' </tr>' // Print yardstick. . ' <!-- YARDSTICK --> <tr class="yardstick">'; for ( $i = 0; $i < ( $totalSlots ); $i++ ) { $ret .= ' <td width="' . $yardWidth . '%"> </td>'; } // We'll close the table later. return $ret . ' </tr> <!-- /YARDSTICK -->'; } $date = ( empty ( $date ) ? date ( 'Ymd' ) : $date ); // Initialize date to first of current month. if ($view_type != 'S') $date = substr ( $date, 0, 6 ) . '01'; set_today ( $date ); // Week timebar. if ($view_type == 'S') { $next = mktime ( 0, 0, 0, $thismonth, $thisday + 7, $thisyear ); $prev = mktime ( 0, 0, 0, $thismonth, $thisday - 7, $thisyear ); $wkstart = get_weekday_before ( $thisyear, $thismonth, $thisday + 1 ); $wkend = $wkstart + 518400; $val_boucle = 7; } else { $next = mktime ( 0, 0, 0, $thismonth + 1, $thisday, $thisyear ); $prev = mktime ( 0, 0, 0, $thismonth - 1, $thisday, $thisyear ); $wkstart = mktime ( 0, 0, 0, $thismonth, 1, $thisyear ); $wkend = mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear ); $val_boucle = date ( 't', $wkstart ); } $nextyear = date ( 'Y', $next ); $nextmonth = date ( 'm', $next ); $nextday = date ( 'd', $next ); $nextdate = sprintf ( "%04d%02d%02d", $nextyear, $nextmonth, $nextday ); $prevyear = date ( 'Y', $prev ); $prevmonth = date ( 'm', $prev ); $prevday = date ( 'd', $prev ); $prevdate = sprintf ( "%04d%02d%02d", $prevyear, $prevmonth, $prevday ); // Get users in this view. $viewusers = view_get_user_list ( $id ); $viewusercnt = count ( $viewusers ); if ( $viewusercnt == 0 ) // This could happen if user_sees_only_his_groups = Y and // this user is not a member of any group assigned to this view. $error = translate( 'No users for this view.' ); $printerStr = generate_printer_friendly ( 'view_t.php' ); print_header( array( 'js/popups.js/true', 'js/dblclick_add.js/true' ) ); if ( ! empty ( $error ) ) { echo print_error( $error ) . print_trailer(); exit; } $nextStr = translate ( 'Next' ); $prevStr = translate ( 'Previous' ); echo ' <div style="width:99%;"> <a title="' . $prevStr . '" class="prev" href="view_t.php?id=' . $id . '&date=' . $prevdate . '"><img src="images/leftarrow.gif" alt="' . $prevStr . '" /></a> <a title="' . $nextStr . '" class="next" href="view_t.php?id=' . $id . '&date=' . $nextdate . '"><img src="images/rightarrow.gif" alt="' . $nextStr . '" /></a> <div class="title"> <span class="date">' . date_to_str ( date ( 'Ymd', $wkstart ), '', false ) . ' - ' . date_to_str ( date ( 'Ymd', $wkend ), '', false ) . '</span><br /> <span class="viewname">' . htmlspecialchars ( $view_name ) . '</span> </div> </div><br /><br />'; // The table has names across the top and dates for rows. Since we need to // spit out an entire row before we can move to the next date, we'll save up all // the HTML for each cell and then print it out when we're done.. // Additionally, we only want to put at most 6 users in one table since // any more than that doesn't really fit in the page. $e_save = $re_save = array(); for ( $i = 0; $i < $viewusercnt; $i++ ) { /* Pre-Load the repeated events for quckier access */ $repeated_events = read_repeated_events ( $viewusers[$i], $wkstart, $wkend, '' ); $re_save = array_merge ( $re_save, $repeated_events ); /* Pre-load the non-repeating events for quicker access subtracting ONE_WEEK to allow cross-day events to display. */ $events = read_events ( $viewusers[$i], $wkstart - 604800, $wkend ); $e_save = array_merge ( $e_save, $events ); } $events = $e_save; $repeated_events = $re_save; $timeBarHeader = print_header_timebar(); echo ' <table class="main">'; for ( $date = $wkstart; $date <= $wkend; $date += 86400 ) { $dateYmd = date ( 'Ymd', $date ); $is_weekend = is_weekend ( $date ); if ( $is_weekend && $DISPLAY_WEEKENDS == 'N' ) continue; echo '<tr' . ( $dateYmd == date ( 'Ymd', $today ) ? '> <th class="today"' : ( $is_weekend ? ' class="weekend"><th class="weekend"' : '><th class="row"' ) ); if ( $can_add ) echo " ondblclick=\"dblclick_add( '$dateYmd', '$login' )\"" . " title=\"" . translate ( 'Double-click on empty cell to add new entry' ) . "\""; echo '>'; echo weekday_name ( date ( 'w', $date ), $DISPLAY_LONG_DAYS ) . ' ' . date ( 'd', $date ) . '</th><td class="timebar">' . $timeBarHeader . print_date_entries_timebar ( $dateYmd, $login, true ) . '</table> </td> </tr>'; } $user = ''; // reset echo ' </table>' . ( empty( $eventinfo ) ? '' : $eventinfo ) . $printerStr . print_trailer(); ?> PK �]�\����؏ ؏ pref.phpnu �[��� <?php // $Id: pref.php,v 1.168.2.2 2013/01/24 21:15:09 cknudsen Exp $ include_once 'includes/init.php'; require_valid_referring_url (); // Force the CSS cache to clear by incrementing webcalendar_csscache cookie. $webcalendar_csscache = 1; if ( isset ( $_COOKIE['webcalendar_csscache'] ) ) { $webcalendar_csscache += $_COOKIE['webcalendar_csscache']; } SetCookie ( 'webcalendar_csscache', $webcalendar_csscache ); function save_pref( $prefs, $src) { global $my_theme, $prefuser; while ( list ( $key, $value ) = each ( $prefs ) ) { if ( $src == 'post' ) { $setting = substr ( $key, 5 ); $prefix = substr ( $key, 0, 5 ); if ( $prefix != 'pref_') continue; // Validate key name. Should start with "pref_" and not include // any unusual characters that might be an SQL injection attack. if ( ! preg_match ( '/pref_[A-Za-z0-9_]+$/', $key ) ) die_miserable_death ( str_replace ( 'XXX', $key, translate ( 'Invalid setting name XXX.' ) ) ); } else { $setting = $key; $prefix = 'pref_'; } //echo "Setting = $setting, key = $key, prefix = $prefix<br />\n"; if ( strlen ( $setting ) > 0 && $prefix == 'pref_' ) { if ( $setting == 'THEME' && $value != 'none' ) $my_theme = strtolower ( $value ); $sql = 'DELETE FROM webcal_user_pref WHERE cal_login = ? ' . 'AND cal_setting = ?'; dbi_execute ( $sql, [$prefuser, $setting] ); if ( strlen ( $value ) > 0 ) { $setting = strtoupper ( $setting ); $sql = 'INSERT INTO webcal_user_pref ' . '( cal_login, cal_setting, cal_value ) VALUES ' . '( ?, ?, ? )'; if ( ! dbi_execute ( $sql, [$prefuser, $setting, $value] ) ) { $error = 'Unable to update preference: ' . dbi_error() . '<br /><br /><span class="bold colon">SQL</span>' . $sql; break; } } } } } $currenttab = ''; $public = getGetValue ('public'); $user = getGetValue ('user'); $updating_public = false; load_global_settings(); if ( $is_admin && ! empty ( $public ) && $PUBLIC_ACCESS == 'Y' ) { $updating_public = true; load_user_preferences ( '__public__' ); $prefuser = '__public__'; } elseif ( ! empty ( $user ) && $user != $login && ($is_admin || $is_nonuser_admin)) { $prefuser = $user; load_user_preferences ( $user ); } else { $prefuser = $login; // Reload preferences so any css changes will take effect load_user_preferences(); } //get list of theme files from /themes directory $themes = []; $dir = 'themes/'; if (is_dir ($dir)) { if ($dh = opendir ($dir)) { while (($file = readdir ($dh)) !== false) { if ( strpos ( $file, '_pref.php' ) ) $themes[] = str_replace ( '_pref.php', '', $file ); } sort ( $themes ); closedir ($dh); } } // Check for malicious 'pref_THEME' passed in (LFI vulnerability) if ( ! empty ( $_POST ) && empty ( $error ) ) { $t = $_POST['pref_THEME']; if ( ! empty ( $t ) ) { $valid = false; foreach ( $themes as $theme ) { if ( $theme == $t ) $valid = true; } if ( ! $valid ) $error = translate('Invalid theme'); } } if ( ! empty ( $_POST ) && empty ( $error )) { $my_theme = ''; $currenttab = getPostValue ( 'currenttab' ); save_pref ( $_POST, 'post' ); if ( ! empty ( $my_theme ) ) { $theme = 'themes/'. $my_theme . '_pref.php'; include_once $theme; save_pref ( $webcal_theme, 'theme' ); } // Reload preferences load_user_preferences(); } if ($user != $login) $user = (($is_admin || $is_nonuser_admin) && $user) ? $user : $login; // Load categories only if editing our own calendar //if (!$user || $user == $login) load_user_categories(); load_user_categories(); // Reload preferences into $prefarray[]. // Get system settings first. $prefarray = []; $res = dbi_execute ( 'SELECT cal_setting, cal_value FROM webcal_config ' ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $prefarray[$row[0]] = $row[1]; } dbi_free_result ( $res ); } //get user settings $res = dbi_execute ( 'SELECT cal_setting, cal_value FROM webcal_user_pref WHERE cal_login = ?', [$prefuser] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $prefarray[$row[0]] = $row[1]; } dbi_free_result ( $res ); } //this will force $LANGUAGE to to the current value and eliminate having //to double click the 'SAVE' buton $translation_loaded = false; //move this include here to allow proper translation include 'includes/date_formats.php'; //get list of menu themes $menuthemes = []; $dir = 'includes/menu/themes/'; if ( is_dir ( $dir ) ) { if ( $dh = opendir ( $dir ) ) { while ( ( $file = readdir ( $dh ) ) !== false ) { if ( $file == '.' || $file == '..' || $file == 'CVS' || $file == 'default') continue; if ( is_dir ( $dir.$file ) ) $menuthemes[] = $file; } closedir ($dh); } } // Make sure global values passed to styles.php are for this user. // Makes the demo calendar accurate. $GLOBALS['BGCOLOR'] = $prefarray['BGCOLOR']; $GLOBALS['H2COLOR'] = $prefarray['H2COLOR']; $GLOBALS['MENU_THEME'] = $prefarray['MENU_THEME']; $GLOBALS['TODAYCELLBG'] = $prefarray['TODAYCELLBG']; $GLOBALS['TABLEBG'] = $prefarray['TABLEBG']; $GLOBALS['TABLEBG'] = $prefarray['TABLEBG']; $GLOBALS['THBG'] = $prefarray['THBG']; $GLOBALS['CELLBG'] = $prefarray['CELLBG']; $GLOBALS['WEEKENDBG'] = $prefarray['WEEKENDBG']; $GLOBALS['OTHERMONTHBG'] = $prefarray['OTHERMONTHBG']; $GLOBALS['FONTS'] = $prefarray['FONTS']; $GLOBALS['MYEVENTS'] = $prefarray['MYEVENTS']; //determine if we can set timezones, if not don't display any options $can_set_timezone = set_env ( 'TZ', $prefarray['TIMEZONE'] ); $dateYmd = date ( 'Ymd' ); $selected = ' selected="selected" '; $minutesStr = translate ( 'minutes' ); //allow css_cache to display public or NUC values @session_start(); $_SESSION['webcal_tmp_login'] = $prefuser; //Prh ... add user to edit_template to get/set correct template $openStr ="\"window.open( 'edit_template.php?type=%s&user=%s','cal_template','dependent,menubar,scrollbars,height=500,width=500,outerHeight=520,outerWidth=520' );\""; $currenttab = getPostValue ( 'currenttab', 'settings' ); $currenttab = ( ! empty ( $currenttab) ? $currenttab : 'settings' ); $BodyX = 'onload="altrows();showTab( \'' . $currenttab . '\' );"'; $INC = array ('js/visible.php', 'js/pref.php'); print_header($INC, '', $BodyX); ?> <h2><?php if ( $updating_public ) echo translate ($PUBLIC_ACCESS_FULLNAME) . ' '; etranslate ( 'Preferences' ); if ( $is_nonuser_admin || ( $is_admin && substr ( $prefuser, 0, 5 ) == '_NUC_' ) ) { nonuser_load_variables ( $user, 'nonuser' ); echo '<br /><strong>-- ' . translate ( 'Admin mode' ) . ': '.$nonuserfullname." --</strong>\n"; } $qryStr = ( ! empty ( $_SERVER['QUERY_STRING'] ) ? '?' . $_SERVER['QUERY_STRING'] : '' ); $formaction = substr ($self, strrpos($self, '/') + 1) . $qryStr; ?> <img src="images/help.gif" alt="<?php etranslate ( 'Help' )?>" class="help" onclick="window.open( 'help_pref.php', 'cal_help', 'dependent,menubar,scrollbars,height=400,width=400,innerHeight=420,outerWidth=420' );" /></h2> <form action="<?php echo htmlspecialchars($formaction) ?>" method="post" onsubmit="return valid_form( this );" name="prefform"> <input type="hidden" name="currenttab" id="currenttab" value="<?php echo $currenttab ?>" /> <?php if ($user) echo "<input type=\"hidden\" name=\"user\" value=\"$user\" />\n"; echo display_admin_link(); ?> <input type="submit" value="<?php etranslate ( 'Save Preferences' )?>" name="" /> <?php if ( $updating_public ) { ?> <input type="hidden" name="public" value="1" /> <?php } /*if ( $updating_public )*/ // If user is admin of a non-user cal, and non-user cal is "public" // (meaning it is a public calendar that requires no login), then allow // the current user to modify prefs for that nonuser cal if ( $is_admin && ! $updating_public ) { if ( empty ( $public ) && ! empty ( $PUBLIC_ACCESS ) && $PUBLIC_ACCESS == 'Y' ) { $public_option = '<option value="pref.php?public=1">' . translate( 'Public Access calendar' ) . "</option>\n"; } } if ( $NONUSER_ENABLED == 'Y' || $PUBLIC_ACCESS == 'Y' ) { if ( ( empty ( $user ) || $user == $login ) && ! $updating_public ) { $nulist = get_my_nonusers ( $login ); echo '<select onchange="location=this.options[this.selectedIndex].value;">' ."\n"; echo "<option $selected disabled=\"disabled\" value=\"\">" . translate ( 'Modify Non User Calendar Preferences') . "</option>\n"; if ( ! empty ( $public_option ) ) echo $public_option . "\n"; for ( $i = 0, $cnt = count ( $nulist ); $i < $cnt; $i++ ) { echo '<option value="pref.php?user='. $nulist[$i]['cal_login']. '">' . $nulist[$i]['cal_fullname'] . "</option>\n"; } echo "</select>\n"; } else { $linktext = translate ( 'Return to My Preferences' ); echo "<a title=\"$linktext\" class=\"nav\" href=\"pref.php\">« $linktext </a>"; } } ?> <br /><br /> <!-- TABS --> <div id="tabs"> <span class="tabfor" id="tab_settings"><a href="" onclick="return setTab( 'settings' );"><?php etranslate ( 'Settings' )?></a></span> <?php if ( $ALLOW_USER_THEMES == 'Y' || $is_admin ) { ?> <span class="tabbak" id="tab_themes"><a href="" onclick="return setTab( 'themes' );"><?php etranslate ( 'Themes' )?></a></span> <?php } if ( $SEND_EMAIL == 'Y' ) { ?> <span class="tabbak" id="tab_email"><a href="" onclick="return setTab( 'email' );"><?php etranslate ( 'Email' )?></a></span> <?php } ?> <span class="tabbak" id="tab_boss"><a href="" onclick="return setTab( 'boss' );"><?php etranslate ( 'When I am the boss' )?></a></span> <?php if ( $PUBLISH_ENABLED == 'Y' || $RSS_ENABLED == 'Y' ) { ?> <span class="tabbak" id="tab_subscribe"><a href="" onclick="return setTab( 'subscribe' );"><?php etranslate ( 'Subscribe/Publish' )?></a></span> <?php } if ( $ALLOW_USER_HEADER == 'Y' && ( $CUSTOM_SCRIPT == 'Y' || $CUSTOM_HEADER == 'Y' || $CUSTOM_TRAILER == 'Y' ) ) { ?> <span class="tabbak" id="tab_header"><a href="" onclick="return setTab( 'header' );"><?php etranslate ( 'Custom Scripts' )?></a></span> <?php } if ( $ALLOW_COLOR_CUSTOMIZATION == 'Y' ) { ?> <span class="tabbak" id="tab_colors" title="<?php etooltip ( 'colors-help' )?>"><a href="" onclick="return setTab( 'colors' );"><?php etranslate ( 'Colors' )?></a></span> <?php } ?> </div> <!-- TABS BODY --> <div id="tabscontent" style="width: 98%;"> <!-- DETAILS --> <div id="tabscontent_settings"> <fieldset> <legend><?php etranslate ('Language')?></legend> <table cellspacing="1" cellpadding="2"> <tr><td class="tooltipselect" title="<?php etooltip ("language-help");?>"> <label for="pref_lang" class="colon"><?php etranslate ( 'Language' )?></label></td><td> <select name="pref_LANGUAGE" id="pref_lang"> <?php define_languages(); //load the language list reset ( $languages ); while ( list ( $key, $val ) = each ( $languages ) ) { // Don't allow users to select browser-defined. We want them to pick // a language so that when we send reminders (done without the benefit // of a browser-preferred language), we'll know which language to use. // DO let them select browser-defined for the public user or NUC. if ( $key != 'Browser-defined' || $updating_public || $is_admin || $is_nonuser_admin ) { echo '<option value="' . $val . '"'; if ( $val == $prefarray['LANGUAGE'] ) echo $selected; echo '>' . $key . "</option>\n"; } } ?> </select> <br /> <?php echo str_replace( 'XXX', translate( get_browser_language( true ) ), translate( 'Your browser default language is XXX.' ) ); ?> </td></tr> </table> </fieldset> <fieldset> <legend><?php etranslate ('Date and Time')?></legend> <table cellspacing="1" cellpadding="2"> <?php if ( $can_set_timezone == true ) { ?> <tr><td class="tooltipselect" title="<?php etooltip ( 'tz-help' )?>"> <label for="pref_TIMEZONE" class="colon"><?php etranslate ( 'Timezone Selection' )?></label></td><td> <?php if ( empty ( $prefarray['TIMEZONE'] ) ) $prefarray['TIMEZONE'] = $SERVER_TIMEZONE; echo print_timezone_select_html ( 'pref_', $prefarray['TIMEZONE']); ?> </td></tr> <?php } //end $can_set_timezone ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'date-format-help' );?>"> <?php etranslate ( 'Date format' )?></td><td> <select name="pref_DATE_FORMAT"> <?php for ( $i = 0, $cnt = count ( $datestyles ); $i < $cnt; $i += 2 ) { echo '<option value="' . $datestyles[$i] . '"'; if ( $prefarray['DATE_FORMAT'] == $datestyles[$i] ) echo $selected; echo '>' . $datestyles[$i + 1] . "</option>\n"; } ?> </select> <?php echo date_to_str ( $dateYmd, $DATE_FORMAT, false, false );?> <br /> <select name="pref_DATE_FORMAT_MY"> <?php for ( $i = 0, $cnt = count ( $datestyles_my ); $i < $cnt; $i += 2 ) { echo '<option value="' . $datestyles_my[$i] . '"'; if ( $prefarray['DATE_FORMAT_MY'] == $datestyles_my[$i] ) echo $selected; echo '>' . $datestyles_my[$i + 1] . "</option>\n"; } ?> </select> <?php echo date_to_str ( $dateYmd, $DATE_FORMAT_MY, false, false );?> <br /> <select name="pref_DATE_FORMAT_MD"> <?php for ( $i = 0, $cnt = count ( $datestyles_md ); $i < $cnt; $i += 2 ) { echo '<option value="' . $datestyles_md[$i] . '"'; if ( $prefarray['DATE_FORMAT_MD'] == $datestyles_md[$i] ) echo $selected; echo '>' . $datestyles_md[$i + 1] . "</option>\n"; } ?> </select> <?php echo date_to_str ( $dateYmd, $DATE_FORMAT_MD, false, false );?> <br /> <select name="pref_DATE_FORMAT_TASK"> <?php for ( $i = 0, $cnt = count ( $datestyles_task ); $i < $cnt; $i += 2 ) { echo '<option value="' . $datestyles_task[$i] . '"'; if ( $prefarray['DATE_FORMAT_TASK'] == $datestyles_task[$i] ) echo $selected; echo '>' . $datestyles_task[$i + 1] . "</option>\n"; } ?> </select> <?php echo translate ( 'Small Task Date' ) . ' ' . date_to_str( $dateYmd, $DATE_FORMAT_TASK, false, false );?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'time-format-help' )?>"> <?php etranslate ( 'Time format' )?></td><td> <?php echo print_radio ( 'TIME_FORMAT', ['12'=>translate ( '12 hour' ), '24'=>translate ( '24 hour' )] ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-week-starts-on' )?>"> <?php etranslate ( 'Week starts on' )?></td><td> <select name="pref_WEEK_START" id="pref_WEEK_START"> <?php for ( $i = 0; $i < 7; $i++ ) { echo "<option value=\"$i\"" . ( $i == $prefarray['WEEK_START'] ? $selected : '' ) . '>' . weekday_name ( $i ) . "</option>\n"; } ?> </select> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-weekend-starts-on' )?>"> <?php etranslate ( 'Weekend starts on' )?></td><td> <select name="pref_WEEKEND_START" id="pref_WEEKEND_START"> <?php for ( $i = -1; $i < 6; $i++ ) { $j = ( $i == -1 ? 6 : $i ); //make sure start with Saturday echo "<option value=\"$j\"" . ( $j == $prefarray['WEEKEND_START'] ? $selected : '' ) . '>' . weekday_name ( $j ) . "</option>\n"; } ?> </select> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'work-hours-help' )?>"> <?php etranslate ( 'Work hours' )?></td><td> <label for="pref_starthr"><?php etranslate ( 'From' )?></label> <select name="pref_WORK_DAY_START_HOUR" id="pref_starthr"> <?php for ( $i = 0; $i < 24; $i++ ) { echo "<option value=\"$i\"" . ( $i == $prefarray['WORK_DAY_START_HOUR'] ? $selected :'' ) . ">" . display_time ( $i * 10000, 1 ) . "</option>\n"; } ?> </select> <label for="pref_endhr"><?php etranslate ( 'to' )?></label> <select name="pref_WORK_DAY_END_HOUR" id="pref_endhr"> <?php for ( $i = 0; $i < 24; $i++ ) { echo "<option value=\"$i\"" . ( $i == $prefarray['WORK_DAY_END_HOUR'] ? $selected : '' ) . ">" . display_time ( $i * 10000, 1 ) . "</option>\n"; } ?> </select> </td></tr> </table> </fieldset> <fieldset> <legend><?php etranslate ('Appearance')?></legend> <table cellspacing="1" cellpadding="2"> <tr><td class="tooltip colon" title="<?php etooltip ( 'preferred-view-help' );?>"><?php etranslate ( 'Preferred view' )?></td><td> <select name="pref_STARTVIEW"> <?php // For backwards compatibility. We used to store without the .php extension if ( $prefarray['STARTVIEW'] == 'month' || $prefarray['STARTVIEW'] == 'day' || $prefarray['STARTVIEW'] == 'week' || $prefarray['STARTVIEW'] == 'year' ) $prefarray['STARTVIEW'] .= '.php'; $choices = $choices_text = []; if ( access_can_access_function ( ACCESS_DAY, $user ) ) { $choices[] = 'day.php'; $choices_text[] = translate ( 'Day' ); } if ( access_can_access_function ( ACCESS_WEEK, $user ) ) { $choices[] = 'week.php'; $choices_text[] = translate ( 'Week' ); } if ( access_can_access_function ( ACCESS_MONTH, $user ) ) { $choices[] = 'month.php'; $choices_text[] = translate ( 'Month' ); } if ( access_can_access_function ( ACCESS_YEAR, $user ) ) { $choices[] = 'year.php'; $choices_text[] = translate ( 'Year' ); } // combo.php contains day, week, month and agenda views.. $choices[] = 'combo.php'; $choices_text[] = translate ( 'Multiview' ); for ( $i = 0, $cnt = count ( $choices ); $i < $cnt; $i++ ) { echo '<option value="' . $choices[$i] . '" '; if ( $prefarray['STARTVIEW'] == $choices[$i] ) echo $selected; echo ' >' . htmlspecialchars ( $choices_text[$i] ) . "</option>\n"; } // Allow user to select a view also for ( $i = 0, $cnt = count ( $views ); $i < $cnt; $i++ ) { if ( $views[$i]['cal_owner'] != $user && $views[$i]['cal_is_global'] != 'Y' ) continue; $xurl = $views[$i]['url']; echo '<option value="'; echo $xurl . '" '; $xurl_strip = str_replace ( '&', '&', $xurl ); if ( $prefarray['STARTVIEW'] == $xurl_strip ) echo $selected; echo '>' . htmlspecialchars ( $views[$i]['cal_name'] ) . "</option>\n"; } ?> </select> </td></tr> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'fonts-help' )?>"> <label for="pref_font"><?php etranslate ( 'Fonts')?></label></td><td> <input type="text" size="40" name="pref_FONTS" id="pref_font" value="<?php echo htmlspecialchars ( $prefarray['FONTS'] );?>" /> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-sm_month-help' );?>"> <?php etranslate ( 'Display small months' )?></td><td> <?php echo print_radio ( 'DISPLAY_SM_MONTH' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-weekends-help' );?>"> <?php etranslate ( 'Display weekends' )?></td><td> <?php echo print_radio ( 'DISPLAY_WEEKENDS' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-long-daynames-help' );?>"> <?php etranslate ( 'Display long day names' )?></td><td> <?php echo print_radio ( 'DISPLAY_LONG_DAYS' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ("display-minutes-help")?>"> <?php etranslate ( 'Display 00 minutes always' )?></td><td> <?php echo print_radio ( 'DISPLAY_MINUTES' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ("display-end-times-help")?>"> <?php etranslate ( 'Display end times on calendars' )?></td><td> <?php echo print_radio ( 'DISPLAY_END_TIMES' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-alldays-help' );?>"> <?php etranslate ( 'Display all days in month view' )?></td><td> <?php echo print_radio ( 'DISPLAY_ALL_DAYS_IN_MONTH' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-week-number-help' )?>"> <?php etranslate ( 'Display week number' )?></td><td> <?php echo print_radio ( 'DISPLAY_WEEKNUMBER' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-tasks-help' )?>"> <?php etranslate ( 'Display small task list' )?></td><td> <?php echo print_radio ( 'DISPLAY_TASKS' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-tasks-in-grid-help' )?>"> <?php etranslate ( 'Display tasks in Calendars' )?></td><td> <?php echo print_radio ( 'DISPLAY_TASKS_IN_GRID' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'lunar-help' )?>"> <?php etranslate ( 'Display Lunar Phases in month view' )?></td><td> <?php echo print_radio ( 'DISPLAY_MOON_PHASES' ) ?> </td></tr> </table> </fieldset> <fieldset> <legend><?php etranslate ('Events')?></legend> <table cellspacing="1" cellpadding="2"> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-unapproved-help' );?>"> <?php etranslate ( 'Display unapproved' )?></td><td> <?php echo print_radio ( 'DISPLAY_UNAPPROVED' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'timed-evt-len-help' );?>"> <?php etranslate ( 'Specify timed event length by' )?></td><td> <?php echo print_radio ( 'TIMED_EVT_LEN', ['D'=>translate ( 'Duration' ), 'E'=>translate ( 'End Time' )] ) ?> </td></tr> <?php if ( ! empty ( $categories ) ) { ?> <tr><td> <label for="pref_cat" class="colon"><?php etranslate ( 'Default Category' )?></label></td><td> <select name="pref_CATEGORY_VIEW" id="pref_cat"> <?php if ( ! empty ( $categories ) ) { foreach ( $categories as $K => $V ) { echo "<option value=\"$K\""; if ( ! empty ( $prefarray['CATEGORY_VIEW'] ) && $prefarray['CATEGORY_VIEW'] == $K ) echo $selected; echo ">{" . htmlentities ( $V['cat_name'] ) . "}</option>\n"; } } ?> </select> </td></tr> <?php } //end if (! empty ($categories ) ) ?> <tr><td class="tooltip colon" title="<?php etooltip ( 'crossday-help' )?>"> <?php etranslate ( 'Disable Cross-Day Events' )?></td><td> <?php echo print_radio ( 'DISABLE_CROSSDAY_EVENTS' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display-desc-print-day-help' );?>"> <?php etranslate ( 'Display description in printer day view' )?></td><td> <?php echo print_radio ( 'DISPLAY_DESC_PRINT_DAY' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'entry-interval-help' )?>"> <?php etranslate ( 'Entry interval' )?></td><td> <select name="pref_ENTRY_SLOTS"> <option value="24" <?php if ( $prefarray['ENTRY_SLOTS'] == "24" ) echo $selected?>>1 <?php etranslate ( 'hour' )?></option> <option value="48" <?php if ( $prefarray['ENTRY_SLOTS'] == "48" ) echo $selected?>>30 <?php echo $minutesStr ?></option> <option value="72" <?php if ( $prefarray['ENTRY_SLOTS'] == "72" ) echo $selected?>>20 <?php echo $minutesStr ?></option> <option value="96" <?php if ( $prefarray['ENTRY_SLOTS'] == "96" ) echo $selected?>>15 <?php echo $minutesStr ?></option> <option value="144" <?php if ( $prefarray['ENTRY_SLOTS'] == "144" ) echo $selected?>>10 <?php echo $minutesStr ?></option> <option value="288" <?php if ( $prefarray['ENTRY_SLOTS'] == "288" ) echo $selected?>>5 <?php echo $minutesStr ?></option> <option value="1440" <?php if ( $prefarray['ENTRY_SLOTS'] == "1440" ) echo $selected?>>1 <?php etranslate ( 'minute' )?></option> </select> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'time-interval-help' )?>"> <?php etranslate ( 'Time interval' )?></td><td> <select name="pref_TIME_SLOTS"> <option value="24" <?php if ( $prefarray['TIME_SLOTS'] == "24" ) echo $selected?>>1 <?php etranslate ( 'hour' )?></option> <option value="48" <?php if ( $prefarray['TIME_SLOTS'] == "48" ) echo $selected?>>30 <?php echo $minutesStr ?></option> <option value="72" <?php if ( $prefarray['TIME_SLOTS'] == "72" ) echo $selected?>>20 <?php echo $minutesStr ?></option> <option value="96" <?php if ( $prefarray['TIME_SLOTS'] == "96" ) echo $selected?>>15 <?php echo $minutesStr ?></option> <option value="144" <?php if ( $prefarray['TIME_SLOTS'] == "144" ) echo $selected?>>10 <?php echo $minutesStr ?></option> </select> </td></tr> </table> </fieldset> <fieldset> <legend><?php etranslate ('Miscellaneous')?></legend> <table cellspacing="1" cellpadding="2"> <tr><td class="tooltip colon" title="<?php etooltip ( 'auto-refresh-help' );?>"> <?php etranslate ( 'Auto-refresh calendars' )?></td><td> <?php echo print_radio ( 'AUTO_REFRESH' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'auto-refresh-time-help' );?>"> <?php etranslate ( 'Auto-refresh time' )?></td><td> <input type="text" name="pref_AUTO_REFRESH_TIME" size="4" value="<?php echo ( empty ( $prefarray['AUTO_REFRESH_TIME'] ) ? 0 : $prefarray['AUTO_REFRESH_TIME'] ); ?>" /> <?php etranslate ( 'minutes' )?> </td></tr> </table> </fieldset> </div> <!-- END SETTINGS --> <?php if ( $ALLOW_USER_THEMES == 'Y' || $is_admin ) { ?> <div id="tabscontent_themes"> <table cellspacing="1" cellpadding="2" width="35%"> <tr><td class="tooltip" title="<?php etooltip ( 'theme-reload-help' );?>"colspan="3"><?php etranslate ( 'Page may need to be reloaded for new Theme to take effect' )?></td></tr> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'themes-help' );?>"> <label for="pref_THEME"><?php etranslate ( 'Themes' )?></label></td><td> <select name="pref_THEME" id="pref_THEME"> <?php echo "<option value=\"none\" disabled=\"disabled\" $selected>" . translate ( 'AVAILABLE THEMES' ) . "</option>\n"; //always use 'none' as default so we don't overwrite manual settings // echo '<option value="none"' . $selected . translate ( 'None' ) . "</option>\n"; foreach ( $themes as $theme ) { echo '<option value="' . $theme . '">' . $theme . "</option>\n"; } ?> </select></td><td> <input type="button" name="preview" value="<?php etranslate ( 'Preview' ) ?>" onclick="return showPreview()" /> </td></tr> <?php if ( $MENU_ENABLED == 'Y' ) { ?> <tr><td class="tooltip colon" title="<?php etooltip ( 'menu-themes-help' );?>"> <label for="pref_MENU_THEME"><?php etranslate ( 'Menu theme' )?></label></td><td> <select name="pref_MENU_THEME" id="pref_MENU_THEME"> <?php echo '<option value="default" ' . ($prefarray['MENU_THEME'] == 'default' ? $selected : '' ) . ">default</option>\n"; foreach ( $menuthemes as $menutheme ) { echo '<option value="' . $menutheme . '"'; if ($prefarray['MENU_THEME'] == $menutheme ) echo $selected; echo '>' . $menutheme . "</option>\n"; } ?> </select> </td></tr> <?php } //end Menu enabled test ?> </table> </div> <!-- END THEMES --> <?php } if ( ! $updating_public ) { if ( $SEND_EMAIL == 'Y' ) { ?> <div id="tabscontent_email"> <table cellspacing="1" cellpadding="2"> <tr><td class="tooltip"> <tr><td class="tooltip colon" title="<?php etooltip('email-format');?>"> <?php etranslate ( 'Email format preference' )?></td><td> <?php echo print_radio ( 'EMAIL_HTML', ['Y'=> translate ( 'HTML' ), 'N'=>translate ( 'Plain Text' )] ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip('email-include-ics');?>"> <?php etranslate ( 'Include iCalendar attachments' )?></td><td> <?php echo print_radio ( 'EMAIL_ATTACH_ICS', '', '', 0 ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip('email-event-reminders-help');?>"> <?php etranslate ( 'Event reminders' )?></td><td> <?php echo print_radio ( 'EMAIL_REMINDER' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip('email-event-added');?>"> <?php etranslate ( 'Events added to my calendar' )?></td><td> <?php echo print_radio ( 'EMAIL_EVENT_ADDED' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip('email-event-updated');?>"> <?php etranslate ( 'Events updated on my calendar' )?></td><td> <?php echo print_radio ( 'EMAIL_EVENT_UPDATED' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip('email-event-deleted');?>"> <?php etranslate ( 'Events removed from my calendar' )?></td><td> <?php echo print_radio ( 'EMAIL_EVENT_DELETED' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip('email-event-rejected');?>"> <?php etranslate ( 'Event rejected by participant' )?></td><td> <?php echo print_radio ( 'EMAIL_EVENT_REJECTED' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip('email-event-create');?>"> <?php etranslate ( 'Event that I create' )?></td><td> <?php echo print_radio ( 'EMAIL_EVENT_CREATE' ) ?> </td></tr> </table> </div> <!-- END EMAIL --> <?php } ?> <div id="tabscontent_boss"> <table cellspacing="1" cellpadding="2"> <?php if ( $SEND_EMAIL == 'Y' ) { ?> <tr><td class="tooltip colon"><?php etranslate ( 'Email me event notification' )?></td><td> <?php echo print_radio ( 'EMAIL_ASSISTANT_EVENTS' ) ?> </td></tr> <?php } //end email ?> <tr><td class="tooltip colon"><?php etranslate ( 'I want to approve events' )?></td><td> <?php echo print_radio ( 'APPROVE_ASSISTANT_EVENT' ) ?> </td></tr> <tr><td class="tooltip colon" title="<?php etooltip ( 'display_byproxy-help' )?>"><?php etranslate ( 'Display if created by Assistant' )?></td><td> <?php echo print_radio ( 'DISPLAY_CREATED_BYPROXY' ) ?> </td></tr> </table> </div> <!-- END BOSS --> <?php } /* if ( ! $updating_public ) */ ?> <div id="tabscontent_subscribe"> <table cellspacing="1" cellpadding="2"> <?php if ( $PUBLISH_ENABLED == 'Y' || $RSS_ENABLED == 'Y') { ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'allow-view-subscriptions-help' )?>"><?php etranslate ( 'Allow remote viewing of' ); $publish_access = ( empty( $prefarray['USER_REMOTE_ACCESS'] ) ? 0 : $prefarray['USER_REMOTE_ACCESS'] ); ?></td><td> <select name="pref_USER_REMOTE_ACCESS"> <option value="0" <?php echo ( $publish_access == '0' ? $selected : '' ) . ' >' . translate ( 'Public' ) . ' ' . translate ( 'entries' )?></option> <option value="1" <?php echo ( $publish_access == '1' ? $selected : '' ) . ' >' . translate ( 'Public' ) . ' & ' . translate ( 'Confidential' ) . ' ' . translate ( 'entries' )?></option> <option value="2" <?php echo ( $publish_access == '2' ? $selected : '' ) . ' >' . translate ( 'All' ) . ' ' . translate ( 'entries' )?></option> </select> </td></tr> <?php } if ( $PUBLISH_ENABLED == 'Y' ) { ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'allow-remote-subscriptions-help' )?>"><?php etranslate ( 'Allow remote subscriptions' )?></td><td> <?php echo print_radio ( 'USER_PUBLISH_ENABLED' ) ?> </td></tr> <?php if ( ! empty ( $SERVER_URL ) ) { ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'remote-subscriptions-url-help' )?>"> <?php etranslate ( 'URL' )?></td> <td> <?php echo htmlspecialchars ( $SERVER_URL ) . 'publish.php/' . ( $updating_public ? '__public__' : $user ) . '.ics'; echo "<br />\n"; echo htmlspecialchars ( $SERVER_URL ) . 'publish.php?user=' . ( $updating_public ? '__public__' : $user ); ?></td></tr> <?php } /* $SERVER_URL */ ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'allow-remote-publishing-help' )?>"><?php etranslate ( 'Allow remote publishing' )?></td> <td> <?php echo print_radio ( 'USER_PUBLISH_RW_ENABLED' ) ?> </td></tr> <?php if ( ! empty ( $SERVER_URL ) ) { ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'remote-publishing-url-help' )?>"> <?php etranslate ( 'URL' )?></td> <td> <?php echo htmlspecialchars ( $SERVER_URL ) . 'icalclient.php'; ?></td></tr> <?php } /* $SERVER_URL */ } /* $PUBLISH_ENABLED */ if ( $RSS_ENABLED == 'Y' ) { ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'rss-enabled-help' )?>"><?php etranslate ( 'Enable RSS feed' )?></td> <td> <?php echo print_radio ( 'USER_RSS_ENABLED' ) ?> </td></tr> <?php if ( ! empty ( $SERVER_URL ) ) { ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'rss-feed-url-help' )?>"> <?php etranslate ( 'URL' )?></td> <td> <?php echo htmlspecialchars ( $SERVER_URL ) . 'rss.php?user=' . ( $updating_public ? '__public__' : $user ); ?></td></tr> <?php } /* $SERVER_URL */ } /* $RSS_ENABLED */ ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'freebusy-enabled-help' )?>"><?php etranslate ( 'Enable FreeBusy publishing' )?></td> <td> <?php echo print_radio ( 'FREEBUSY_ENABLED' ) ?> </td></tr> <?php if ( ! empty ( $SERVER_URL ) ) { ?> <tr><td class="tooltipselect colon" title="<?php etooltip ( 'freebusy-url-help' )?>"> <?php etranslate ( 'URL' )?></td> <td> <?php echo htmlspecialchars ( $SERVER_URL ) . 'freebusy.php/' . ( $updating_public ? '__public__' : $user ) . '.ifb'; echo "<br />\n"; echo htmlspecialchars ( $SERVER_URL ) . 'freebusy.php?user=' . ( $updating_public ? '__public__' : $user ); ?></td></tr> <?php } /* $SERVER_URL */ ?> </table> </div> <!-- END SUBSCRIBE --> <?php if ( $ALLOW_USER_HEADER == 'Y' ) { ?> <div id="tabscontent_header"> <table cellspacing="1" cellpadding="2"> <?php if ( $CUSTOM_SCRIPT == 'Y' ) { ?> <tr><td class="tooltip colon" title="<?php etooltip ( 'custom-script-help' );?>"> <?php etranslate ( 'Custom script/stylesheet' )?></td><td> <input type="button" value="<?php etranslate ( 'Edit' );?>..." onclick=<?php printf ( $openStr, 'S',$prefuser ) ?> name="" /> </td></tr> <?php } if ( $CUSTOM_HEADER == 'Y' ) { ?> <tr><td class="tooltip colon" title="<?php etooltip ( 'custom-header-help' );?>"> <?php etranslate ( 'Custom header' )?></td><td> <input type="button" value="<?php etranslate ( 'Edit' );?>..." onclick=<?php printf ( $openStr, 'H',$prefuser ) ?> name="" /> </td></tr> <?php } if ( $CUSTOM_TRAILER == 'Y' ) { ?> <tr><td class="tooltip colon" title="<?php etooltip ( 'custom-trailer-help' );?>"> <?php etranslate ( 'Custom trailer' )?></td><td> <input type="button" value="<?php etranslate ( 'Edit' );?>..." onclick=<?php printf ( $openStr, 'T',$prefuser ) ?> name="" /> </td></tr> <?php } ?> </table> </div> <!-- END HEADER --> <?php } // if $ALLOW_USER_HEADER ?> <!-- BEGIN COLORS --> <?php if ( $ALLOW_COLOR_CUSTOMIZATION == 'Y' ) { ?> <div id="tabscontent_colors"> <table> <tr class="ignore"><td class="aligntop"> <table> <tr><td> <?php echo print_color_input_html ( 'BGCOLOR', translate ( 'Document background' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'H2COLOR', translate ( 'Document title' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'TEXTCOLOR', translate ( 'Document text' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'MYEVENTS', translate ( 'My event text' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'TABLEBG', translate ( 'Table grid color' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'THBG', translate ( 'Table header background' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'THFG', translate ( 'Table header text' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'CELLBG', translate ( 'Table cell background' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'TODAYCELLBG', translate ( 'Table cell background for current day' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'HASEVENTSBG', translate ( 'Table cell background for days with events' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'WEEKENDBG', translate ( 'Table cell background for weekends' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'OTHERMONTHBG', translate ( 'Table cell background for other month' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'WEEKNUMBER', translate ( 'Table cell background for other month' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'POPUP_BG', translate ( 'Event popup background' ) ) ?> </td></tr> <tr><td> <?php echo print_color_input_html ( 'POPUP_FG', translate ( 'Event popup text' ) ) ?> </td></tr> </table> </td><td class="aligncenter aligntop"> <br /> <!-- BEGIN EXAMPLE MONTH --> <table style="width:90%; background-color:<?php echo $BGCOLOR?>"><tr> <td width="1%" rowspan="3"> </td> <td style="text-align:center; color:<?php echo $H2COLOR?>; font-weight:bold;"><?php echo date_to_str ( $dateYmd, $DATE_FORMAT_MY, false );?></td> <td width="1%" rowspan="3"> </td></tr> <tr><td bgcolor="<?php echo $BGCOLOR?>"> <?php set_today( $dateYmd ); echo display_month ( date ( 'm' ), date( 'Y' ), true ); ?> </td></tr> <tr><td> </td></tr> </table> <!-- END EXAMPLE MONTH --> </td></tr></table> </div> <!-- END COLORS --> <?php } // if $ALLOW_COLOR_CUSTOMIZATION ?> </div> <!-- END TABS --> <br /><br /> <div> <input type="submit" value="<?php etranslate ( 'Save Preferences' )?>" name="" /> <br /><br /> </div> </form> <?php echo print_trailer(); ?> PK �]�\��� � assistant_edit.phpnu �[��� <?php include_once 'includes/init.php'; if ( empty ( $login ) || $login == '__public__' ) { // Do not allow public access. do_redirect ( empty ( $STARTVIEW ) ? 'month.php' : "$STARTVIEW" ); exit; } if ( $user != $login ) $user = ( ( $is_admin || $is_nonuser_admin ) && $user ) ? $user : $login; print_header( '', ! $GROUPS_ENABLED == 'Y' ? '' : '<script type="text/javascript" src="includes/js/assistant_edit.js"></script>' ); echo ' <form action="assistant_edit_handler.php" method="post" ' . 'name="assistanteditform">' . ( $user ? ' <input type="hidden" name="user" value="' . $user . '" />' : '' ) . ' <h2>'; $assistStr = translate ( 'Assistants' ); if ( $is_nonuser_admin ) { nonuser_load_variables ( $user, 'nonuser' ); echo $nonuserfullname . ' ' . $assistStr . '<br /><span class="dblHyphens"> ' . translate ( 'Admin mode' ) . '</span>'; } else echo translate ( 'Your assistants' ); echo '</h2> ' . display_admin_link() . ' <table> <tr> <td class="aligntop colon"><label for="users">' . $assistStr . '</label></td> <td> <select name="users[]" id="users" size="10" multiple="multiple">'; // Get list of all users. $users = get_my_users(); // Get list of users for this view. $res = dbi_execute ( 'SELECT cal_boss, cal_assistant FROM webcal_asst WHERE cal_boss = ?', [$user] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $assistantuser[$row[1]] = 1; } dbi_free_result ( $res ); } for ( $i = 0, $cnt = count ( $users ); $i < $cnt; $i++ ) { $u = $users[$i]['cal_login']; if ( $u == $login || $u == '__public__' ) continue; echo ' <option value="' . $u . '"' . ( ! empty ( $assistantuser[$u] ) ? ' selected="selected"' : '' ) . '>' . $users[$i]['cal_fullname'] . '</option>'; } echo ' </select>' . ( $GROUPS_ENABLED == 'Y' ? ' <input type="button" onclick="selectUsers()" value="' . translate ( 'Select' ) . '..." />' : '' ) . ' </td> </tr> <tr> <td colspan="2" class="aligncenter"><br /><input type="submit" ' . 'name="action" value="' . translate ( 'Save' ) . '" /> </td> </tr> </table> </form> ' . print_trailer (); ?> PK �]�\�O�� � help_pref.phpnu �[��� <?php include_once 'includes/init.php'; include_once 'includes/help_list.php'; print_header ( '', '', '', true ); echo $helpListStr . ' <h2>' . translate ( 'Help' ) . ': ' . translate ( 'Preferences' ) . '</h2> <h3>' . translate ( 'Settings' ) . '</h3> <div class="helpbody"> <div>'; $tmp_arr = [ translate ( 'Auto-refresh calendars' ) => translate ( 'auto-refresh-help' ), translate ( 'Auto-refresh time' ) => translate ( 'auto-refresh-time-help' ), translate ( 'Date format' ) => translate ( 'date-format-help' ), translate ( 'Default Category' ) => translate ( 'default-category-help' ), translate ( 'Display description in printer day view' ) => translate ( 'display-desc-print-day-help' ), translate ( 'Display unapproved' ) => translate ( 'display-unapproved-help' ), translate ( 'Display week number' ) => translate ( 'display-week-number-help' ), translate ( 'Display weekends in week view' ) => translate ( 'display-weekends-help' ), translate ( 'Fonts' ) => translate ( 'fonts-help' ), translate ( 'Language' ) => translate ( 'language-help' ), translate ( 'Preferred view' ) => translate ( 'preferred-view-help' ), translate ( 'Specify timed event length by' ) => translate ( 'timed-evt-len-help' ), translate ( 'Time format' ) => translate ( 'time-format-help' ), translate ( 'Time interval' ) => translate ( 'time-interval-help' ), translate ( 'Timezone Offset' ) => translate ( 'tz-help' ), translate ( 'Week starts on' ) => translate ( 'display-week-starts-on' ), translate ( 'Work hours' ) => translate ( 'work-hours-help' )]; list_help ( $tmp_arr ); echo ' </div> <h3>' . translate ( 'Email' ) . '</h3> <div>'; $tmp_arr = [ translate ( 'Event rejected by participant' ) => translate ( 'email-event-rejected' ), translate ( 'Event reminders' ) => translate ( 'email-event-reminders-help' ), translate ( 'Events added to my calendar' ) => translate ( 'email-event-added' ), translate ( 'Events removed from my calendar' ) => translate ( 'email-event-deleted' ), translate ( 'Events updated on my calendar' ) => translate ( 'email-event-updated' )]; list_help ( $tmp_arr ); echo ' </div> <h3>' . translate ( 'When I am the boss' ) . '</h3> <div>'; $tmp_arr = [ translate ( 'Email me event notification' ) => translate ( 'email-boss-notifications-help' ), translate ( 'I want to approve events' ) => translate ( 'boss-approve-event-help' )]; list_help ( $tmp_arr ); echo ' </div>'; if ( $PUBLISH_ENABLED == 'Y' ) { echo ' <h3>' . translate ( 'Subscribe/Publish' ) . '</h3> <div>'; $tmp_arr = [ translate ( 'Allow remote publishing' ) => translate ( 'allow-remote-publishing-help' ), translate ( 'URL' ) => translate ( 'remote-publishing-url-help' ), translate ( 'Allow remote subscriptions' ) => translate ( 'allow-remote-subscriptions-help' ), translate ( 'URL' ) => translate ( 'remote-subscriptions-url-help' ), translate ( 'Enable FreeBusy publishing' ) => translate ( 'freebusy-enabled-help' ), translate ( 'URL' ) => translate ( 'freebusy-url-help' ), translate ( 'Enable RSS feed' ) => translate ( 'rss-enabled-help' ), translate ( 'URL' ) => translate ( 'rss-feed-url-help' )]; list_help ( $tmp_arr ); echo ' </div'; } if ( $ALLOW_COLOR_CUSTOMIZATION == 'Y' ) echo ' <h3>' . translate ( 'Colors' ) . '</h3> <p>' . translate ( 'colors-help' ) . '</p>'; echo ' </div>'; echo print_trailer ( false, true, true ); ?> PK �]�\��*�A �A report.phpnu �[��� <?php /** * Lists a user's reports or displays a specific report. * * Input Parameters: * - <var>report_id</var> (optional) - specified report id in webcal_report table * - <var>offset</var> (optional) - specifies how many days/weeks/months +/- to * display. For example, if the report type is 1 (today) with offset=5, then * the report will display 5 days from now. Should only be specified if * report_id is specified. Will be ignored if specified report does not have * the webcal_report.cal_allow_nav field set to 'Y'. * - <var>user</var> (optional) - specifies which user's calendar to use for * the report. This will be ignored if the chosen report is tied to a * specific user. * * @author Craig Knudsen <cknudsen@cknudsen.com> * @copyright Craig Knudsen, <cknudsen@cknudsen.com>, http://www.k5n.us/cknudsen * @license http://www.gnu.org/licenses/gpl.html GNU GPL * @package WebCalendar * @subpackage Reports */ /* Security: * If system setting $REPORTS_ENABLED is set to anything other than 'Y', * then don't allow access to this page. * If webcal_report.cal_is_global is set to: * 'Y', any user can view the report. * 'N', only the creator (set in webcal_report.cal_login) can view the report. * If webcal_report.cal_allow_nav is: * 'Y', then present Next and Previous links. * 'N', then no Next / Previous links and the offset parameter will be ignored. * Public user cannot edit/list reports. */ include_once 'includes/init.php'; /** * Replaces all site_extras placeholders in a template with the actual data. * * All occurences of '${extra:ExtraName}' (where 'ExtraName' is the unique name * of a site_extra) will be replaced with that extra's data. * * @param string $template The template * @param array $extras The formatted site_extras as returned by * {@link format_site_extras()} * * @return string The template with site_extras replaced */ function replace_site_extras_in_template ( $template, $extras ) { $extra_names = get_site_extras_names(); $ret = $template; foreach ( $extra_names as $extra_name ) { $ret = str_replace ( '${extra:' . $extra_name . '}', ( empty ( $extras[$extra_name] ) ? '' : $extras[$extra_name]['data'] ), $ret ); } return $ret; } /** * Generates the HTML for one event for a report. * * @param Event $event The event * @param string $date The date for which we're printing (in YYYYMMDD format) * * @return string HTML for this event based on report template. */ function event_to_text ( $event, $date ) { global $ALLOW_HTML_DESCRIPTION, $event_template, $login, $report_id, $user; $allDayStr = translate ( 'All day event' ); $confStr = translate ( 'This event is confidential.' ); $privStr = translate ( '(Private)' ); $end_time_str = $start_time_str = $time_str = ''; $tempAllDay = $event->isAllDay(); $tempDurStr = $event->getDuration(); if ( $tempAllDay ) $time_str = $allDayStr; else if ( $event->isUntimed() ) $time_str = translate ( 'Untimed event' ); else { $start_time_str = $time_str = display_time ( $event->getDateTime() ); $time_short = getShortTime ( $time_str ); if ( $tempDurStr > 0 ) { if ( $tempAllDay ) $time_str = $allDayStr; else { $tempEDT = $event->getEndDateTime(); $end_time_str = display_time ( $tempEDT ); $time_str .= ' - ' . display_time ( $tempEDT ); } } } $name = $event->getName(); $tempAcc = $event->getAccess(); $tempDesc = $event->getDescription(); $tempExtForID = $event->getExtForID(); $tempLog = $event->getLogin(); if ( $tempExtForID != '' ) { $id = $tempExtForID; $name .= ' ' . translate ( '(cont.)' ); } else $id = $event->getID(); if ( $tempAcc == 'R' ) { if ( ( $login != $user && strlen ( $user ) ) || ( $login != $tempLog && strlen ( $tempLog ) ) ) { $description_str = $confStr; $name_str = $privStr; } } else { $name_str = htmlspecialchars ( $name ); if ( ! empty ( $ALLOW_HTML_DESCRIPTION ) && $ALLOW_HTML_DESCRIPTION == 'Y' ) { $str = str_replace ( '&', '&', $tempDesc ); //fix any broken special characters $str = preg_replace( "/&(#[0-9]+|[a-z]+);/i", "&$1;", $str ); $description_str = str_replace ( '&amp;', '&', $str ); if ( strstr ( $description_str, '<' ) && strstr ( $description_str, '>' ) ) { // Found some HTML. } else // No HTML found. Add line breaks. $description_str = nl2br ( $description_str ); } else $description_str = nl2br ( activate_urls ( htmlspecialchars ( $tempDesc ) ) ); } $date_full_str = date_to_str ( $date ); $date_str = date_to_str ( $date, '', false ); $duration_str = ( $tempDurStr > 0 ? $tempDurStr . ' ' . translate ( 'minutes' ) : '' ); $temp = $event->getPriority(); $pri_str = ( $temp > 6 ? translate ( 'Low' ) : ( $temp < 4 ? translate ( 'High' ) : translate ( 'Medium' ) ) ); $temp = $event->getStatus(); if ( $temp == 'A' ) $status_str = translate ( 'Approved' ); elseif ( $temp == 'D' ) $status_str = translate ( 'Deleted' ); elseif ( $temp == 'R' ) $status_str = translate ( 'Rejected' ); elseif ( $temp == 'W' ) $status_str = translate ( 'Waiting for approval' ); else $status_str = translate ( 'Unknown' ); $location = $event->getLocation(); $url = $event->getUrl(); $href_str = 'view_entry.php?id=' . $id; // Get user's fullname. user_load_variables ( $tempLog, 'report_' ); $fullname = $GLOBALS['report_fullname']; // Replace all variables in the event template. $text = str_replace ( ['${date}', '${dateYmd}', '${description}', '${duration}', '${endtime}', '${fulldate}', '${fullname}', '${href}', '${id}', '${location}', '${name}', '${priority}', '${report_id}', '${starttime}', '${time}', '${url}', '${user}'], [$date_str, $date, $description_str, $duration_str, $end_time_str, $date_full_str, $fullname, $href_str, $id, $location, $name_str, $pri_str, $report_id, $start_time_str, $time_str, $url, $tempLog], $event_template ); $text = replace_site_extras_in_template ( $text, format_site_extras ( get_site_extra_fields ( $id ), EXTRA_DISPLAY_REPORT ) ); return $text; } $error = $list =/* List of reports when no id specified. */ $u_url = ''; if ( ! empty ( $user ) && $user != $login && ( ( ! empty ( $ALLOW_VIEW_OTHER ) && $ALLOW_VIEW_OTHER == 'Y' ) || $is_admin ) ) { $report_user = $user; $u_url = '&user=' . $user; } if ( empty ( $REPORTS_ENABLED ) || $REPORTS_ENABLED != 'Y' ) $error = print_not_auth(); $updating_public = false; if ( $is_admin && ! empty ( $public ) && $PUBLIC_ACCESS == 'Y' ) { $report_user = '__public__'; $updating_public = true; } $offset = getValue ( 'offset', '-?[0-9]+', true ); if ( empty ( $offset ) ) $offset = 0; $report_id = getValue ( 'report_id', '-?[0-9]+', true ); // If no report id is specified, // then generate a list of reports from which the user may choose. if ( empty ( $error ) && empty ( $report_id ) && $login == '__public__' ) $error = print_not_auth(); $invalidID = translate ( 'Invalid report id.' ); if ( empty ( $error ) && empty ( $report_id ) ) { $list = ''; $sql = 'SELECT cal_report_id, cal_report_name FROM webcal_report WHERE cal_login = '; $sql_params = []; if ( $is_admin ) { if ( ! $updating_public ) { if ( $PUBLIC_ACCESS == 'Y' ) { $clickStr = translate ( 'Click here to manage reports for the Public Access calendar.' ); $list .= ' <p><a title="' . $clickStr . '" href="report.php?public=1">' . $clickStr . '</a></p>'; } $sql .= '? OR cal_is_global = \'Y\''; $sql_params[] = $login; } else $sql .= '\'__public__\''; } else { $sql_params[] = $login; $sql .= '?'; } $res = dbi_execute ( $sql . ' ORDER BY cal_update_date DESC, cal_report_name', $sql_params ); $list .= ' <ul>'; if ( $res ) { $addStr = translate ( 'Add new report' ); $unnamesStr = translate ( 'Unnamed Report' ); while ( $row = dbi_fetch_row ( $res ) ) { $rep_name = trim ( $row[1] ); if ( empty ( $rep_name ) ) $rep_name = $unnamesStr; $list .= ' <li><a href="edit_report.php?report_id=' . $row[0] . '" class="nav">' . $rep_name . '</a></li>'; } $list .= ' </ul>'; $addurl = 'edit_report.php' . ( $updating_public ? '?public=1' : '' ); $list .= ' <p><a title="' . $addStr . '" href="' . $addurl . '" class="nav">' . $addStr . '</a></p>'; dbi_free_result ( $res ); } else $error = $invalidID; } // Load the specified report. if ( empty ( $error ) && empty ( $list ) ) { $res = dbi_execute ( 'SELECT cal_login, cal_report_id, cal_is_global, cal_report_type, cal_include_header, cal_report_name, cal_time_range, cal_user, cal_allow_nav, cal_cat_id, cal_include_empty, cal_update_date FROM webcal_report WHERE cal_report_id = ?', [$report_id] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { if ( $row[2] != 'Y' && $login != $row[0] ) $error = print_not_auth(); else { $i = 0; $report_login = $row[$i++]; $report_id = $row[$i++]; $report_is_global = $row[$i++]; $report_type = $row[$i++]; $report_include_header = $row[$i++]; $report_name = $row[$i++]; $report_time_range = $row[$i++]; $test_report_user = $row[$i++]; // If this report type specifies a specific user, // then we will use that user even if a user was passed in via URL. if ( ! empty ( $test_report_user ) ) $report_user = $test_report_user; $report_allow_nav = $row[$i++]; $report_cat_id = $row[$i++]; $report_include_empty = $row[$i++]; $report_update_date = $row[$i++]; } } else $error = $invalidID; dbi_free_result ( $res ); } else $error = db_error(); } if ( empty ( $report_user ) ) $report_user = $login; // Set default templates (in case there are none in the database for this report.) $day_str = $printerStr = ''; $day_template = '<dt><b>${date}</b></dt><dd><dl>${events}</dl></dd>'; $event_template = '<dt>${name}</dt> <dd><b class="colon">' . translate ( 'Date' ) . '</b> ${date}<br /> <b class="colon">' . translate ( 'Time' ) . '</b> ${time}<br /> ${description}</dd>'; $page_template = '<dl>${days}</dl>'; // Load templates for this report. if ( empty ( $error ) && empty ( $list ) ) { $res = dbi_execute ( 'SELECT cal_template_type, cal_template_text FROM webcal_report_template WHERE cal_report_id = ?', [$report_id] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { if ( $row[0] == 'D' ) $day_template = $row[1]; elseif ( $row[0] == 'E' ) $event_template = $row[1]; elseif ( $row[0] == 'P' ) $page_template = $row[1]; else { // This shouldn't happen under normal circumstances, so no need translate. echo 'Invalid template type: ' . $row[0]; exit; } } dbi_free_result ( $res ); } else $error = db_error(); } $include_header = ( ! empty ( $report_include_header ) && $report_include_header == 'Y' ); if ( $include_header || ! empty ( $list ) || ! empty ( $error ) ) { $printerStr = ( empty ( $report_id ) ? '' : generate_printer_friendly ( 'report.php' ) ); print_header(); } if ( empty ( $offset ) || empty ( $report_allow_nav ) || $report_allow_nav != 'Y' ) $offset = 0; // Set time range based on cal_time_range field. $dated = date ( 'd' ); $datem = date ( 'm' ); $dateY = date ( 'Y' ); $DISPLAY_WEEKENDS = 'Y'; $next = $offset + 1; $prev = $offset - 1; $wkstart = get_weekday_before ( $dateY, $datem, $dated + 1 ); if ( ! isset ( $report_time_range ) ) { // Manage reports. } else if ( $report_time_range >= 0 && $report_time_range < 10 ) { $today = mktime ( 0, 0, 0, $datem, $dated, $dateY ); $days_offset = 1 - $report_time_range + $offset; $end_date = $start_date = $today + ( $days_offset * 86400 ); } else if ( $report_time_range > 9 && $report_time_range < 20 ) { $week_offset = 11 - $report_time_range + $offset; $start_date = $wkstart + ( $week_offset * 604800 ); $end_date = $start_date + 518400; } else if ( $report_time_range > 19 && $report_time_range < 30 ) { $week_offset = 21 - $report_time_range + $offset; $start_date = $wkstart + ( $week_offset * 604800 ); $end_date = $start_date + 1123200; } else if ( $report_time_range > 29 && $report_time_range < 40 ) { $thismonth = $datem; $month_offset = 31 - $report_time_range + $offset; $start_date = mktime ( 0, 0, 0, $thismonth + $month_offset, 1, $dateY ); $end_date = mktime ( 23, 59, 59, $thismonth + $month_offset + 1, 0, $dateY ); } else if ( $report_time_range > 39 && $report_time_range < 50 ) { $thisyear = $dateY; $year_offset = 41 - $report_time_range + $offset; $start_date = mktime ( 0, 0, 0, 1, 1, $thisyear + $year_offset ); $end_date = mktime ( 23, 59, 59, 12, 31, $thisyear + $year_offset ); } else if ( $report_time_range > 49 && $report_time_range < 60 ) { // This series of reports is today + N days switch ( $report_time_range ) { case 50: $x = 14; break; case 51: $x = 30; break; case 52: $x = 60; break; case 53: $x = 90; break; case 54: $x = 180; break; case 55: $x = 365; break; default: echo 'Invalid cal_time_range setting for report id ' . $report_id; exit; } $today = mktime ( 0, 0, 0, $datem, $dated, $dateY ); $start_date = $today + ( 86400 * $offset * $x ); $end_date = $start_date + ( 86400 * $x ); } else { // Programmer's bug (no translation needed). echo 'Invalid cal_time_range setting for report id ' . $report_id; exit; } // The read_repeated_events calculates all event repeat dates for // some time period after the values of $thismonth and $thisyear. if ( ! empty ( $end_date ) ) { $thismonth = date ( 'm', $end_date ); $thisyear = date ( 'Y', $end_date ); } if ( empty ( $error ) && empty ( $list ) ) { $cat_id = empty ( $report_cat_id ) ? '' : $report_cat_id; $repeated_events = read_repeated_events ( $report_user, $start_date, $end_date, $cat_id ); $events = read_events ( $report_user, $start_date, $end_date, $cat_id ); $get_unapproved = ( $DISPLAY_UNAPPROVED == 'Y' ); // Loop through each day. // Get events for each day (both normal and repeating). // (Most of this code was copied from week.php.) for ( $cur_time = $start_date; $cur_time <= $end_date; $cur_time += 86400 ) { $event_str = ''; $dateYmd = date ( 'Ymd', $cur_time ); $ev = combine_and_sort_events ( get_entries ( $dateYmd ), get_repeating_entries ( $report_user, $dateYmd ) ); for ( $i = 0, $cnt = count ( $ev ); $i < $cnt; $i++ ) { if ( $get_unapproved || $ev[$i]->getStatus() == 'A' ) $event_str .= event_to_text ( $ev[$i], $dateYmd ); } if ( ! empty ( $event_str ) || $report_include_empty == 'Y' || $report_time_range < 10 ) { $date_str = date_to_str ( $dateYmd, '', false ); $date_full_str = date_to_str ( $dateYmd ); $day_str .= str_replace ( ['${date}', '${events}', '${fulldate}', '${report_id}'], [$date_str, $event_str, $date_full_str, $report_id], $day_template ); } } } if ( ! empty ( $error ) ) { echo print_error ( $error ) . print_trailer(); exit; } $adminLinkStr = $manageStr = $nextLinkStr = $prevLinkStr = $textStr = ''; $nextStr = translate ( 'Next' ); $prevStr = translate ( 'Previous' ); $reportNameStr = ( $include_header ? ' <h2>' . $report_name . '</h2>' : '' ); if ( ! empty ( $report_allow_nav ) && $report_allow_nav == 'Y' ) { $temp = '" href="report.php?report_id=' . $report_id . $u_url . '&offset='; $nextLinkStr = $prevLinkStr = ' <a class="nav" title="'; $nextLinkStr .= $nextStr . $temp . $next . '">' . $nextStr . '</a>'; $prevLinkStr .= $prevStr . $temp . $prev . '">' . $prevStr . '</a> '; } if ( empty ( $list ) ) { $textStr = str_replace ( '${days}', $day_str, str_replace ( '${report_id}', $report_id, $page_template ) ); $trailerStr = print_trailer ( $include_header ); } else { $adminLinkStr = display_admin_link(); $manageStr = ' <h2>' . ( $updating_public ? translate ( $PUBLIC_ACCESS_FULLNAME ) . ' ' : '' ) . translate ( 'Manage Reports' ) . '</h2>'; $trailerStr = print_trailer(); } echo <<<EOT {$reportNameStr}{$prevLinkStr}{$nextLinkStr}{$manageStr} {$adminLinkStr}{$list} {$textStr} {$printerStr} {$trailerStr} EOT; ?> PK �]�\�'B B access.phpnu �[��� <?php /** * $Id: access.php,v 1.60.2.1 2012/02/28 15:43:09 cknudsen Exp $ * * This page is used to manage user access rights. * * It has three different modes: * - list users to manage (no parameters) * - manage a single user's rights (just "user" parameter) * this will include which functions the user can access and * (if $ALLOW_VIEW_OTHER is 'Y') which calendars thay can view/edit/approve * - update the database (form handler) * * Input Parameters: * user - specifies which user to manage, a form will be presented * that allows editing rights of this user * * access_N - where N is 0 to ACCESS_NUMBER_FUNCTIONS as defined in * includes/access.php. Each should be either 'Y' or 'N'. */ include_once 'includes/init.php'; require_valid_referring_url (); $allow_view_other = ( ! empty( $ALLOW_VIEW_OTHER ) && $ALLOW_VIEW_OTHER == 'Y' ); if( ! access_is_enabled() ) { echo print_not_auth(); exit; } $dbErrStr = translate( 'Database error XXX.' ); $defConfigStr = translate( 'DEFAULT CONFIGURATION' ); $goStr = ' </select> <input type="submit" value="' . translate( 'Go' ) . '" /> </form>'; $saveStr = translate( 'Save' ); $undoStr = translate( 'Undo' ); $saved = ''; // Are we handling the access form? // If so, do that, then redirect. // Handle function access first. if( getPostValue( 'auser' ) != '' && getPostValue( 'submit' ) == $saveStr ) { $auser = getPostValue( 'auser' ); $perm = ''; for( $i = 0; $i < ACCESS_NUMBER_FUNCTIONS; $i++ ) { $perm .= ( getPostValue( 'access_' . $i ) == 'Y' ? 'Y' : 'N' ); } dbi_execute( 'DELETE FROM webcal_access_function WHERE cal_login = ?', [$auser] ); if( ! dbi_execute( 'INSERT INTO webcal_access_function( cal_login, cal_permissions ) VALUES ( ?, ? )', [$auser, $perm] ) ) die_miserable_death( str_replace( 'XXX', dbi_error(), $dbErrStr ) ); $saved = true; } // Are we handling the other user form? If so, do that, then redirect. if( getPostValue( 'otheruser' ) != '' && getPostValue( 'submit' ) == $saveStr ) { $puser = getPostValue( 'guser' ); $pouser = getPostValue( 'otheruser' ); if( $allow_view_other ) { // Handle access to other users' calendars. // If user is not admin, // reverse values so they are granting access to their own calendar. if( ! $is_admin ) list( $puser, $pouser ) = [$pouser, $puser]; dbi_execute( 'DELETE FROM webcal_access_user WHERE cal_login = ? AND cal_other_user = ?', [$puser, $pouser] ); $approve_total = $edit_total = $view_total = 0; for( $i = 1; $i <= 256; ) { $approve_total += getPostValue( 'a_' . $i ); $edit_total += getPostValue( 'e_' . $i ); $view_total += getPostValue( 'v_' . $i ); $i += $i; } $email = getPostValue( 'email' ); $invite = getPostValue( 'invite' ); $time = getPostValue( 'time' ); if( ! dbi_execute( 'INSERT INTO webcal_access_user ( cal_login, cal_other_user, cal_can_view, cal_can_edit, cal_can_approve, cal_can_invite, cal_can_email, cal_see_time_only ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )', [ $puser, $pouser, ( $view_total > 0 ? $view_total : 0 ), ( $edit_total > 0 && $puser != '__public__' ? $edit_total : 0 ), ( $approve_total > 0 && $puser != '__public__' ? $approve_total : 0 ), ( strlen( $invite ) ? $invite : 'N' ), ( strlen( $email ) ? $email : 'N' ), ( strlen( $time ) ? $time : 'N' )] ) ) die_miserable_death( str_replace( 'XXX', dbi_error(), $dbErrStr ) ); $saved = true; } } $checked = ' checked="checked"'; $guser = getPostValue( 'guser' ); $selected = ' selected="selected"'; if( $guser == '__default__' ) { $otheruser = $guser; $user_fullname = $defConfigStr; } else $otheruser = getPostValue( 'otheruser' ); if( $otheruser == '__default__' ) { $otheruser_fullname = $defConfigStr; $otheruser_login = '__default__'; } elseif( $otheruser == '__public__' ) { $otheruser_fullname = translate( 'Public Access' ); $otheruser_login = '__public__'; } if( ! empty( $otheruser ) ) { if( $allow_view_other ) { user_load_variables( $otheruser, 'otheruser_' ); // Turn off admin override so we see the users own settings. $ADMIN_OVERRIDE_UAC = 'N'; // Now load all the data from webcal_access_user. $allPermissions = access_load_user_permissions( false ); // Load default-default values if exist. if( ! empty( $allPermissions['__default__.__default__'] ) ) $op = $allPermissions['__default__.__default__']; if( $is_admin ) { // Load user-default values if exist. if( ! empty( $allPermissions[ $guser . '.__default__' ] ) ) $op = $allPermissions[ $guser . '.__default__' ]; // Load user-otheruser values if exist. if( ! empty( $allPermissions[ $guser . '.' . $otheruser ] ) ) $op = $allPermissions[ $guser . '.' . $otheruser ]; } else { // Load default-user values if exist. if( ! empty( $allPermissions['__default__.' . $guser] ) ) $op = $allPermissions['__default__.' . $guser ]; // Load otheruser-user values if exist. if( ! empty( $allPermissions[$otheruser . '.' . $guser] ) ) $op = $allPermissions[$otheruser . '.' . $guser]; } } } print_header( '', '<script type="text/javascript" src="includes/js/access.js?' . filemtime( 'includes/js/access.js' ) . '"></script> <link type="text/css" href="includes/css/access.css?' . filemtime( 'includes/css/access.css' ) . '" rel="stylesheet" />', ( ! empty( $op['time'] ) && $op['time'] == 'Y' ? 'onload="enableAll( true );"' : '' ) ); echo print_success( $saved ); if( ! empty( $guser ) && $is_admin ) user_load_variables( $guser, 'user_' ); if( $is_admin ) { $adminStr = translate( 'Admin' ); $userlist = get_my_users(); $nonuserlist = get_nonuser_cals(); // If we are here... we must need to print out a list of users. echo ' <h2>' . translate( 'User Access Control' ) . ( empty( $user_fullname ) ? '' : ': ' . $user_fullname ) . '</h2> ' . display_admin_link( false ) . ' <form action="access.php" method="post" name="SelectUser"> <select name="guser" onchange="document.SelectUser.submit()">' // Add a DEFAULT CONFIGURATION to be used as a mask. . ' <option value="__default__"' . ( $guser == '__default__' ? $selected : '' ) . '>' . $defConfigStr . '</option>'; for( $i = 0, $cnt = count( $userlist ); $i < $cnt; $i++ ) { echo ' <option value="' . $userlist[$i]['cal_login'] . '"' . ( $guser == $userlist[$i]['cal_login'] ? $selected : '' ) . '>' . $userlist[$i]['cal_fullname'] . '</option>'; } for( $i = 0, $cnt = count( $nonuserlist ); $i < $cnt; $i++ ) { echo ' <option value="' . $nonuserlist[$i]['cal_login'] . '"' . ( $guser == $nonuserlist[$i]['cal_login'] ? $selected : '' ) . '>' . $nonuserlist[$i]['cal_fullname'] . ' ' . ( $nonuserlist[$i]['cal_is_public'] == 'Y' ? '*' : '' ) . '</option>'; } echo $goStr; } //end admin $guser !- default test if( ! empty( $guser ) || ! $is_admin ) { if( $is_admin ) { // Present a page to allow editing a user's rights. $access = access_load_user_functions( $guser ); $div = ceil( ACCESS_NUMBER_FUNCTIONS / 4 ); // We can reorder the display of user rights here. $order = [ 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 27, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]; // Make sure that we have defined all the types of access // defined in access.php. assert( count( $order ) == ACCESS_NUMBER_FUNCTIONS ); echo ' <form action="access.php" method="post" id="accessform" name="accessform"> <input type="hidden" name="auser" value="' . $guser . '" /> <input type="hidden" name="guser" value="' . $guser . '" /> <table> <tbody> <tr> <td>'; for( $i = 0; $i < ACCESS_NUMBER_FUNCTIONS; $i++ ) { // Public access and NUCs can never use some of these functions. $show = true; if( $guser == '__public__' || substr( $guser, 0, 5 ) == $NONUSER_PREFIX ) { switch( $order[$i] ) { case ACCESS_ACCESS_MANAGEMENT: case ACCESS_ACCOUNT_INFO: case ACCESS_ACTIVITY_LOG: case ACCESS_ADMIN_HOME: case ACCESS_ASSISTANTS: case ACCESS_CATEGORY_MANAGEMENT: case ACCESS_IMPORT: case ACCESS_PREFERENCES: case ACCESS_SYSTEM_SETTINGS: case ACCESS_USER_MANAGEMENT: case ACCESS_VIEW_MANAGEMENT: // Skip these... $show = false; } } if( $show ) echo print_checkbox ( ['access_' . $order[$i], 'Y', access_get_function_description( $order[$i] ), substr( $access, $order[$i], 1 )], 'dito' ) . '<br />'; if( ( $i + 1 ) % $div == 0 ) echo ' </td> <td>'; } echo ' </td> </tr> </tbody> </table> <input type="submit" value="' . $undoStr . '" /> <input type="submit" name="submit" value="' . $saveStr . '" /> </form>'; $pagetitle = translate( 'Allow Access to Other Users Calendar' ); } else { // Get list of users that this user can see (may depend on group settings) // along with all nonuser calendars. // if( $guser != '__default__' ) { $guser = $login; $pagetitle = translate( 'Grant This User Access to My Calendar' ); } if( $guser == '__default__' ) { $userlist = ['__default__']; $otheruser = $otheruser_login = '__default__'; $otheruser_fullname = $defConfigStr; } else if( $allow_view_other ) { $userlist = get_list_of_users( $guser ); echo ' <h2 style="margin-bottom: 2px;">' . $pagetitle . '</h2> <form action="access.php" method="post" name="SelectOther"> <input type="hidden" name="guser" value="' . $guser . '" /> <select name="otheruser" onchange="document.SelectOther.submit()">' // Add a DEFAULT CONFIGURATION to be used as a mask. . ' <option value="__default__"' . ( $otheruser == '__default__' ? $selected : '' ) . '>' . $defConfigStr . '</option>'; for( $i = 0, $cnt = count( $userlist ); $i < $cnt; $i++ ) { if( $userlist[$i]['cal_login'] != $guser ) echo ' <option value="' . $userlist[$i]['cal_login'] . '"' . ( ! empty( $otheruser ) && $otheruser == $userlist[$i]['cal_login'] ? $selected : '' ) . '>' . $userlist[$i]['cal_fullname'] . '</option>'; } echo $goStr; } } if( ! empty( $otheruser ) ) { if( $allow_view_other ) { $typeStr = translate( 'Type' ); echo ' <form action="access.php" method="post" name="EditOther"> <input type="hidden" name="guser" value="' . $guser . '" /> <input type="hidden" name="otheruser" value="' . $otheruser . '" /><br /> <table cellpadding="5"> <tbody> <tr> <th class="boxtop boxbottom boxleft" width=' . ( $guser == '__public__' ? '"60%" class="aligncenter">' . translate( 'Calendar' ) . '</th> <th class="boxtop boxbottom" width="20%">' . $typeStr . '</th> <th class="boxtop boxright boxbottom" colspan="3" width="20%">' . translate( 'View Event' ) : '"25%">' . $otheruser_fullname . '</th> <th class="boxtop boxbottom" width="15%">' . $typeStr . '</th> <th width="15%" colspan="3" class="boxtop boxbottom">' . translate( 'View' ) . '</th> <th width="15%" colspan="3" class="boxtop boxbottom">' . translate( 'Edit' ) . '</th> <th width="15%" colspan="3" class="boxtop boxright boxbottom">' . translate( 'Approve/Reject' ) ) . '</th> </tr>'; $access_type = [ '', translate( 'Events' ), translate( 'Tasks' ), '', translate( 'Journals' )]; for( $j = 1; $j < 5; $j++ ) { $bottomedge = ''; if( $j == 3 ) continue; echo ' <tr> <td class="boxleft leftpadded' . ( $j > 3 ? ' boxbottom' : '' ) . '"><input type="checkbox" value="Y" name='; if( $j == 1 ) echo '"invite"' . ( ! empty( $op['invite'] ) && $op['invite'] == 'N' ? '' : $checked ) . ' />' . translate( 'Can Invite' ); elseif( $j == 2 ) echo '"email"' . ( ! empty( $op['email'] ) && $op['email'] == 'N' ? '' : $checked ) . ' />' . translate( 'Can Email' ); else { echo '"time"' . ( ! empty( $op['time'] ) && $op['time'] == 'Y' ? $checked : '' ) . ' onclick="enableAll( this.checked );" />' . translate( 'Can See Time Only' ); $bottomedge = 'boxbottom'; } echo '</td> <td class="aligncenter boxleft ' . $bottomedge . '">' . $access_type[$j] . '</td> <td class="aligncenter boxleft pub ' . $bottomedge . '">' . '<input type="checkbox" value="' . $j . '" name="v_' . $j . '"' . ( ! empty( $op['view'] ) && ( $op['view'] & $j ) ? $checked : '' ) . ' /></td> <td class="conf ' . $bottomedge . '"><input type="checkbox" value="' . $j * 8 . '" name="v_' . $j * 8 . '"' . ( ! empty( $op['view'] ) && ( $op['view'] & ( $j * 8 ) ) ? $checked : '' ) . ' /></td> <td class="priv ' . $bottomedge . '"><input type="checkbox" value="' . $j * 64 . '" name="v_' . $j * 64 . '"' . ( ! empty( $op['view'] ) && ( $op['view'] & ( $j * 64 ) ) ? $checked : '' ) . ' /></td>' . ( $guser != '__public__' ? ' <td class="aligncenter boxleft pub ' . $bottomedge . '"><input ' . 'type="checkbox" value="' . $j . '" name="e_' . $j . '"' . ( ! empty( $op['edit'] ) && ( $op['edit'] & $j ) ? $checked : '' ) . ' /></td> <td class="conf ' . $bottomedge . '"><input type="checkbox" value="' . $j * 8 . '" name="e_' . $j * 8 . '"' . ( ! empty( $op['edit'] ) && ( $op['edit'] & ( $j * 8 ) ) ? $checked : '' ) . ' /></td> <td class="priv ' . $bottomedge . '"><input type="checkbox" value="' . $j * 64 . '" name="e_' . $j * 64 . '"' . ( ! empty( $op['edit'] ) && ( $op['edit'] & ( $j * 64 ) ) ? $checked : '' ) . ' /></td> <td class="aligncenter boxleft pub ' . $bottomedge . '"><input ' . 'type="checkbox" value="' . $j . '" name="a_' . $j . '"' . ( ! empty( $op['approve'] ) && ( $op['approve'] & $j ) ? $checked : '' ) . ' /></td> <td class="conf ' . $bottomedge . '"><input type="checkbox" value="' . $j * 8 . '" name="a_' . $j * 8 . '"' . ( ! empty( $op['approve'] ) && ( $op['approve'] & ( $j * 8 ) ) ? $checked : '' ) . ' /></td> <td class="boxright priv ' . $bottomedge . '"><input type="checkbox" value="' . $j * 64 . '" name="a_' . $j * 64 . '"' . ( ! empty( $op['approve'] ) && ( $op['approve'] & ( $j * 64 ) ) ? $checked : '' ) . ' /></td>' : '' ) . ' </tr>'; } echo ' <tr> <td colspan="2" class="boxleft alignright">' . ( $otheruser != '__default__' && $otheruser != '__public__' ? ' <input type="button" value="' . translate( 'Assistant' ) . '" onclick="selectAll(63);" /> ' : '' ) . ' <input type="button" value="' . translate( 'Select All' ) . '" onclick="selectAll(256);" /> <input type="button" value="' . translate( 'Clear All' ) . '" onclick="selectAll(0);" /> </td> <td colspan="9" class="boxright"> <table class="aligncenter" cellpadding="5" cellspacing="2"> <tr> <td class="pub">' . translate( 'Public' ) . '</td> <td class="conf">' . translate( 'Confidential' ) . '</td> <td class="priv">' . translate( 'Private' ) . '</td> </tr> </table> </td> </tr>'; } echo ' <tr> <td colspan="11" class="boxleft boxbottom boxright"> <input type="submit" value="' . $undoStr . '" /> <input type="submit" name="submit" value="' . $saveStr . '" /> </td> </tr> </tbody> </table> </form>'; } echo print_trailer(); /** * Get the list of users that the specified user can see. */ function get_list_of_users( $user ) { global $is_admin, $is_nonuser_admin; $u = get_my_users( $user, 'view' ); if( $is_admin || $is_nonuser_admin ) { // Get public NUCs also. $nonusers = get_my_nonusers( $user, true ); $u = array_merge( $nonusers, $u ); } return $u; } ?> PK �]�\UPGv v import_palmdesktop.phpnu �[��� <?php /** * Parse the datebook file. * * @return the data hash. */ function parse_palmdesktop ( $file, $exc_private = 1 ) { $file = EscapeShellArg ( $file ); $exc_private = EscapeShellArg ( $exc_private ); exec ( 'perl tools/palm_datebook.pl ' . "$file $exc_private", $Entries ); $data = []; while ( list ( $line_num, $line ) = each ( $Entries ) ) { $data[] = ParseLine ( $line ); } return $data; } /** * Delete all Palm Events for $login to clear any events deleted in the palm. * * @return 1 if successful. */ function delete_palm_events ( $login ) { $res = dbi_execute ( 'SELECT cal_id FROM webcal_import_data WHERE cal_login = ? AND cal_import_type = ?', [$login, 'palm'] ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { dbi_execute ( 'DELETE FROM webcal_blob WHERE cal_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_entry_log WHERE cal_entry_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_entry_repeats WHERE cal_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_entry_repeats_not WHERE cal_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_import_data WHERE cal_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_reminders WHERE cal_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_site_extras WHERE cal_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_entry_user WHERE cal_id = ?', [$row[0]] ); dbi_execute ( 'DELETE FROM webcal_entry WHERE cal_id = ?', [$row[0]] ); } } dbi_free_result ( $res ); return 1; } function ParseLine ( $line ) { global $calUser; list ( $Entry['RecordID'], $Entry['StartTime'], $Entry['EndTime'], $Entry['Summary'], $Entry['Duration'], $Entry['Description'], $Entry['Untimed'], $Entry['Private'], $Entry['Category'], $Entry['AlarmSet'], $Entry['AlarmAdvanceAmount'], $Entry['AlarmAdvanceType'], $Entry['Repeat']['Interval'], $Entry['Repeat']['Frequency'], $Entry['Repeat']['EndTime'], $Exceptions, $Entry['Repeat']['RepeatDays'], $WeekNum, ) = explode ( '|', $line ); // Adjust times to users Timezone if not Untimed. if ( isset ( $Entry['Untimed'] ) && $Entry['Untimed'] == 0 ) { $Entry['StartTime'] -= date ( 'Z', $Entry['StartTime'] ); $Entry['EndTime'] -= date ( 'Z', $Entry['EndTime'] ); } if ( $Exceptions ) $Entry['Repeat']['Exceptions'] = explode ( ': ', $Exceptions ); if ( ( $WeekNum == '5' ) && ( $Entry['Repeat']['Interval'] == '3' ) ) $Entry['Repeat']['Interval'] = '6'; return $Entry; } ?> PK �]�\��6$O $O view_r.phpnu �[��� <?php /** * Page Description: * This is the "Week by Time" and "Week by Day" view. * This view will show either a week's worth of events (type='R') * or a single day of events (type='E') * using a format with days across the top of the table and time * showing down the left side. (This is just like the standard * layout of day.php and week.php.) * However, each cell will be subdivided into * however many users are part of this view. * * Input Parameters: * id (*) - specify view id in webcal_view table * date - specify the starting date of the view. * If not specified, current date will be used. * friendly - if set to 1, then page does not include links or * trailer navigation. * (*) required field * * Comments: * The week view of this page will only show weekends if the * user has set "display weekends in week view" in their * user preferences. * * The week version of this page has the potential to contain * a large table. The layout will be skewed to try and fit this * into a page. * If you want to allow the table to grow larger than the viewable * area in the browser, set the $fit_to_window_week to be false below. * (You can do the same for the day view with $fit_to_window_day.) * * Should we make this an option when creating/updating the view? * If we did make this an option in the UI, we would need to either: * (A) add a column to the webcal_view table * (B) use different view types for this option ('E' and 'R' for * fit-to-window, 'G' and 'X' for expand?) * * Security: * Must have "allow view others" enabled ($ALLOW_VIEW_OTHER) in * System Settings unless the user is an admin user ($is_admin). * If the view is not global, the user must be owner of the view. * If the view is global, and user_sees_only_his_groups is * enabled, then we remove users not in this user's groups * (except for nonuser calendars... which we allow regardless of group). */ include_once 'includes/init.php'; include_once 'includes/views.php'; $error = ''; $can_add = true; // include '+' add icons in this view? // Set this to true to allow the table to be larger than the browser's // viewable area. // Only if you have more than 7 users, would you need to set this to // false for the day view. // On the week view, 3 or more users start to // get crowded and you may want to set this to true. $fit_to_window_day = false; $fit_to_window_week = true; // This defines how wide the smallest column will be for the view $col_pixels_week = 90; // if above is true, how large is each column in table // This defines how wide the smallest column will be for the view $col_pixels_day = 150; // if above is true, how large is each column in table // Should the time of the event be displayed $show_time_day = true; $show_time_week = false; // Display abbreviated Timezone name in popup $DISPLAY_TZ = 2; // Should there always be a row for untimed/all-day events? // Normally we only show this if there are some of these events, but // if you want to be able to add an all-day event quickly, you can // double-click in one of these table cells, so it's handy to have // this row around in all cases. $show_untimed_row_always = true; view_init ( $id ); // view type 'E' = Day by Time, 'R' = Week by Time $is_day_view = ( $view_type == 'E' ); $col_pixels = ( $is_day_view ? $col_pixels_day : $col_pixels_week ); $fit_to_window = ( $is_day_view ? $fit_to_window_day : $fit_to_window_week ); $show_time = ( $is_day_view ? $show_time_day : $show_time_week ); $printerStr = generate_printer_friendly ( 'view_r.php' ); set_today ( $date ); print_header( array( 'js/popups.js/true' ) ); $thisdate = sprintf ( "%04d%02d%02d", $thisyear, $thismonth, $thisday ); if ( $is_day_view ) $next = mktime ( 0, 0, 0, $thismonth, $thisday + 1, $thisyear ); else $next = mktime ( 0, 0, 0, $thismonth, $thisday + 7, $thisyear ); $nextyear = date ( 'Y', $next ); $nextmonth = date ( 'm', $next ); $nextday = date ( 'd', $next ); $nextdate = sprintf ( "%04d%02d%02d", $nextyear, $nextmonth, $nextday ); if ( $is_day_view ) $prev = mktime ( 0, 0, 0, $thismonth, $thisday - 1, $thisyear ); else $prev = mktime ( 0, 0, 0, $thismonth, $thisday - 7, $thisyear ); $prevyear = date ( 'Y', $prev ); $prevmonth = date ( 'm', $prev ); $prevday = date ( 'd', $prev ); $prevdate = sprintf ( "%04d%02d%02d", $prevyear, $prevmonth, $prevday ); $wkstart = get_weekday_before ( $thisyear, $thismonth, $thisday +1 ); $wkend = $wkstart + 604800; if ( ! $fit_to_window ) $time_w = '100px'; else $time_w = '8%'; // 8% for time column // Set the day of week range (0=Sun, 6=Sat) // $start_ind = start of range // $end_ind = end of range (inclusive) if ( $is_day_view ) { $thistime = mktime ( 0, 0, 0, $thismonth, $thisday, $thisyear ); $start_ind = $end_ind = ( date ( 'w', $thistime ) - $WEEK_START + 7 ) % 7; } else { if ( $DISPLAY_WEEKENDS == 'N' ) { if ( $WEEK_START == 1 ) { $start_ind = 0; $end_ind = 4; } else { $start_ind = 1; $end_ind = 5; } } else { $start_ind = 0; $end_ind = 6; } } // Generate the column headers for each day and the unix datetime // values for each date. for ( $i = $start_ind; $i <= $end_ind; $i++ ) { $days[$i] = ( $wkstart + 86400 * $i ) + 43200; $weekdays[$i] = weekday_name ( ( $i + $WEEK_START ) % 7, $DISPLAY_LONG_DAYS ); $header[$i] = $weekdays[$i] . '<br />' . month_name ( date ( 'm', $days[$i] ) - 1, 'M' ) . ' ' . date ( 'd', $days[$i] ); if ( empty ( $first_date ) ) $first_date = date_to_str ( date ( 'Ymd', $days[$i] ), '', false ); $last_date = date_to_str ( date ( 'Ymd', $days[$i] ), '', false ); } // The table has dates across the top and times for rows. Since we need // to spit out an entire row before we can move to the next time slot, we'll // save up all the HTML for each cell and then print it out when we're // done. $viewusers = view_get_user_list ( $id ); $viewusercnt = count ( $viewusers ); //echo "<pre>"; print_r ( $viewusers ); echo "</pre>\n"; // Make sure we have at least one user in our view. // If this is a global view, we may have removed all the users if // the current user does not have permission to view any of the // users in the view. // In theory, we whould always at least have ourselves in the view, right? if ( $viewusercnt == 0 ) { // I don't think we need to translate this. $error = 'No users for this view.'; } if ( ! empty ( $error ) ) { echo print_error ( $error ); echo print_trailer(); exit; } // table_width = width in pixels of entire table // col_pixels = width of smallest column // 100 = width of time column on left of table if ( ! $fit_to_window ) { $table_width = ( $col_pixels * $viewusercnt ) * ( $end_ind - $start_ind + 1 ) + 100; } //echo "table_width=$table_width<br />\n"; // tdw is the cell width for each day if ( ! $fit_to_window ) // pixels $tdw = floor ( ( $table_width - $time_w ) / ( $end_ind - $start_ind + 1 ) ); else // % $tdw = floor ( ( 100 - $time_w ) / ( $end_ind - $start_ind + 1 ) ); $untimed_found = false; $get_unapproved = ( $DISPLAY_UNAPPROVED == 'Y' ); // public access events cannot override $DISPLAY_UNAPPROVED if ( $user == '__public__' && $PUBLIC_ACCESS_VIEW_UNAPPROVED != 'Y' ) $get_unapproved = false; // Step through each user and load events for that user. // Store in $e_save[] (normal events) and $re_save[] (repeating events). $e_save = array(); $re_save = array(); if ( ! $fit_to_window ) $uwf = $col_pixels . 'px'; else $uwf = sprintf ( "%0.2f", $tdw / $viewusercnt ) . '%'; $uheader = ''; for ( $i = 0; $i < $viewusercnt; $i++ ) { /* Pre-Load the repeated events for quckier access */ $repeated_events = read_repeated_events ( $viewusers[$i], $wkstart, $wkend, '' ); $re_save[$i] = $repeated_events; /* Pre-load the non-repeating events for quicker access subtracting ONE_WEEK to allow cross-day events to display. */ $events = read_events( $viewusers[$i], $wkstart - 604800, $wkend ); $e_save[$i] = $events; user_load_variables ( $viewusers[$i], 'temp' ); $uheader .= "<th class=\"small\" width=\"$uwf\" style=\"width:$uwf;\">" . $tempfullname . "</th>\n"; //echo "$viewusers[$i]: loaded " . count ( $events ) . " events<br />\n"; } $num_users = $viewusercnt; // $TIME_SLOTS is set in both admin system settings and user preferences. if ( empty ( $TIME_SLOTS ) ) $TIME_SLOTS = 24; $interval = 1440 / $TIME_SLOTS; $first_slot = (int)( ( $WORK_DAY_START_HOUR * 60 ) / $interval ); $last_slot = (int)( ( $WORK_DAY_END_HOUR * 60 ) / $interval ); ?> <div style="width:99%;"> <a href="view_r.php?id=<?php echo $id?>&date=<?php echo $prevdate?>" class="prev"><img src="images/leftarrow.gif" alt="<?php etranslate ( 'Previous' )?>" /></a> <a href="view_r.php?id=<?php echo $id?>&date=<?php echo $nextdate?>" class="next"><img src="images/rightarrow.gif" alt="<?php etranslate ( 'Next' )?>" /></a> <div class="title"> <span class="date"><?php if ( $is_day_view ) { echo date_to_str ( date ( 'Ymd', $thistime ), false ); } else { echo $first_date . " - " . $last_date; } ?></span><br /> <span class="viewname"><?php echo htmlspecialchars ( $view_name ) ?></span> <?php if ( $DISPLAY_WEEKNUMBER == 'Y' ) { echo "<br />\n<span class=\"titleweek\">(" . translate( 'Week' ) . ' ' . date( 'W', $wkstart + 86400 ) . ')</span>'; } ?> </div></div><br /> <?php $help = ( $can_add ? 'title="' . translate ( 'Double-click on empty cell to add new entry' ) . '"' : '' ); if ( ! $fit_to_window ) { ?> <table <?php echo $help;?> class="main" style="width:<?php echo $table_width;?>px;" width="<?php echo $table_width;?>"> <?php } else { ?> <table <?php echo $help;?> class="main"> <?php } ?> <!-- table header --> <tr><th class="empty" width="<?php echo $time_w;?>" style="width:<?php echo $time_w;?>;"> </th> <?php // heading row that displays day of week and date if ( ! $fit_to_window ) $tdwf = ( $col_pixels * $viewusercnt ) . 'px'; else $tdwf = sprintf ( "%0.2f", $tdw ) . "%"; $todayYmd = date ( 'Ymd', $today ); for ( $i = $start_ind; $i <= $end_ind; $i++ ) { if ( is_weekend ( $days[$i] ) && $DISPLAY_WEEKENDS == 'N' ) continue; if ( $todayYmd == date ( 'Ymd', $days[$i] ) ) $class = 'class="today"'; else if ( is_weekend ( $days[$i] ) ) $class = 'class="weekend"'; else $class = ''; echo '<th ' . $class . ' style="width:' . $tdwf . ';" colspan="' . $num_users . '">' . $header[$i] . "</th>\n"; } ?> </tr> <tr><th class="empty" width="<?php echo $time_w;?>" style="width:<?php echo $time_w;?>;"> </th> <?php for ( $i = $start_ind; $i <= $end_ind; $i++ ) { echo $uheader; } ?> </tr> <!-- end table header --> <?php // We need to store all the events and where they go before we begin // printing any output. $all_day = array(); //<long-winded-explanation> // We loop through the events once checking for the start time. If we // find a start time before the normal work hours, we will reset $first_slot // to this new time. We do this in a separate loop because all-day events // will assume a start time slot of the beginning of normal work hours. // So, if there is an all-day event on Monday, it might use the first_slot // that represents 8am only to find an event on Thu has a time of 7am which // would change the first_slot value. There is then a gap above the all-day // event. //</long-winded-explanation> $am_part = array(); // am I a participant array for ( $d = $start_ind; $d <= $end_ind; $d++ ) { for ( $u = 0; $u < $viewusercnt; $u++ ) { $untimed = array(); $user = $viewusers[$u]; $events = $e_save[$u]; $repeated_events = $re_save[$u]; // get all the repeating events for this date and store in array $rep $dateYmd = date ( 'Ymd', $days[$d] ); $rep = get_repeating_entries ( $user, $dateYmd ); $repcnt = count ( $rep ); for ( $j = 0; $j < $repcnt; $j++ ) { if( ! isset( $am_part[$rep[$j]->getID()] ) ) { $am_part[$rep[$j]->getID()] = user_is_participant( $rep[$j]->getID(), $login ); } if( $get_unapproved || $rep[$j]->getStatus() == 'A' ) { if ( $rep[$j]->getDuration() > 0 && $rep[$j]->getDuration() != 1440 ) { $slot = calc_time_slot( $rep[$j]->getTime(), false ); if ( $slot < $first_slot ) { $first_slot = $slot; } } } } $ev = get_entries ( $dateYmd, $get_unapproved, 1, 1); $evcnt = count ( $ev ); for ( $j = 0; $j < $evcnt; $j++ ) { if( ! isset( $am_part[$ev[$j]->getID()] ) ) { $am_part[$ev[$j]->getID()] = user_is_participant( $ev[$j]->getID(), $login ); } if( $ev[$j]->getDuration() > 0 && $ev[$j]->getDuration() != 1440 ) { $slot = calc_time_slot( $ev[$j]->getTime(), false ); if ( $slot < $first_slot ) { $first_slot = $slot; } } } } } for ( $d = $start_ind; $d <= $end_ind; $d++ ) { for ( $u = 0; $u < $viewusercnt; $u++ ) { $untimed = array(); $user = $viewusers[$u]; $events = $e_save[$u]; $repeated_events = $re_save[$u]; // get all the repeating events for this date and store in array $rep $dateYmd = date ( 'Ymd', $days[$d] ); $rep = get_repeating_entries ( $user, $dateYmd ); $cur_rep = 0; // Get static non-repeating events $ev = get_entries ( $dateYmd, $get_unapproved, 1, 1 ); $hour_arr = array(); $rowspan_arr = array(); $evcnt = count ( $ev ); $repcnt = count ( $rep ); for ( $i = 0; $i < $evcnt; $i++ ) { // print out any repeating events that are before this one... while ( $cur_rep < $repcnt && $rep[$cur_rep]->getTime() < $ev[$i]->getTime() ) { if( $get_unapproved || $rep[$cur_rep]->getStatus() == 'A' ) { if( $rep[$cur_rep]->getDuration() == 1440 ) $all_day[$d] = 1; html_for_event_week_at_a_glance ( $rep[$cur_rep], $dateYmd, 'small', $show_time ); } $cur_rep++; } if( $get_unapproved || $ev[$i]->getStatus() == 'A' ) { if( $ev[$i]->getDuration() == 1440 ) $all_day[$d] = 1; html_for_event_week_at_a_glance ( $ev[$i], $dateYmd, 'small', $show_time ); //echo "Found event date=$dateYmd name='$viewname'<br />\n"; //print_r ( $rowspan_arr ); } } // print out any remaining repeating events while ( $cur_rep < $repcnt ) { if( $get_unapproved || $rep[$cur_rep]->getStatus() == 'A' ) { if( $rep[$cur_rep]->getDuration() == 1440 ) $all_day[$d] = 1; html_for_event_week_at_a_glance ( $rep[$cur_rep], $dateYmd, 'small', $show_time ); } $cur_rep++; } // squish events that use the same cell into the same cell. // For example, an event from 8:00-9:15 and another from 9:30-9:45 both // want to show up in the 8:00-9:59 cell. $rowspan = 0; $last_row = -1; for ( $i = 0; $i < $TIME_SLOTS; $i++ ) { if ( $rowspan > 1 ) { if ( !empty ( $hour_arr[$i] ) ) { if ( $rowspan_arr[$i] > 1 ) { $rowspan_arr[$last_row] += ( $rowspan_arr[$i] - 1 ); $rowspan += ( $rowspan_arr[$i] - 1 ); } else $rowspan_arr[$last_row] += $rowspan_arr[$i]; // this will move entries apart that appear in one field, // yet start on different hours $start_time = $i; $diff_start_time = $start_time - $last_row; for ( $x = $diff_start_time; $x > 0; $x-- ) $hour_arr[$last_row] .= "<br />\n"; $hour_arr[$last_row] .= $hour_arr[$i]; $hour_arr[$i] = ''; $rowspan_arr[$i] = 0; } $rowspan--; } else if ( !empty ( $rowspan_arr[$i] ) && $rowspan_arr[$i] > 1 ) { $rowspan = $rowspan_arr[$i]; $last_row = $i; } } // now save the output... if ( ! empty ( $hour_arr[9999] ) && strlen ( $hour_arr[9999] ) ) { $untimed[$d] = $hour_arr[9999]; $untimed_found = true; } $save_hour_arr[$u][$d] = $hour_arr; $save_rowspan_arr[$u][$d] = $rowspan_arr; $save_untimed[$u][$d] = $untimed; } } // untimed events first if ( $untimed_found || $show_untimed_row_always ) { echo '<tr><th class="empty" width="' .$time_w. '" style="width:' . $time_w . ';"> </th>' . "\n"; for ( $d = $start_ind; $d <= $end_ind; $d++ ) { $dateYmd = date ( 'Ymd', $days[$d] ); $is_weekend = is_weekend ( $days[$d] ); if ( $is_weekend && $DISPLAY_WEEKENDS == 'N' ) continue; if ( $dateYmd == $todayYmd ) $class .= 'class="today"'; else if ( $is_weekend ) $class .= 'class="weekend"'; else $class = ''; for ( $u = 0; $u < $viewusercnt; $u++ ) { $untimed = $save_untimed[$u][$d]; // Use the class 'hasevents' for any hour block that has events // in it. if ( !empty ( $untimed[$d] ) && strlen ( $untimed[$d] ) ) { $class = 'class="hasevents"'; } echo "<td $class "; if ( $can_add ) { echo " ondblclick=\"dblclick( '$dateYmd', '$viewusers[$u]' )\""; } echo '>'; if ( !empty ( $untimed[$d] ) && strlen ( $untimed[$d] ) ) { echo $untimed[$d]; } else { echo ' '; } echo "</td>\n"; } } echo "</tr>\n"; } $rowspan_day = array(); for ( $u = 0; $u < $viewusercnt; $u++ ) { for ( $d = $start_ind; $d <= $end_ind; $d++ ) $rowspan_day[$u][$d] = 0; } for ( $i = $first_slot; $i <= $last_slot; $i++ ) { $time_h = ( int ) ( ( $i * $interval ) / 60 ); $time_m = ( $i * $interval ) % 60; $time = display_time ( ( $time_h * 100 + $time_m ) * 100, 1 ); echo "<tr>\n<th class=\"aligntop row\" width=\"$time_w" . '">' . $time . "</th>\n"; for ( $d = $start_ind; $d <= $end_ind; $d++ ) { $dateYmd = date ( 'Ymd', $days[$d] ); for ( $u = 0; $u < $viewusercnt; $u++ ) { $hour_arr = $save_hour_arr[$u][$d]; $rowspan_arr = $save_rowspan_arr[$u][$d]; $is_weekend = is_weekend ( $days[$d] ); if ( $dateYmd == $todayYmd ) $class .= 'class="today"'; else if ( $is_weekend ) $class .= 'class="weekend"'; else $class = ''; // Use the class 'hasevents' for any hour block that has events // in it. if ( ! empty ( $hour_arr[$i] ) && strlen ( $hour_arr[$i] ) ) { $class = 'class="hasevents"'; } if ( $rowspan_day[$u][$d] > 1 ) { // this might mean there's an overlap, or it could mean one event // ends at 11:15 and another starts at 11:30. if ( !empty ( $hour_arr[$i] ) ) { echo "<td $class>" . $hour_arr[$i]. "</td>\n"; } $rowspan_day[$u][$d]--; } else { if ( empty ( $hour_arr[$i] ) ) { echo "<td $class "; if ( $can_add ) { echo " ondblclick=\"dblclick( '$dateYmd', " . "'$viewusers[$u]', '$time_h', '$time_m' )\""; } echo '>'; echo " </td>\n"; } else { $rowspan_day[$u][$d] = $save_rowspan_arr[$u][$d][$i]; if ( $rowspan_day[$u][$d] > 1 ) { echo "<td $class "; echo ' rowspan="' . $rowspan_day[$u][$d] . '"'; if ( $can_add ) { echo " ondblclick=\"dblclick( '$dateYmd', " . "'$user', '$time_h', '$time_m' )\""; } echo '>'; echo $hour_arr[$i]."</td>\n"; } else { echo "<td $class "; if ( $can_add ) { echo " ondblclick=\"dblclick( '$dateYmd', " . "'$user', '$time_h', '$time_m' )\""; } echo '>'; echo $hour_arr[$i]."</td>\n"; } } } } } echo "</tr>\n"; } ?> </table> <script> <!-- <![CDATA[ function dblclick( date, name, hour, minute ) { window.location.href = 'edit_entry.php?date=' + date + '&defusers=' + name + ( hour ? '&hour=' + hour + '&minute=' + ( minute ? minute : 0 ) : '&duration=1440' ); } //]]> --> </script> <?php $user = ''; // reset if ( ! empty ( $eventinfo ) ) echo $eventinfo; echo $printerStr; echo print_trailer(); ?> PK �]�\0��]� � view_w.phpnu �[��� <?php // $Id: view_w.php,v 1.81 2009/11/22 22:26:18 bbannon Exp $ /** * Page Description: * Display view of a week with users side by side. * * Input Parameters: * id (*) - specify view id in webcal_view table * date - specify the starting date of the view. * If not specified, current date will be used. * friendly - if set to 1, then page does not include links or * trailer navigation. * (*) required field * * Security: * Must have "allow view others" enabled ($ALLOW_VIEW_OTHER) in System Settings * unless the user is an admin ($is_admin). * If the view is not global, the user must be owner of the view. * If the view is global, and user_sees_only_his_groups is enabled, * then we remove users not in this user's groups * (except for nonuser calendars... which we allow regardless of group). */ include_once 'includes/init.php'; include_once 'includes/views.php'; $error = ''; $USERS_PER_TABLE = 6; $id = getValue ( 'id' ); view_init ( $id ); $printerStr = generate_printer_friendly ( 'view_w.php' ); set_today ( $date ); $next = mktime ( 0, 0, 0, $thismonth, $thisday + 7, $thisyear ); $prev = mktime ( 0, 0, 0, $thismonth, $thisday - 7, $thisyear ); $todayYmd = date ( 'Ymd', $today ); $wkstart = get_weekday_before ( $thisyear, $thismonth, $thisday + 1 ); $wkend = $wkstart + ( 86400 * ( $DISPLAY_WEEKENDS == 'N' ? 5 : 7 ) ); $nextStr = translate ( 'Next' ); $prevStr = translate ( 'Previous' ); $can_add = ( empty ( $ADD_LINK_IN_VIEWS ) || $ADD_LINK_IN_VIEWS != 'N' ); print_header( array( 'js/popups.js/true', 'js/dblclick_add.js/true' ) ); // Get users in this view. $viewusers = view_get_user_list ( $id ); $viewusercnt = count ( $viewusers ); if ( $viewusercnt == 0 ) // This could happen if user_sees_only_his_groups = Y and // this user is not a member of any group assigned to this view. $error = translate( 'No users for this view.' ); if ( ! empty ( $error ) ) { echo print_error( $error ) . print_trailer(); exit; } echo ' <div style="width:99%;"> <a title="' . $prevStr . '" class="prev" href="view_w.php?id=' . $id . '&date=' . sprintf ( "%04d%02d%02d", date ( 'Y', $prev ), date ( 'm', $prev ), date ( 'd', $prev ) ) . '"> <img src="images/leftarrow.gif" alt="' . $prevStr . '" /></a> <a title="' . $nextStr . '" class="next" href="view_w.php?id=' . $id . '&date=' . sprintf ( "%04d%02d%02d", date ( 'Y', $next ), date ( 'm', $next ), date ( 'd', $next ) ) . '"> <img src="images/rightarrow.gif" alt="' . $nextStr . '" /></a> <div class="title"> <span class="date">' . date_to_str ( date ( 'Ymd', $wkstart ), '', false ) . ' - ' . date_to_str ( date ( 'Ymd', $wkend ), '', false ) . '</span><br /> <span class="viewname">' . htmlspecialchars ( $view_name ) . '</span> </div> </div><br />'; // The table has names across the top and dates for rows. Since we need to spit // out an entire row before we can move to the next date, we'll save up all the // HTML for each cell and then print it out when we're done... // Additionally, we only want to put at most 6 users in one table since // any more than that doesn't really fit in the page. $e_save = $re_save = array(); for ( $i = 0; $i < $viewusercnt; $i++ ) { /* Pre-Load the repeated events for quckier access. */ $repeated_events = read_repeated_events ( $viewusers[$i], $wkstart, $wkend, '' ); $re_save[$i] = $repeated_events; /* Pre-load the non-repeating events for quicker access subtracting ONE_WEEK to allow cross-day events to display. */ $e_save[$i] = $events = read_events ( $viewusers[$i], $wkstart - 604800, $wkend ); } for ( $j = 0; $j < $viewusercnt; $j += $USERS_PER_TABLE ) { // Since print_date_entries is rather stupid, we can swap the event data // around for users by changing what $events points to. // Calculate width of columns in this table. $num_left = $viewusercnt - $j; if ( $num_left > $USERS_PER_TABLE ) $num_left = $USERS_PER_TABLE; $tdw = ( $num_left > 0 ? intval ( 90 / ( $num_left < $USERS_PER_TABLE ? $num_left : $USERS_PER_TABLE ) ) : 5 ); echo ' <table class="main" cellpadding="1"'; if ( $can_add ) echo 'title="' . translate ( 'Double-click on empty cell to add new entry' ) . '"'; echo '> <tr> <th class="empty"> </th>'; // $j points to start of this table/row. // $k is counter starting at 0. // $i starts at table start and goes until end of this table/row. for ( $i = $j, $k = 0; $i < $viewusercnt && $k < $USERS_PER_TABLE; $i++, $k++ ) { $user = $viewusers[$i]; user_load_variables ( $user, 'temp' ); echo ' <th style="width:' . $tdw . '%;">' . $tempfullname . '</th>'; } echo ' </tr>'; for ( $date = $wkstart; $date < $wkend; $date += 86400 ) { $dateYmd = date ( 'Ymd', $date ); $is_weekend = is_weekend ( $date ); if ( $is_weekend && $DISPLAY_WEEKENDS == 'N' ) continue; $class = 'class="' . ( $dateYmd == $todayYmd ? 'today"' : ( $is_weekend ? 'weekend"' : 'row"' ) ); echo ' <tr> <th ' . $class . '>' . weekday_name ( date ( 'w', $date ), $DISPLAY_LONG_DAYS ) . ' ' . date ( 'd', $date ) . '</th>'; for ( $i = $j, $k = 0; $i < $viewusercnt && $k < $USERS_PER_TABLE; $i++, $k++ ) { $user = $viewusers[$i]; $events = $e_save[$i]; $repeated_events = $re_save[$i]; $entryStr = print_date_entries ( $dateYmd, $user, true ); // Unset class from above if needed. if ( $class == 'class="row"' || $class == 'class="hasevents"' ) $class = ''; if ( ! empty ( $entryStr ) && $entryStr != ' ' ) $class = 'class="hasevents"'; else if ( $dateYmd == $todayYmd ) $class = 'class="today"'; else if ( $is_weekend ) $class = 'class="weekend"'; echo ' <td ' . $class . ' style="width:' . $tdw . '%;"'; if ( $can_add ) echo " ondblclick=\"dblclick_add( '$dateYmd', '$user', 0, 0 )\""; echo '>' . $entryStr . '</td>'; } echo ' </tr>'; } echo ' </table>'; } $user = ''; // reset echo ( empty( $eventinfo ) ? '' : $eventinfo ) . $printerStr . print_trailer(); ?> PK �]�\�x[I I week_details.phpnu �[��� <?php // $Id: week_details.php,v 1.78 2009/11/22 22:26:18 bbannon Exp $ include_once 'includes/init.php'; send_no_cache_header(); load_user_layers ( $user != $login && $is_nonuser_admin ? $user : '' ); load_user_categories(); $next = mktime ( 0, 0, 0, $thismonth, $thisday + 7, $thisyear ); $prev = mktime ( 0, 0, 0, $thismonth, $thisday - 7, $thisyear ); $wkstart = get_weekday_before ( $thisyear, $thismonth, $thisday + 1 ); $start_ind = 0; $thisdate = date ( 'Ymd', $wkstart ); $wkend = $wkstart + ( 86400 * ( $DISPLAY_WEEKENDS == 'N' ? 5 : 7 ) ); if ( $DISPLAY_WEEKENDS == 'N' ) { if ( $WEEK_START == 1 ) $end_ind = 4; else { $start_ind = 1; $end_ind = 5; } } else $end_ind = 6; $printerStr = generate_printer_friendly ( 'week_details.php' ); /* Pre-Load the repeated events for quckier access. */ $repeated_events = read_repeated_events ( ( strlen ( $user ) ? $user : $login ), $wkstart, $wkend, $cat_id ); /* Pre-load the non-repeating events for quicker access. */ $events = read_events ( ( strlen ( $user ) ? $user : $login ), $wkstart, $wkend, $cat_id ); if ( $WEEK_START == 0 && $DISPLAY_WEEKENDS == 'N' ) $wkstart = $wkstart - 86400; for ( $i = 0; $i < 7; $i++ ) { $days[$i] = ( $wkstart + 86400 * $i ) + 43200; $weekdays[$i] = weekday_name ( ( $i + $WEEK_START ) % 7, $DISPLAY_LONG_DAYS ); $header[$i] = $weekdays[$i] . ' ' . date_to_str ( date ( 'Ymd', $days[$i] ), $DATE_FORMAT_MD, false ); } $nextStr = translate ( 'Next' ); $newEntryStr = translate ( 'New Entry' ); $prevStr = translate ( 'Previous' ); print_header( array( 'js/popups.js/true' ), generate_refresh_meta() ); echo ' <div class="title"> <a title="' . $prevStr . '" class="prev" href="week_details.php?' . $u_url . 'date=' . date ( 'Ymd', $prev ) . $caturl . '"><img src="images/leftarrow.gif" alt="' . $prevStr . '" /></a> <a title="' . $nextStr . '" class="next" href="week_details.php?' . $u_url . 'date=' . date ( 'Ymd', $next ) . $caturl . '"><img src="images/rightarrow.gif" alt="' . $nextStr . '" /></a> <span class="date">' . date_to_str ( date ( 'Ymd', $wkstart ), '', false ) . ' - ' . date_to_str ( date ( 'Ymd', $wkend ), '', false ) . '</span>' . ( $DISPLAY_WEEKNUMBER == 'Y' ? '<br /> <span class="titleweek">(' . translate ( 'Week' ) . ' ' . date ( 'W', $wkstart + 86400 ) . ')</span>' : '' ) . ' <span class="user">' . ( $single_user == 'N' ? '<br /> ' . $user_fullname : '' ) . ( $is_nonuser_admin ? '<br />-- ' . translate ( 'Admin mode' ) . ' --' : '' ) . ( $is_assistant ? '<br />-- ' . translate ( 'Assistant mode' ) . ' --' : '' ) . '</span>' . ( $CATEGORIES_ENABLED == 'Y' ? '<br /><br />' . print_category_menu( 'week', sprintf ( "%04d%02d%02d", $thisyear, $thismonth, $thisday ), $cat_id ) : '' ) . ' </div><br /> <center> <table class="main">'; $untimed_found = false; for ( $d = 0; $d < 7; $d++ ) { $date = date ( 'Ymd', $days[$d] ); $thiswday = date ( 'w', $days[$d] ); $is_weekend = ( $thiswday == 0 || $thiswday == 6 ); if ( $is_weekend && $DISPLAY_WEEKENDS == 'N' ) continue; $class = ( $date == date ( 'Ymd', $today ) ? ' class="today">' : ( $is_weekend ? ' class="weekend">' : '>' ) ); echo ' <tr> <th' . $class . ( $can_add ? ' <a title="' . $newEntryStr . '" href="edit_entry.php?' . $u_url . 'date=' . date ( 'Ymd', $days[$d] ) . '"><img src="images/new.gif" class="new" alt="' . $newEntryStr . '" /></a>' : '' ) . ' <a title="' . $header[$d] . '" href="day.php?' . $u_url . 'date=' . date ( 'Ymd', $days[$d] ) . $caturl . '">' . $header[$d] . '</a> </th> </tr> <tr> <td' . $class; print_det_date_entries ( $date, $user, true ); echo ' </td> </tr>'; } echo ' </table> </center> ' . ( empty ( $eventinfo ) ? '' : $eventinfo ) . '<br />' . $printerStr . print_trailer (); /** * Prints the HTML for one event in detailed view. * * @param Event $event The event * @param string $date The date for which we're printing (in YYYYMMDD format) */ function print_detailed_entry ( $event, $date ) { global $eventinfo, $layers, $login, $user; static $key = 0; $descStr = $event->getDescription(); $evAccessStr = $event->getAccess(); $evPri = ( $event->getPriority() < 4 ); $getExtStr = $event->getExtForID(); $loginStr = $event->getLogin(); $name = $event->getName(); $class = ( $login != $loginStr && strlen ( $loginStr ) ? 'layer' : ( $event->getStatus() == 'W' ? 'unapproved' : '' ) ) . 'entry'; if ( $getExtStr != '' ) { $id = $getExtStr; $name .= ' (' . translate ( 'cont.' ) . ')'; } else $id = $event->getID(); $linkid = 'pop' . "$id-$key"; $key++; echo ( $evPri ? ' <strong>' : '' ) . ' <a title="' . translate ( 'View this entry' ) . '" class="' . $class . '" id="' . $linkid . '" href="view_entry.php?id=' . $id . '&date=' . $date; if ( strlen ( $user ) > 0 ) echo '&user=' . $user; else if ( $class == 'layerentry' ) echo '&user=' . $loginStr; echo '<img src="images/circle.gif" class="bullet" alt="view icon" />'; if ( $login != $loginStr && strlen ( $loginStr ) ) { if ( $layers ) { foreach ( $layers as $layer ) { if ( $layer['cal_layeruser'] == $loginStr ) { $in_span = true; echo ' <span style="color:#' . $layer['cal_color'] . ';">'; } } } } $timestr = ''; if ( $event->isAllDay() ) $timestr = translate ( 'All day event' ); else if ( $event->getDuration() > 0 ) { $timestr = display_time ( $event->getDateTime() ) . ' - ' . display_time ( $event->getEndDateTime() ); echo $timestr . '» '; } if ( $login != $user && $evAccessStr == 'R' && strlen ( $user ) ) $PN = $PD = '(' . translate ( 'Private' ) . ')'; elseif ( $login != $loginStr && $evAccessStr == 'R' && strlen ( $loginStr ) ) $PN = $PD = '(' . translate ( 'Private' ) . ')'; elseif ( $login != $loginStr && strlen ( $loginStr ) ) { $PN = htmlspecialchars ( $name ); $PD = activate_urls ( htmlspecialchars ( $descStr ) ); } else { $PN = htmlspecialchars ( $name ); $PD = activate_urls ( htmlspecialchars ( $descStr ) ); } if ( ! empty ( $in_span ) ) $PN .= '</span>'; echo $PN . '</a>' . ( $evPri ? ' </strong>' : '' ) # Only display description if it is different than the event name. . ( $PN != $PD ? ' - ' . $PD : '' ) . '<br />'; $eventinfo .= build_entry_popup ( 'eventinfo-' . $linkid, $loginStr, $descStr, $timestr, site_extras_for_popup ( $id ) ); } /** * Print all the calendar entries for the specified user for the specified date. * If we are displaying data from someone other than the logged in user, * then check the access permission of the entry. * * @param string $date - date in YYYYMMDD format * @param string $user - username * @param bool $is_ssi - is this being called from week_ssi.php? */ function print_det_date_entries ( $date, $user, $ssi ) { global $events, $is_admin, $readonly; $date = mktime ( 0, 0, 0, substr ( $date, 4, 2 ), substr ( $date, 6, 2 ), substr ( $date, 0, 4 ) ); // Get and sort all the repeating and non-repeating events for this date. $ev = combine_and_sort_events ( get_entries ( $date ), get_repeating_entries ( $user, $date ) ); for ( $i = 0, $cnt = count ( $ev ); $i < $cnt; $i++ ) { if ( ( ! empty ( $DISPLAY_UNAPPROVED ) && $DISPLAY_UNAPPROVED != 'N' ) || $ev[$i]->getStatus() == 'A' ) print_detailed_entry ( $ev[$i], $date ); } } ?> PK �]�\rJ7� � colors.phpnu �[��� <?php // $Id: colors.php,v 1.37 2009/11/22 16:47:44 bbannon Exp $ include_once 'includes/init.php'; $color = getGetValue ( 'color' ); if ( empty ( $color ) ) exit; $addcustomStr = translate ( 'Add Custom' ); $basicStr = translate ( 'Basic Colors' ); $cancelStr = translate ( 'Cancel' ); $currentStr = translate ( 'Current Color' ); $customStr = translate ( 'Custom Colors' ); $oldStr = translate ( 'Old Color' ); $okStr = ' ' . translate ( 'OK' ). ' '; print_header( '', '<script type="text/javascript" src="includes/js/colors.js"></script>', 'onload="fillhtml(); setInit();"', true, false, true ); /* HTML Color Editor v1.2 (c) 2000 by Sebastian Weber <webersebastian@yahoo.de> Modified by Ray Jones for inclusion into WebCalendar. NOTE: In-line CSS styles must remain in this file for proper operation */ echo <<<EOT <form action="colors.php" name="colorpicker"> <input type="hidden" id="colorcell" value="{$color}" /> <table cellspacing="2" class="aligncenter"> <tr> <td colspan="3"> <img height="1" src="images/blank.gif" alt="" /></td> </tr> <tr> <td class="aligncenter">{$basicStr}</td> <!-- COLORS PICTURE --> <td rowspan="5" width="220" class="aligncenter"> <img id="colorpic" height="192" width="192" src="images/colors.jpg" onclick="setFromImage(event);" alt="" /></td> <!-- ***** SLIDER **** --> <td rowspan="5"> <table width="24" onclick="setFromSlider(event);"> <tr> <td id="slider"></td> </tr> </table> </td> </tr> <tr> <!-- BASIC COLORS PALETTE --> <td class="aligncenter" id="colorchoices"></td> </tr> <tr> <td class="aligncenter">{$customStr}</td> </tr> <tr> <!-- Custom Colors --> <td class="aligncenter" id="colorcustom"></td> </tr> <tr> <td class="aligncenter"><input type="button" value="{$addcustomStr}" onclick="definePreColor()" /></td> </tr> <tr> <td class="aligntop" colspan="3"> <table cellpadding="2"> <tr class="aligncenter"> <td colspan="2" height="30" class="alignbottom">{$currentStr}</td> <td class="alignbottom">{$oldStr}</td> </tr> <tr> <!-- RGB INPUT --> <td class="boxtop boxbottom boxleft aligntop alignright"> R: <input id="rgb_r" type="text" size="3" maxlength="3" value="255" onchange="setFromRGB()" /><br /> G: <input id="rgb_g" type="text" size="3" maxlength="3" value="255" onchange="setFromRGB()" /><br /> B: <input id="rgb_b" type="text" size="3" maxlength="3" value="255" onchange="setFromRGB()" /><br /> HTML: <input id="htmlcolor" type="text" size="6" maxlength="6" value="FFFFFF" onchange="setFromHTML()" /> </td> <td class="boxtop boxright boxbottom" width="120"> <table id="thecell" bgcolor="#FFFFFF" class="aligncenter" border="1"> <tr> <td><img src="images/blank.gif" width="55" height="53" alt="" /></td> </tr> </table> </td> <td class="alignmiddle aligncenter boxtop boxright boxbottom"> <!-- Display New Color --> <table id="theoldcell" bgcolor="#FFFFFF" border="1"> <tr> <td><img src="images/blank.gif" width="55" height="53" alt="" /></td> </tr> </table> </td> </tr> </table> </td> </tr> <tr> <td colspan="3" class="aligncenter" height="30"> <input type="button" value=" {$okStr} " onclick="transferColor(); window.close()" /> <input type="button" value="{$cancelStr}" onclick="window.close()" /> </td> </tr> </table> </form> <img id="cross" src="images/cross.gif" alt="" style="position:absolute; left:0; top:0" /> <img id="sliderarrow" src="images/arrow.gif" alt="" style="position:absolute; left:0; top:0" /> </body> </html> EOT; ?> PK �]�\Uy�0 edit_nonusers_handler.phpnu �[��� <?php include_once 'includes/init.php'; require_valid_referring_url (); load_user_layers(); if ( ! $is_admin ) { echo print_not_auth( true ) . '</body></html>'; exit; } $error = ''; $delete = getPostValue ( 'delete' ); $save = getPostValue ( 'Save' ); $add = getPostValue ( 'Add' ); $nid = getPostValue ( 'nid' ); $nfirstname = getPostValue ( 'nfirstname' ); $nlastname = getPostValue ( 'nlastname' ); $nadmin = getPostValue ( 'nadmin' ); $old_admin = getPostValue ( 'old_admin' ); $ispublic = getPostValue ( 'ispublic' ); if ( empty ( $ispublic ) ) $ispublic = 'N'; if ( ! empty ( $delete ) ) { // delete this nonuser calendar // Get event ids for all events this user is a participant $events = get_users_event_ids ( $nid ); // Now count number of participants in each event... // If just 1, then save id to be deleted $delete_em = []; for ( $i = 0, $cnt = count ( $events ); $i < $cnt; $i++ ) { $res = dbi_execute ( 'SELECT COUNT( * ) FROM webcal_entry_user WHERE cal_id = ?', [$events[$i]] ); if ( $res ) { if ( $row = dbi_fetch_row ( $res ) ) { if ( $row[0] == 1 ) $delete_em[] = $events[$i]; } dbi_free_result ( $res ); } } // Now delete events that were just for this user for ( $i = 0, $cnt = count ( $delete_em ); $i < $cnt; $i++ ) { dbi_execute ( 'DELETE FROM webcal_entry_repeats WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_repeats_not WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_log WHERE cal_entry_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_import_data WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_site_extras WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry_ext_user WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_reminders WHERE cal_id =? ', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_blob WHERE cal_id = ?', [$delete_em[$i]] ); dbi_execute ( 'DELETE FROM webcal_entry WHERE cal_id = ?', [$delete_em[$i]] ); } // Delete user participation from events dbi_execute ( 'DELETE FROM webcal_entry_user WHERE cal_login = ?', [$nid] ); // Delete any layers other users may have that point to this user. dbi_execute ( 'DELETE FROM webcal_user_layers WHERE cal_layeruser = ?', [$nid] ); // Delete any UAC calendar access entries for this user. dbi_execute ( 'DELETE FROM webcal_access_user WHERE cal_login = ? OR cal_other_user = ?', [$nid, $nid] ); // Delete any UAC function access entries for this user. dbi_execute ( 'DELETE FROM webcal_access_function WHERE cal_login = ?', [$nid] ); // Delete user if ( ! dbi_execute ( 'DELETE FROM webcal_nonuser_cals WHERE cal_login = ?', [$nid] ) ) $error = db_error(); } else { if ( ! empty ( $save ) ) { // Updating $query_params = []; $sql = 'UPDATE webcal_nonuser_cals SET '; if ($nlastname) { $sql .= ' cal_lastname = ?, '; $query_params[] = $nlastname; } if ($nfirstname) { $sql .= ' cal_firstname = ?, '; $query_params[] = $nfirstname; } if ( $ispublic ) { $sql .= ' cal_is_public = ?, '; $query_params[] = $ispublic; } $query_params[] = $nadmin; $query_params[] = $nid; if ( ! dbi_execute ( $sql . 'cal_admin = ? WHERE cal_login = ?', $query_params ) ) $error = db_error(); } else { // Adding if ( preg_match ( '/^[\w]+$/', $nid ) ) { $nid = $NONUSER_PREFIX.$nid; if ( ! dbi_execute ( 'INSERT INTO webcal_nonuser_cals ( cal_login, cal_firstname, cal_lastname, cal_admin, cal_is_public ) VALUES ( ?, ?, ?, ?, ? )', [$nid, $nfirstname, $nlastname, $nadmin, $ispublic] ) ) { $error = db_error(); } } else { $error = translate ( 'Calendar ID' ).' '.translate ( 'word characters only' ).'.'; } } //Add entry in UAC access table for new admin and remove for of admin //first delete any record for this user/nuc combo dbi_execute ( 'DELETE FROM webcal_access_user WHERE cal_login = ? AND cal_other_user = ?', [$nadmin, $nid] ); if ( ! dbi_execute ( 'INSERT INTO webcal_access_user ( cal_login, cal_other_user, cal_can_view, cal_can_edit, cal_can_approve, cal_can_invite, cal_can_email, cal_see_time_only ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )', [$nadmin, $nid, 511, 511, 511, 'Y', 'Y', 'N'] ) ) { die_miserable_death ( translate ( 'Database error' ) . ': ' . dbi_error() ); } // Delete old admin... //TODO Make this an optional step if ( ! empty ( $old_admin ) ) dbi_execute ( 'DELETE FROM webcal_access_user WHERE cal_login = ? AND cal_other_user = ?', [$old_admin, $nid] ); } echo error_check('users.php?tab=nonusers', false); ?> PK �]�\�I��� � help_edit_entry.phpnu �[��� <?php include_once 'includes/init.php'; include_once 'includes/help_list.php'; print_header ( '', '', '', true ); echo $helpListStr . ' <h2>' . translate ( 'Help' ) . ': ' . translate ( 'Adding/Editing Calendar Entries' ) . '</h2>'; $tmp_arr = [ translate ( 'Brief Description' ) => translate ( 'brief-description-help' ), translate ( 'Full Description' ) => translate ( 'full-description-help' ), translate ( 'Date' ) => translate ( 'date-help' ), translate ( 'Time' ) => translate ( 'time-help' )]; if ( $TIMED_EVT_LEN != 'E' ) $tmp_arr[ translate ( 'Duration' ) ] = translate ( 'duration-help' ); else $tmp_arr[ translate ( 'End Time' ) ] = translate ( 'end-time-help' ); if ( $DISABLE_PRIORITY_FIELD != 'Y' ) $tmp_arr[ translate ( 'Priority' ) ] = translate ( 'priority-help' ); if ( $DISABLE_ACCESS_FIELD != 'Y' ) $tmp_arr[ translate ( 'Access' ) ] = translate ( 'access-help' ); if ( $single_user == 'N' && ( $is_admin || $DISABLE_PARTICIPANTS_FIELD != 'Y' ) ) $tmp_arr[ translate ( 'Participants' ) ] = translate ( 'participants-help' ); if ( $DISABLE_REPEATING_FIELD != 'Y' ) { $tmp_arr[ translate ( 'Repeat Type' ) ] = translate ( 'repeat-type-help' ); list_help ( $tmp_arr ); echo ' <p><a class="underline" href="docs/WebCalendar-UserManual.html#repeat">' . translate ( 'For More Information...' ) . '</a></p>'; $tmp_arr = [ translate ( 'Repeat End Date' ) => translate ( 'repeat-end-date-help' ), translate ( 'Repeat Day' ) => translate ( 'repeat-day-help' ), translate ( 'Frequency' ) => translate ( 'repeat-frequency-help' )]; list_help ( $tmp_arr ); } echo print_trailer ( false, true, true ); ?> PK �]�\�r89�# �# search_handler.phpnu �[��� <?php /** * This page produces search results. * * "Advanced Search" adds the ability to search other users' calendars. * We do a number of security checks to make sure this is allowed. * * @author Craig Knudsen <cknudsen@cknudsen.com> * @copyright Craig Knudsen, <cknudsen@cknudsen.com>, http://www.k5n.us/cknudsen * @license http://www.gnu.org/licenses/gpl.html GNU GPL * @package WebCalendar */ include_once 'includes/init.php'; require_valid_referring_url (); $error = ''; // Disable if public access and OVERRIDE_PUBLIC in use if ( $login == '__public__' && ! empty ( $OVERRIDE_PUBLIC ) && $OVERRIDE_PUBLIC == 'Y' ) { print_header(); echo print_not_auth(); print_trailer(); exit; } $keywords = getValue ( 'keywords' ); $advanced = getValue ( 'advanced' ); if ( strlen ( $keywords ) == 0 ) $error = translate( 'You must enter one or more search keywords.' ); $matches = 0; // Determine if this user is allowed to search the calendar of other users $search_others = false; // show "Advanced Search" if ( $single_user == 'Y' ) $search_others = false; if ( $is_admin ) $search_others = true; else if ( access_is_enabled() ) $search_others = access_can_access_function ( ACCESS_ADVANCED_SEARCH ); else if ( $login != '__public__' && ! empty ( $ALLOW_VIEW_OTHER ) && $ALLOW_VIEW_OTHER == 'Y' ) $search_others = true; else if ( $login == '__public__' && ! empty ( $PUBLIC_ACCESS_OTHERS ) && $PUBLIC_ACCESS_OTHERS == 'Y' ) $search_others = true; $users = getValue ( 'users' ); if ( empty ( $users ) || empty ( $users[0] ) ) $search_others = false; // Security precaution -- make sure users listed in participants list // was not hacked up to include users that they don't really have access to. if ( $search_others ) { // If user can only see users in his group, then remove users not in his group. if ( ! empty ( $USER_SEES_ONLY_HIS_GROUPS ) && $USER_SEES_ONLY_HIS_GROUPS == 'Y' && ! empty ( $GROUPS_ENABLED ) && $GROUPS_ENABLED == 'Y' ) { $myusers = get_my_users ( '', 'view' ); $userlookup = []; for ( $i = 0, $cnt = count ( $myusers ); $i < $cnt; $i++ ) { $userlookup[$myusers[$i]['cal_login']] = 1; } $newlist = []; $cnt = count ( $users ); for ( $i = 0; $i < $cnt; $i++ ) { if ( ! empty ( $userlookup[$users[$i]] ) ) $newlist[] = $users[$i]; } $users = $newlist; } // Now, use access control to remove more users :-) if ( access_is_enabled() && ! $is_admin ) { $newlist = []; for ( $i = 0; $i < count ( $users ); $i++ ) { if ( access_user_calendar ( 'view', $users[$i] ) ) { $newlist[] = $users[$i]; //echo "can access $users[$i] <br />"; } else { //echo "cannot access $users[$i] <br />"; } } $users = $newlist; } } if ( empty ( $users ) || empty ( $users[0] ) ) $search_others = false; //Get advanced filters $cat_filter = getPostValue ( 'cat_filter' ); $extra_filter = getPostValue ( 'extra_filter' ); $date_filter = getPostValue ( 'date_filter' ); $from_YMD = getPostValue ( 'from__YMD' ); if ( empty ( $from_YMD ) ) { $start_day = $start_month = $start_year = ''; } else { $start_year = intval ( substr ( $from_YMD, 0, 4 ) ); $start_month = intval ( substr ( $from_YMD, 4, 2 ) ); $start_day = intval ( substr ( $from_YMD, 6, 2 ) ); if ( $start_year < 1970 ) $start_year = 1970; } $end_YMD = getPostValue ( 'until__YMD' ); if ( empty ( $end_YMD ) ) { $end_day = $end_month = $end_year = ''; } else { $end_year = intval ( substr ( $end_YMD, 0, 4 ) ); $end_month = intval ( substr ( $end_YMD, 4, 2 ) ); $end_day = intval ( substr ( $end_YMD, 6, 2 ) ); if ( $end_year < 1970 ) $end_year = 1970; } if ( $date_filter == 3 ) {//Use Date Range $startDate = gmdate( 'Ymd', gmmktime( 0, 0, 0, $start_month, $start_day, $start_year ) ); $endDate = gmdate( 'Ymd', gmmktime( 23, 59, 59, $end_month, $end_day, $end_year ) ); } print_header(); echo ' <h2>' . translate ( 'Search Results' ) . '</h2>'; if ( ! empty ( $error ) ) echo print_error ( $error ); else { // *** "Phrase" feature by Steve Weyer saweyer@comcast.net 4-May-2005 // check if keywords is surrounded by quotes // an alternative might be to add a checkbox/list on search.php // to indicate Phrase or other mode via an arg // if a phrase, use (after removing quotes) rather than split into words // also add query (keywords) to "match results" heading near end // e.g., search_handler.php?keywords=%22Location:%20Arts%20and%20Crafts%22 // begin Phrase modification $klen = strlen ( $keywords ); $phrasedelim = "\\\""; $plen = strlen ( $phrasedelim ); if ( substr ( $keywords, 0, $plen ) == $phrasedelim && substr ( $keywords, $klen - $plen ) == $phrasedelim ) { $phrase = substr ( $keywords, $plen, $klen - ( $plen * 2 ) ); $words = [$phrase]; } else // original (default) behavior $words = explode ( ' ', $keywords ); // end Phrase modification $order = 'DESC'; $word_cnt = count ( $words ); for ( $i = 0; $i < $word_cnt; $i++ ) { $sql_params = []; // Note: we only search approved/waiting events (not deleted). $sql = 'SELECT we.cal_id, we.cal_name, we.cal_date, weu.cal_login ' . ( empty( $extra_filter ) ? '' : ', wse.cal_data ' ) . 'FROM webcal_entry_user weu LEFT JOIN webcal_entry we ' . ( empty( $cat_filter ) ? '' : ', webcal_entry_categories wec ' ) . ( empty( $extra_filter ) ? '' : ', webcal_site_extras wse ' ) . 'ON weu.cal_id = we.cal_id WHERE weu.cal_status in ( \'A\',\'W\' ) AND weu.cal_login IN ( ?'; if ( $search_others ) { if ( empty ( $users[0] ) ) $sql_params[0] = $users[0] = $login; $user_cnt = count ( $users ); for ( $j = 0; $j < $user_cnt; $j++ ) { if ( $j > 0 ) $sql .= ', ?'; $sql_params[] = $users[$j]; } } else $sql_params[] = $login; $sql .= ' ) '; if ( $search_others ) { // Don't search confidential entries of other users. $sql .= 'AND ( weu.cal_login = ? OR ( weu.cal_login != ? AND we.cal_access = \'P\' ) ) '; $sql_params[] = $login; $sql_params[] = $login; } // We get an error using mssql trying to read text column as varchar. // This workaround seems to fix it up ROJ // but, will only search the first 1kb of the description. $sql .= 'AND ( UPPER( we.cal_name ) LIKE UPPER( ? ) OR UPPER( ' . ( strcmp ( $GLOBALS['db_type'], 'mssql' ) == 0 ? 'CAST ( we.cal_description AS varchar (1024) )' : 'we.cal_description' ) . ' ) LIKE UPPER( ? ) '; $sql_params[] = '%' . $words[$i] . '%'; $sql_params[] = '%' . $words[$i] . '%'; //process advanced filters if ( ! empty ( $extra_filter ) ) { $sql .= ' OR wse.cal_data LIKE UPPER( ? )'; $sql_params[] = '%' . $words[$i] . '%'; } //close AND statement from above $sql .= ')'; if ( ! empty ( $cat_filter ) ) { $sql .= ' AND wec.cat_id = ? AND we.cal_id = wec.cal_id '; $sql_params[] = $cat_filter; } if ( ! empty ( $extra_filter ) ) $sql .= ' AND we.cal_id = wse.cal_id '; if ( ! empty ( $date_filter ) ) { if ( $date_filter == 1 ) { //Past entries $sql .= 'AND we.cal_date < ? '; $sql_params[] = date ( 'Ymd' ); } if ( $date_filter == 2 ) {//Upcoming entries $sql .= 'AND we.cal_date >= ? '; $sql_params[] = date ( 'Ymd' ); $order = 'ASC'; } if ( $date_filter == 3 ) {//Use Date Range $sql .= 'AND ( we.cal_date >= ? AND we.cal_date <= ? )'; $sql_params[] = $startDate; $sql_params[] = $endDate; } } $res = dbi_execute ( $sql . ' ORDER BY we.cal_date ' . $order . ', we.cal_name', $sql_params ); if ( $res ) { while ( $row = dbi_fetch_row ( $res ) ) { $info[$matches]['id'] = $row[0]; $info[$matches]['text'] = $row[1] . ' ( ' . date_to_str( $row[2] ) . ' )'; $info[$matches]['user'] = $row[3]; $matches++; } } dbi_free_result ( $res ); } } echo ' <p><strong>'; if ( $matches > 0 ) { // Let update_translation.pl pick up translations. // translate ( 'match found' ) translate ( 'matches found' ) echo $matches . ' ' . translate ( // line break to bypass update_translation.pl here. 'match' . ( $matches == 1 ? '' : 'es' ) . ' found' ); } else echo translate ( 'No matches found' ); echo ": " . htmlentities ( $keywords ) . '</strong>.</p>'; // now sort by number of hits if ( empty ( $error ) && empty ( $info ) ) { // no mtaches } else if ( empty ( $error ) ) { echo ' <ul>'; foreach ( $info as $result ) { echo ' <li><a class="nav" href="view_entry.php?id=' . $result['id'] . '&user=' . $result['user'] . '">' . $result['text'] . '</a></li>'; } echo ' </ul>'; } echo ' <form action="search.php' . ( ! empty ( $advanced ) ? '?adv=1' : '' ) . '" style="margin-left: 13px;" method="post"> <input type="submit" value="' . translate ( 'New Search' ) . '" /></form> ' . print_trailer (); ?> PK �]�\Ӿ��T&