PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 0ms 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

Large files files are truncated, but you can click here to view the full file

  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 da…

Large files files are truncated, but you can click here to view the full file