PageRenderTime 308ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 1ms

/virtuoso-opensource-6.1.5/binsrc/tutorial/hosting/ho_s_30/WebCalendar/includes/functions.php

#
PHP | 3080 lines | 2277 code | 316 blank | 487 comment | 790 complexity | 1c68ddb71a9489b820e9e8ad51fa037f MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.0
  1. <?php
  2. #
  3. # This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
  4. # project.
  5. #
  6. # Copyright (C) 1998-2012 OpenLink Software
  7. #
  8. # This project is free software; you can redistribute it and/or modify it
  9. # under the terms of the GNU General Public License as published by the
  10. # Free Software Foundation; only version 2 of the License, dated June 1991.
  11. #
  12. # This program is distributed in the hope that it will be useful, but
  13. # WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. # General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. #
  21. #
  22. ?>
  23. <?php
  24. // Global variables for activity log
  25. $LOG_CREATE = "C";
  26. $LOG_APPROVE = "A";
  27. $LOG_REJECT = "X";
  28. $LOG_UPDATE = "U";
  29. $LOG_DELETE = "D";
  30. $LOG_NOTIFICATION = "N";
  31. $LOG_REMINDER = "R";
  32. $ONE_DAY = 86400;
  33. // Don't allow a user to put "login=XXX" in the URL if they are not
  34. // coming from the login.php page.
  35. if ( ! strstr ( $PHP_SELF, "login.php" ) && ! empty ( $GLOBALS["login"] ) ) {
  36. $GLOBALS["login"] = "";
  37. }
  38. // This code is a temporary hack to make the application work when
  39. // register_globals is set to Off in php.ini (the default setting in
  40. // PHP 4.2.0 and after).
  41. if ( ! empty ( $HTTP_GET_VARS ) ) {
  42. while (list($key, $val) = @each($HTTP_GET_VARS)) {
  43. if ( $key == "login" ) {
  44. if ( strstr ( $PHP_SELF, "login.php" ) ) {
  45. $GLOBALS[$key] = $val;
  46. }
  47. } else {
  48. $GLOBALS[$key] = $val;
  49. //echo "XXX $key<BR>";
  50. }
  51. //echo "GET var '$key' = '$val' <BR>";
  52. }
  53. reset ( $HTTP_GET_VARS );
  54. }
  55. if ( ! empty ( $HTTP_POST_VARS ) ) {
  56. while (list($key, $val) = @each($HTTP_POST_VARS)) {
  57. $GLOBALS[$key] = $val;
  58. }
  59. reset ( $HTTP_POST_VARS );
  60. }
  61. //while (list($key, $val) = @each($HTTP_POST_FILES)) {
  62. // $GLOBALS[$key] = $val;
  63. //}
  64. //while (list($key, $val) = @each($HTTP_SESSION_VARS)) {
  65. // $GLOBALS[$key] = $val;
  66. //}
  67. if ( ! empty ( $HTTP_COOKIE_VARS ) ) {
  68. while (list($key, $val) = @each($HTTP_COOKIE_VARS)) {
  69. $GLOBALS[$key] = $val;
  70. //echo "COOKIE var '$key' = '$val' <BR>";
  71. }
  72. reset ( $HTTP_COOKIE_VARS );
  73. }
  74. // Load default system settings (which can be updated via admin.php)
  75. // System settings are stored in webcal_config.
  76. // In addition to WebCalendar settings, plugin settings are also stored.
  77. // The convention for plugin settings is to prefix all settings with
  78. // the short name of the plugin. For example, for a plugin
  79. // called "Package Tracking" and a short name of "pt", all settings
  80. // would be prefixed with "pt." (as in "pt.somesetting").
  81. // (Some can also be overridden with user settings.
  82. // User settings are stored in webcal_pref.)
  83. function load_global_settings () {
  84. global $login, $readonly;
  85. global $SERVER_NAME, $SERVER_PORT, $REQUEST_URI, $_SERVER;
  86. if ( empty ( $SERVER_NAME ) )
  87. $REQUEST_URI = $_SERVER["SERVER_NAME"];
  88. if ( empty ( $SERVER_PORT ) )
  89. $REQUEST_URI = $_SERVER["SERVER_PORT"];
  90. if ( empty ( $REQUEST_URI ) )
  91. $REQUEST_URI = $_SERVER["REQUEST_URI"];
  92. $res = dbi_query ( "SELECT cal_setting, cal_value FROM webcal_config" );
  93. if ( $res ) {
  94. while ( $row = dbi_fetch_row ( $res ) ) {
  95. $setting = $row[0];
  96. $value = $row[1];
  97. //echo "Setting '$setting' to '$value' <br>\n";
  98. $GLOBALS[$setting] = $value;
  99. }
  100. dbi_free_result ( $res );
  101. }
  102. // If app name not set.... default to "Title". This gets translated
  103. // later since this function is typically called before translate.php
  104. // is included.
  105. // Note: We usually use translate($application_name) instead of
  106. // translate("Title").
  107. if ( ! isset ( $GLOBALS["application_name"] ) )
  108. $GLOBALS["application_name"] = "Title";
  109. // If $server_url not set, then calculate one for them, then store it
  110. // in the database.
  111. if ( empty ( $GLOBALS["server_url"] ) ) {
  112. if ( ! empty ( $SERVER_NAME ) && ! empty ( $REQUEST_URI ) ) {
  113. $ptr = strrpos ( $REQUEST_URI, "/" );
  114. if ( $ptr > 0 ) {
  115. $uri = substr ( $REQUEST_URI, 0, $ptr + 1 );
  116. $server_url = "http://" . $SERVER_NAME;
  117. if ( ! empty ( $SERVER_PORT ) && $SERVER_PORT != 80 )
  118. $server_url .= ":" . $SERVER_PORT;
  119. $server_url .= $uri;
  120. dbi_query ( "INSERT INTO webcal_config ( cal_setting, cal_value ) ".
  121. "VALUES ( 'server_url', '$server_url' )" );
  122. $GLOBALS["server_url"] = $server_url;
  123. }
  124. }
  125. }
  126. // If no font settings, then set some
  127. if ( empty ( $GLOBALS["FONTS"] ) ) {
  128. if ( $GLOBALS["LANGUAGE"] == "Japanese" )
  129. $GLOBALS["FONTS"] = "Osaka, Arial, Helvetica, sans-serif";
  130. else
  131. $GLOBALS["FONTS"] = "Arial, Helvetica, sans-serif";
  132. }
  133. }
  134. // Return a list of active plugins.
  135. // Should be called after load_global_settings() and
  136. // load_user_preferences().
  137. function get_plugin_list ( $include_disabled=false ) {
  138. // first get list of available plugins
  139. $sql = "SELECT cal_setting FROM webcal_config " .
  140. "WHERE cal_setting LIKE '%.plugin_status'";
  141. if ( ! $include_disabled )
  142. $sql .= " AND cal_value = 'Y'";
  143. $sql .= " ORDER BY cal_setting";
  144. $res = dbi_query ( $sql );
  145. $plugins = array ();
  146. if ( $res ) {
  147. while ( $row = dbi_fetch_row ( $res ) ) {
  148. $e = explode ( ".", $row[0] );
  149. if ( $e[0] != "" ) {
  150. $plugins[] = $e[0];
  151. }
  152. }
  153. dbi_free_result ( $res );
  154. } else {
  155. echo translate("Database error") . ": " . dbi_error (); exit;
  156. }
  157. if ( count ( $plugins ) == 0 ) {
  158. $plugins[] = "webcalendar";
  159. }
  160. return $plugins;
  161. }
  162. // Get plugins available to the current user.
  163. // Do this by getting a list of all plugins that are not disabled by
  164. // the administrator and make sure this user has not disabled any of
  165. // them.
  166. // It's done this was so that when an admin adds a new plugin, it
  167. // shows up on each users system automatically (until they disable it).
  168. function get_user_plugin_list () {
  169. $ret = array ();
  170. $all_plugins = get_plugin_list ();
  171. for ( $i = 0; $i < count ( $all_plugins ); $i++ ) {
  172. if ( $GLOBALS[$all_plugins[$i] . ".disabled"] != "N" )
  173. $ret[] = $all_plugins[$i];
  174. }
  175. return $ret;
  176. }
  177. // determine which browser
  178. // currently supported return values:
  179. // Mozilla (open source Mozilla 5.0) = "Mozilla/5"
  180. // Netscape (3.X, 4.X) = "Mozilla/[3,4]"
  181. // MSIE (4.X) = "MSIE 4"
  182. function get_web_browser () {
  183. if ( ereg ( "MSIE [0-9]", getenv ( "HTTP_USER_AGENT" ) ) )
  184. return "MSIE";
  185. if ( ereg ( "Mozilla/[234]", getenv ( "HTTP_USER_AGENT" ) ) )
  186. return "Netscape";
  187. if ( ereg ( "Mozilla/[5678]", getenv ( "HTTP_USER_AGENT" ) ) )
  188. return "Mozilla";
  189. return "Uknown";
  190. }
  191. // log a debug message
  192. function do_debug ( $msg ) {
  193. // log to /tmp/webcal-debug.log
  194. //error_log ( date ( "Y-m-d H:i:s" ) . "> $msg\n",
  195. // 3, "/tmp/webcal-debug.log" );
  196. //error_log ( date ( "Y-m-d H:i:s" ) . "> $msg\n",
  197. // 2, "sockieman:2000" );
  198. }
  199. // send a redirect to the specified page
  200. // MS IIS/PWS has a bug in which it does not allow us to send a cookie
  201. // and a redirect in the same HTTP header.
  202. // See the following for more info on the IIS bug:
  203. // http://www.faqts.com/knowledge_base/view.phtml/aid/9316/fid/4
  204. function do_redirect ( $url ) {
  205. global $SERVER_SOFTWARE, $_SERVER;
  206. if ( empty ( $SERVER_SOFTWARE ) )
  207. $SERVER_SOFTWARE = $_SERVER["SERVER_SOFTWARE"];
  208. //echo "SERVER_SOFTWARE = $SERVER_SOFTWARE <BR>"; exit;
  209. if ( substr ( $SERVER_SOFTWARE, 0, 5 ) == "Micro" ) {
  210. echo "<HTML><HEAD><TITLE>Redirect</TITLE>" .
  211. "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0; URL=$url\"></HEAD><BODY>" .
  212. "Redirecting to ... <A HREF=\"" . $url . "\">here</A>.</BODY></HTML>.\n";
  213. } else {
  214. Header ( "Location: $url" );
  215. echo "<HTML><HEAD><TITLE>Redirect</TITLE></HEAD><BODY>" .
  216. "Redirecting to ... <A HREF=\"" . $url . "\">here</A>.</BODY></HTML>.\n";
  217. }
  218. exit;
  219. }
  220. // send an HTTP login request
  221. function send_http_login () {
  222. global $lang_file, $application_name;
  223. if ( strlen ( $lang_file ) ) {
  224. Header ( "WWW-Authenticate: Basic realm=\"" . translate("Title") . "\"");
  225. Header ( "HTTP/1.0 401 Unauthorized" );
  226. echo "<HTML><HEAD><TITLE>Unauthorized</TITLE></HEAD><BODY>\n" .
  227. "<H2>" . translate("Title") . "</H2>" .
  228. translate("You are not authorized") .
  229. "\n</BODY></HTML>\n";
  230. } else {
  231. Header ( "WWW-Authenticate: Basic realm=\"WebCalendar\"");
  232. Header ( "HTTP/1.0 401 Unauthorized" );
  233. echo "<HTML><HEAD><TITLE>Unauthorized</TITLE></HEAD><BODY>\n" .
  234. "<H2>WebCalendar</H2>" .
  235. "You are not authorized" .
  236. "\n</BODY></HTML>\n";
  237. }
  238. exit;
  239. }
  240. // Generate a cookie that saves the last calendar view (month, week, day)
  241. // so we can return to this same page after a user edits/deletes/etc an
  242. // event
  243. function remember_this_view () {
  244. global $server_url, $REQUEST_URI;
  245. if ( empty ( $REQUEST_URI ) )
  246. $REQUEST_URI = $_SERVER["REQUEST_URI"];
  247. if ( empty ( $server_url ) )
  248. SetCookie ( "webcalendar_last_view", $REQUEST_URI );
  249. else
  250. SetCookie ( "webcalendar_last_view", $REQUEST_URI, 0, $server_url );
  251. }
  252. // Get the last page stored using above function.
  253. // Return empty string if we don't know.
  254. function get_last_view () {
  255. $val = $HTTP_COOKIE_VARS["webcalendar_last_view"];
  256. if ( empty ( $val ))
  257. $val = $_COOKIE["webcalendar_last_view"];
  258. return $val;
  259. }
  260. // Send header stuff that tells the browser not to cache this page.
  261. function send_no_cache_header () {
  262. header ( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
  263. header ( "Last-Modified: " . gmdate ( "D, d M Y H:i:s" ) . " GMT" );
  264. header ( "Cache-Control: no-store, no-cache, must-revalidate" );
  265. header ( "Cache-Control: post-check=0, pre-check=0", false );
  266. header ( "Pragma: no-cache" );
  267. }
  268. // Load the current user's preferences as global variables.
  269. // Also load the list of views for this user (not really a preference,
  270. // but this is a convenient place to put this...)
  271. function load_user_preferences () {
  272. global $login, $browser, $views, $prefarray, $is_assistant, $has_boss, $user;
  273. $lang_found = false;
  274. $browser = get_web_browser ();
  275. $browser_lang = get_browser_language ();
  276. $prefarray = array ();
  277. // Note: default values are set in config.php
  278. $res = dbi_query (
  279. "SELECT cal_setting, cal_value FROM webcal_user_pref " .
  280. "WHERE cal_login = '$login'" );
  281. if ( $res ) {
  282. while ( $row = dbi_fetch_row ( $res ) ) {
  283. $setting = $row[0];
  284. $value = $row[1];
  285. $sys_setting = "sys_" . $setting;
  286. // save system defaults
  287. if ( ! empty ( $GLOBALS[$setting] ) )
  288. $GLOBALS["sys_" . $setting] = $GLOBALS[$setting];
  289. $GLOBALS[$setting] = $value;
  290. $prefarray[$setting] = $value;
  291. if ( $setting == "LANGUAGE" )
  292. $lang_found = true;
  293. }
  294. dbi_free_result ( $res );
  295. }
  296. // get views for this user
  297. $res = dbi_query (
  298. "SELECT cal_view_id, cal_name, cal_view_type FROM webcal_view " .
  299. "WHERE cal_owner = '$login'" );
  300. if ( $res ) {
  301. $views = array ();
  302. while ( $row = dbi_fetch_row ( $res ) ) {
  303. $v = array (
  304. "cal_view_id" => $row[0],
  305. "cal_name" => $row[1],
  306. "cal_view_type" => $row[2]
  307. );
  308. $views[] = $v;
  309. }
  310. dbi_free_result ( $res );
  311. }
  312. // If user has not set a language preference, then use their browser
  313. // settings to figure it out, and save it in the database for future
  314. // use (email reminders).
  315. if ( ! $lang_found && strlen ( $login ) && $login != "__public__" ) {
  316. $LANGUAGE = $browser_lang;
  317. dbi_query ( "INSERT INTO webcal_user_pref " .
  318. "( cal_login, cal_setting, cal_value ) VALUES " .
  319. "( '$login', 'LANGUAGE', '$LANGUAGE' )" );
  320. }
  321. if ( empty ( $GLOBALS["DATE_FORMAT_MY"] ) )
  322. $GLOBALS["DATE_FORMAT_MY"] = "__month__ __yyyy__";
  323. if ( empty ( $GLOBALS["DATE_FORMAT_MD"] ) )
  324. $GLOBALS["DATE_FORMAT_MD"] = "__month__ __dd__";
  325. $is_assistant = user_is_assistant ( $login, $user );
  326. $has_boss = user_has_boss ( $login );
  327. }
  328. // Get the list of external users for an event
  329. // $use_mailto - when set to 1, email address will contain an HREF
  330. // link with a mailto URL.
  331. function event_get_external_users ( $event_id, $use_mailto=0 ) {
  332. global $error;
  333. $ret = "";
  334. $res = dbi_query ( "SELECT cal_fullname, cal_email " .
  335. "FROM webcal_entry_ext_user " .
  336. "WHERE cal_id = $event_id " .
  337. "ORDER by cal_fullname" );
  338. if ( $res ) {
  339. while ( $row = dbi_fetch_row ( $res ) ) {
  340. if ( strlen ( $ret ) )
  341. $ret .= "\n";
  342. $ret .= $row[0];
  343. if ( strlen ( $row[1] ) ) {
  344. if ( $use_mailto ) {
  345. $ret .= " <A HREF=\"mailto:$row[1]\">&lt;" .
  346. htmlentities ( $row[1] ) . "&gt;</A>";
  347. } else {
  348. $ret .= " &lt;". htmlentities ( $row[1] ) . "&gt;";
  349. }
  350. }
  351. }
  352. dbi_free_result ( $res );
  353. } else {
  354. echo translate("Database error") .": " . dbi_error ();
  355. echo "<P>SQL:<BR>$sql";
  356. exit;
  357. }
  358. return $ret;
  359. }
  360. // Add something to the activity log for an event
  361. // $user - user doing this
  362. // $user_cal - user who's calendar is affected
  363. function activity_log ( $event_id, $user, $user_cal, $type, $text ) {
  364. $next_id = 1;
  365. if ( empty ( $type ) ) {
  366. echo "Error: type not set for activity log!";
  367. // but don't exit since we may be in mid-transaction
  368. return;
  369. }
  370. $res = dbi_query ( "SELECT MAX(cal_log_id) FROM webcal_entry_log" );
  371. if ( $res ) {
  372. if ( $row = dbi_fetch_row ( $res ) ) {
  373. $next_id = $row[0] + 1;
  374. }
  375. dbi_free_result ( $res );
  376. }
  377. $date = date ( "Ymd" );
  378. $time = date ( "Gis" );
  379. $sql_text = empty ( $text ) ? "NULL" : "'$text'";
  380. $sql_user_cal = empty ( $user_cal ) ? "NULL" : "'$user_cal'";
  381. $sql = "INSERT INTO webcal_entry_log ( " .
  382. "cal_log_id, cal_entry_id, cal_login, cal_user_cal, cal_type, " .
  383. "cal_date, cal_time, cal_text ) VALUES ( $next_id, $event_id, " .
  384. "'$user', $sql_user_cal, '$type', $date, $time, $sql_text )";
  385. if ( ! dbi_query ( $sql ) ) {
  386. echo "Database error: " . dbi_error ();
  387. echo "<P>SQL:<BR>$sql";
  388. exit;
  389. }
  390. }
  391. // Get a list of users. We used to just call user_get_users() directly.
  392. // Now, we use this instead. If groups are enabled, this can restrict
  393. // the list of users to only those users who are in the same group(s)
  394. // as the user.
  395. // We allow admin users to see all users because they can also edit
  396. // someone else's events (so they may need access to users who are not
  397. // in the same groups that they are in).
  398. function get_my_users () {
  399. global $login, $is_admin, $groups_enabled, $user_sees_only_his_groups;
  400. if ( $groups_enabled == "Y" && $user_sees_only_his_groups == "Y" &&
  401. ! $is_admin ) {
  402. // get groups that current user is in
  403. $res = dbi_query ( "SELECT cal_group_id FROM webcal_group_user " .
  404. "WHERE cal_login = '$login'" );
  405. $groups = array ();
  406. if ( $res ) {
  407. while ( $row = dbi_fetch_row ( $res ) ) {
  408. $groups[] = $row[0];
  409. }
  410. dbi_fetch_row ( $res );
  411. }
  412. $u = user_get_users ();
  413. $u_byname = array ();
  414. for ( $i = 0; $i < count ( $u ); $i++ ) {
  415. $name = $u[$i]['cal_login'];
  416. $u_byname[$name] = $u[$i];
  417. }
  418. $ret = array ();
  419. if ( count ( $groups ) == 0 ) {
  420. // Eek. User is in no groups... Return only themselves
  421. $ret[] = $u_byname[$login];
  422. return $ret;
  423. }
  424. // get list of users in the same groups as current user
  425. $sql = "SELECT DISTINCT(cal_login) from webcal_group_user " .
  426. "WHERE cal_group_id ";
  427. if ( count ( $groups ) == 1 )
  428. $sql .= "= " . $groups[0];
  429. else {
  430. $sql .= "IN ( " . implode ( ", ", $groups ) . " )";
  431. }
  432. //echo "SQL: $sql <P>\n";
  433. $res = dbi_query ( $sql );
  434. if ( $res ) {
  435. while ( $row = dbi_fetch_row ( $res ) ) {
  436. $ret[] = $u_byname[$row[0]];
  437. }
  438. dbi_free_result ( $res );
  439. }
  440. return $ret;
  441. } else {
  442. // groups not enabled... return all users
  443. //echo "No groups. ";
  444. return user_get_users ();
  445. }
  446. }
  447. // Get a preference setting for the specified user. If no value is
  448. // found in the db, then the system default setting will be returned.
  449. // params:
  450. // $user - user login we are getting preference for
  451. // $setting - the name of the setting
  452. function get_pref_setting ( $user, $setting ) {
  453. // set default
  454. if ( $GLOBALS["sys_" .$setting] == "" ) {
  455. // this could happen if the current user has not saved any pref. yet
  456. $ret = $GLOBALS[$setting];
  457. } else {
  458. $ret = $GLOBALS["sys_" .$setting];
  459. }
  460. $sql = "SELECT cal_value FROM webcal_user_pref " .
  461. "WHERE cal_login = '" . $user . "' AND " .
  462. "cal_setting = '" . $setting . "'";
  463. //echo "SQL: $sql <P>\n";
  464. $res = dbi_query ( $sql );
  465. if ( $res ) {
  466. if ( $row = dbi_fetch_row ( $res ) )
  467. $ret = $row[0];
  468. dbi_free_result ( $res );
  469. }
  470. return $ret;
  471. }
  472. // Get browser-specified language preference
  473. function get_browser_language () {
  474. global $HTTP_ACCEPT_LANGUAGE, $browser_languages;
  475. $ret = "";
  476. if ( strlen ( $HTTP_ACCEPT_LANGUAGE ) == 0 )
  477. return "none";
  478. $langs = explode ( ",", $HTTP_ACCEPT_LANGUAGE );
  479. for ( $i = 0; $i < count ( $langs ); $i++ ) {
  480. $l = strtolower ( trim ( $langs[$i] ) );
  481. $ret .= "\"$l\" ";
  482. if ( isset ( $browser_languages[$l] ) ) {
  483. return $browser_languages[$l];
  484. }
  485. }
  486. //if ( strlen ( $HTTP_ACCEPT_LANGUAGE ) )
  487. // return "none ($HTTP_ACCEPT_LANGUAGE not supported)";
  488. //else
  489. return "none";
  490. }
  491. // Load current user's layer info and stuff it into layer global variable.
  492. function load_user_layers ($user="",$force=0) {
  493. global $login;
  494. global $layers;
  495. global $LAYERS_STATUS;
  496. if ( $user == "" )
  497. $user = $login;
  498. $layers = array ();
  499. if ( $force || ( ! empty ( $LAYERS_STATUS ) && $LAYERS_STATUS != "N" ) ) {
  500. $res = dbi_query (
  501. "SELECT cal_layerid, cal_layeruser, cal_color, cal_dups " .
  502. "FROM webcal_user_layers " .
  503. "WHERE cal_login = '$user' ORDER BY cal_layerid" );
  504. if ( $res ) {
  505. $count = 0;
  506. while ( $row = dbi_fetch_row ( $res ) ) {
  507. $layers[$count] = array (
  508. "cal_layerid" => $row[0],
  509. "cal_layeruser" => $row[1],
  510. "cal_color" => $row[2],
  511. "cal_dups" => $row[3]
  512. );
  513. $count++;
  514. }
  515. dbi_free_result ( $res );
  516. }
  517. } else {
  518. //echo "Not loading!";
  519. }
  520. }
  521. // Build the HTML for the event popup (but don't print it yet since we
  522. // don't want this HTML to go inside the table for the month).
  523. function build_event_popup ( $divname, $user, $description, $time ) {
  524. global $login, $popup_fullnames, $popuptemp_fullname;
  525. $ret = "<DIV ID=\"" . $divname .
  526. "\" STYLE=\"position: absolute; z-index: 20; visibility: hidden; top: 0px; left: 0px;\">\n" .
  527. "<TABLE BORDER=\"0\" WIDTH=\"30%\" CELLPADDING=\"0\" CELLSPACING=\"1\"><TR><TD BGCOLOR=\"" .
  528. $GLOBALS["POPUP_FG"] . "\">\n" .
  529. "<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"0\" CELLSPACING=\"1\"><TR><TD BGCOLOR=\"" .
  530. $GLOBALS["POPUP_BG"] . "\" CLASS=\"popup\">\n" .
  531. "<FONT COLOR=\"" . $GLOBALS["POPUP_FG"] . "\">";
  532. if ( empty ( $popup_fullnames ) )
  533. $popup_fullnames = array ();
  534. if ( $user != $login ) {
  535. if ( empty ( $popup_fullnames[$user] ) ) {
  536. user_load_variables ( $user, "popuptemp_" );
  537. $popup_fullnames[$user] = $popuptemp_fullname;
  538. }
  539. $ret .= "<B>" . translate ("User") .
  540. ":</B> $popup_fullnames[$user]<BR>";
  541. }
  542. if ( strlen ( $time ) )
  543. $ret .= "<B>" . translate ("Time") . ":</B> $time<BR>";
  544. $ret .= "<B>" . translate ("Description") . ":</B>\n";
  545. $ret .= nl2br ( htmlspecialchars ( $description ) );
  546. $ret .= "</FONT></TD></TR></TABLE>\n" .
  547. "</TD></TR></TABLE>\n" .
  548. "</DIV>\n";
  549. return $ret;
  550. }
  551. // Print out a date selection for use in a form.
  552. // params:
  553. // $prefix - prefix to use in front of form element names
  554. // $date - currently selected date (in YYYYMMDD) format
  555. function print_date_selection ( $prefix, $date ) {
  556. print date_selection_html ( $prefix, $date );
  557. }
  558. // Generate a date selection for use in a form and return in.
  559. // params:
  560. // $prefix - prefix to use in front of form element names
  561. // $date - currently selected date (in YYYYMMDD) format
  562. function date_selection_html ( $prefix, $date ) {
  563. $ret = "";
  564. if ( strlen ( $date ) != 8 )
  565. $date = date ( "Ymd" );
  566. $thisyear = $year = substr ( $date, 0, 4 );
  567. $thismonth = $month = substr ( $date, 4, 2 );
  568. $thisday = $day = substr ( $date, 6, 2 );
  569. $ret .= "<SELECT NAME=\"" . $prefix . "day\">";
  570. for ( $i = 1; $i <= 31; $i++ )
  571. $ret .= "<OPTION " . ( $i == $thisday ? " SELECTED" : "" ) . ">$i";
  572. $ret .= "</SELECT>\n<SELECT NAME=\"" . $prefix . "month\">";
  573. for ( $i = 1; $i <= 12; $i++ ) {
  574. $m = month_short_name ( $i - 1 );
  575. $ret .= "<OPTION VALUE=\"$i\"" .
  576. ( $i == $thismonth ? " SELECTED" : "" ) . ">$m";
  577. }
  578. $ret .= "</SELECT>\n<SELECT NAME=\"" . $prefix . "year\">";
  579. for ( $i = -1; $i < 5; $i++ ) {
  580. $y = date ( "Y" ) + $i;
  581. $ret .= "<OPTION VALUE=\"$y\"" .
  582. ( $y == $thisyear ? " SELECTED" : "" ) . ">$y";
  583. }
  584. $ret .= "</SELECT>\n";
  585. $ret .= "<INPUT TYPE=\"button\" ONCLICK=\"selectDate('" .
  586. $prefix . "day','" . $prefix . "month','" . $prefix . "year',$date)\" VALUE=\"" .
  587. translate("Select") . "...\">";
  588. return $ret;
  589. }
  590. // Print the HTML for one day's events in the month view.
  591. // params:
  592. // $id - event id
  593. // $date - date (not used)
  594. // $time - time (in HHMMSS format)
  595. // $duration - event duration (in minutes)
  596. // $name - event name
  597. // $description - long description of event
  598. // $status - event status
  599. // $pri - event priority
  600. // $access - event access
  601. // $event_owner - user associated with this event
  602. // $hide_icons - hide icons to make printer-friendly
  603. function print_entry ( $id, $date, $time, $duration,
  604. $name, $description, $status,
  605. $pri, $access, $event_owner, $hide_icons ) {
  606. global $eventinfo, $login, $user, $PHP_SELF, $TZ_OFFSET;
  607. static $key = 0;
  608. global $layers;
  609. echo "<FONT SIZE=\"-1\">";
  610. if ( $login != $event_owner && strlen ( $event_owner ) ) {
  611. $class = "layerentry";
  612. } else {
  613. $class = "entry";
  614. if ( $status == "W" ) $class = "unapprovedentry";
  615. }
  616. // if we are looking at a view, then always use "entry"
  617. if ( strstr ( $PHP_SELF, "view_m.php" ) ||
  618. strstr ( $PHP_SELF, "view_w.php" ) ||
  619. strstr ( $PHP_SELF, "view_v.php" ) ||
  620. strstr ( $PHP_SELF, "view_t.php" ) )
  621. $class = "entry";
  622. if ( $pri == 3 ) echo "<B>";
  623. if ( ! $hide_icons ) {
  624. $divname = "eventinfo-$id-$key";
  625. $key++;
  626. echo "<A CLASS=\"$class\" HREF=\"view_entry.php?id=$id&date=$date";
  627. if ( strlen ( $user ) > 0 )
  628. echo "&user=" . $user;
  629. echo "\" onMouseOver=\"window.status='" . translate("View this entry") .
  630. "'; show(event, '$divname'); return true;\" onMouseOut=\"hide('$divname'); return true;\">";
  631. echo "<IMG SRC=\"circle.gif\" WIDTH=\"5\" HEIGHT=\"7\" BORDER=\"0\">";
  632. }
  633. if ( $login != $event_owner && strlen ( $event_owner ) )
  634. {
  635. for($index = 0; $index < sizeof($layers); $index++)
  636. {
  637. if($layers[$index]['cal_layeruser'] == $event_owner)
  638. {
  639. echo("<FONT COLOR=\"" . $layers[$index]['cal_color'] . "\">");
  640. }
  641. }
  642. }
  643. $timestr = "";
  644. if ( $duration == ( 24 * 60 ) ) {
  645. $timestr = translate("All day event");
  646. } else if ( $time != -1 ) {
  647. $my_time = $time + ( $TZ_OFFSET * 10000 );
  648. if ( $GLOBALS["TIME_FORMAT"] == "24" ) {
  649. printf ( "%02d:%02d", ( $my_time / 10000 ) % 24,
  650. ( $my_time / 100 ) % 100 );
  651. } else {
  652. $h = ( (int) ( $my_time / 10000 ) ) % 12;
  653. if ( $h == 0 ) $h = 12;
  654. echo $h;
  655. $m = ( $my_time / 100 ) % 100;
  656. if ( $m > 0 )
  657. printf ( ":%02d", $m );
  658. echo ( (int) ( $my_time / 10000 ) ) < 12 ? translate("am") : translate("pm");
  659. echo "&gt;";
  660. }
  661. $timestr = display_time ( $time );
  662. if ( $duration > 0 ) {
  663. if ( $duration == ( 24 * 60 ) ) {
  664. $timestr = translate("All day event");
  665. } else {
  666. // calc end time
  667. $h = (int) ( $time / 10000 );
  668. $m = ( $time / 100 ) % 100;
  669. $m += $duration;
  670. $d = $duration;
  671. while ( $m >= 60 ) {
  672. $h++;
  673. $m -= 60;
  674. }
  675. $end_time = sprintf ( "%02d%02d00", $h, $m );
  676. $timestr .= " - " . display_time ( $end_time );
  677. }
  678. }
  679. }
  680. if ( $login != $user && $access == 'R' && strlen ( $user ) )
  681. echo "(" . translate("Private") . ")";
  682. else
  683. if ( $login != $event_owner && $access == 'R' && strlen ( $event_owner ) )
  684. echo "(" . translate("Private") . ")";
  685. else
  686. if ( $login != $event_owner && strlen ( $event_owner ) )
  687. {
  688. echo htmlspecialchars ( $name );
  689. echo ("</FONT>");
  690. }
  691. else
  692. echo htmlspecialchars ( $name );
  693. echo "</A>";
  694. if ( $pri == 3 ) echo "</B>";
  695. echo "</FONT><BR>";
  696. if ( ! $hide_icons ) {
  697. if ( $login != $user && $access == 'R' && strlen ( $user ) )
  698. $eventinfo .= build_event_popup ( $divname, $event_owner,
  699. translate("This event is confidential"), "" );
  700. else
  701. if ( $login != $event_owner && $access == 'R' && strlen ( $event_owner ) )
  702. $eventinfo .= build_event_popup ( $divname, $event_owner,
  703. translate("This event is confidential"), "" );
  704. else
  705. $eventinfo .= build_event_popup ( $divname, $event_owner,
  706. $description, $timestr );
  707. }
  708. }
  709. // Get any site-specific fields for an entry that are stored in the database.
  710. // Return an array.
  711. // params:
  712. // $eventid - unique event id
  713. function get_site_extra_fields ( $eventid ) {
  714. $sql = "SELECT cal_name, cal_type, cal_date, cal_remind, cal_data " .
  715. "FROM webcal_site_extras " .
  716. "WHERE cal_id = $eventid";
  717. $res = dbi_query ( $sql );
  718. $extras = array ();
  719. if ( $res ) {
  720. while ( $row = dbi_fetch_row ( $res ) ) {
  721. // save by cal_name (e.g. "URL")
  722. $extras[$row[0]] = array (
  723. "cal_name" => $row[0],
  724. "cal_type" => $row[1],
  725. "cal_date" => $row[2],
  726. "cal_remind" => $row[3],
  727. "cal_data" => $row[4]
  728. );
  729. }
  730. dbi_free_result ( $res );
  731. }
  732. return $extras;
  733. }
  734. // Read all the events for a user for the specified range of dates.
  735. // This is only called once per page request to improve performance.
  736. // All the events get loaded into the array $events sorted by
  737. // time of day (not date).
  738. // params:
  739. // $user - username
  740. // $startdate - start date range, inclusive (in YYYYMMDD format)
  741. // $enddate - end date range, inclusive (in YYYYMMDD format)
  742. // $cat_id - category ID to filter on
  743. function read_events ( $user, $startdate, $enddate, $cat_id = '' ) {
  744. global $login;
  745. global $layers;
  746. global $TZ_OFFSET;
  747. $sy = substr ( $startdate, 0, 4 );
  748. $sm = substr ( $startdate, 4, 2 );
  749. $sd = substr ( $startdate, 6, 2 );
  750. $ey = substr ( $enddate, 0, 4 );
  751. $em = substr ( $enddate, 4, 2 );
  752. $ed = substr ( $enddate, 6, 2 );
  753. if ( $startdate == $enddate ) {
  754. if ( $TZ_OFFSET == 0 ) {
  755. $date_filter = " AND webcal_entry.cal_date = $startdate";
  756. } else if ( $TZ_OFFSET > 0 ) {
  757. $prev_day = mktime ( 3, 0, 0, $sm, $sd - 1, $sy );
  758. $cutoff = 24 - $TZ_OFFSET . "0000";
  759. $date_filter = " AND ( ( webcal_entry.cal_date = $startdate AND " .
  760. "( webcal_entry.cal_time <= $cutoff OR " .
  761. "webcal_entry.cal_time = -1 ) ) OR " .
  762. "( webcal_entry.cal_date = " . date("Ymd", $prev_day ) .
  763. " AND webcal_entry.cal_time >= $cutoff ) )";
  764. } else {
  765. $next_day = mktime ( 3, 0, 0, $sm, $sd + 1, $sy );
  766. $cutoff = 24 + $TZ_OFFSET . "0000";
  767. $date_filter = " AND ( ( webcal_entry.cal_date = $startdate AND " .
  768. "( webcal_entry.cal_time >= $cutoff OR " .
  769. "webcal_entry.cal_time = -1 ) ) OR " .
  770. "( webcal_entry.cal_date = " . date("Ymd", $next_day ) .
  771. " AND webcal_entry.cal_time < $cutoff ) )";
  772. }
  773. } else {
  774. if ( $TZ_OFFSET == 0 ) {
  775. $date_filter = " AND webcal_entry.cal_date >= $startdate " .
  776. "AND webcal_entry.cal_date <= $enddate";
  777. } else if ( $TZ_OFFSET > 0 ) {
  778. $prev_day = date ( ( "Ymd" ), mktime ( 3, 0, 0, $sm, $sd - 1, $sy ) );
  779. $enddate_minus1 = date ( ( "Ymd" ), mktime ( 3, 0, 0, $em, $ed - 1, $ey ) );
  780. $cutoff = 24 - $TZ_OFFSET . "0000";
  781. $date_filter = " AND ( ( webcal_entry.cal_date >= $startdate " .
  782. "AND webcal_entry.cal_date <= $enddate AND " .
  783. "webcal_entry.cal_time = -1 ) OR " .
  784. "( webcal_entry.cal_date = $prev_day AND " .
  785. "webcal_entry.cal_time >= $cutoff ) OR " .
  786. "( webcal_entry.cal_date = $enddate AND " .
  787. "webcal_entry.cal_time < $cutoff ) OR " .
  788. "( webcal_entry.cal_date >= $startdate AND " .
  789. "webcal_entry.cal_date <= $enddate_minus1 ) )";
  790. } else {
  791. // TZ_OFFSET < 0
  792. $next_day = date ( ( "Ymd" ), mktime ( 3, 0, 0, $sm, $sd + 1, $sy ) );
  793. $enddate_plus1 =
  794. date ( ( "Ymd" ), mktime ( 3, 0, 0, $em, $ed + 1, $ey ) );
  795. $cutoff = 24 + $TZ_OFFSET . "0000";
  796. $date_filter = " AND ( ( webcal_entry.cal_date >= $startdate " .
  797. "AND webcal_entry.cal_date <= $enddate AND " .
  798. "webcal_entry.cal_time = -1 ) OR " .
  799. "( webcal_entry.cal_date = $startdate AND " .
  800. "webcal_entry.cal_time >= $cutoff ) OR " .
  801. "( webcal_entry.cal_date = $enddate_plus1 AND " .
  802. "webcal_entry.cal_time < $cutoff ) OR " .
  803. "( webcal_entry.cal_date > $startdate AND " .
  804. "webcal_entry.cal_date < $enddate ) )";
  805. }
  806. }
  807. return query_events ( $user, false, $date_filter, $cat_id );
  808. }
  809. // Get all the events for a specific date from the array of pre-loaded
  810. // events (which was loaded all at once to improve performance).
  811. // The returned events will be sorted by time of day.
  812. // params:
  813. // $user - username
  814. // $date - date to get events for in YYYYMMDD format
  815. function get_entries ( $user, $date ) {
  816. global $events, $TZ_OFFSET;
  817. $n = 0;
  818. $ret = array ();
  819. //echo "<P>Checking " . count ( $events ) . " events. TZ_OFFSET = $TZ_OFFSET<P>";
  820. for ( $i = 0; $i < count ( $events ); $i++ ) {
  821. if ( $TZ_OFFSET == 0 ) {
  822. if ( $events[$i]['cal_date'] == $date )
  823. $ret[$n++] = $events[$i];
  824. } else if ( $TZ_OFFSET > 0 ) {
  825. $cutoff = ( 24 - $TZ_OFFSET ) * 10000;
  826. //echo "<P> cal_time " . $events[$i]['cal_time'] . "<P>";
  827. $sy = substr ( $date, 0, 4 );
  828. $sm = substr ( $date, 4, 2 );
  829. $sd = substr ( $date, 6, 2 );
  830. $prev_time = mktime ( 3, 0, 0, $sm, $sd - 1, $sy );
  831. $prev_date = date ( "Ymd", $prev_time );
  832. //echo "prev_date = $prev_day <P>";
  833. if ( $events[$i]['cal_date'] == $date &&
  834. $events[$i]['cal_time'] == -1 ) {
  835. $ret[$n++] = $events[$i];
  836. //echo "added event $events[$i][cal_id] <BR>";
  837. } if ( $events[$i]['cal_date'] == $date &&
  838. $events[$i]['cal_time'] < $cutoff ) {
  839. $ret[$n++] = $events[$i];
  840. //echo "added event $events[$i][cal_id] <BR>";
  841. } else if ( $events[$i]['cal_date'] == $prev_date &&
  842. $events[$i]['cal_time'] >= $cutoff ) {
  843. $ret[$n++] = $events[$i];
  844. //echo "added event $events[$i][cal_id] <BR>";
  845. }
  846. } else {
  847. $cutoff = ( 24 + $TZ_OFFSET ) * 10000;
  848. //echo "<P> cal_time " . $events[$i]['cal_time'] . "<P>";
  849. $sy = substr ( $date, 0, 4 );
  850. $sm = substr ( $date, 4, 2 );
  851. $sd = substr ( $date, 6, 2 );
  852. $next_time = mktime ( 3, 0, 0, $sm, $sd + 1, $sy );
  853. $next_date = date ( "Ymd", $next_time );
  854. //echo "next_date = $next_day <P>";
  855. if ( $events[$i]['cal_date'] == $date &&
  856. $events[$i]['cal_time'] == -1 ) {
  857. $ret[$n++] = $events[$i];
  858. //echo "added event $events[$i][cal_id] <BR>";
  859. } if ( $events[$i]['cal_date'] == $date &&
  860. $events[$i]['cal_time'] >= $cutoff ) {
  861. $ret[$n++] = $events[$i];
  862. //echo "added event $events[$i][cal_id] <BR>";
  863. } else if ( $events[$i]['cal_date'] == $next_date &&
  864. $events[$i]['cal_time'] < $cutoff ) {
  865. $ret[$n++] = $events[$i];
  866. //echo "added event $events[$i][cal_id] <BR>";
  867. }
  868. }
  869. }
  870. return $ret;
  871. }
  872. // Read events visible to a user (including layers); return results
  873. // in an array sorted by time of day.
  874. // params:
  875. // $user - username
  876. // $want_repeated - true to get repeating events; false to get
  877. // non-repeating.
  878. // $date_filter - SQL phrase starting with AND, to be appended to
  879. // the WHERE clause. May be empty string.
  880. // $cat_id - category ID to filter on. May be empty.
  881. function query_events ( $user, $want_repeated, $date_filter, $cat_id = '' ) {
  882. global $login;
  883. global $layers;
  884. $result = array ();
  885. $layers_byuser = array ();
  886. $sql = "SELECT webcal_entry.cal_name, webcal_entry.cal_description, "
  887. . "webcal_entry.cal_date, webcal_entry.cal_time, "
  888. . "webcal_entry.cal_id, webcal_entry.cal_ext_for_id, "
  889. . "webcal_entry.cal_priority, "
  890. . "webcal_entry.cal_access, webcal_entry.cal_duration, "
  891. . "webcal_entry_user.cal_status, "
  892. . "webcal_entry_user.cal_login ";
  893. if ( $want_repeated ) {
  894. $sql .= ", "
  895. . "webcal_entry_repeats.cal_type, webcal_entry_repeats.cal_end, "
  896. . "webcal_entry_repeats.cal_frequency, webcal_entry_repeats.cal_days "
  897. . "FROM webcal_entry, webcal_entry_repeats, webcal_entry_user "
  898. . "WHERE webcal_entry.cal_id = webcal_entry_repeats.cal_id AND ";
  899. } else {
  900. $sql .= "FROM webcal_entry, webcal_entry_user WHERE ";
  901. }
  902. $sql .= "webcal_entry.cal_id = webcal_entry_user.cal_id " .
  903. "AND webcal_entry_user.cal_status IN ('A','W') ";
  904. if ( $cat_id != '' ) $sql .= "AND webcal_entry_user.cal_category LIKE '$cat_id' ";
  905. if ( strlen ( $user ) > 0 )
  906. $sql .= "AND (webcal_entry_user.cal_login = '" . $user . "' ";
  907. if ( $user == $login && strlen ( $user ) > 0 ) {
  908. for ($index = 0; $index < sizeof($layers); $index++) {
  909. $layeruser = $layers[$index]['cal_layeruser'];
  910. $sql .= "OR webcal_entry_user.cal_login = '" . $layeruser . "' ";
  911. // while we are parsing the whole layers array, build ourselves
  912. // a new array that will help when we have to check for dups
  913. $layers_byuser["$layeruser"] = $layers[$index]['cal_dups'];
  914. }
  915. }
  916. if ( strlen ( $user ) > 0 )
  917. $sql .= ") ";
  918. $sql .= $date_filter;
  919. // now order the results by time and by entry id.
  920. $sql .= " ORDER BY webcal_entry.cal_time, webcal_entry.cal_id";
  921. //echo "<B>SQL:</B> $sql<P>";
  922. $res = dbi_query ( $sql );
  923. if ( $res ) {
  924. $i = 0;
  925. $checkdup_id = -1;
  926. $first_i_this_id = -1;
  927. while ( $row = dbi_fetch_row ( $res ) ) {
  928. if ($row[8] == 'R' || $row[8] == 'D') {
  929. continue; // don't show rejected/deleted ones
  930. }
  931. $item = array (
  932. "cal_name" => $row[0],
  933. "cal_description" => $row[1],
  934. "cal_date" => $row[2],
  935. "cal_time" => $row[3],
  936. "cal_id" => $row[4],
  937. "cal_ext_for_id" => $row[5],
  938. "cal_priority" => $row[6],
  939. "cal_access" => $row[7],
  940. "cal_duration" => $row[8],
  941. "cal_status" => $row[9],
  942. "cal_login" => $row[10],
  943. "cal_exceptions" => array()
  944. );
  945. if ( $want_repeated && ! empty ( $row[11] ) ) {
  946. $item['cal_type'] = empty ( $row[11] ) ? "" : $row[11];
  947. $item['cal_end'] = empty ( $row[12] ) ? "" : $row[12];
  948. $item['cal_frequency'] = empty ( $row[13] ) ? "" : $row[13];
  949. $item['cal_days'] = empty ( $row[14] ) ? "" : $row[14];
  950. }
  951. if ( $item['cal_id'] != $checkdup_id ) {
  952. $checkdup_id = $item['cal_id'];
  953. $first_i_this_id = $i;
  954. }
  955. if ( $item['cal_login'] == $user ) {
  956. // Insert this one before all other ones with this ID.
  957. my_array_splice ( $result, $first_i_this_id, 0, array($item) );
  958. $i++;
  959. if ($first_i_this_id + 1 < $i) {
  960. // There's another one with the same ID as the one we inserted.
  961. // Check for dup and if so, delete it.
  962. $other_item = $result[$first_i_this_id + 1];
  963. if ($layers_byuser[$other_item['cal_login']] == 'N') {
  964. // NOTE: array_splice requires PHP4
  965. my_array_splice ( $result, $first_i_this_id + 1, 1, "" );
  966. $i--;
  967. }
  968. }
  969. }
  970. else {
  971. if ($i == $first_i_this_id
  972. || ( ! empty ( $layers_byuser[$item['cal_login']] ) &&
  973. $layers_byuser[$item['cal_login']] != 'N' ) ) {
  974. // This item either is the first one with its ID, or allows dups.
  975. // Add it to the end of the array.
  976. $result [$i++] = $item;
  977. }
  978. }
  979. }
  980. dbi_free_result ( $res );
  981. }
  982. // Now load event exceptions and store as array in 'cal_exceptions' field
  983. if ( $want_repeated ) {
  984. for ( $i = 0; $i < count ( $result ); $i++ ) {
  985. if ( ! empty ( $result[$i]['cal_id'] ) ) {
  986. $res = dbi_query ( "SELECT cal_date FROM webcal_entry_repeats_not " .
  987. "WHERE cal_id = " . $result[$i]['cal_id'] );
  988. while ( $row = dbi_fetch_row ( $res ) ) {
  989. $result[$i]['cal_exceptions'][] = $row[0];
  990. }
  991. }
  992. }
  993. }
  994. return $result;
  995. }
  996. // Read all the repeated events for a user. This is only called once
  997. // per page request to improve performance. All the events get loaded
  998. // into the array $repeated_events sorted by time of day (not date).
  999. // params:
  1000. // $user - username
  1001. // $cat_id - category ID to filter on. May be empty.
  1002. function read_repeated_events ( $user, $cat_id = '' ) {
  1003. global $login;
  1004. global $layers;
  1005. return query_events ( $user, true, "", $cat_id );
  1006. }
  1007. //Returns all the dates a specific event will fall on accounting for
  1008. //the repeating. Any event with no end will be assigned one.
  1009. //params:
  1010. // $date - initial date in raw format
  1011. // $rpt_type - repeating type as stored in the database
  1012. // $end - end date
  1013. // $days - days events occurs on (for weekly)
  1014. // $ex_dates - array of exception dates for this event in YYYYMMDD format
  1015. // $freq - frequency of repetition
  1016. function get_all_dates ( $date, $rpt_type, $end, $days, $ex_days, $freq=1 ) {
  1017. global $conflict_repeat_months;
  1018. global $ONE_DAY;
  1019. $currentdate = floor($date/$ONE_DAY)*$ONE_DAY;
  1020. $realend = floor($end/$ONE_DAY)*$ONE_DAY;
  1021. $dateYmd = date ( "Ymd", $date );
  1022. if ($end=='NULL') {
  1023. // Check for $conflict_repeat_months months into future for conflicts
  1024. $thismonth = substr($dateYmd, 4, 2);
  1025. $thisyear = substr($dateYmd, 0, 4);
  1026. $thisday = substr($dateYmd, 6, 2);
  1027. $thismonth += $conflict_repeat_months;
  1028. if ($thismonth > 12) {
  1029. $thisyear++;
  1030. $thismonth -= 12;
  1031. }
  1032. $realend = mktime(3,0,0,$thismonth,$thisday,$thisyear);
  1033. }
  1034. $ret = array();
  1035. $ret[0] = $date;
  1036. //do iterative checking here.
  1037. //I floored the $realend so I check it against the floored date
  1038. if ($rpt_type && $currentdate < $realend) {
  1039. $cdate = $date;
  1040. if (!$freq) $freq = 1;
  1041. $n = 1;
  1042. if ($rpt_type == 'daily') {
  1043. //we do inclusive counting on end dates.
  1044. $cdate += $ONE_DAY * $freq;
  1045. while ($cdate <= $realend+$ONE_DAY) {
  1046. if ( ! is_exception ( $cdate, $ex_days ) )
  1047. $ret[$n++]=$cdate;
  1048. $cdate += $ONE_DAY * $freq;
  1049. }
  1050. } else if ($rpt_type == 'weekly') {
  1051. $daysarray = array();
  1052. $r=0;
  1053. $dow = date("w",$date);
  1054. $cdate = $date - ($dow * $ONE_DAY);
  1055. for ($i = 0; $i < 7; $i++) {
  1056. $isDay = substr($days, $i, 1);
  1057. if (strcmp($isDay,"y")==0) {
  1058. $daysarray[$r++]=$i * $ONE_DAY;
  1059. }
  1060. }
  1061. //we do inclusive counting on end dates.
  1062. while ($cdate <= $realend+$ONE_DAY) {
  1063. //add all of the days of the week.
  1064. for ($j=0; $j<$r;$j++) {
  1065. $td = $cdate + $daysarray[$j];
  1066. if ($td >= $date) {
  1067. if ( ! is_exception ( $cdate, $ex_days ) )
  1068. $ret[$n++] = $td;
  1069. }
  1070. }
  1071. //skip to the next week in question.
  1072. $cdate += ( $ONE_DAY * 7 ) * $freq;
  1073. }
  1074. } else if ($rpt_type == 'monthlyByDay') {
  1075. $dow = date('w', $date);
  1076. $thismonth = substr($dateYmd, 4, 2);
  1077. $thisyear = substr($dateYmd, 0, 4);
  1078. $week = floor(date("d", $date)/7);
  1079. $thismonth+=$freq;
  1080. $dow1 += date('w',mktime (3,0,0,$thismonth,1,$thisyear));
  1081. $t = $dow - $dow1;
  1082. if ($t < 0) $t += 7;
  1083. $day = 7*$week + $t + 1;
  1084. $cdate = mktime (3,0,0,$thismonth,$day,$thisyear);
  1085. while ($cdate <= $realend+$ONE_DAY) {
  1086. if ( ! is_exception ( $cdate, $ex_days ) )
  1087. $ret[$n++] = $cdate;
  1088. $thismonth+=$freq;
  1089. $dow1 += date('w',mktime (3,0,0,$thismonth,1,$thisyear));
  1090. $t = $dow - $dow1;
  1091. if ($t < 0) $t += 7;
  1092. $day = 7*$week + $t + 1;
  1093. $cdate = mktime (3,0,0,$thismonth,$day,$thisyear);
  1094. }
  1095. } else if ($rpt_type == 'monthlyByDate') {
  1096. $thismonth = substr($dateYmd, 4, 2);
  1097. $thisyear = substr($dateYmd, 0, 4);
  1098. $thisday = substr($dateYmd, 6, 2);
  1099. $hour = date('H',$date);
  1100. $minute = date('i',$date);
  1101. $thismonth += $freq;
  1102. $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
  1103. while ($cdate <= $realend+$ONE_DAY) {
  1104. if ( ! is_exception ( $cdate, $ex_days ) )
  1105. $ret[$n++] = $cdate;
  1106. $thismonth += $freq;
  1107. $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
  1108. }
  1109. } else if ($rpt_type == 'yearly') {
  1110. $thismonth = substr($dateYmd, 4, 2);
  1111. $thisyear = substr($dateYmd, 0, 4);
  1112. $thisday = substr($dateYmd, 6, 2);
  1113. $hour = date('H',$date);
  1114. $minute = date('i',$date);
  1115. $thisyear += $freq;
  1116. $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
  1117. while ($cdate <= $realend+$ONE_DAY) {
  1118. if ( ! is_exception ( $cdate, $ex_days ) )
  1119. $ret[$n++] = $cdate;
  1120. $thisyear += $freq;
  1121. $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
  1122. }
  1123. }
  1124. }
  1125. return $ret;
  1126. }
  1127. // Get all the repeating events for the specified data and return them
  1128. // in an array (which is sorted by time of day).
  1129. // params:
  1130. // $user - username
  1131. // $date - date to get events for in YYYYMMDD format
  1132. function get_repeating_entries ( $user, $dateYmd ) {
  1133. global $repeated_events;
  1134. $n = 0;
  1135. $ret = array ();
  1136. //echo count($repeated_events)."<BR>";
  1137. for ( $i = 0; $i < count ( $repeated_events ); $i++ ) {
  1138. if ( repeated_event_matches_date ( $repeated_events[$i], $dateYmd ) ) {
  1139. // make sure this is not an exception date...
  1140. $unixtime = date_to_epoch ( $dateYmd );
  1141. if ( ! is_exception ( $unixtime, $repeated_events[$i]['cal_exceptions'] ) )
  1142. $ret[$n++] = $repeated_events[$i];
  1143. }
  1144. }
  1145. return $ret;
  1146. }
  1147. //Returns a boolean stating whether or not the event passed
  1148. //in will fall on the date passed.
  1149. function repeated_event_matches_date($event,$dateYmd) {
  1150. // only repeat after the beginning, and if there is an end
  1151. // before the end
  1152. $date = date_to_epoch ( $dateYmd );
  1153. $thisyear = substr($dateYmd, 0, 4);
  1154. $start = date_to_epoch ( $event['cal_date'] );
  1155. $end = date_to_epoch ( $event['cal_end'] );
  1156. $freq = $event['cal_frequency'];
  1157. $thismonth = substr($dateYmd, 4, 2);
  1158. if ($event['cal_end'] && $dateYmd > date("Ymd",$end) )
  1159. return false;
  1160. if ( $dateYmd <= date("Ymd",$start) )
  1161. return false;
  1162. $id = $event['cal_id'];
  1163. if ($event['cal_type'] == 'daily') {
  1164. if ( (floor(($date - $start)/86400)%$freq) )
  1165. return false;
  1166. return true;
  1167. } else if ($event['cal_type'] == 'weekly') {
  1168. $dow = date("w", $date);
  1169. $dow1 = date("w", $start);
  1170. $isDay = substr($event['cal_days'], $dow, 1);
  1171. $wstart = $start - ($dow1 * 86400);
  1172. if (floor(($date - $wstart)/604800)%$freq)
  1173. return false;
  1174. if (strcmp($isDay,"y") == 0) {
  1175. return true;
  1176. }
  1177. } else if ($event['cal_type'] == 'monthlyByDay') {
  1178. $dowS = date("w", $start);
  1179. $dayS = ceil(date("d", $start)/7);
  1180. $mthS = date("m", $start);
  1181. $yrS = date("Y", $start);
  1182. $dow = date("w", $date);
  1183. $day = ceil(date("d", $date)/7);
  1184. $mth = date("m", $date);
  1185. $yr = date("Y", $date);
  1186. if ((($yr - $yrS)*12 + $mth - $mthS) % $freq)
  1187. return false;
  1188. if (($dowS == $dow) && ($day == $dayS)) {
  1189. return true;
  1190. }
  1191. } else if ($event['cal_type'] == 'monthlyByDate') {
  1192. $mthS = date("m", $start);
  1193. $yrS = date("Y", $start);
  1194. $mth = date("m", $date);
  1195. $yr = date("Y", $date);
  1196. if ((($yr - $yrS)*12 + $mth - $mthS) % $freq)
  1197. return false;
  1198. if (date("d", $date) == date("d", $start)) {
  1199. return true;
  1200. }
  1201. }
  1202. else if ($event['cal_type'] == 'yearly') {
  1203. $yrS = date("Y", $start);
  1204. $yr = date("Y", $date);
  1205. if (($yr - $yrS)%$freq)
  1206. return false;
  1207. if (date("dm", $date) == date("dm", $start)) {
  1208. return true;
  1209. }
  1210. } else {
  1211. // unknown repeat type
  1212. return false;
  1213. }
  1214. }
  1215. function date_to_epoch ( $d ) {
  1216. return mktime ( 3, 0, 0, substr ( $d, 4, 2 ), substr ( $d, 6, 2 ),
  1217. substr ( $d, 0, 4 ) );
  1218. }
  1219. // check if a date is an exception for an event
  1220. // $date - date in timestamp format
  1221. // $exdays - array of dates in YYYYMMDD format
  1222. function is_exception ( $date, $ex_days ) {
  1223. $size = count ( $ex_days );
  1224. $count = 0;
  1225. $date = date ( "Ymd", $date );
  1226. //echo "Exception $date check.. count is $size <br>";
  1227. while ( $count < $size ) {
  1228. //echo "Exception date: $ex_days[$count] <br>";
  1229. if ( $date == $ex_days[$count++] )
  1230. return true;
  1231. }
  1232. return false;
  1233. }
  1234. // Get the Sunday of the week that the specified date is in.
  1235. // (If the date specified is a Sunday, then that date is returned.)
  1236. function get_sunday_before ( $year, $month, $day ) {
  1237. $weekday = date ( "w", mktime ( 3, 0, 0, $month, $day, $year ) );
  1238. $newdate = mktime ( 3, 0, 0, $month, $day - $weekday, $year );
  1239. return $newdate;
  1240. }
  1241. // Get the Monday of the week that the specified date is in.
  1242. // (If the date specified is a Monday, then that date is returned.)
  1243. function get_monday_before ( $year, $month, $day ) {
  1244. $weekday = date ( "w", mktime ( 3, 0, 0, $month, $day, $year ) );
  1245. if ( $weekday == 0 )
  1246. return mktime ( 3, 0, 0, $month, $day - 6, $year );
  1247. if ( $weekday == 1 )
  1248. return mktime ( 3, 0, 0, $month, $day, $year );
  1249. return mktime ( 3, 0, 0, $month, $day - ( $weekday - 1 ), $year );
  1250. }
  1251. // Returns week number for specified date
  1252. // depending from week numbering settings.
  1253. // params:
  1254. // $date - date in UNIX time format
  1255. function week_number ( $date ) {
  1256. $ret = "";
  1257. if ( $GLOBALS["WEEK_START"] == "1" ) {
  1258. $ret = strftime ( "%V", $date ); // ISO Weeks -- which start on Mondays
  1259. if ( $ret == "" ) // %V not implemented on older versions of PHP :-(
  1260. $ret = strftime ( "%W", $date ); // not 100%
  1261. } else {
  1262. $ret = strftime ( "%W", $date );
  1263. }
  1264. return $ret;
  1265. }
  1266. // This function is not yet used. Some of the places that will call it
  1267. // have to be updated to also get the event owner so we know if the current
  1268. // user has access to edit and delete.
  1269. function icon_text ( $id, $can_edit, $can_delete ) {
  1270. global $readonly, $is_admin;
  1271. $ret = "<A HREF=\"view_entry.php?id=$id\">" .
  1272. "<IMG SRC=\"view.gif\" ALT=\"" . translate("View this entry") .
  1273. "\" BORDER=\"0\" " .
  1274. "WIDTH=\"10\" HEIGHT=\"10\">" .
  1275. "</A>";
  1276. if ( $can_edit && $readonly == "N" )
  1277. $ret .= "<A HREF=\"edit_entry.php?id=$id\">" .
  1278. "<IMG SRC=\"edit.gif\" ALT=\"" . translate("Edit entry") .
  1279. "\" BORDER=\"0\" " .
  1280. "WIDTH=\"10\" HEIGHT=\"10\">" .
  1281. "</A>";
  1282. if ( $can_delete && ( $readonly == "N" || $is_admin ) )
  1283. $ret .= "<A HREF=\"del_entry.php?id=$id\" " .
  1284. "onClick=\"return confirm('" .
  1285. translate("Are you sure you want to delete this entry?") .
  1286. "\\n\\n" . translate("This will delete this entry for all users.") .
  1287. "');\">" .
  1288. "<IMG SRC=\"delete.gif\" ALT=\"" . translate("Delete entry") .
  1289. "\" BORDER=\"0\" " .
  1290. "WIDTH=\"10\" HEIGHT=\"10\">" .
  1291. "</A>";
  1292. return $ret;
  1293. }
  1294. //
  1295. // Print all the calendar entries for the specified user for the
  1296. // specified date. If we are displaying data from someone other than
  1297. // the logged in user, then check the access permission of the entry.
  1298. // params:
  1299. // $date - date in YYYYMMDD format
  1300. // $user - username
  1301. // $hide_icons - hide icons to make printer-friendly
  1302. // $is_ssi - is this being called from week_ssi.php?
  1303. function print_date_entries ( $date, $user, $hide_icons, $ssi ) {
  1304. global $events, $readonly, $is_admin,
  1305. $public_access, $public_access_can_add;
  1306. $cnt = 0;
  1307. $get_unapproved = ( $GLOBALS["DISPLAY_UNAPPROVED"] == "Y" );
  1308. // public access events always must be approved before being displayed
  1309. if ( $user == "__public__" )
  1310. $get_unapproved = false;
  1311. $year = substr ( $date, 0, 4 );
  1312. $month = substr ( $date, 4, 2 );
  1313. $day = substr ( $date, 6, 2 );
  1314. $dateu = mktime ( 3, 0, 0, $month, $day, $year );
  1315. $can_add = ( $readonly == "N" || $is_admin );
  1316. if ( $public_access == "Y" && $public_access_can_add != "Y" &&
  1317. $user == "__public__" )
  1318. $can_add = false;
  1319. if ( ! $hide_icons && ! $ssi && $can_add ) {
  1320. print "<A HREF=\"edit_entry.php?";
  1321. if ( strcmp ( $user, $GLOBALS["login"] ) )
  1322. print "user=$user&";
  1323. print "date=$date\">" .
  1324. "<IMG SRC=\"new.gif\" WIDTH=\"10\" HEIGHT=\"10\" ALT=\"" .
  1325. translate("New Entry") . "\" BORDER=\"0\" ALIGN=\"right\">" .
  1326. "</A>";
  1327. $cnt++;
  1328. }
  1329. if ( ! $ssi ) {
  1330. echo "<FONT SIZE=\"-1\"><A CLASS=\"dayofmonth\" HREF=\"day.php?";
  1331. if ( strcmp ( $user, $GLOBALS["login"] ) )
  1332. echo "user=$user&";
  1333. echo "date=$date\">$day</A></FONT>";
  1334. if ( $GLOBALS["DISPLAY_WEEKNUMBER"] == "Y" &&
  1335. date ( "w", $dateu ) == $GLOBALS["WEEK_START"] ) {
  1336. echo "<A HREF=\"week.php?date=$date";
  1337. if ( strcmp ( $user, $GLOBALS["login"] ) )
  1338. echo "&user=$user";
  1339. echo "\" CLASS=\"weeknumber\">";
  1340. echo "<FONT SIZE=\"-2\" CLASS=\"weeknumber\">(" .
  1341. translate("Week") . " " . week_number ( $dateu ) . ")</FONT></A>";
  1342. }
  1343. print "<BR>\n";
  1344. $cnt++;
  1345. }
  1346. // get all the repeating events for this date and store in array $rep
  1347. $rep = get_repeating_entries ( $user, $date );
  1348. $cur_rep = 0;
  1349. // get all the non-repeating events for this date and store in $ev
  1350. $ev = get_entries ( $user, $date );
  1351. for ( $i = 0; $i < count ( $ev ); $i++ ) {
  1352. // print out any repeating events that are before this one...
  1353. while ( $cur_rep < count ( $rep ) &&
  1354. $rep[$cur_rep]['cal_time'] < $ev[$i]['cal_time'] ) {
  1355. if ( $get_unapproved || $rep[$cur_rep]['cal_status'] == 'A' ) {
  1356. if ( ! empty ( $rep[$cur_rep]['cal_ext_for_id'] ) ) {
  1357. $viewid = $rep[$cur_rep]['cal_ext_for_id'];
  1358. $viewname = $rep[$cur_rep]['cal_name'] . " (" .
  1359. translate("cont.") . ")";
  1360. } else {
  1361. $viewid = $rep[$cur_rep]['cal_id'];
  1362. $viewname = $rep[$cur_rep]['cal_name'];
  1363. }
  1364. print_entry ( $viewid,
  1365. $date, $rep[$cur_rep]['cal_time'], $rep[$cur_rep]['cal_duration'],
  1366. $viewname, $rep[$cur_rep]['cal_description'],
  1367. $rep[$cur_rep]['cal_status'], $rep[$cur_rep]['cal_priority'],
  1368. $rep[$cur_rep]['cal_access'], $rep[$cur_rep]['cal_login'],
  1369. $hide_icons );
  1370. $cnt++;
  1371. }
  1372. $cur_rep++;
  1373. }
  1374. if ( $get_unapproved || $ev[$i]['cal_status'] == 'A' ) {
  1375. if ( ! empty ( $ev[$i]['cal_ext_for_id'] ) ) {
  1376. $viewid = $ev[$i]['cal_ext_for_id'];
  1377. $viewname = $ev[$i]['cal_name'] . " (" .
  1378. translate("cont.") . ")";
  1379. } else {
  1380. $viewid = $ev[$i]['cal_id'];
  1381. $viewname = $ev[$i]['cal_name'];
  1382. }
  1383. print_entry ( $viewid,
  1384. $date, $ev[$i]['cal_time'], $ev[$i]['cal_duration'],
  1385. $viewname, $ev[$i]['cal_description'],
  1386. $ev[$i]['cal_status'], $ev[$i]['cal_priority'],
  1387. $ev[$i]['cal_access'], $ev[$i]['cal_login'], $hide_icons );
  1388. $cnt++;
  1389. }
  1390. }
  1391. // print out any remaining repeating events
  1392. while ( $cur_rep < count ( $rep ) ) {
  1393. if ( $get_unapproved || $rep[$cur_rep]['cal_status'] == 'A' ) {
  1394. if ( ! empty ( $rep[$cur_rep]['cal_ext_for_id'] ) ) {
  1395. $viewid = $rep[$cur_rep]['cal_ext_for_id'];
  1396. $viewname = $rep[$cur_rep]['cal_name'] . " (" .
  1397. translate("cont.") . ")";
  1398. } else {
  1399. $viewid = $rep[$cur_rep]['cal_id'];
  1400. $viewname = $rep[$cur_rep]['cal_name'];
  1401. }
  1402. print_entry ( $viewid,
  1403. $date, $rep[$cur_rep]['cal_time'], $rep[$cur_rep]['cal_duration'],
  1404. $viewname, $rep[$cur_rep]['cal_description'],
  1405. $rep[$cur_rep]['cal_status'], $rep[$cur_rep]['cal_priority'],
  1406. $rep[$cur_rep]['cal_access'], $rep[$cur_rep]['cal_login'],
  1407. $hide_icons );
  1408. $cnt++;
  1409. }
  1410. $cur_rep++;
  1411. }
  1412. if ( $cnt == 0 )
  1413. echo "&nbsp;"; // so the table cell has at least something
  1414. }
  1415. // check to see if two events overlap
  1416. // time1 and time2 should be an integer like 235900
  1417. // duration1 and duration2 are integers in minutes
  1418. function times_overlap ( $time1, $duration1, $time2, $duration2 ) {
  1419. //echo "times_overlap ( $time1, $duration1, $time2, $duration2 )<BR>";
  1420. $hour1 = (int) ( $time1 / 10000 );
  1421. $min1 = ( $time1 / 100 ) % 100;
  1422. $hour2 = (int) ( $time2 / 10000 );
  1423. $min2 = ( $time2 / 100 ) % 100;
  1424. // convert to minutes since midnight
  1425. // remove 1 minute from duration so 9AM-10AM will not conflict with 10AM-11AM
  1426. if ( $duration1 > 0 )
  1427. $duration1 -= 1;
  1428. if ( $duration2 > 0 )
  1429. $duration2 -= 1;
  1430. $tmins1start = $hour1 * 60 + $min1;
  1431. $tmins1end = $tmins1start + $duration1;
  1432. $tmins2start = $hour2 * 60 + $min2;
  1433. $tmins2end = $tmins2start + $duration2;
  1434. //echo "tmins1start=$tmins1start, tmins1end=$tmins1end, tmins2start=$tmins2start, tmins2end=$tmins2end<BR>";
  1435. if ( ( $tmins1start >= $tmins2end ) || ( $tmins2start >= $tmins1end ) )
  1436. return false;
  1437. return true;
  1438. }
  1439. // Check for conflicts.
  1440. // Find overlaps between an array of dates and the other dates in the database.
  1441. // $date is an array of dates in Ymd format that is check for overlaps.
  1442. // the $duration, $hour, and $minute are integers that show the time of
  1443. // the event which is shared among the dates.
  1444. // $particpants are those whose calendars are to be checked.
  1445. // $login is the current user name.
  1446. // $id is the current calendar entry being checked if it has been stored before
  1447. // (this keeps overlaps from wrongly checking an event against itself.
  1448. // TODO: Update this to handle exceptions to repeating events
  1449. //
  1450. // Appt limits: if enabled we will store each event in an array using
  1451. // the key $user-$date, so for testuser on 12/31/95
  1452. // we would use $evtcnt["testuser-19951231"]
  1453. //
  1454. // Return empty string for no conflicts or return the HTML of the
  1455. // conflicts when one or more are found.
  1456. function check_for_conflicts ( $dates, $duration, $hour, $minute,
  1457. $participants, $login, $id ) {
  1458. global $single_user_login, $single_user;
  1459. global $repeated_events, $limit_appts, $limit_appts_number;
  1460. if (!count($dates)) return false;
  1461. $evtcnt = array ();
  1462. $sql = "SELECT distinct webcal_entry_user.cal_login, webcal_entry.cal_time," .
  1463. "webcal_entry.cal_duration, webcal_entry.cal_name, " .
  1464. "webcal_entry.cal_id, webcal_entry.cal_ext_for_id, " .
  1465. "webcal_entry.cal_access, " .
  1466. "webcal_entry_user.cal_status, webcal_entry.cal_date " .
  1467. "FROM webcal_entry, webcal_entry_user " .
  1468. "WHERE webcal_entry.cal_id = webcal_entry_user.cal_id " .
  1469. "AND (";
  1470. for ($x = 0; $x < count($dates); $x++) {
  1471. if ($x != 0) $sql .= " OR ";
  1472. $sql.="webcal_entry.cal_date = " . date ( "Ymd", $dates[$x] );
  1473. }
  1474. $sql .= ") AND webcal_entry.cal_time >= 0 " .
  1475. "AND webcal_entry_user.cal_status IN ('A','W') AND ( ";
  1476. if ( $single_user == "Y" ) {
  1477. $participants[0] = $single_user_login;
  1478. } else if ( strlen ( $participants[0] ) == 0 ) {
  1479. // likely called from a form with 1 user
  1480. $participants[0] = $login;
  1481. }
  1482. for ( $i = 0; $i < count ( $participants ); $i++ ) {
  1483. if ( $i > 0 )
  1484. $sql .= " OR ";
  1485. $sql .= " webcal_entry_user.cal_login = '" . $participants[$i] . "'";
  1486. }
  1487. $sql .= " )";
  1488. // make sure we don't get something past the end date of the
  1489. // event we are saving.
  1490. //echo "SQL: $sql<P>";
  1491. $conflicts = "";
  1492. $res = dbi_query ( $sql );
  1493. $found = array();
  1494. $count = 0;
  1495. if ( $res ) {
  1496. $time1 = sprintf ( "%d%02d00", $hour, $minute );
  1497. $duration1 = sprintf ( "%d", $duration );
  1498. while ( $row = dbi_fetch_row ( $res ) ) {
  1499. //Add to an array to see if it has been found already for the next part.
  1500. $found[$count++] = $row[4];
  1501. // see if either event overlaps one another
  1502. if ( $row[4] != $id && ( empty ( $row[5] ) || $row[5] != $id ) ) {
  1503. $time2 = $row[1];
  1504. $duration2 = $row[2];
  1505. $cntkey = $user . "-" . $row[8];
  1506. $evtcnt[$cntkey]++;
  1507. $over_limit = 0;
  1508. if ( $limit_appts == "Y" && $limit_appts_number > 0
  1509. && $evtcnt[$cntkey] >= $limit_appts_number ) {
  1510. $over_limit = 1;
  1511. }
  1512. if ( $over_limit ||
  1513. times_overlap ( $time1, $duration1, $time2, $duration2 ) ) {
  1514. $conflicts .= "<LI>";
  1515. if ( $single_user == "Y" )
  1516. $conflicts .= "$row[0]: ";
  1517. if ( $row[6] == 'R' && $row[0] != $login )
  1518. $conflicts .= "(" . translate("Private") . ")";
  1519. else {
  1520. $conflicts .= "<A HREF=\"view_entry.php?id=$row[4]";
  1521. if ( $user != $login )
  1522. $conflicts .= "&user=$user";
  1523. $conflicts .= "\">$row[3]</A>";
  1524. }
  1525. if ( $duration2 == ( 24 * 60 ) ) {
  1526. $conflicts .= " (" . translate("All day event") . ")";
  1527. } else {
  1528. $conflicts .= " (" . display_time ( $time2 );
  1529. if ( $duration2 > 0 )
  1530. $conflicts .= "-" .
  1531. display_time ( add_duration ( $time2, $duration2 ) );
  1532. $conflicts .= ")";
  1533. }
  1534. $conflicts .= " on " . date_to_str( $row[8] );
  1535. if ( $over_limit ) {
  1536. $tmp = translate ( "exceeds limit of XXX events per day" );
  1537. $tmp = str_replace ( "XXX", $limit_appts_number, $tmp );
  1538. $conflicts .= " (" . $tmp . ")";
  1539. }
  1540. }
  1541. }
  1542. }
  1543. dbi_free_result ( $res );
  1544. } else {
  1545. echo translate("Database error") . ": " . dbi_error (); exit;
  1546. }
  1547. //echo "<br>hello";
  1548. for ($q=0;$q<count($participants);$q++) {
  1549. $time1 = sprintf ( "%d%02d00", $hour, $minute );
  1550. $duration1 = sprintf ( "%d", $duration );
  1551. //This date filter is not necessary for functional reasons, but it eliminates some of the
  1552. //events that couldn't possibly match. This could be made much more complex to put more
  1553. //of the searching work onto the database server, or it could be dropped all together to put
  1554. //the searching work onto the client.
  1555. $date_filter = "AND (webcal_entry.cal_date <= " . date("Ymd",$dates[count($dates)-1]);
  1556. $date_filter .= " AND (webcal_entry_repeats.cal_end IS NULL OR webcal_entry_repeats.cal_end >= " . date("Ymd",$dates[0]) . "))";
  1557. //Read repeated events for the participants only once for a participant for
  1558. //for performance reasons.
  1559. $repeated_events=query_events($participants[$q],true,$date_filter);
  1560. //for ($dd=0; $dd<count($repeated_events); $dd++) {
  1561. // echo $repeated_events[$dd]['cal_id'] . "<BR>";
  1562. //}
  1563. for ($i=0; $i < count($dates); $i++) {
  1564. $dateYmd = date ( "Ymd", $dates[$i] );
  1565. $list = get_repeating_entries($participants[$q],$dateYmd);
  1566. $thisyear = substr($dateYmd, 0, 4);
  1567. $thismonth = substr($dateYmd, 4, 2);
  1568. for ($j=0; $j < count($list);$j++) {
  1569. //okay we've narrowed it down to a day, now I just gotta check the time...
  1570. //I hope this is right...
  1571. $row = $list[$j];
  1572. if ( $row['cal_id'] != $id && $row['cal_ext_for_id'] != $id ) {
  1573. $time2 = $row['cal_time'];
  1574. $duration2 = $row['cal_duration'];
  1575. if ( times_overlap ( $time1, $duration1, $time2, $duration2 ) ) {
  1576. $conflicts .= "<LI>";
  1577. if ( $single_user != "Y" )
  1578. $conflicts .= $row['cal_login'] . ": ";
  1579. if ( $row['cal_access'] == 'R' && $row['cal_login'] != $login )
  1580. $conflicts .= "(" . translate("Private") . ")";
  1581. else {
  1582. $conflicts .= "<A HREF=\"view_entry.php?id=" . $row['cal_id'];
  1583. if ( $user != $login )
  1584. $conflicts .= "&user=$user";
  1585. $conflicts .= "\">" . $row['cal_name'] . "</A>";
  1586. }
  1587. $conflicts .= " (" . display_time ( $time2 );
  1588. if ( $duration2 > 0 )
  1589. $conflicts .= "-" .
  1590. display_time ( add_duration ( $time2, $duration2 ) );
  1591. $conflicts .= ")";
  1592. $conflicts .= " on " . date("l, F j, Y", $dates[$i]);
  1593. }
  1594. }
  1595. }
  1596. }
  1597. }
  1598. return $conflicts;
  1599. }
  1600. // Convert a time format HHMMSS (like 131000 for 1PM) into number of
  1601. // minutes past midnight.
  1602. function time_to_minutes ( $time ) {
  1603. $h = (int) ( $time / 10000 );
  1604. $m = (int) ( $time / 100 ) % 100;
  1605. $num = $h * 60 + $m;
  1606. return $num;
  1607. }
  1608. // Calculate which row/slot this time represents.
  1609. // $time is input time in YYMMDD format
  1610. // $round_down indicates if we should change 1100 to 1059 so a
  1611. // 10AM-11AM appt just shows up in the 10AM slot, not the 11AM slot also.
  1612. function calc_time_slot ( $time, $round_down = false ) {
  1613. global $TIME_SLOTS, $TZ_OFFSET;
  1614. $interval = ( 24 * 60 ) / $TIME_SLOTS;
  1615. $mins_since_midnight = time_to_minutes ( $time );
  1616. $ret = (int) ( $mins_since_midnight / $interval );
  1617. if ( $round_down ) {
  1618. if ( $ret * $interval == $mins_since_midnight )
  1619. $ret--;
  1620. }
  1621. //echo "$mins_since_midnight / $interval = $ret <BR>";
  1622. if ( $ret > $TIME_SLOTS )
  1623. $ret = $TIME_SLOTS;
  1624. //echo "<P>calc_time_slot($time) = $ret <BR> TIME_SLOTS = $TIME_SLOTS<BR>";
  1625. return $ret;
  1626. }
  1627. // Generate the HTML for the add icon.
  1628. // date = date in YYYYMMDD format
  1629. // hour = hour of day (eg. 1,13,23)
  1630. function html_for_add_icon ( $date=0,$hour="", $minute="", $user="" ) {
  1631. global $TZ_OFFSET;
  1632. if ( ! empty ( $hour ) )
  1633. $hour += $TZ_OFFSET;
  1634. return "<A HREF=\"edit_entry.php?" . $u_url .
  1635. "date=$date" . ( $hour > 0 ? "&hour=$hour" : "" ) .
  1636. ( $minute > 0 ? "&minute=$minute" : "" ) .
  1637. ( empty ( $user ) ? "" : "&defusers=$user" ) .
  1638. "\"><IMG SRC=\"new.gif\" WIDTH=\"10\" HEIGHT=\"10\" ALT=\"" .
  1639. translate("New Entry") . "\" BORDER=\"0\" ALIGN=\"right\">" . "</A>";
  1640. }
  1641. // Generate the HTML for an event to be viewed in the week-at-glance.
  1642. // The HTML will be stored in an array ($hour_arr) indexed on the event's
  1643. // starting hour.
  1644. function html_for_event_week_at_a_glance ( $id, $date, $time,
  1645. $name, $description, $status, $pri, $access, $duration, $event_owner,
  1646. $hide_icons ) {
  1647. global $first_slot, $last_slot, $hour_arr, $rowspan_arr, $rowspan,
  1648. $eventinfo, $login, $user;
  1649. static $key = 0;
  1650. global $DISPLAY_ICONS, $PHP_SELF, $TIME_SLOTS;
  1651. global $layers;
  1652. $divname = "eventinfo-day-$id-$key";
  1653. $key++;
  1654. // Figure out which time slot it goes in.
  1655. if ( $time >= 0 && $duration != ( 24 * 60 ) ) {
  1656. $ind = calc_time_slot ( $time );
  1657. if ( $ind < $first_slot )
  1658. $first_slot = $ind;
  1659. if ( $ind > $last_slot )
  1660. $last_slot = $ind;
  1661. } else
  1662. $ind = 9999;
  1663. if ( $login != $event_owner && strlen ( $event_owner ) ) {
  1664. $class = "layerentry";
  1665. } else {
  1666. $class = "entry";
  1667. if ( $status == "W" ) $class = "unapprovedentry";
  1668. }
  1669. // if we are looking at a view, then always use "entry"
  1670. if ( strstr ( $PHP_SELF, "view_m.php" ) ||
  1671. strstr ( $PHP_SELF, "view_w.php" ) ||
  1672. strstr ( $PHP_SELF, "view_v.php" ) ||
  1673. strstr ( $PHP_SELF, "view_t.php" ) )
  1674. $class = "entry";
  1675. // avoid php warning for undefined array index
  1676. if ( empty ( $hour_arr[$ind] ) )
  1677. $hour_arr[$ind] = "";
  1678. if ( ! $hide_icons ) {
  1679. $hour_arr[$ind] .=
  1680. "<A CLASS=\"$class\" HREF=\"view_entry.php?id=$id&date=$date";
  1681. if ( strlen ( $GLOBALS["user"] ) > 0 )
  1682. $hour_arr[$ind] .= "&user=" . $GLOBALS["user"];
  1683. $hour_arr[$ind] .= "\" onMouseOver=\"window.status='" .
  1684. translate("View this entry") .
  1685. "'; show(event, '$divname'); return true;\" onMouseOut=\"hide('$divname'); return true;\">";
  1686. }
  1687. if ( $pri == 3 )
  1688. $hour_arr[$ind] .= "<B>";
  1689. if ( $login != $event_owner && strlen ( $event_owner ) ) {
  1690. for ( $index = 0; $index < sizeof($layers); $index++ ) {
  1691. if ( $layers[$index]['cal_layeruser'] == $event_owner ) {
  1692. $hour_arr[$ind] .= "<FONT COLOR=\"" .
  1693. $layers[$index]['cal_color'] . "\">";
  1694. }
  1695. }
  1696. }
  1697. if ( $duration == ( 24 * 60 ) ) {
  1698. $timestr = translate("All day event");
  1699. } else if ( $time >= 0 ) {
  1700. $hour_arr[$ind] .= display_time ( $time ) . "&gt; ";
  1701. $timestr = display_time ( $time );
  1702. if ( $duration > 0 ) {
  1703. // calc end time
  1704. $h = (int) ( $time / 10000 );
  1705. $m = ( $time / 100 ) % 100;
  1706. $m += $duration;
  1707. $d = $duration;
  1708. while ( $m >= 60 ) {
  1709. $h++;
  1710. $m -= 60;
  1711. }
  1712. $end_time = sprintf ( "%02d%02d00", $h, $m );
  1713. $timestr .= "-" . display_time ( $end_time );
  1714. }
  1715. if ( empty ( $rowspan_arr[$ind] ) )
  1716. $rowspan_arr[$ind] = 0; // avoid warning below
  1717. // which slot is end time in? take one off so we don't
  1718. // show 11:00-12:00 as taking up both 11 and 12 slots.
  1719. $endind = calc_time_slot ( $end_time, true );
  1720. if ( $endind == $ind )
  1721. $rowspan = 0;
  1722. else
  1723. $rowspan = $endind - $ind + 1;
  1724. if ( $rowspan > $rowspan_arr[$ind] && $rowspan > 1 )
  1725. $rowspan_arr[$ind] = $rowspan;
  1726. } else {
  1727. $timestr = "";
  1728. }
  1729. // avoid php warning of undefined index when using .= below
  1730. if ( empty ( $hour_arr[$ind] ) )
  1731. $hour_arr[$ind] = "";
  1732. if ( $login != $user && $access == 'R' && strlen ( $user ) ) {
  1733. $hour_arr[$ind] .= "(" . translate("Private") . ")";
  1734. } else if ( $login != $event_owner && $access == 'R' &&
  1735. strlen ( $event_owner ) ) {
  1736. $hour_arr[$ind] .= "(" . translate("Private") . ")";
  1737. } else if ( $login != $event_owner && strlen ( $event_owner ) ) {
  1738. $hour_arr[$ind] .= htmlspecialchars ( $name );
  1739. $hour_arr[$ind] .= "</FONT>";
  1740. } else {
  1741. $hour_arr[$ind] .= htmlspecialchars ( $name );
  1742. }
  1743. if ( $pri == 3 ) $hour_arr[$ind] .= "</B>";
  1744. $hour_arr[$ind] .= "</A>";
  1745. //if ( $DISPLAY_ICONS == "Y" ) {
  1746. // $hour_arr[$ind] .= icon_text ( $id, true, true );
  1747. //}
  1748. $hour_arr[$ind] .= "<BR>";
  1749. if ( $login != $user && $access == 'R' && strlen ( $user ) ) {
  1750. $eventinfo .= build_event_popup ( $divname, $event_owner,
  1751. translate("This event is confidential"), "" );
  1752. } else if ( $login != $event_owner && $access == 'R' &&
  1753. strlen ( $event_owner ) ) {
  1754. $eventinfo .= build_event_popup ( $divname, $event_owner,
  1755. translate("This event is confidential"), "" );
  1756. } else {
  1757. $eventinfo .= build_event_popup ( $divname, $event_owner,
  1758. $description, $timestr );
  1759. }
  1760. }
  1761. // Generate the HTML for an event to be viewed in the day-at-glance.
  1762. // The HTML will be stored in an array ($hour_arr) indexed on the event's
  1763. // starting hour.
  1764. function html_for_event_day_at_a_glance ( $id, $date, $time,
  1765. $name, $description, $status, $pri, $access, $duration, $event_owner, $hide_icons ) {
  1766. global $first_slot, $last_slot, $hour_arr, $rowspan_arr, $rowspan,
  1767. $eventinfo, $login, $user;
  1768. static $key = 0;
  1769. global $layers, $PHP_SELF, $TIME_SLOTS, $TZ_OFFSET;
  1770. $divname = "eventinfo-day-$id-$key";
  1771. $key++;
  1772. if ( $login != $user && $access == 'R' && strlen ( $user ) )
  1773. $eventinfo .= build_event_popup ( $divname, $event_owner,
  1774. translate("This event is confidential"), "" );
  1775. else if ( $login != $event_owner && $access == 'R' &&
  1776. strlen ( $event_owner ) )
  1777. $eventinfo .= build_event_popup ( $divname, $event_owner,
  1778. translate("This event is confidential"), "" );
  1779. else
  1780. $eventinfo .= build_event_popup ( $divname, $event_owner, $description, "" );
  1781. // calculate slot length in minutes
  1782. $interval = ( 60 * 24 ) / $TIME_SLOTS;
  1783. // If TZ_OFFSET make this event before the start of the day or
  1784. // after the end of the day, adjust the time slot accordingly.
  1785. if ( $time >= 0 && $duration != ( 24 * 60 ) ) {
  1786. if ( $time + ( $TZ_OFFSET * 10000 ) > 240000 )
  1787. $time -= 240000;
  1788. else if ( $time + ( $TZ_OFFSET * 10000 ) < 0 )
  1789. $time += 240000;
  1790. $ind = calc_time_slot ( $time );
  1791. if ( $ind < $first_slot )
  1792. $first_slot = $ind;
  1793. if ( $ind > $last_slot )
  1794. $last_slot = $ind;
  1795. } else
  1796. $ind = 9999;
  1797. //echo "time = $time <BR> ind = $ind <BR> first_slot = $first_slot <BR>";
  1798. if ( empty ( $hour_arr[$ind] ) )
  1799. $hour_arr[$ind] = "";
  1800. if ( $login != $event_owner && strlen ( $event_owner ) ) {
  1801. $class = "layerentry";
  1802. } else {
  1803. $class = "entry";
  1804. if ( $status == "W" )
  1805. $class = "unapprovedentry";
  1806. }
  1807. // if we are looking at a view, then always use "entry"
  1808. if ( strstr ( $PHP_SELF, "view_m.php" ) ||
  1809. strstr ( $PHP_SELF, "view_w.php" ) ||
  1810. strstr ( $PHP_SELF, "view_v.php" ) ||
  1811. strstr ( $PHP_SELF, "view_t.php" ) )
  1812. $class = "entry";
  1813. if ( ! $hide_icons ) {
  1814. $hour_arr[$ind] .=
  1815. "<A CLASS=\"$class\" HREF=\"view_entry.php?id=$id&date=$date";
  1816. if ( strlen ( $GLOBALS["user"] ) > 0 )
  1817. $hour_arr[$ind] .= "&user=" . $GLOBALS["user"];
  1818. $hour_arr[$ind] .= "\" onMouseOver=\"window.status='" .
  1819. translate("View this entry") .
  1820. "'; show(event, '$divname'); return true;\" onMouseOut=\"hide('$divname'); return true;\">";
  1821. }
  1822. if ( $pri == 3 ) $hour_arr[$ind] .= "<B>";
  1823. if ( $login != $event_owner && strlen ( $event_owner ) ) {
  1824. for ( $index = 0; $index < sizeof($layers); $index++) {
  1825. if ( $layers[$index]['cal_layeruser'] == $event_owner) {
  1826. $hour_arr[$ind] .= "<FONT COLOR=\"" .
  1827. $layers[$index]['cal_color'] . "\">";
  1828. }
  1829. }
  1830. }
  1831. if ( $duration == ( 24 * 60 ) ) {
  1832. $hour_arr[$ind] .= "[" . translate("All day event") . "] ";
  1833. } else if ( $time >= 0 ) {
  1834. $hour_arr[$ind] .= "[" . display_time ( $time );
  1835. if ( $duration > 0 ) {
  1836. // calc end time
  1837. $h = (int) ( $time / 10000 );
  1838. $m = ( $time / 100 ) % 100;
  1839. $m += $duration;
  1840. $d = $duration;
  1841. while ( $m >= 60 ) {
  1842. $h++;
  1843. $m -= 60;
  1844. }
  1845. $end_time = sprintf ( "%02d%02d00", $h, $m );
  1846. $hour_arr[$ind] .= "-" . display_time ( $end_time );
  1847. // which slot is end time in? take one off so we don't
  1848. // show 11:00-12:00 as taking up both 11 and 12 slots.
  1849. $endind = calc_time_slot ( $end_time, true );
  1850. if ( $endind == $ind )
  1851. $rowspan = 0;
  1852. else
  1853. $rowspan = $endind - $ind + 1;
  1854. if ( $rowspan > $rowspan_arr[$ind] && $rowspan > 1 )
  1855. $rowspan_arr[$ind] = $rowspan;
  1856. }
  1857. $hour_arr[$ind] .= "] ";
  1858. }
  1859. if ( $login != $user && $access == 'R' && strlen ( $user ) )
  1860. $hour_arr[$ind] .= "(" . translate("Private") . ")";
  1861. else
  1862. if ( $login != $event_owner && $access == 'R' && strlen ( $event_owner ) )
  1863. $hour_arr[$ind] .= "(" . translate("Private") . ")";
  1864. else
  1865. if ( $login != $event_owner && strlen ( $event_owner ) )
  1866. {
  1867. $hour_arr[$ind] .= htmlspecialchars ( $name );
  1868. $hour_arr[$ind] .= "</FONT>";
  1869. }
  1870. else
  1871. $hour_arr[$ind] .= htmlspecialchars ( $name );
  1872. if ( $pri == 3 ) $hour_arr[$ind] .= "</B>";
  1873. $hour_arr[$ind] .= "</A><BR>";
  1874. }
  1875. //
  1876. // Print all the calendar entries for the specified user for the
  1877. // specified date in day-at-a-glance format.
  1878. // If we are displaying data from someone other than
  1879. // the logged in user, then check the access permission of the entry.
  1880. // We output a two column format like: time: event
  1881. // params:
  1882. // $date - date in YYYYMMDD format
  1883. // $user - username
  1884. // $hide_icons - should we hide the icons to make it printer-friendly
  1885. function print_day_at_a_glance ( $date, $user, $hide_icons, $can_add=0 ) {
  1886. global $first_slot, $last_slot, $hour_arr, $rowspan_arr, $rowspan;
  1887. global $CELLBG, $TODAYCELLBG, $THFG, $THBG, $TIME_SLOTS, $TZ_OFFSET;
  1888. global $WORK_DAY_START_HOUR, $WORK_DAY_END_HOUR;
  1889. global $repeated_events;
  1890. $get_unapproved = ( $GLOBALS["DISPLAY_UNAPPROVED"] == "Y" );
  1891. if ( $user == "__public__" )
  1892. $get_unapproved = false;
  1893. if ( empty ( $TIME_SLOTS ) ) {
  1894. echo "Error: TIME_SLOTS undefined!<P>";
  1895. return;
  1896. }
  1897. // $interval is number of minutes per slot
  1898. $interval = ( 24 * 60 ) / $TIME_SLOTS;
  1899. $rowspan_arr = array ();
  1900. for ( $i = 0; $i < $TIME_SLOTS; $i++ ) {
  1901. $rowspan_arr[$i] = 0;
  1902. }
  1903. // get all the repeating events for this date and store in array $rep
  1904. $rep = get_repeating_entries ( $user, $date );
  1905. $cur_rep = 0;
  1906. // Get static non-repeating events
  1907. $ev = get_entries ( $user, $date );
  1908. $hour_arr = array ();
  1909. $interval = ( 24 * 60 ) / $TIME_SLOTS;
  1910. $first_slot = (int) ( ( ( $WORK_DAY_START_HOUR - $TZ_OFFSET ) * 60 ) / $interval );
  1911. $last_slot = (int) ( ( ( $WORK_DAY_END_HOUR - $TZ_OFFSET ) * 60 ) / $interval);
  1912. //echo "first_slot = $first_slot <BR> last_slot = $last_slot <BR> interval = $interval <BR> TIME_SLOTS = $TIME_SLOTS <BR>";
  1913. $rowspan_arr = array ();
  1914. $all_day = 0;
  1915. for ( $i = 0; $i < count ( $ev ); $i++ ) {
  1916. // print out any repeating events that are before this one...
  1917. while ( $cur_rep < count ( $rep ) &&
  1918. $rep[$cur_rep]['cal_time'] < $ev[$i]['cal_time'] ) {
  1919. if ( $get_unapproved || $rep[$cur_rep]['cal_status'] == 'A' ) {
  1920. if ( ! empty ( $rep[$cur_rep]['cal_ext_for_id'] ) ) {
  1921. $viewid = $rep[$cur_rep]['cal_ext_for_id'];
  1922. $viewname = $rep[$cur_rep]['cal_name'] . " (" .
  1923. translate("cont.") . ")";
  1924. } else {
  1925. $viewid = $rep[$cur_rep]['cal_id'];
  1926. $viewname = $rep[$cur_rep]['cal_name'];
  1927. }
  1928. if ( $rep['cal_duration'] == ( 24 * 60 ) )
  1929. $all_day = 1;
  1930. html_for_event_day_at_a_glance ( $viewid,
  1931. $date, $rep[$cur_rep]['cal_time'],
  1932. $viewname, $rep[$cur_rep]['cal_description'],
  1933. $rep[$cur_rep]['cal_status'], $rep[$cur_rep]['cal_priority'],
  1934. $rep[$cur_rep]['cal_access'], $rep[$cur_rep]['cal_duration'],
  1935. $rep[$cur_rep]['cal_login'], $hide_icons );
  1936. }
  1937. $cur_rep++;
  1938. }
  1939. if ( $get_unapproved || $ev[$i]['cal_status'] == 'A' ) {
  1940. if ( ! empty ( $ev[$i]['cal_ext_for_id'] ) ) {
  1941. $viewid = $ev[$i]['cal_ext_for_id'];
  1942. $viewname = $ev[$i]['cal_name'] . " (" .
  1943. translate("cont.") . ")";
  1944. } else {
  1945. $viewid = $ev[$i]['cal_id'];
  1946. $viewname = $ev[$i]['cal_name'];
  1947. }
  1948. if ( $ev[$i]['cal_duration'] == ( 24 * 60 ) )
  1949. $all_day = 1;
  1950. html_for_event_day_at_a_glance ( $viewid,
  1951. $date, $ev[$i]['cal_time'],
  1952. $viewname, $ev[$i]['cal_description'],
  1953. $ev[$i]['cal_status'], $ev[$i]['cal_priority'],
  1954. $ev[$i]['cal_access'], $ev[$i]['cal_duration'],
  1955. $ev[$i]['cal_login'], $hide_icons );
  1956. }
  1957. }
  1958. // print out any remaining repeating events
  1959. while ( $cur_rep < count ( $rep ) ) {
  1960. if ( $get_unapproved || $rep[$cur_rep]['cal_status'] == 'A' ) {
  1961. if ( ! empty ( $rep[$cur_rep]['cal_ext_for_id'] ) ) {
  1962. $viewid = $rep[$cur_rep]['cal_ext_for_id'];
  1963. $viewname = $rep[$cur_rep]['cal_name'] . " (" .
  1964. translate("cont.") . ")";
  1965. } else {
  1966. $viewid = $rep[$cur_rep]['cal_id'];
  1967. $viewname = $rep[$cur_rep]['cal_name'];
  1968. }
  1969. if ( $rep['cal_duration'] == ( 24 * 60 ) )
  1970. $all_day = 1;
  1971. html_for_event_day_at_a_glance ( $viewid,
  1972. $date, $rep[$cur_rep]['cal_time'],
  1973. $viewname, $rep[$cur_rep]['cal_description'],
  1974. $rep[$cur_rep]['cal_status'], $rep[$cur_rep]['cal_priority'],
  1975. $rep[$cur_rep]['cal_access'], $rep[$cur_rep]['cal_duration'],
  1976. $rep[$cur_rep]['cal_login'], $hide_icons );
  1977. }
  1978. $cur_rep++;
  1979. }
  1980. // squish events that use the same cell into the same cell.
  1981. // For example, an event from 8:00-9:15 and another from 9:30-9:45 both
  1982. // want to show up in the 8:00-9:59 cell.
  1983. $rowspan = 0;
  1984. $last_row = -1;
  1985. //echo "First SLot: $first_slot; Last Slot: $last_slot <BR>";
  1986. $i = 0;
  1987. if ( $first_slot < 0 )
  1988. $i = $first_slot;
  1989. for ( ; $i < $TIME_SLOTS; $i++ ) {
  1990. if ( $rowspan > 1 ) {
  1991. if ( ! empty ( $hour_arr[$i] ) ) {
  1992. if ( $rowspan_arr[$i] > 1 ) {
  1993. $rowspan_arr[$last_row] += ( $rowspan_arr[$i] - 1 );
  1994. $rowspan += ( $rowspan_arr[$i] - 1 );
  1995. } else
  1996. $rowspan_arr[$last_row] += $rowspan_arr[$i];
  1997. // this will move entries apart that appear in one field,
  1998. // yet start on different hours
  1999. $start_time = $i;
  2000. $diff_start_time = $start_time - $last_row;
  2001. for ( $u = $diff_start_time ; $u > 0 ; $u-- )
  2002. $hour_arr[$last_row] .= "<BR>";
  2003. $hour_arr[$last_row] .= $hour_arr[$i];
  2004. $hour_arr[$i] = "";
  2005. $rowspan_arr[$i] = 0;
  2006. }
  2007. $rowspan--;
  2008. } else if ( ! empty ( $rowspan_arr[$i] ) && $rowspan_arr[$i] > 1 ) {
  2009. $rowspan = $rowspan_arr[$i];
  2010. $last_row = $i;
  2011. }
  2012. }
  2013. if ( ! empty ( $hour_arr[9999] ) ) {
  2014. echo "<TR><TD HEIGHT=\"40\" BGCOLOR=\"$TODAYCELLBG\">&nbsp;</TD><TD VALIGN=\"top\" HEIGHT=\"40\" BGCOLOR=\"$TODAYCELLBG\">$hour_arr[9999]</TD></TR>\n";
  2015. }
  2016. $rowspan = 0;
  2017. //echo "first_slot = $first_slot <BR> last_slot = $last_slot <BR> interval = $interval <BR>";
  2018. for ( $i = $first_slot; $i <= $last_slot; $i++ ) {
  2019. $time_h = (int) ( ( $i * $interval ) / 60 );
  2020. $time_m = ( $i * $interval ) % 60;
  2021. $time = display_time ( ( $time_h * 100 + $time_m ) * 100 );
  2022. echo "<TR><TH VALIGN=\"top\" HEIGHT=\"40\" WIDTH=\"14%\" BGCOLOR=\"$THBG\" CLASS=\"tableheader\">" .
  2023. "<FONT COLOR=\"$THFG\">" .
  2024. $time . "</FONT></TH>\n";
  2025. if ( $rowspan > 1 ) {
  2026. // this might mean there's an overlap, or it could mean one event
  2027. // ends at 11:15 and another starts at 11:30.
  2028. if ( strlen ( $hour_arr[$i] ) ) {
  2029. echo "<TD VALIGN=\"top\" HEIGHT=\"40\" BGCOLOR=\"$TODAYCELLBG\">";
  2030. if ( $can_add && ! $hide_icons )
  2031. echo html_for_add_icon ( $date, $time_h, $time_m );
  2032. echo "$hour_arr[$i]</TD>";
  2033. }
  2034. $rowspan--;
  2035. } else {
  2036. $color = $all_day ? $TODAYCELLBG : $CELLBG;
  2037. if ( empty ( $hour_arr[$i] ) ) {
  2038. echo "<TD HEIGHT=\"40\" BGCOLOR=\"$color\">";
  2039. if ( $can_add && ! $hide_icons )
  2040. echo html_for_add_icon ( $date, $time_h, $time_m );
  2041. echo "&nbsp;</TD></TR>\n";
  2042. } else {
  2043. $rowspan = $rowspan_arr[$i];
  2044. if ( $rowspan > 1 ) {
  2045. echo "<TD VALIGN=\"top\" BGCOLOR=\"$TODAYCELLBG\" ROWSPAN=\"$rowspan\">";
  2046. if ( $can_add && ! $hide_icons )
  2047. echo html_for_add_icon ( $date, $time_h, $time_m );
  2048. echo "$hour_arr[$i]</TD></TR>\n";
  2049. } else {
  2050. echo "<TD VALIGN=\"top\" HEIGHT=\"40\" BGCOLOR=\"$TODAYCELLBG\">";
  2051. if ( $can_add && ! $hide_icons )
  2052. echo html_for_add_icon ( $date, $time_h, $time_m );
  2053. echo "$hour_arr[$i]</TD></TR>\n";
  2054. }
  2055. }
  2056. }
  2057. }
  2058. }
  2059. // display a link to any unapproved events
  2060. // If the user is an admin user, also count up any public events.
  2061. function display_unapproved_events ( $user ) {
  2062. global $public_access, $is_admin;
  2063. // Don't do this for public access login, admin user must approve public
  2064. // events
  2065. if ( $user == "__public__" )
  2066. return;
  2067. $sql = "SELECT COUNT(webcal_entry_user.cal_id) " .
  2068. "FROM webcal_entry_user, webcal_entry " .
  2069. "WHERE webcal_entry_user.cal_id = webcal_entry.cal_id " .
  2070. "AND webcal_entry_user.cal_status = 'W' " .
  2071. "AND ( webcal_entry.cal_ext_for_id IS NULL " .
  2072. "OR webcal_entry.cal_ext_for_id = 0 ) " .
  2073. "AND ( webcal_entry_user.cal_login = '$user'";
  2074. if ( $public_access == "Y" && $is_admin )
  2075. $sql .= " OR webcal_entry_user.cal_login = '__public__' )";
  2076. else
  2077. $sql .= " )";
  2078. //print "SQL: $sql<BR>";
  2079. $res = dbi_query ( $sql );
  2080. if ( $res ) {
  2081. if ( $row = dbi_fetch_row ( $res ) ) {
  2082. if ( $row[0] > 0 )
  2083. $str = translate ("You have XXX unapproved events");
  2084. $str = str_replace ( "XXX", $row[0], $str );
  2085. echo "<A CLASS=\"navlinks\" " .
  2086. "HREF=\"list_unapproved.php\">" . $str . "</A><BR>\n";
  2087. }
  2088. dbi_free_result ( $res );
  2089. }
  2090. }
  2091. // Look for URLs in the given text, and make them into links.
  2092. // params:
  2093. // $text - input text
  2094. function activate_urls ( $text ) {
  2095. $str = eregi_replace ( "(http://[^[:space:]$]+)",
  2096. "<A HREF=\"\\1\">\\1</A>", $text );
  2097. return $str;
  2098. }
  2099. // Display a time in either 12 or 24 hour format
  2100. // params:
  2101. // $time - an interger like 235900
  2102. // The global variable $TZ_OFFSET to adjust the time.
  2103. // Note that this is somewhat of a kludge for timezone support. If an
  2104. // event is set for 11PM server time and the user is 2 hours ahead, it
  2105. // will show up as 1AM, but the date will not be adjusted to the next day.
  2106. function display_time ( $time, $ignore_offset=0 ) {
  2107. global $TZ_OFFSET;
  2108. $hour = (int) ( $time / 10000 );
  2109. if ( ! $ignore_offset )
  2110. $hour += $TZ_OFFSET;
  2111. while ( $hour < 0 )
  2112. $hour += 24;
  2113. while ( $hour > 23 )
  2114. $hour -= 24;
  2115. $min = ( $time / 100 ) % 100;
  2116. if ( $GLOBALS["TIME_FORMAT"] == "12" ) {
  2117. $ampm = $hour >= 12 && $hour != 24 ? translate("pm") : translate("am");
  2118. $hour %= 12;
  2119. if ( $hour == 0 )
  2120. $hour = 12;
  2121. $ret = sprintf ( "%d:%02d%s", $hour, $min, $ampm );
  2122. } else {
  2123. $ret = sprintf ( "%d:%02d", $hour, $min );
  2124. }
  2125. return $ret;
  2126. }
  2127. // Return the full month name
  2128. // params:
  2129. // $m - month (0-11)
  2130. function month_name ( $m ) {
  2131. switch ( $m ) {
  2132. case 0: return translate("January");
  2133. case 1: return translate("February");
  2134. case 2: return translate("March");
  2135. case 3: return translate("April");
  2136. case 4: return translate("May_"); // needs to be different than "May"
  2137. case 5: return translate("June");
  2138. case 6: return translate("July");
  2139. case 7: return translate("August");
  2140. case 8: return translate("September");
  2141. case 9: return translate("October");
  2142. case 10: return translate("November");
  2143. case 11: return translate("December");
  2144. }
  2145. return "unknown-month($m)";
  2146. }
  2147. // Return the abbreviated month name
  2148. // params:
  2149. // $m - month (0-11)
  2150. function month_short_name ( $m ) {
  2151. switch ( $m ) {
  2152. case 0: return translate("Jan");
  2153. case 1: return translate("Feb");
  2154. case 2: return translate("Mar");
  2155. case 3: return translate("Apr");
  2156. case 4: return translate("May");
  2157. case 5: return translate("Jun");
  2158. case 6: return translate("Jul");
  2159. case 7: return translate("Aug");
  2160. case 8: return translate("Sep");
  2161. case 9: return translate("Oct");
  2162. case 10: return translate("Nov");
  2163. case 11: return translate("Dec");
  2164. }
  2165. return "unknown-month($m)";
  2166. }
  2167. // Return the full weekday name
  2168. // params:
  2169. // $w - weekday (0=Sunday,...,6=Saturday)
  2170. function weekday_name ( $w ) {
  2171. switch ( $w ) {
  2172. case 0: return translate("Sunday");
  2173. case 1: return translate("Monday");
  2174. case 2: return translate("Tuesday");
  2175. case 3: return translate("Wednesday");
  2176. case 4: return translate("Thursday");
  2177. case 5: return translate("Friday");
  2178. case 6: return translate("Saturday");
  2179. }
  2180. return "unknown-weekday($w)";
  2181. }
  2182. // Return the abbreviated weekday name
  2183. // params:
  2184. // $w - weekday (0=Sun,...,6=Sat)
  2185. function weekday_short_name ( $w ) {
  2186. switch ( $w ) {
  2187. case 0: return translate("Sun");
  2188. case 1: return translate("Mon");
  2189. case 2: return translate("Tue");
  2190. case 3: return translate("Wed");
  2191. case 4: return translate("Thu");
  2192. case 5: return translate("Fri");
  2193. case 6: return translate("Sat");
  2194. }
  2195. return "unknown-weekday($w)";
  2196. }
  2197. // convert a date from an int format "19991231" into
  2198. // "Friday, December 31, 1999", "Friday, 12-31-1999" or whatever format
  2199. // the user prefers.
  2200. function date_to_str ( $indate, $format="", $show_weekday=true, $short_months=false, $server_time="" ) {
  2201. global $DATE_FORMAT, $TZ_OFFSET;
  2202. if ( strlen ( $indate ) == 0 ) {
  2203. $indate = date ( "Ymd" );
  2204. }
  2205. $newdate = $indate;
  2206. if ( ! empty ( $server_time ) ) {
  2207. $y = substr ( $indate, 0, 4 );
  2208. $m = substr ( $indate, 4, 2 );
  2209. $d = substr ( $indate, 6, 2 );
  2210. if ( $server_time + $TZ_OFFSET * 10000 > 240000 ) {
  2211. $newdate = date ( "Ymd", mktime ( 3, 0, 0, $m, $d + 1, $y ) );
  2212. } else if ( $server_time + $TZ_OFFSET * 10000 < 0 ) {
  2213. $newdate = date ( "Ymd", mktime ( 3, 0, 0, $m, $d - 1, $y ) );
  2214. }
  2215. }
  2216. // if they have not set a preference yet...
  2217. if ( $DATE_FORMAT == "" )
  2218. $DATE_FORMAT = "__month__ __dd__, __yyyy__";
  2219. if ( empty ( $format ) )
  2220. $format = $DATE_FORMAT;
  2221. $y = (int) ( $newdate / 10000 );
  2222. $m = (int) ( $newdate / 100 ) % 100;
  2223. $d = $newdate % 100;
  2224. $date = mktime ( 3, 0, 0, $m, $d, $y );
  2225. $wday = strftime ( "%w", $date );
  2226. if ( $short_months ) {
  2227. $weekday = weekday_short_name ( $wday );
  2228. $month = month_short_name ( $m - 1 );
  2229. } else {
  2230. $weekday = weekday_name ( $wday );
  2231. $month = month_name ( $m - 1 );
  2232. }
  2233. $yyyy = $y;
  2234. $yy = sprintf ( "%02d", $y %= 100 );
  2235. $ret = $format;
  2236. $ret = str_replace ( "__yyyy__", $yyyy, $ret );
  2237. $ret = str_replace ( "__yy__", $yy, $ret );
  2238. $ret = str_replace ( "__month__", $month, $ret );
  2239. $ret = str_replace ( "__mon__", $month, $ret );
  2240. $ret = str_replace ( "__dd__", $d, $ret );
  2241. $ret = str_replace ( "__mm__", $m, $ret );
  2242. if ( $show_weekday )
  2243. return "$weekday, $ret";
  2244. else
  2245. return $ret;
  2246. }
  2247. // Define an array to use to jumble up the key
  2248. $offsets = array ( 31, 41, 59, 26, 54 );
  2249. function hextoint ( $val ) {
  2250. if ( empty ( $val ) )
  2251. return 0;
  2252. switch ( strtoupper ( $val ) ) {
  2253. case "0": return 0;
  2254. case "1": return 1;
  2255. case "2": return 2;
  2256. case "3": return 3;
  2257. case "4": return 4;
  2258. case "5": return 5;
  2259. case "6": return 6;
  2260. case "7": return 7;
  2261. case "8": return 8;
  2262. case "9": return 9;
  2263. case "A": return 10;
  2264. case "B": return 11;
  2265. case "C": return 12;
  2266. case "D": return 13;
  2267. case "E": return 14;
  2268. case "F": return 15;
  2269. }
  2270. return 0;
  2271. }
  2272. // Extract a user's name from a session id
  2273. // This is a lame attempt at security. Otherwise, users would be
  2274. // able to edit their cookies.txt file and set the username in plain
  2275. // text.
  2276. // $instr is a hex-encoded string. "Hello" would be "678ea786a5".
  2277. function decode_string ( $instr ) {
  2278. global $offsets;
  2279. //echo "<P>DECODE <BR>";
  2280. $orig = "";
  2281. for ( $i = 0; $i < strlen ( $instr ); $i += 2 ) {
  2282. //echo "<P>";
  2283. $ch1 = substr ( $instr, $i, 1 );
  2284. $ch2 = substr ( $instr, $i + 1, 1 );
  2285. $val = hextoint ( $ch1 ) * 16 + hextoint ( $ch2 );
  2286. //echo "decoding \"" . $ch1 . $ch2 . "\" = $val <br>\n";
  2287. $j = ( $i / 2 ) % count ( $offsets );
  2288. //echo "Using offsets $j = " . $offsets[$j] . "<br>";
  2289. $newval = $val - $offsets[$j] + 256;
  2290. $newval %= 256;
  2291. //echo " neval \"$newval\" <br>\n";
  2292. $dec_ch = chr ( $newval );
  2293. //echo " which is \"$dec_ch\" <br>\n";
  2294. $orig .= $dec_ch;
  2295. }
  2296. return $orig;
  2297. }
  2298. // Take an input string and encoded it into a slightly encoded hexval
  2299. // that we can use as a session cookie.
  2300. function encode_string ( $instr ) {
  2301. global $offsets;
  2302. //echo "<P>ENCODE<BR>";
  2303. $ret = "";
  2304. for ( $i = 0; $i < strlen ( $instr ); $i++ ) {
  2305. //echo "<P>";
  2306. $ch1 = substr ( $instr, $i, 1 );
  2307. $val = ord ( $ch1 );
  2308. //echo "val = $val for \"$ch1\" <br>\n";
  2309. $j = $i % count ( $offsets );
  2310. //echo "Using offsets $j = $offsets[$j]<br>";
  2311. $newval = $val + $offsets[$j];
  2312. $newval %= 256;
  2313. //echo "newval = $newval for \"$ch1\" <br>\n";
  2314. $ret .= bin2hex ( chr ( $newval ) );
  2315. }
  2316. return $ret;
  2317. }
  2318. function user_external_auth ( $login, $password ) {
  2319. $ret = exec ( escapeshellcmd ( "/usr/bin/ypmatch $login passwd" ) );
  2320. if ( strlen ( $ret ) ) {
  2321. $ret = explode ( ":", $ret );
  2322. if ( $user_external_group && $user_external_group != $ret[3] ) {
  2323. return "";
  2324. }
  2325. if ( strcmp ( $ret[1], crypt ( $password, substr ( $ret[1], 0, 2 ) ) ) ) {
  2326. return "";
  2327. }
  2328. return $ret;
  2329. }
  2330. return "";
  2331. }
  2332. // an implementatin of array_splice() for PHP3
  2333. // test cases:
  2334. // insert an element
  2335. // array_splice($array,$offset,0,array($item));
  2336. // delete an element
  2337. // array_splice($array,$offset,1);
  2338. function my_array_splice(&$input,$offset,$length,$replacement) {
  2339. if ( floor(phpversion()) < 4 ) {
  2340. // if offset is negative, then it starts at the end of array
  2341. if ( $offset < 0 )
  2342. $offset = count($input) + $offset;
  2343. for ($i=0;$i<$offset;$i++) {
  2344. $new_array[] = $input[$i];
  2345. }
  2346. // if we have a replacement, insert it
  2347. for ($i=0;$i<count($replacement);$i++) {
  2348. $new_array[] = $replacement[$i];
  2349. }
  2350. // now tack on the rest of the original array
  2351. for ($i=$offset+$length;$i<count($input);$i++) {
  2352. $new_array[] = $input[$i];
  2353. }
  2354. $input = $new_array;
  2355. } else {
  2356. array_splice($input,$offset,$length,$replacement);
  2357. }
  2358. }
  2359. // Load current user's category info and stuff it into category global variable.
  2360. // $ex_global - Don't include global categories.
  2361. function load_user_categories ($ex_global = '') {
  2362. global $login;
  2363. global $categories, $category_owners;
  2364. global $categories_enabled;
  2365. $categories = array ();
  2366. $category_owners = array ();
  2367. if ( $categories_enabled == "Y" ) {
  2368. $sql = "SELECT cat_id, cat_name, cat_owner FROM webcal_categories WHERE ";
  2369. $sql .= ($ex_global == '') ? " (cat_owner = '$login') OR (cat_owner IS NULL) ORDER BY cat_owner, cat_name" : " cat_owner = '$login' ORDER BY cat_name";
  2370. $res = dbi_query ( $sql );
  2371. if ( $res ) {
  2372. while ( $row = dbi_fetch_row ( $res ) ) {
  2373. $cat_id = $row[0];
  2374. $categories[$cat_id] = $row[1];
  2375. $category_owners[$cat_id] = $row[2];
  2376. }
  2377. dbi_free_result ( $res );
  2378. }
  2379. } else {
  2380. //echo "Categories disabled.";
  2381. }
  2382. }
  2383. // Build dropdown of categories
  2384. // $form - the page to submit data to (without .php)
  2385. // $date - YYYYMMDD
  2386. // $ID - category that should be pre-selected
  2387. // $friendly - printer friendly?
  2388. function print_category_menu ( $form, $date = '', $cat_id = '', $friendly = '' ) {
  2389. global $categories;
  2390. if ( $friendly == '' ) {
  2391. echo "<form ACTION=\"{$form}.php\" METHOD=\"GET\" NAME=\"SelectCategory\">\n";
  2392. if ( ! empty($date) ) echo "<input type=\"hidden\" NAME=\"date\" VALUE=\"$date\">\n";
  2393. echo translate ('Category').": <select name=\"cat_id\" ONCHANGE=\"document.SelectCategory.submit()\">\n";
  2394. echo "<option value=\"\"";
  2395. if ( $cat_id == '' ) echo " SELECTED";
  2396. echo ">" . translate("All") . "</option>\n";
  2397. if ( is_array ( $categories ) ) {
  2398. foreach( $categories as $K => $V ){
  2399. echo "<option value=\"$K\"";
  2400. if ( $cat_id == $K ) echo " SELECTED";
  2401. echo ">$V\n";
  2402. }
  2403. }
  2404. echo "</select>\n";
  2405. echo "</FORM>\n";
  2406. } else {
  2407. echo translate ('Category').": ";
  2408. echo ( $cat_id != '' ) ? $categories[$cat_id] . "\n" : translate ('All')."\n";
  2409. }
  2410. }
  2411. // Convert HTML entities in 8bit
  2412. // Only supported for PHP4 (not PHP3)
  2413. function html_to_8bits ( $html ) {
  2414. if ( floor(phpversion()) < 4 ) {
  2415. return $html;
  2416. } else {
  2417. return strtr ( $html, array_flip (
  2418. get_html_translation_table (HTML_ENTITIES) ) );
  2419. }
  2420. }
  2421. // ***********************************************************************
  2422. // Functions for getting information about boss and their assistant.
  2423. // ***********************************************************************
  2424. // Get a list of a boss assistants
  2425. function user_get_assistants ( $boss ) {
  2426. $res = dbi_query ( "SELECT u.cal_login, u.cal_lastname, u.cal_firstname " .
  2427. "FROM webcal_user as u, webcal_asst as b " .
  2428. "WHERE b.cal_boss = '$boss' AND b.cal_assistant = u.cal_login " .
  2429. "ORDER BY u.cal_lastname, u.cal_firstname, u.cal_login" );
  2430. $count = 0;
  2431. $ret = array ();
  2432. if ( $res ) {
  2433. while ( $row = dbi_fetch_row ( $res ) ) {
  2434. if ( strlen ( $row[1] ) && strlen ( $row[2] ) )
  2435. $fullname = "$row[2] $row[1]";
  2436. else
  2437. $fullname = $row[0];
  2438. $ret[$count++] = array (
  2439. "cal_login" => $row[0],
  2440. "cal_lastname" => $row[1],
  2441. "cal_firstname" => $row[2],
  2442. "cal_fullname" => $fullname
  2443. );
  2444. }
  2445. dbi_free_result ( $res );
  2446. }
  2447. return $ret;
  2448. }
  2449. // Get a list of an assistant's boss
  2450. function user_get_boss_list ( $assistant ) {
  2451. $res = dbi_query (
  2452. "SELECT u.cal_login, u.cal_lastname, u.cal_firstname " .
  2453. "FROM webcal_user as u, webcal_asst as b " .
  2454. "WHERE b.cal_assistant = '$assistant' AND b.cal_boss = u.cal_login " .
  2455. "ORDER BY u.cal_lastname, u.cal_firstname, u.cal_login" );
  2456. $count = 0;
  2457. $ret = array ();
  2458. if ( $res ) {
  2459. while ( $row = dbi_fetch_row ( $res ) ) {
  2460. if ( strlen ( $row[1] ) && strlen ( $row[2] ) )
  2461. $fullname = "$row[2] $row[1]";
  2462. else
  2463. $fullname = $row[0];
  2464. $ret[$count++] = array (
  2465. "cal_login" => $row[0],
  2466. "cal_lastname" => $row[1],
  2467. "cal_firstname" => $row[2],
  2468. "cal_fullname" => $fullname
  2469. );
  2470. }
  2471. dbi_free_result ( $res );
  2472. }
  2473. return $ret;
  2474. }
  2475. // Return true if $user is $boss assistant
  2476. function user_is_assistant ( $assistant, $boss ) {
  2477. $ret = false;
  2478. $res = dbi_query ( "SELECT * FROM webcal_asst as b " .
  2479. "WHERE b.cal_assistant = '$assistant' AND b.cal_boss = '$boss'" );
  2480. if ( $res ) {
  2481. if ( dbi_fetch_row ( $res ) )
  2482. $ret = true;
  2483. dbi_free_result ( $res );
  2484. }
  2485. return $ret;
  2486. }
  2487. // return true if assistant has boss
  2488. function user_has_boss ( $assistant ) {
  2489. $ret = false;
  2490. $res = dbi_query ( "SELECT * FROM webcal_asst as b " .
  2491. "WHERE b.cal_assistant = '$assistant'" );
  2492. if ( $res ) {
  2493. if ( dbi_fetch_row ( $res ) )
  2494. $ret = true;
  2495. dbi_free_result ( $res );
  2496. }
  2497. return $ret;
  2498. }
  2499. // Use this for testing....
  2500. function fake_mail ( $mailto, $subj, $text, $hdrs ) {
  2501. echo "To: $mailto <BR>" .
  2502. "Subject: $subj <BR>" .
  2503. nl2br ( $hdrs ) . "<P>" .
  2504. nl2br ( $text );
  2505. }
  2506. //
  2507. // Print all the entries in a time bar format for the specified user
  2508. // for the
  2509. // specified date. If we are displaying data from someone other than
  2510. // the logged in user, then check the access permission of the entry.
  2511. // params:
  2512. // $date - date in YYYYMMDD format
  2513. // $user - username
  2514. // $hide_icons - hide icons to make printer-friendly
  2515. // $is_ssi - is this being called from week_ssi.php?
  2516. function print_date_entries_timebar ( $date, $user, $hide_icons, $ssi ) {
  2517. global $events, $readonly, $is_admin,
  2518. $public_access, $public_access_can_add;
  2519. $cnt = 0;
  2520. $get_unapproved = ( $GLOBALS["DISPLAY_UNAPPROVED"] == "Y" );
  2521. // public access events always must be approved before being displayed
  2522. if ( $GLOBALS["login"] == "__public__" )
  2523. $get_unapproved = false;
  2524. $year = substr ( $date, 0, 4 );
  2525. $month = substr ( $date, 4, 2 );
  2526. $day = substr ( $date, 6, 2 );
  2527. $dateu = mktime ( 3, 0, 0, $month, $day, $year );
  2528. $can_add = ( $readonly == "N" || $is_admin );
  2529. if ( $public_access == "Y" && $public_access_can_add != "Y" &&
  2530. $GLOBALS["login"] == "__public__" )
  2531. $can_add = false;
  2532. // get all the repeating events for this date and store in array $rep
  2533. $rep = get_repeating_entries ( $users[$i], $date ) ;
  2534. $cur_rep = 0;
  2535. // get all the non-repeating events for this date and store in $ev
  2536. $ev = get_entries ( $users[$i], $date );
  2537. for ( $i = 0; $i < count ( $ev ); $i++ ) {
  2538. // print out any repeating events that are before this one...
  2539. while ( $cur_rep < count ( $rep ) &&
  2540. $rep[$cur_rep]['cal_time'] < $ev[$i]['cal_time'] ) {
  2541. if ( $get_unapproved || $rep[$cur_rep]['cal_status'] == 'A' ) {
  2542. print_entry_timebar ( $rep[$cur_rep]['cal_id'],
  2543. $date, $rep[$cur_rep]['cal_time'], $rep[$cur_rep]['cal_duration'],
  2544. $rep[$cur_rep]['cal_name'], $rep[$cur_rep]['cal_description'],
  2545. $rep[$cur_rep]['cal_status'], $rep[$cur_rep]['cal_priority'],
  2546. $rep[$cur_rep]['cal_access'], $rep[$cur_rep]['cal_login'],
  2547. $hide_icons );
  2548. $cnt++;
  2549. }
  2550. $cur_rep++;
  2551. }
  2552. if ( $get_unapproved || $ev[$i]['cal_status'] == 'A' ) {
  2553. print_entry_timebar ( $ev[$i]['cal_id'],
  2554. $date, $ev[$i]['cal_time'], $ev[$i]['cal_duration'],
  2555. $ev[$i]['cal_name'], $ev[$i]['cal_description'],
  2556. $ev[$i]['cal_status'], $ev[$i]['cal_priority'],
  2557. $ev[$i]['cal_access'], $ev[$i]['cal_login'], $hide_icons );
  2558. $cnt++;
  2559. }
  2560. }
  2561. // print out any remaining repeating events
  2562. while ( $cur_rep < count ( $rep ) ) {
  2563. if ( $get_unapproved || $rep[$cur_rep]['cal_status'] == 'A' ) {
  2564. print_entry_timebar ( $rep[$cur_rep]['cal_id'],
  2565. $date, $rep[$cur_rep]['cal_time'], $rep[$cur_rep]['cal_duration'],
  2566. $rep[$cur_rep]['cal_name'], $rep[$cur_rep]['cal_description'],
  2567. $rep[$cur_rep]['cal_status'], $rep[$cur_rep]['cal_priority'],
  2568. $rep[$cur_rep]['cal_access'], $rep[$cur_rep]['cal_login'],
  2569. $hide_icons );
  2570. $cnt++;
  2571. }
  2572. $cur_rep++;
  2573. }
  2574. if ( $cnt == 0 )
  2575. echo "&nbsp;"; // so the table cell has at least something
  2576. }
  2577. // Print the HTML for an events with a timebar.
  2578. // params:
  2579. // $id - event id
  2580. // $date - date (not used)
  2581. // $time - time (in HHMMSS format)
  2582. // $duration - duration (in minutes)
  2583. // $name - event name
  2584. // $description - long description of event
  2585. // $status - event status
  2586. // $pri - event priority
  2587. // $access - event access
  2588. // $event_owner - user associated with this event
  2589. // $hide_icons - hide icons to make printer-friendly
  2590. function print_entry_timebar ( $id, $date, $time, $duration,
  2591. $name, $description, $status,
  2592. $pri, $access, $event_owner, $hide_icons ) {
  2593. global $eventinfo, $login, $user, $PHP_SELF;
  2594. static $key = 0;
  2595. global $layers;
  2596. // compute time offsets in % of total table width
  2597. $day_start=$prefarray["WORK_DAY_START_HOUR"] * 60;
  2598. if ( $day_start == 0 ) $day_start = 9*60;
  2599. $day_end=$prefarray["WORK_DAY_END_HOUR"] * 60;
  2600. if ( $day_end == 0 ) $day_end = 19*60;
  2601. if ( $day_end <= $day_start ) $day_end = $day_start + 60; //avoid exceptions
  2602. if ($time >= 0) {
  2603. $ev_start=$time/10000 * 60 + (($time/100)%100);
  2604. $ev_start = round(100 * ($ev_start - $day_start) / ($day_end - $day_start));
  2605. }else{
  2606. $ev_start= 0;
  2607. }
  2608. if ($duration > 0) {
  2609. $ev_duration = round(100 * $duration / ($day_end - $day_start)) ;
  2610. if ($ev_start + $ev_duration > 100 ) {
  2611. $ev_duration = 100 - $ev_start;
  2612. }
  2613. }else{
  2614. if ($time >= 0) {
  2615. $ev_duration = 1;
  2616. } else{
  2617. $ev_duration=100-$ev_start;
  2618. }
  2619. }
  2620. $ev_padding = 100 - $ev_start - $ev_duration;
  2621. // choose where to position the text (pos=0->before,pos=1->on,pos=2->after)
  2622. if ($ev_duration > 20) { $pos = 1; }
  2623. elseif ($ev_padding > 20) { $pos = 2; }
  2624. else { $pos = 0; }
  2625. echo "<TABLE WIDTH=\"100%\" BGCOLOR=\"black\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\">\n";
  2626. echo "<TR>";
  2627. echo "<TD ALIGN=\"right\" WIDTH=\"$ev_start%\" BGCOLOR=\"white\">";
  2628. if ( $pos > 0 ) {
  2629. echo "&nbsp;</TD>";
  2630. echo "<TD WIDTH=\"$ev_duration%\">
  2631. <TABLE WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"black\" CELLSPACING=\"1\">
  2632. <TR><TD ALIGN=\"middle\" BGCOLOR=\"#F5DEB3\">";
  2633. if ( $pos > 1 ) {
  2634. echo "&nbsp;</TD></TR></TABLE></TD>";
  2635. echo "<TD ALIGN=\"left\" WIDTH=\"$ev_padding%\" BGCOLOR=\"white\">";
  2636. }
  2637. };
  2638. echo "<FONT SIZE=\"-1\">";
  2639. if ( $login != $event_owner && strlen ( $event_owner ) ) {
  2640. $class = "layerentry";
  2641. } else {
  2642. $class = "entry";
  2643. if ( $status == "W" ) $class = "unapprovedentry";
  2644. }
  2645. // if we are looking at a view, then always use "entry"
  2646. if ( strstr ( $PHP_SELF, "view_m.php" ) ||
  2647. strstr ( $PHP_SELF, "view_w.php" ) ||
  2648. strstr ( $PHP_SELF, "view_v.php" ) ||
  2649. strstr ( $PHP_SELF, "view_t.php" ) )
  2650. $class = "entry";
  2651. if ( $pri == 3 ) echo "<B>";
  2652. if ( ! $hide_icons ) {
  2653. $divname = "eventinfo-$id-$key";
  2654. $key++;
  2655. echo "<A CLASS=\"$class\" HREF=\"view_entry.php?id=$id&date=$date";
  2656. if ( strlen ( $user ) > 0 )
  2657. echo "&user=" . $user;
  2658. echo "\" onMouseOver=\"window.status='" . translate("View this entry") .
  2659. "'; show(event, '$divname'); return true;\" onMouseOut=\"hide('$divname'); return true;\">";
  2660. }
  2661. if ( $login != $event_owner && strlen ( $event_owner ) )
  2662. {
  2663. for($index = 0; $index < sizeof($layers); $index++)
  2664. {
  2665. if($layers[$index]['cal_layeruser'] == $event_owner)
  2666. {
  2667. echo("<FONT COLOR=\"" . $layers[$index]['cal_color'] . "\">");
  2668. }
  2669. }
  2670. }
  2671. echo "[$event_owner]";
  2672. $timestr = "";
  2673. if ( $duration == ( 24 * 60 ) ) {
  2674. $timestr = translate("All day event");
  2675. } else if ( $time >= 0 ) {
  2676. $timestr = display_time ( $time );
  2677. if ( $duration > 0 ) {
  2678. // calc end time
  2679. $h = (int) ( $time / 10000 );
  2680. $m = ( $time / 100 ) % 100;
  2681. $m += $duration;
  2682. $d = $duration;
  2683. while ( $m >= 60 ) {
  2684. $h++;
  2685. $m -= 60;
  2686. }
  2687. $end_time = sprintf ( "%02d%02d00", $h, $m );
  2688. $timestr .= " - " . display_time ( $end_time );
  2689. }
  2690. }
  2691. if ( $login != $user && $access == 'R' && strlen ( $user ) )
  2692. echo "(" . translate("Private") . ")";
  2693. else
  2694. if ( $login != $event_owner && $access == 'R' && strlen ( $event_owner ) )
  2695. echo "(" . translate("Private") . ")";
  2696. else
  2697. if ( $login != $event_owner && strlen ( $event_owner ) )
  2698. {
  2699. echo htmlspecialchars ( $name );
  2700. echo ("</FONT>");
  2701. }
  2702. else
  2703. echo htmlspecialchars ( $name );
  2704. echo "</A>";
  2705. if ( $pri == 3 ) echo "</B>";
  2706. echo "</FONT>";
  2707. echo "</TD>";
  2708. if ( $pos < 2 ) {
  2709. if ( $pos < 1 ) {
  2710. echo "<TD WIDTH=\"$ev_duration%\"> <TABLE WIDTH=\"100%\"
  2711. BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"1\"
  2712. BGCOLOR=\"black\"><TR><TD ALIGN=\"middle\"
  2713. BGCOLOR=\"#F5DEB3\">&nbsp;</TD>";
  2714. }
  2715. echo "</TR></TABLE></TD>";
  2716. echo "<TD ALIGN=\"left\" WIDTH=\"$ev_padding%\" BGCOLOR=\"white\"> &nbsp;</TD>";
  2717. }
  2718. echo "</TR></TABLE>";
  2719. if ( ! $hide_icons ) {
  2720. if ( $login != $user && $access == 'R' && strlen ( $user ) )
  2721. $eventinfo .= build_event_popup ( $divname, $event_owner,
  2722. translate("This event is confidential"), "" );
  2723. else
  2724. if ( $login != $event_owner && $access == 'R' && strlen ( $event_owner ) )
  2725. $eventinfo .= build_event_popup ( $divname, $event_owner,
  2726. translate("This event is confidential"), "" );
  2727. else
  2728. $eventinfo .= build_event_popup ( $divname, $event_owner,
  2729. $description, $timestr );
  2730. }
  2731. }
  2732. function print_header_timebar($start_hour, $end_hour) {
  2733. // sh+1 ... eh-1
  2734. // +------+----....----+------+
  2735. // | | | |
  2736. // print hours
  2737. if ( ($end_hour - $start_hour) == 0 )
  2738. $offset = 0;
  2739. else
  2740. $offset = round(100/($end_hour - $start_hour)/2);
  2741. echo "<TABLE WIDTH=\"100%\" BGCOLOR=\"white\" BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">
  2742. <TR><TD BGCOLOR=\"white\" WIDTH=\"$offset%\">&nbsp;</TD>\n";
  2743. for ($i = $start_hour+1; $i < $end_hour; $i++) {
  2744. $prev_offset = $offset;
  2745. $offset = round(100/($end_hour - $start_hour)*($i - $start_hour + .5));
  2746. $width = $offset - $prev_offset;
  2747. echo "<TD BGCOLOR=\"white\" WIDTH=\"$width%\"
  2748. ALIGN=\"middle\"><FONT COLOR=\"#C0C0C0\" SIZE=\"-2\">$i</FONT></TD>\n";
  2749. }
  2750. $width = 100 - $offset;
  2751. echo "<TD WIDTH=\"$width%\">&nbsp;</TD>\n";
  2752. echo "</TR></TABLE>\n";
  2753. // print yardstick
  2754. echo "<TABLE WIDTH=\"100%\" BGCOLOR=\"#C0C0C0\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"0\">
  2755. <TR>\n";
  2756. for ($i = $start_hour, $offset = 0; $i < $end_hour; $i++) {
  2757. $prev_offset = $offset;
  2758. $offset = round(100/($end_hour - $start_hour)*(i - $start_hour));
  2759. $width = $offset - $prev_offset;
  2760. echo "<TD WIDTH\"$width%\" BGCOLOR=\"white\">&nbsp;</TD>\n";
  2761. }
  2762. echo "</TR></TABLE>\n";
  2763. }
  2764. ?>