PageRenderTime 36ms CodeModel.GetById 4ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 2ms

/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

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
  25// Global variables for activity log
  26$LOG_CREATE = "C";
  27$LOG_APPROVE = "A";
  28$LOG_REJECT = "X";
  29$LOG_UPDATE = "U";
  30$LOG_DELETE = "D";
  31$LOG_NOTIFICATION = "N";
  32$LOG_REMINDER = "R";
  33
  34$ONE_DAY = 86400;
  35
  36// Don't allow a user to put "login=XXX" in the URL if they are not
  37// coming from the login.php page.
  38if ( ! strstr ( $PHP_SELF, "login.php" ) && ! empty ( $GLOBALS["login"] ) ) {
  39  $GLOBALS["login"] = "";
  40}
  41
  42
  43// This code is a temporary hack to make the application work when
  44// register_globals is set to Off in php.ini (the default setting in
  45// PHP 4.2.0 and after).
  46if ( ! empty ( $HTTP_GET_VARS ) ) {
  47  while (list($key, $val) = @each($HTTP_GET_VARS)) {
  48    if ( $key == "login" ) {
  49      if ( strstr ( $PHP_SELF, "login.php" ) ) {
  50        $GLOBALS[$key] = $val;
  51      }
  52    } else {
  53      $GLOBALS[$key] = $val;
  54      //echo "XXX $key<BR>";
  55    }
  56    //echo "GET var '$key' = '$val' <BR>";
  57  }
  58  reset ( $HTTP_GET_VARS );
  59}
  60if ( ! empty ( $HTTP_POST_VARS ) ) {
  61  while (list($key, $val) = @each($HTTP_POST_VARS)) {
  62    $GLOBALS[$key] = $val;
  63  }
  64  reset ( $HTTP_POST_VARS );
  65}
  66//while (list($key, $val) = @each($HTTP_POST_FILES)) {
  67//       $GLOBALS[$key] = $val;
  68//}
  69//while (list($key, $val) = @each($HTTP_SESSION_VARS)) {
  70//       $GLOBALS[$key] = $val;
  71//}
  72if ( ! empty ( $HTTP_COOKIE_VARS ) ) {
  73  while (list($key, $val) = @each($HTTP_COOKIE_VARS)) {
  74    $GLOBALS[$key] = $val;
  75    //echo "COOKIE var '$key' = '$val' <BR>";
  76  }
  77  reset ( $HTTP_COOKIE_VARS );
  78}
  79
  80
  81
  82
  83// Load default system settings (which can be updated via admin.php)
  84// System settings are stored in webcal_config.
  85// In addition to WebCalendar settings, plugin settings are also stored.
  86// The convention for plugin settings is to prefix all settings with
  87// the short name of the plugin.  For example, for a plugin
  88// called "Package Tracking" and a short name of "pt", all settings
  89// would be prefixed with "pt." (as in "pt.somesetting").
  90// (Some can also be overridden with user settings.
  91// User settings are stored in webcal_pref.)
  92function load_global_settings () {
  93  global $login, $readonly;
  94  global $SERVER_NAME, $SERVER_PORT, $REQUEST_URI, $_SERVER;
  95
  96  if ( empty ( $SERVER_NAME ) )
  97    $REQUEST_URI = $_SERVER["SERVER_NAME"];
  98  if ( empty ( $SERVER_PORT ) )
  99    $REQUEST_URI = $_SERVER["SERVER_PORT"];
 100  if ( empty ( $REQUEST_URI ) )
 101    $REQUEST_URI = $_SERVER["REQUEST_URI"];
 102
 103  $res = dbi_query ( "SELECT cal_setting, cal_value FROM webcal_config" );
 104  if ( $res ) {
 105    while ( $row = dbi_fetch_row ( $res ) ) {
 106      $setting = $row[0];
 107      $value = $row[1];
 108      //echo "Setting '$setting' to '$value' <br>\n";
 109      $GLOBALS[$setting] = $value;
 110
 111    }
 112    dbi_free_result ( $res );
 113  }
 114
 115  // If app name not set.... default to "Title".  This gets translated
 116  // later since this function is typically called before translate.php
 117  // is included.
 118  // Note: We usually use translate($application_name) instead of
 119  // translate("Title").
 120  if ( ! isset ( $GLOBALS["application_name"] ) )
 121    $GLOBALS["application_name"] = "Title";
 122
 123  // If $server_url not set, then calculate one for them, then store it
 124  // in the database.
 125  if ( empty ( $GLOBALS["server_url"] ) ) {
 126    if ( ! empty ( $SERVER_NAME ) && ! empty ( $REQUEST_URI ) ) {
 127      $ptr = strrpos ( $REQUEST_URI, "/" );
 128      if ( $ptr > 0 ) {
 129        $uri = substr ( $REQUEST_URI, 0, $ptr + 1 );
 130        $server_url = "http://" . $SERVER_NAME;
 131        if ( ! empty ( $SERVER_PORT ) && $SERVER_PORT != 80 )
 132          $server_url .= ":" . $SERVER_PORT;
 133        $server_url .= $uri;
 134      
 135        dbi_query ( "INSERT INTO webcal_config ( cal_setting, cal_value ) ".
 136          "VALUES ( 'server_url', '$server_url' )" );
 137        $GLOBALS["server_url"] = $server_url;
 138      }
 139    }
 140  }
 141
 142  // If no font settings, then set some
 143  if ( empty ( $GLOBALS["FONTS"] ) ) {
 144    if ( $GLOBALS["LANGUAGE"] == "Japanese" )
 145      $GLOBALS["FONTS"] = "Osaka, Arial, Helvetica, sans-serif";
 146    else
 147      $GLOBALS["FONTS"] = "Arial, Helvetica, sans-serif";
 148  }
 149}
 150
 151
 152
 153// Return a list of active plugins.
 154// Should be called after load_global_settings() and
 155// load_user_preferences().
 156function get_plugin_list ( $include_disabled=false ) {
 157  // first get list of available plugins
 158  $sql = "SELECT cal_setting FROM webcal_config " .
 159    "WHERE cal_setting LIKE '%.plugin_status'";
 160  if ( ! $include_disabled )
 161    $sql .= " AND cal_value = 'Y'";
 162  $sql .= " ORDER BY cal_setting";
 163  $res = dbi_query ( $sql );
 164  $plugins = array ();
 165  if ( $res ) {
 166    while ( $row = dbi_fetch_row ( $res ) ) {
 167      $e = explode ( ".", $row[0] );
 168      if ( $e[0] != "" ) {
 169        $plugins[] = $e[0];
 170      }
 171    }
 172    dbi_free_result ( $res );
 173  } else {
 174    echo translate("Database error") . ": " . dbi_error (); exit;
 175  }
 176  if ( count ( $plugins ) == 0 ) {
 177    $plugins[] = "webcalendar";
 178  }
 179  return $plugins;
 180}
 181
 182// Get plugins available to the current user.
 183// Do this by getting a list of all plugins that are not disabled by
 184// the administrator and make sure this user has not disabled any of
 185// them.
 186// It's done this was so that when an admin adds a new plugin, it
 187// shows up on each users system automatically (until they disable it).
 188function get_user_plugin_list () {
 189  $ret = array ();
 190  $all_plugins = get_plugin_list ();
 191  for ( $i = 0; $i < count ( $all_plugins ); $i++ ) {
 192    if ( $GLOBALS[$all_plugins[$i] . ".disabled"] != "N" )
 193      $ret[] = $all_plugins[$i];
 194  }
 195  return $ret;
 196}
 197
 198// determine which browser
 199// currently supported return values:
 200//      Mozilla (open source Mozilla 5.0) = "Mozilla/5"
 201//      Netscape (3.X, 4.X) = "Mozilla/[3,4]"
 202//      MSIE (4.X) = "MSIE 4"
 203function get_web_browser () {
 204  if ( ereg ( "MSIE [0-9]", getenv ( "HTTP_USER_AGENT" ) ) )
 205    return "MSIE";
 206  if ( ereg ( "Mozilla/[234]", getenv ( "HTTP_USER_AGENT" ) ) )
 207    return "Netscape";
 208  if ( ereg ( "Mozilla/[5678]", getenv ( "HTTP_USER_AGENT" ) ) )
 209    return "Mozilla";
 210  return "Uknown";
 211}
 212
 213
 214// log a debug message
 215function do_debug ( $msg ) {
 216  // log to /tmp/webcal-debug.log
 217  //error_log ( date ( "Y-m-d H:i:s" ) .  "> $msg\n",
 218  //  3, "/tmp/webcal-debug.log" );
 219  //error_log ( date ( "Y-m-d H:i:s" ) .  "> $msg\n",
 220  //  2, "sockieman:2000" );
 221}
 222
 223
 224// send a redirect to the specified page
 225// MS IIS/PWS has a bug in which it does not allow us to send a cookie
 226// and a redirect in the same HTTP header.
 227// See the following for more info on the IIS bug:
 228//   http://www.faqts.com/knowledge_base/view.phtml/aid/9316/fid/4
 229function do_redirect ( $url ) {
 230  global $SERVER_SOFTWARE, $_SERVER;
 231  if ( empty ( $SERVER_SOFTWARE ) )
 232    $SERVER_SOFTWARE = $_SERVER["SERVER_SOFTWARE"];
 233  //echo "SERVER_SOFTWARE = $SERVER_SOFTWARE <BR>"; exit;
 234  if ( substr ( $SERVER_SOFTWARE, 0, 5 ) == "Micro" ) {
 235    echo "<HTML><HEAD><TITLE>Redirect</TITLE>" .
 236      "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0; URL=$url\"></HEAD><BODY>" .
 237      "Redirecting to ... <A HREF=\"" . $url . "\">here</A>.</BODY></HTML>.\n";
 238  } else {
 239    Header ( "Location: $url" );
 240    echo "<HTML><HEAD><TITLE>Redirect</TITLE></HEAD><BODY>" .
 241      "Redirecting to ... <A HREF=\"" . $url . "\">here</A>.</BODY></HTML>.\n";
 242  }
 243  exit;
 244}
 245
 246
 247// send an HTTP login request
 248function send_http_login () {
 249  global $lang_file, $application_name;
 250
 251  if ( strlen ( $lang_file ) ) {
 252    Header ( "WWW-Authenticate: Basic realm=\"" . translate("Title") . "\"");
 253    Header ( "HTTP/1.0 401 Unauthorized" );
 254    echo "<HTML><HEAD><TITLE>Unauthorized</TITLE></HEAD><BODY>\n" .
 255      "<H2>" . translate("Title") . "</H2>" .
 256      translate("You are not authorized") .
 257      "\n</BODY></HTML>\n";
 258  } else {
 259    Header ( "WWW-Authenticate: Basic realm=\"WebCalendar\"");
 260    Header ( "HTTP/1.0 401 Unauthorized" );
 261    echo "<HTML><HEAD><TITLE>Unauthorized</TITLE></HEAD><BODY>\n" .
 262      "<H2>WebCalendar</H2>" .
 263      "You are not authorized" .
 264      "\n</BODY></HTML>\n";
 265  }
 266  exit;
 267}
 268
 269
 270// Generate a cookie that saves the last calendar view (month, week, day)
 271// so we can return to this same page after a user edits/deletes/etc an
 272// event
 273function remember_this_view () {
 274  global $server_url, $REQUEST_URI;
 275  if ( empty ( $REQUEST_URI ) )
 276    $REQUEST_URI = $_SERVER["REQUEST_URI"];
 277
 278  if ( empty ( $server_url ) )
 279    SetCookie ( "webcalendar_last_view", $REQUEST_URI );
 280  else
 281    SetCookie ( "webcalendar_last_view", $REQUEST_URI, 0, $server_url );
 282}
 283
 284// Get the last page stored using above function.
 285// Return empty string if we don't know.
 286function get_last_view () {
 287  $val = $HTTP_COOKIE_VARS["webcalendar_last_view"];
 288  if ( empty ( $val )) 
 289    $val = $_COOKIE["webcalendar_last_view"];
 290  return $val;
 291}
 292
 293
 294
 295// Send header stuff that tells the browser not to cache this page.
 296function send_no_cache_header () {
 297  header ( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
 298  header ( "Last-Modified: " . gmdate ( "D, d M Y H:i:s" ) . " GMT" );
 299  header ( "Cache-Control: no-store, no-cache, must-revalidate" );
 300  header ( "Cache-Control: post-check=0, pre-check=0", false );
 301  header ( "Pragma: no-cache" );
 302}
 303
 304
 305
 306// Load the current user's preferences as global variables.
 307// Also load the list of views for this user (not really a preference,
 308// but this is a convenient place to put this...)
 309function load_user_preferences () {
 310  global $login, $browser, $views, $prefarray, $is_assistant, $has_boss, $user;
 311  $lang_found = false;
 312
 313  $browser = get_web_browser ();
 314  $browser_lang = get_browser_language ();
 315  $prefarray = array ();
 316
 317  // Note: default values are set in config.php
 318  $res = dbi_query (
 319    "SELECT cal_setting, cal_value FROM webcal_user_pref " .
 320    "WHERE cal_login = '$login'" );
 321  if ( $res ) {
 322    while ( $row = dbi_fetch_row ( $res ) ) {
 323      $setting = $row[0];
 324      $value = $row[1];
 325      $sys_setting = "sys_" . $setting;
 326      // save system defaults
 327      if ( ! empty ( $GLOBALS[$setting] ) )
 328        $GLOBALS["sys_" . $setting] = $GLOBALS[$setting];
 329      $GLOBALS[$setting] = $value;
 330      $prefarray[$setting] = $value;
 331      if ( $setting == "LANGUAGE" )
 332        $lang_found = true;
 333    }
 334    dbi_free_result ( $res );
 335  }
 336  // get views for this user
 337  $res = dbi_query (
 338    "SELECT cal_view_id, cal_name, cal_view_type FROM webcal_view " .
 339    "WHERE cal_owner = '$login'" );
 340  if ( $res ) {
 341    $views = array ();
 342    while ( $row = dbi_fetch_row ( $res ) ) {
 343      $v = array (
 344        "cal_view_id" => $row[0],
 345        "cal_name" => $row[1],
 346        "cal_view_type" => $row[2]
 347        );
 348      $views[] = $v;
 349    }
 350    dbi_free_result ( $res );
 351  }
 352
 353  // If user has not set a language preference, then use their browser
 354  // settings to figure it out, and save it in the database for future
 355  // use (email reminders).
 356  if ( ! $lang_found && strlen ( $login ) && $login != "__public__" ) {
 357    $LANGUAGE = $browser_lang;
 358    dbi_query ( "INSERT INTO webcal_user_pref " .
 359      "( cal_login, cal_setting, cal_value ) VALUES " .
 360      "( '$login', 'LANGUAGE', '$LANGUAGE' )" );
 361  }
 362
 363  if ( empty ( $GLOBALS["DATE_FORMAT_MY"] ) )
 364    $GLOBALS["DATE_FORMAT_MY"] = "__month__ __yyyy__";
 365  if ( empty ( $GLOBALS["DATE_FORMAT_MD"] ) )
 366    $GLOBALS["DATE_FORMAT_MD"] = "__month__ __dd__";
 367  $is_assistant = user_is_assistant ( $login, $user );
 368  $has_boss = user_has_boss ( $login );
 369}
 370
 371
 372
 373// Get the list of external users for an event
 374// $use_mailto - when set to 1, email address will contain an HREF
 375//   link with a mailto URL.
 376function event_get_external_users ( $event_id, $use_mailto=0 ) {
 377  global $error;
 378  $ret = "";
 379
 380  $res = dbi_query ( "SELECT cal_fullname, cal_email " .
 381    "FROM webcal_entry_ext_user " .
 382    "WHERE cal_id = $event_id " .
 383    "ORDER by cal_fullname" );
 384  if ( $res ) {
 385    while ( $row = dbi_fetch_row ( $res ) ) {
 386      if ( strlen ( $ret ) )
 387        $ret .= "\n";
 388      $ret .= $row[0];
 389      if ( strlen ( $row[1] ) ) {
 390        if ( $use_mailto ) {
 391          $ret .= " <A HREF=\"mailto:$row[1]\">&lt;" .
 392            htmlentities ( $row[1] ) . "&gt;</A>";
 393        } else {
 394          $ret .= " &lt;". htmlentities ( $row[1] ) . "&gt;";
 395        }
 396      }
 397    }
 398    dbi_free_result ( $res );
 399  } else {
 400    echo translate("Database error") .": " . dbi_error ();
 401    echo "<P>SQL:<BR>$sql";
 402    exit;
 403  }
 404
 405  return $ret;
 406}
 407
 408
 409
 410
 411// Add something to the activity log for an event
 412// $user - user doing this
 413// $user_cal - user who's calendar is affected
 414function activity_log ( $event_id, $user, $user_cal, $type, $text ) {
 415  $next_id = 1;
 416
 417  if ( empty ( $type ) ) {
 418    echo "Error: type not set for activity log!";
 419    // but don't exit since we may be in mid-transaction
 420    return;
 421  }
 422
 423  $res = dbi_query ( "SELECT MAX(cal_log_id) FROM webcal_entry_log" );
 424  if ( $res ) {
 425    if ( $row = dbi_fetch_row ( $res ) ) {
 426      $next_id = $row[0] + 1;
 427    }
 428    dbi_free_result ( $res );
 429  }
 430
 431  $date = date ( "Ymd" );
 432  $time = date ( "Gis" );
 433  $sql_text = empty ( $text ) ? "NULL" : "'$text'";
 434  $sql_user_cal = empty ( $user_cal ) ? "NULL" : "'$user_cal'";
 435
 436  $sql = "INSERT INTO webcal_entry_log ( " .
 437    "cal_log_id, cal_entry_id, cal_login, cal_user_cal, cal_type, " .
 438    "cal_date, cal_time, cal_text ) VALUES ( $next_id, $event_id, " .
 439    "'$user', $sql_user_cal, '$type', $date, $time, $sql_text )";
 440  if ( ! dbi_query ( $sql ) ) {
 441    echo "Database error: " . dbi_error ();
 442    echo "<P>SQL:<BR>$sql";
 443    exit;
 444  }
 445}
 446
 447
 448// Get a list of users.  We used to just call user_get_users() directly.
 449// Now, we use this instead.  If groups are enabled, this can restrict
 450// the list of users to only those users who are in the same group(s)
 451// as the user.
 452// We allow admin users to see all users because they can also edit
 453// someone else's events (so they may need access to users who are not
 454// in the same groups that they are in).
 455function get_my_users () {
 456  global $login, $is_admin, $groups_enabled, $user_sees_only_his_groups;
 457
 458  if ( $groups_enabled == "Y" && $user_sees_only_his_groups == "Y" &&
 459    ! $is_admin ) {
 460    // get groups that current user is in
 461    $res = dbi_query ( "SELECT cal_group_id FROM webcal_group_user " .
 462      "WHERE cal_login = '$login'" );
 463    $groups = array ();
 464    if ( $res ) {
 465      while ( $row = dbi_fetch_row ( $res ) ) {
 466        $groups[] = $row[0];
 467      }
 468      dbi_fetch_row ( $res );
 469    }
 470    $u = user_get_users ();
 471    $u_byname = array ();
 472    for ( $i = 0; $i < count ( $u ); $i++ ) {
 473      $name = $u[$i]['cal_login'];
 474      $u_byname[$name] = $u[$i];
 475    }
 476    $ret = array ();
 477    if ( count ( $groups ) == 0 ) {
 478      // Eek.  User is in no groups... Return only themselves
 479      $ret[] = $u_byname[$login];
 480      return $ret;
 481    }
 482    // get list of users in the same groups as current user
 483    $sql = "SELECT DISTINCT(cal_login) from webcal_group_user " .
 484      "WHERE cal_group_id ";
 485    if ( count ( $groups ) == 1 )
 486      $sql .= "= " . $groups[0];
 487    else {
 488      $sql .= "IN ( " . implode ( ", ", $groups ) . " )";
 489    }
 490    //echo "SQL: $sql <P>\n";
 491    $res = dbi_query ( $sql );
 492    if ( $res ) {
 493      while ( $row = dbi_fetch_row ( $res ) ) {
 494        $ret[] = $u_byname[$row[0]];
 495      }
 496      dbi_free_result ( $res );
 497    }
 498    return $ret;
 499  } else {
 500    // groups not enabled... return all users
 501    //echo "No groups. ";
 502    return user_get_users ();
 503  }
 504}
 505
 506
 507// Get a preference setting for the specified user.  If no value is
 508// found in the db, then the system default setting will be returned.
 509// params:
 510//   $user - user login we are getting preference for
 511//   $setting - the name of the setting
 512function get_pref_setting ( $user, $setting ) {
 513
 514  // set default
 515  if ( $GLOBALS["sys_" .$setting] == "" ) {
 516    // this could happen if the current user has not saved any pref. yet
 517    $ret = $GLOBALS[$setting];
 518  } else {
 519    $ret = $GLOBALS["sys_" .$setting];
 520  }
 521
 522  $sql = "SELECT cal_value FROM webcal_user_pref " .
 523    "WHERE cal_login = '" . $user . "' AND " .
 524    "cal_setting = '" . $setting . "'";
 525  //echo "SQL: $sql <P>\n";
 526  $res = dbi_query ( $sql );
 527  if ( $res ) {
 528    if ( $row = dbi_fetch_row ( $res ) )
 529      $ret = $row[0];
 530    dbi_free_result ( $res );
 531  }
 532  return $ret;
 533}
 534
 535
 536// Get browser-specified language preference
 537function get_browser_language () {
 538  global $HTTP_ACCEPT_LANGUAGE, $browser_languages;
 539  $ret = "";
 540  if ( strlen ( $HTTP_ACCEPT_LANGUAGE ) == 0 )
 541    return "none";
 542  $langs = explode ( ",", $HTTP_ACCEPT_LANGUAGE );
 543  for ( $i = 0; $i < count ( $langs ); $i++ ) {
 544    $l = strtolower ( trim ( $langs[$i] ) );
 545    $ret .= "\"$l\" ";
 546    if ( isset ( $browser_languages[$l] ) ) {
 547      return $browser_languages[$l];
 548    }
 549  }
 550  //if ( strlen ( $HTTP_ACCEPT_LANGUAGE ) )
 551  //  return "none ($HTTP_ACCEPT_LANGUAGE not supported)";
 552  //else
 553    return "none";
 554}
 555
 556
 557// Load current user's layer info and stuff it into layer global variable.
 558function load_user_layers ($user="",$force=0) {
 559  global $login;
 560  global $layers;
 561  global $LAYERS_STATUS;
 562
 563  if ( $user == "" )
 564    $user = $login;
 565
 566  $layers = array ();
 567
 568  if ( $force || ( ! empty ( $LAYERS_STATUS ) && $LAYERS_STATUS != "N" ) ) {
 569    $res = dbi_query (
 570      "SELECT cal_layerid, cal_layeruser, cal_color, cal_dups " .
 571      "FROM webcal_user_layers " .
 572      "WHERE cal_login = '$user' ORDER BY cal_layerid" );
 573    if ( $res ) {
 574      $count = 0;
 575      while ( $row = dbi_fetch_row ( $res ) ) {
 576        $layers[$count] = array (
 577          "cal_layerid" => $row[0],
 578          "cal_layeruser" => $row[1],
 579          "cal_color" => $row[2],
 580          "cal_dups" => $row[3]
 581        );
 582        $count++;
 583      }
 584      dbi_free_result ( $res );
 585    }
 586  } else {
 587    //echo "Not loading!";
 588  }
 589}
 590
 591
 592
 593
 594// Build the HTML for the event popup (but don't print it yet since we
 595// don't want this HTML to go inside the table for the month).
 596function build_event_popup ( $divname, $user, $description, $time ) {
 597  global $login, $popup_fullnames, $popuptemp_fullname;
 598  $ret = "<DIV ID=\"" . $divname .
 599    "\" STYLE=\"position: absolute; z-index: 20; visibility: hidden; top: 0px; left: 0px;\">\n" .
 600    "<TABLE BORDER=\"0\" WIDTH=\"30%\" CELLPADDING=\"0\" CELLSPACING=\"1\"><TR><TD BGCOLOR=\"" .
 601    $GLOBALS["POPUP_FG"] . "\">\n" .
 602    "<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"0\" CELLSPACING=\"1\"><TR><TD BGCOLOR=\"" .
 603    $GLOBALS["POPUP_BG"] . "\" CLASS=\"popup\">\n" .
 604    "<FONT COLOR=\"" . $GLOBALS["POPUP_FG"] . "\">";
 605
 606  if ( empty ( $popup_fullnames ) )
 607    $popup_fullnames = array ();
 608  
 609  if ( $user != $login ) {
 610    if ( empty ( $popup_fullnames[$user] ) ) {
 611      user_load_variables ( $user, "popuptemp_" );
 612      $popup_fullnames[$user] = $popuptemp_fullname;
 613    }
 614    $ret .= "<B>" . translate ("User") .
 615      ":</B> $popup_fullnames[$user]<BR>";
 616  }
 617  if ( strlen ( $time ) )
 618    $ret .= "<B>" . translate ("Time") . ":</B> $time<BR>";
 619  $ret .= "<B>" . translate ("Description") . ":</B>\n";
 620  $ret .= nl2br ( htmlspecialchars ( $description ) );
 621  $ret .= "</FONT></TD></TR></TABLE>\n" .
 622    "</TD></TR></TABLE>\n" .
 623    "</DIV>\n";
 624  return $ret;
 625}
 626
 627
 628
 629// Print out a date selection for use in a form.
 630// params:
 631//   $prefix - prefix to use in front of form element names
 632//   $date - currently selected date (in YYYYMMDD) format
 633function print_date_selection ( $prefix, $date ) {
 634  print date_selection_html ( $prefix, $date );
 635}
 636
 637// Generate a date selection for use in a form and return in.
 638// params:
 639//   $prefix - prefix to use in front of form element names
 640//   $date - currently selected date (in YYYYMMDD) format
 641function date_selection_html ( $prefix, $date ) {
 642  $ret = "";
 643  if ( strlen ( $date ) != 8 )
 644    $date = date ( "Ymd" );
 645  $thisyear = $year = substr ( $date, 0, 4 );
 646  $thismonth = $month = substr ( $date, 4, 2 );
 647  $thisday = $day = substr ( $date, 6, 2 );
 648  $ret .= "<SELECT NAME=\"" . $prefix . "day\">";
 649  for ( $i = 1; $i <= 31; $i++ )
 650    $ret .= "<OPTION " . ( $i == $thisday ? " SELECTED" : "" ) . ">$i";
 651  $ret .= "</SELECT>\n<SELECT NAME=\"" . $prefix . "month\">";
 652  for ( $i = 1; $i <= 12; $i++ ) {
 653    $m = month_short_name ( $i - 1 );
 654    $ret .= "<OPTION VALUE=\"$i\"" .
 655      ( $i == $thismonth ? " SELECTED" : "" ) . ">$m";
 656  }
 657  $ret .= "</SELECT>\n<SELECT NAME=\"" . $prefix . "year\">";
 658  for ( $i = -1; $i < 5; $i++ ) {
 659    $y = date ( "Y" ) + $i;
 660    $ret .= "<OPTION VALUE=\"$y\"" .
 661      ( $y == $thisyear ? " SELECTED" : "" ) . ">$y";
 662  }
 663  $ret .= "</SELECT>\n";
 664  $ret .= "<INPUT TYPE=\"button\" ONCLICK=\"selectDate('" .
 665    $prefix . "day','" . $prefix . "month','" . $prefix . "year',$date)\" VALUE=\"" .
 666    translate("Select") . "...\">";
 667
 668  return $ret;
 669}
 670
 671
 672
 673// Print the HTML for one day's events in the month view.
 674// params:
 675//   $id - event id
 676//   $date - date (not used)
 677//   $time - time (in HHMMSS format)
 678//   $duration - event duration (in minutes)
 679//   $name - event name
 680//   $description - long description of event
 681//   $status - event status
 682//   $pri - event priority
 683//   $access - event access
 684//   $event_owner - user associated with this event
 685//   $hide_icons - hide icons to make printer-friendly
 686function print_entry ( $id, $date, $time, $duration,
 687  $name, $description, $status,
 688  $pri, $access, $event_owner, $hide_icons ) {
 689  global $eventinfo, $login, $user, $PHP_SELF, $TZ_OFFSET;
 690  static $key = 0;
 691  
 692  global $layers;
 693
 694
 695  echo "<FONT SIZE=\"-1\">";
 696
 697  if ( $login != $event_owner && strlen ( $event_owner ) ) {
 698    $class = "layerentry";
 699  } else {
 700    $class = "entry";
 701    if ( $status == "W" ) $class = "unapprovedentry";
 702  }
 703  // if we are looking at a view, then always use "entry"
 704  if ( strstr ( $PHP_SELF, "view_m.php" ) ||
 705    strstr ( $PHP_SELF, "view_w.php" ) ||
 706    strstr ( $PHP_SELF, "view_v.php" ) ||
 707    strstr ( $PHP_SELF, "view_t.php" ) )
 708    $class = "entry";
 709
 710  if ( $pri == 3 ) echo "<B>";
 711  if ( ! $hide_icons ) {
 712    $divname = "eventinfo-$id-$key";
 713    $key++;
 714    echo "<A CLASS=\"$class\" HREF=\"view_entry.php?id=$id&date=$date";
 715    if ( strlen ( $user ) > 0 )
 716      echo "&user=" . $user;
 717    echo "\" onMouseOver=\"window.status='" . translate("View this entry") .
 718      "'; show(event, '$divname'); return true;\" onMouseOut=\"hide('$divname'); return true;\">";
 719    echo "<IMG SRC=\"circle.gif\" WIDTH=\"5\" HEIGHT=\"7\" BORDER=\"0\">";
 720  }
 721
 722
 723  if ( $login != $event_owner && strlen ( $event_owner ) )
 724  {
 725    for($index = 0; $index < sizeof($layers); $index++)
 726    {
 727        if($layers[$index]['cal_layeruser'] == $event_owner)
 728        {
 729            echo("<FONT COLOR=\"" . $layers[$index]['cal_color'] . "\">");
 730        }
 731    }
 732  }
 733
 734
 735  $timestr = "";
 736  if ( $duration == ( 24 * 60 ) ) {
 737    $timestr = translate("All day event");
 738  } else if ( $time != -1 ) {
 739    $my_time = $time + ( $TZ_OFFSET * 10000 );
 740    if ( $GLOBALS["TIME_FORMAT"] == "24" ) {
 741      printf ( "%02d:%02d", ( $my_time / 10000 ) % 24,
 742        ( $my_time / 100 ) % 100 );
 743    } else {
 744      $h = ( (int) ( $my_time / 10000 ) ) % 12;
 745      if ( $h == 0 ) $h = 12;
 746      echo $h;
 747      $m = ( $my_time / 100 ) % 100;
 748      if ( $m > 0 )
 749        printf ( ":%02d", $m );
 750      echo ( (int) ( $my_time / 10000 ) ) < 12 ? translate("am") : translate("pm");
 751      echo "&gt;";
 752    }
 753    $timestr = display_time ( $time );
 754    if ( $duration > 0 ) {
 755      if ( $duration == ( 24 * 60 ) ) {
 756        $timestr = translate("All day event");
 757      } else {
 758        // calc end time
 759        $h = (int) ( $time / 10000 );
 760        $m = ( $time / 100 ) % 100;
 761        $m += $duration;
 762        $d = $duration;
 763        while ( $m >= 60 ) {
 764          $h++;
 765          $m -= 60;
 766        }
 767        $end_time = sprintf ( "%02d%02d00", $h, $m );
 768        $timestr .= " - " . display_time ( $end_time );
 769      }
 770    }
 771  }
 772  if ( $login != $user && $access == 'R' && strlen ( $user ) )
 773    echo "(" . translate("Private") . ")";
 774
 775  else
 776  if ( $login != $event_owner && $access == 'R' && strlen ( $event_owner ) )
 777    echo "(" . translate("Private") . ")";
 778  else
 779  if ( $login != $event_owner && strlen ( $event_owner ) )
 780  {
 781    echo htmlspecialchars ( $name );
 782    echo ("</FONT>");
 783  }
 784
 785  else
 786    echo htmlspecialchars ( $name );
 787
 788  echo "</A>";
 789  if ( $pri == 3 ) echo "</B>";
 790  echo "</FONT><BR>";
 791  if ( ! $hide_icons ) {
 792    if ( $login != $user && $access == 'R' && strlen ( $user ) )
 793      $eventinfo .= build_event_popup ( $divname, $event_owner,
 794        translate("This event is confidential"), "" );
 795
 796    else
 797    if ( $login != $event_owner && $access == 'R' && strlen ( $event_owner ) )
 798      $eventinfo .= build_event_popup ( $divname, $event_owner,
 799        translate("This event is confidential"), "" );
 800
 801    else
 802      $eventinfo .= build_event_popup ( $divname, $event_owner,
 803        $description, $timestr );
 804  }
 805}
 806
 807
 808
 809// Get any site-specific fields for an entry that are stored in the database.
 810// Return an array.
 811// params:
 812//   $eventid - unique event id
 813function get_site_extra_fields ( $eventid ) {
 814  $sql = "SELECT cal_name, cal_type, cal_date, cal_remind, cal_data " .
 815    "FROM webcal_site_extras " .
 816    "WHERE cal_id = $eventid";
 817  $res = dbi_query ( $sql );
 818  $extras = array ();
 819  if ( $res ) {
 820    while ( $row = dbi_fetch_row ( $res ) ) {
 821      // save by cal_name (e.g. "URL")
 822      $extras[$row[0]] = array (
 823        "cal_name" => $row[0],
 824        "cal_type" => $row[1],
 825        "cal_date" => $row[2],
 826        "cal_remind" => $row[3],
 827        "cal_data" => $row[4]
 828      );
 829    }
 830    dbi_free_result ( $res );
 831  }
 832
 833  return $extras;
 834}
 835
 836
 837
 838
 839// Read all the events for a user for the specified range of dates.
 840// This is only called once per page request to improve performance.
 841// All the events get loaded into the array $events sorted by
 842// time of day (not date).
 843// params:
 844//   $user - username
 845//   $startdate - start date range, inclusive (in YYYYMMDD format)
 846//   $enddate - end date range, inclusive (in YYYYMMDD format)
 847//   $cat_id - category ID to filter on
 848function read_events ( $user, $startdate, $enddate, $cat_id = ''  ) {
 849  global $login;
 850  global $layers;
 851  global $TZ_OFFSET;
 852
 853  $sy = substr ( $startdate, 0, 4 );
 854  $sm = substr ( $startdate, 4, 2 );
 855  $sd = substr ( $startdate, 6, 2 );
 856  $ey = substr ( $enddate, 0, 4 );
 857  $em = substr ( $enddate, 4, 2 );
 858  $ed = substr ( $enddate, 6, 2 );
 859  if ( $startdate == $enddate ) {
 860    if ( $TZ_OFFSET == 0 ) {
 861      $date_filter = " AND webcal_entry.cal_date = $startdate";
 862    } else if ( $TZ_OFFSET > 0 ) {
 863      $prev_day = mktime ( 3, 0, 0, $sm, $sd - 1, $sy );
 864      $cutoff = 24 - $TZ_OFFSET .  "0000";
 865      $date_filter = " AND ( ( webcal_entry.cal_date = $startdate AND " .
 866        "( webcal_entry.cal_time <= $cutoff OR " .
 867        "webcal_entry.cal_time = -1 ) ) OR " .
 868        "( webcal_entry.cal_date = " . date("Ymd", $prev_day ) .
 869        " AND webcal_entry.cal_time >= $cutoff ) )";
 870    } else {
 871      $next_day = mktime ( 3, 0, 0, $sm, $sd + 1, $sy );
 872      $cutoff = 24 + $TZ_OFFSET . "0000";
 873      $date_filter = " AND ( ( webcal_entry.cal_date = $startdate AND " .
 874        "( webcal_entry.cal_time >= $cutoff OR " .
 875        "webcal_entry.cal_time = -1 ) ) OR " .
 876        "( webcal_entry.cal_date = " . date("Ymd", $next_day ) .
 877        " AND webcal_entry.cal_time < $cutoff ) )";
 878    }
 879  } else {
 880    if ( $TZ_OFFSET == 0 ) {
 881      $date_filter = " AND webcal_entry.cal_date >= $startdate " .
 882        "AND webcal_entry.cal_date <= $enddate";
 883    } else if ( $TZ_OFFSET > 0 ) {
 884      $prev_day = date ( ( "Ymd" ), mktime ( 3, 0, 0, $sm, $sd - 1, $sy ) );
 885      $enddate_minus1 = date ( ( "Ymd" ), mktime ( 3, 0, 0, $em, $ed - 1, $ey ) );
 886      $cutoff = 24 - $TZ_OFFSET . "0000";
 887      $date_filter = " AND ( ( webcal_entry.cal_date >= $startdate " .
 888        "AND webcal_entry.cal_date <= $enddate AND " .
 889        "webcal_entry.cal_time = -1 ) OR " .
 890        "( webcal_entry.cal_date = $prev_day AND " .
 891        "webcal_entry.cal_time >= $cutoff ) OR " .
 892        "( webcal_entry.cal_date = $enddate AND " .
 893        "webcal_entry.cal_time < $cutoff ) OR " .
 894        "( webcal_entry.cal_date >= $startdate AND " .
 895        "webcal_entry.cal_date <= $enddate_minus1 ) )";
 896    } else {
 897      // TZ_OFFSET < 0
 898      $next_day = date ( ( "Ymd" ), mktime ( 3, 0, 0, $sm, $sd + 1, $sy ) );
 899      $enddate_plus1 =
 900        date ( ( "Ymd" ), mktime ( 3, 0, 0, $em, $ed + 1, $ey ) );
 901      $cutoff = 24 + $TZ_OFFSET . "0000";
 902      $date_filter = " AND ( ( webcal_entry.cal_date >= $startdate " .
 903        "AND webcal_entry.cal_date <= $enddate AND " .
 904        "webcal_entry.cal_time = -1 ) OR " .
 905        "( webcal_entry.cal_date = $startdate AND " .
 906        "webcal_entry.cal_time >= $cutoff ) OR " .
 907        "( webcal_entry.cal_date = $enddate_plus1 AND " .
 908        "webcal_entry.cal_time < $cutoff ) OR " .
 909        "( webcal_entry.cal_date > $startdate AND " .
 910        "webcal_entry.cal_date < $enddate ) )";
 911    }
 912  }
 913
 914  return query_events ( $user, false, $date_filter, $cat_id  );
 915}
 916
 917
 918// Get all the events for a specific date from the array of pre-loaded
 919// events (which was loaded all at once to improve performance).
 920// The returned events will be sorted by time of day.
 921// params:
 922//   $user - username
 923//   $date - date to get events for in YYYYMMDD format
 924function get_entries ( $user, $date ) {
 925  global $events, $TZ_OFFSET;
 926  $n = 0;
 927  $ret = array ();
 928
 929  //echo "<P>Checking " . count ( $events ) . " events.  TZ_OFFSET = $TZ_OFFSET<P>";
 930
 931  for ( $i = 0; $i < count ( $events ); $i++ ) {
 932    if ( $TZ_OFFSET == 0 ) {
 933      if ( $events[$i]['cal_date'] == $date )
 934        $ret[$n++] = $events[$i];
 935    } else if ( $TZ_OFFSET > 0 ) {
 936      $cutoff = ( 24 - $TZ_OFFSET ) * 10000;
 937      //echo "<P> cal_time " . $events[$i]['cal_time'] . "<P>";
 938      $sy = substr ( $date, 0, 4 );
 939      $sm = substr ( $date, 4, 2 );
 940      $sd = substr ( $date, 6, 2 );
 941      $prev_time = mktime ( 3, 0, 0, $sm, $sd - 1, $sy );
 942      $prev_date = date ( "Ymd", $prev_time );
 943        //echo "prev_date = $prev_day <P>";
 944      if ( $events[$i]['cal_date'] == $date &&
 945        $events[$i]['cal_time'] == -1 ) {
 946        $ret[$n++] = $events[$i];
 947        //echo "added event $events[$i][cal_id] <BR>";
 948      } if ( $events[$i]['cal_date'] == $date &&
 949        $events[$i]['cal_time'] < $cutoff ) {
 950        $ret[$n++] = $events[$i];
 951        //echo "added event $events[$i][cal_id] <BR>";
 952      } else if ( $events[$i]['cal_date'] == $prev_date &&
 953        $events[$i]['cal_time'] >= $cutoff ) {
 954        $ret[$n++] = $events[$i];
 955        //echo "added event $events[$i][cal_id] <BR>";
 956      }
 957    } else {
 958      $cutoff = ( 24 + $TZ_OFFSET ) * 10000;
 959      //echo "<P> cal_time " . $events[$i]['cal_time'] . "<P>";
 960      $sy = substr ( $date, 0, 4 );
 961      $sm = substr ( $date, 4, 2 );
 962      $sd = substr ( $date, 6, 2 );
 963      $next_time = mktime ( 3, 0, 0, $sm, $sd + 1, $sy );
 964      $next_date = date ( "Ymd", $next_time );
 965      //echo "next_date = $next_day <P>";
 966      if ( $events[$i]['cal_date'] == $date &&
 967        $events[$i]['cal_time'] == -1 ) {
 968        $ret[$n++] = $events[$i];
 969        //echo "added event $events[$i][cal_id] <BR>";
 970      } if ( $events[$i]['cal_date'] == $date &&
 971        $events[$i]['cal_time'] >= $cutoff ) {
 972        $ret[$n++] = $events[$i];
 973        //echo "added event $events[$i][cal_id] <BR>";
 974      } else if ( $events[$i]['cal_date'] == $next_date &&
 975        $events[$i]['cal_time'] < $cutoff ) {
 976        $ret[$n++] = $events[$i];
 977        //echo "added event $events[$i][cal_id] <BR>";
 978      }
 979    }
 980  }
 981
 982  return $ret;
 983}
 984
 985
 986// Read events visible to a user (including layers); return results
 987// in an array sorted by time of day.
 988// params:
 989//   $user - username
 990//   $want_repeated - true to get repeating events; false to get
 991//     non-repeating.
 992//   $date_filter - SQL phrase starting with AND, to be appended to
 993//     the WHERE clause.  May be empty string.
 994//   $cat_id - category ID to filter on.  May be empty.
 995
 996function query_events ( $user, $want_repeated, $date_filter, $cat_id = '' ) {
 997  global $login;
 998  global $layers;
 999  $result = array ();
1000  $layers_byuser = array ();
1001
1002  $sql = "SELECT webcal_entry.cal_name, webcal_entry.cal_description, "
1003    . "webcal_entry.cal_date, webcal_entry.cal_time, "
1004    . "webcal_entry.cal_id, webcal_entry.cal_ext_for_id, "
1005    . "webcal_entry.cal_priority, "
1006    . "webcal_entry.cal_access, webcal_entry.cal_duration, "
1007    . "webcal_entry_user.cal_status, "
1008    . "webcal_entry_user.cal_login ";
1009  if ( $want_repeated ) {
1010    $sql .= ", "
1011      . "webcal_entry_repeats.cal_type, webcal_entry_repeats.cal_end, "
1012      . "webcal_entry_repeats.cal_frequency, webcal_entry_repeats.cal_days "
1013      . "FROM webcal_entry, webcal_entry_repeats, webcal_entry_user "
1014      . "WHERE webcal_entry.cal_id = webcal_entry_repeats.cal_id AND ";
1015  } else {
1016    $sql .= "FROM webcal_entry, webcal_entry_user WHERE ";
1017  }
1018  $sql .= "webcal_entry.cal_id = webcal_entry_user.cal_id " .
1019    "AND webcal_entry_user.cal_status IN ('A','W') ";
1020
1021  if ( $cat_id != '' ) $sql .= "AND webcal_entry_user.cal_category LIKE '$cat_id' ";
1022
1023  if ( strlen ( $user ) > 0 )
1024    $sql .= "AND (webcal_entry_user.cal_login = '" . $user . "' ";
1025
1026  if ( $user == $login && strlen ( $user ) > 0 ) {
1027    for ($index = 0; $index < sizeof($layers); $index++) {
1028      $layeruser = $layers[$index]['cal_layeruser'];
1029
1030      $sql .= "OR webcal_entry_user.cal_login = '" . $layeruser . "' ";
1031
1032      // while we are parsing the whole layers array, build ourselves
1033      // a new array that will help when we have to check for dups
1034      $layers_byuser["$layeruser"] = $layers[$index]['cal_dups'];
1035    }
1036  }
1037  if ( strlen ( $user ) > 0 )
1038    $sql .= ") ";
1039  $sql .= $date_filter;
1040
1041  // now order the results by time and by entry id.
1042  $sql .= " ORDER BY webcal_entry.cal_time, webcal_entry.cal_id";
1043
1044  //echo "<B>SQL:</B> $sql<P>";
1045  
1046  $res = dbi_query ( $sql );
1047  if ( $res ) {
1048    $i = 0;
1049    $checkdup_id = -1;
1050    $first_i_this_id = -1;
1051
1052    while ( $row = dbi_fetch_row ( $res ) ) {
1053
1054      if ($row[8] == 'R' || $row[8] == 'D') {
1055        continue;  // don't show rejected/deleted ones
1056      }
1057      $item = array (
1058        "cal_name" => $row[0],
1059        "cal_description" => $row[1],
1060        "cal_date" => $row[2],
1061        "cal_time" => $row[3],
1062        "cal_id"   => $row[4],
1063        "cal_ext_for_id"   => $row[5],
1064        "cal_priority" => $row[6],
1065        "cal_access" => $row[7],
1066        "cal_duration" => $row[8],
1067        "cal_status" => $row[9],
1068        "cal_login" => $row[10],
1069	"cal_exceptions" => array()
1070        );
1071      if ( $want_repeated && ! empty ( $row[11] ) ) {
1072        $item['cal_type'] = empty ( $row[11] ) ? "" : $row[11];
1073        $item['cal_end'] = empty ( $row[12] ) ? "" : $row[12];
1074        $item['cal_frequency'] = empty ( $row[13] ) ? "" : $row[13];
1075        $item['cal_days'] = empty ( $row[14] ) ? "" : $row[14];
1076      }
1077
1078      if ( $item['cal_id'] != $checkdup_id ) {
1079        $checkdup_id = $item['cal_id'];
1080        $first_i_this_id = $i;
1081      }
1082
1083      if ( $item['cal_login'] == $user ) {
1084        // Insert this one before all other ones with this ID.
1085        my_array_splice ( $result, $first_i_this_id, 0, array($item) );
1086        $i++;
1087
1088        if ($first_i_this_id + 1 < $i) {
1089          // There's another one with the same ID as the one we inserted.
1090          // Check for dup and if so, delete it.
1091          $other_item = $result[$first_i_this_id + 1];
1092          if ($layers_byuser[$other_item['cal_login']] == 'N') {
1093            // NOTE: array_splice requires PHP4
1094            my_array_splice ( $result, $first_i_this_id + 1, 1, "" );
1095            $i--;
1096          }
1097        }
1098      }
1099      else {
1100        if ($i == $first_i_this_id
1101          || ( ! empty ( $layers_byuser[$item['cal_login']] ) &&
1102          $layers_byuser[$item['cal_login']] != 'N' ) ) {
1103          // This item either is the first one with its ID, or allows dups.
1104          // Add it to the end of the array.
1105          $result [$i++] = $item;
1106        }
1107      }
1108    }
1109    dbi_free_result ( $res );
1110  }
1111
1112  // Now load event exceptions and store as array in 'cal_exceptions' field
1113  if ( $want_repeated ) {
1114    for ( $i = 0; $i < count ( $result ); $i++ ) {
1115      if ( ! empty ( $result[$i]['cal_id'] ) ) {
1116        $res = dbi_query ( "SELECT cal_date FROM webcal_entry_repeats_not " .
1117            "WHERE cal_id = " . $result[$i]['cal_id'] );
1118        while ( $row = dbi_fetch_row ( $res ) ) {
1119          $result[$i]['cal_exceptions'][] = $row[0];
1120        }
1121      }
1122    }
1123  }
1124
1125  return $result;
1126}
1127
1128// Read all the repeated events for a user.  This is only called once
1129// per page request to improve performance.  All the events get loaded
1130// into the array $repeated_events sorted by time of day (not date).
1131// params:
1132//   $user - username
1133//   $cat_id - category ID to filter on.  May be empty.
1134function read_repeated_events ( $user, $cat_id = ''  ) {
1135  global $login;
1136  global $layers;
1137
1138  return query_events ( $user, true, "", $cat_id );
1139}
1140//Returns all the dates a specific event will fall on accounting for
1141//the repeating.  Any event with no end will be assigned one.
1142//params:
1143//  $date - initial date in raw format
1144//  $rpt_type - repeating type as stored in the database
1145//  $end  - end date
1146//  $days - days events occurs on (for weekly)
1147//  $ex_dates - array of exception dates for this event in YYYYMMDD format
1148//  $freq - frequency of repetition
1149function get_all_dates ( $date, $rpt_type, $end, $days, $ex_days, $freq=1 ) {
1150  global $conflict_repeat_months;
1151  global $ONE_DAY;
1152  $currentdate = floor($date/$ONE_DAY)*$ONE_DAY;
1153  $realend = floor($end/$ONE_DAY)*$ONE_DAY;
1154  $dateYmd = date ( "Ymd", $date );
1155  if ($end=='NULL') {
1156    // Check for $conflict_repeat_months months into future for conflicts
1157    $thismonth = substr($dateYmd, 4, 2);
1158    $thisyear = substr($dateYmd, 0, 4);
1159    $thisday = substr($dateYmd, 6, 2);
1160    $thismonth += $conflict_repeat_months;
1161    if ($thismonth > 12) {
1162      $thisyear++;
1163      $thismonth -= 12;
1164    }
1165    $realend = mktime(3,0,0,$thismonth,$thisday,$thisyear);
1166  }
1167  $ret = array();
1168  $ret[0] = $date;
1169  //do iterative checking here.
1170  //I floored the $realend so I check it against the floored date
1171  if ($rpt_type && $currentdate < $realend) {
1172    $cdate = $date;
1173    if (!$freq) $freq = 1;
1174    $n = 1;
1175    if ($rpt_type == 'daily') {
1176      //we do inclusive counting on end dates.
1177      $cdate += $ONE_DAY * $freq;
1178      while ($cdate <= $realend+$ONE_DAY) {
1179        if ( ! is_exception ( $cdate, $ex_days ) )
1180          $ret[$n++]=$cdate;
1181        $cdate += $ONE_DAY * $freq;
1182      }
1183    } else if ($rpt_type == 'weekly') {
1184      $daysarray = array();
1185      $r=0;
1186      $dow = date("w",$date);
1187      $cdate = $date - ($dow * $ONE_DAY);
1188      for ($i = 0; $i < 7; $i++) {
1189        $isDay = substr($days, $i, 1);
1190        if (strcmp($isDay,"y")==0) {
1191          $daysarray[$r++]=$i * $ONE_DAY;
1192        }
1193      }
1194      //we do inclusive counting on end dates.
1195      while ($cdate <= $realend+$ONE_DAY) {
1196        //add all of the days of the week.
1197        for ($j=0; $j<$r;$j++) {
1198          $td = $cdate + $daysarray[$j];
1199          if ($td >= $date) {
1200            if ( ! is_exception ( $cdate, $ex_days ) )
1201              $ret[$n++] = $td;
1202          }
1203        }
1204        //skip to the next week in question.
1205        $cdate += ( $ONE_DAY * 7 ) * $freq;
1206      }
1207    } else if ($rpt_type == 'monthlyByDay') {
1208      $dow  = date('w', $date);
1209      $thismonth = substr($dateYmd, 4, 2);
1210      $thisyear  = substr($dateYmd, 0, 4);
1211      $week  = floor(date("d", $date)/7);
1212      $thismonth+=$freq;
1213      $dow1 += date('w',mktime (3,0,0,$thismonth,1,$thisyear));
1214      $t = $dow - $dow1;
1215      if ($t < 0) $t += 7;
1216      $day = 7*$week + $t + 1;
1217      $cdate = mktime (3,0,0,$thismonth,$day,$thisyear);
1218      while ($cdate <= $realend+$ONE_DAY) {
1219        if ( ! is_exception ( $cdate, $ex_days ) )
1220          $ret[$n++] = $cdate;
1221        $thismonth+=$freq;
1222        $dow1 += date('w',mktime (3,0,0,$thismonth,1,$thisyear));
1223        $t = $dow - $dow1;
1224        if ($t < 0) $t += 7;
1225        $day = 7*$week + $t + 1;
1226        $cdate = mktime (3,0,0,$thismonth,$day,$thisyear);
1227      }
1228    } else if ($rpt_type == 'monthlyByDate') {
1229      $thismonth = substr($dateYmd, 4, 2);
1230      $thisyear  = substr($dateYmd, 0, 4);
1231      $thisday   = substr($dateYmd, 6, 2);
1232      $hour      = date('H',$date);
1233      $minute    = date('i',$date);
1234
1235      $thismonth += $freq;
1236      $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
1237      while ($cdate <= $realend+$ONE_DAY) {
1238        if ( ! is_exception ( $cdate, $ex_days ) )
1239          $ret[$n++] = $cdate;
1240        $thismonth += $freq;
1241        $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
1242      }
1243    } else if ($rpt_type == 'yearly') {
1244      $thismonth = substr($dateYmd, 4, 2);
1245      $thisyear  = substr($dateYmd, 0, 4);
1246      $thisday   = substr($dateYmd, 6, 2);
1247      $hour      = date('H',$date);
1248      $minute    = date('i',$date);
1249
1250      $thisyear += $freq;
1251      $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
1252      while ($cdate <= $realend+$ONE_DAY) {
1253        if ( ! is_exception ( $cdate, $ex_days ) )
1254          $ret[$n++] = $cdate;
1255        $thisyear += $freq;
1256        $cdate = mktime (3,0,0,$thismonth,$thisday,$thisyear);
1257      }
1258    }
1259  }
1260  return $ret;
1261}
1262// Get all the repeating events for the specified data and return them
1263// in an array (which is sorted by time of day).
1264// params:
1265//   $user - username
1266//   $date - date to get events for in YYYYMMDD format
1267function get_repeating_entries ( $user, $dateYmd ) {
1268  global $repeated_events;
1269  $n = 0;
1270  $ret = array ();
1271  //echo count($repeated_events)."<BR>";
1272  for ( $i = 0; $i < count ( $repeated_events ); $i++ ) {
1273    if ( repeated_event_matches_date ( $repeated_events[$i], $dateYmd ) ) {
1274      // make sure this is not an exception date...
1275      $unixtime = date_to_epoch ( $dateYmd );
1276      if ( ! is_exception ( $unixtime, $repeated_events[$i]['cal_exceptions'] ) )
1277        $ret[$n++] = $repeated_events[$i];
1278    }
1279  }
1280  return $ret;
1281}
1282//Returns a boolean stating whether or not the event passed
1283//in will fall on the date passed.
1284function repeated_event_matches_date($event,$dateYmd) {
1285  // only repeat after the beginning, and if there is an end
1286  // before the end
1287  $date = date_to_epoch ( $dateYmd );
1288  $thisyear = substr($dateYmd, 0, 4);
1289  $start = date_to_epoch ( $event['cal_date'] );
1290  $end   = date_to_epoch ( $event['cal_end'] );
1291  $freq = $event['cal_frequency'];
1292  $thismonth = substr($dateYmd, 4, 2);
1293  if ($event['cal_end'] && $dateYmd > date("Ymd",$end) )
1294    return false;
1295  if ( $dateYmd <= date("Ymd",$start) )
1296    return false;
1297  $id = $event['cal_id'];
1298
1299  if ($event['cal_type'] == 'daily') {
1300    if ( (floor(($date - $start)/86400)%$freq) )
1301      return false;
1302    return true;
1303  } else if ($event['cal_type'] == 'weekly') {
1304    $dow  = date("w", $date);
1305    $dow1 = date("w", $start);
1306    $isDay = substr($event['cal_days'], $dow, 1);
1307    $wstart = $start - ($dow1 * 86400);
1308    if (floor(($date - $wstart)/604800)%$freq)
1309      return false;
1310    if (strcmp($isDay,"y") == 0) {
1311      return true;
1312    }
1313  } else if ($event['cal_type'] == 'monthlyByDay') {
1314    $dowS = date("w", $start);
1315    $dayS = ceil(date("d", $start)/7);
1316    $mthS = date("m", $start);
1317    $yrS  = date("Y", $start);
1318
1319    $dow  = date("w", $date);
1320    $day  = ceil(date("d", $date)/7);
1321    $mth  = date("m", $date);
1322    $yr   = date("Y", $date);
1323
1324    if ((($yr - $yrS)*12 + $mth - $mthS) % $freq)
1325      return false;
1326
1327    if (($dowS == $dow) && ($day == $dayS)) {
1328      return true;
1329    }
1330
1331  } else if ($event['cal_type'] == 'monthlyByDate') {
1332    $mthS = date("m", $start);
1333    $yrS  = date("Y", $start);
1334
1335    $mth  = date("m", $date);
1336    $yr   = date("Y", $date);
1337
1338    if ((($yr - $yrS)*12 + $mth - $mthS) % $freq)
1339      return false;
1340
1341    if (date("d", $date) == date("d", $start)) {
1342      return true;
1343    }
1344  }
1345  else if ($event['cal_type'] == 'yearly') {
1346    $yrS = date("Y", $start);
1347    $yr  = date("Y", $date);
1348
1349    if (($yr - $yrS)%$freq)
1350      return false;
1351
1352    if (date("dm", $date) == date("dm", $start)) {
1353      return true;
1354    }
1355  } else {
1356    // unknown repeat type
1357    return false;
1358  }
1359}
1360function date_to_epoch ( $d ) {
1361  return mktime ( 3, 0, 0, substr ( $d, 4, 2 ), substr ( $d, 6, 2 ),
1362    substr ( $d, 0, 4 ) );
1363}
1364
1365// check if a date is an exception for an event
1366// $date - date in timestamp format
1367// $exdays - array of dates in YYYYMMDD format
1368function is_exception ( $date, $ex_days ) {
1369  $size = count ( $ex_days );
1370  $count = 0;
1371  $date = date ( "Ymd", $date );
1372  //echo "Exception $date check.. count is $size <br>";
1373  while ( $count < $size ) {
1374    //echo "Exception date: $ex_days[$count] <br>";
1375    if ( $date == $ex_days[$count++] )
1376      return true;
1377  }
1378  return false;
1379}
1380
1381
1382
1383// Get the Sunday of the week that the specified date is in.
1384// (If the date specified is a Sunday, then that date is returned.)
1385function get_sunday_before ( $year, $month, $day ) {
1386  $weekday = date ( "w", mktime ( 3, 0, 0, $month, $day, $year ) );
1387  $newdate = mktime ( 3, 0, 0, $month, $day - $weekday, $year );
1388  return $newdate;
1389}
1390
1391// Get the Monday of the week that the specified date is in.
1392// (If the date specified is a Monday, then that date is returned.)
1393function get_monday_before ( $year, $month, $day ) {
1394  $weekday = date ( "w", mktime ( 3, 0, 0, $month, $day, $year ) );
1395  if ( $weekday == 0 )
1396    return mktime ( 3, 0, 0, $month, $day - 6, $year );
1397  if ( $weekday == 1 )
1398    return mktime ( 3, 0, 0, $month, $day, $year );
1399  return mktime ( 3, 0, 0, $month, $day - ( $weekday - 1 ), $year );
1400}
1401
1402
1403// Returns week number for specified date
1404// depending from week numbering settings.
1405// params:
1406//   $date - date in UNIX time format
1407function week_number ( $date ) {
1408  $ret = "";
1409  if ( $GLOBALS["WEEK_START"] == "1" ) {
1410    $ret = strftime ( "%V", $date ); // ISO Weeks -- which start on Mondays
1411    if ( $ret == "" ) // %V not implemented on older versions of PHP :-(
1412      $ret = strftime ( "%W", $date ); // not 100%
1413  } else {
1414    $ret = strftime ( "%W", $date );
1415  }
1416  return $ret;
1417}
1418
1419
1420
1421// This function is not yet used.  Some of the places that will call it
1422// have to be updated to also get the event owner so we know if the current
1423// user has access to edit and delete.
1424function icon_text ( $id, $can_edit, $can_delete ) {
1425  global $readonly, $is_admin;
1426  $ret = "<A HREF=\"view_entry.php?id=$id\">" .
1427    "<IMG SRC=\"view.gif\" ALT=\"" . translate("View this entry") .
1428    "\" BORDER=\"0\" " .
1429    "WIDTH=\"10\" HEIGHT=\"10\">" .
1430    "</A>";
1431  if ( $can_edit && $readonly == "N" )
1432    $ret .= "<A HREF=\"edit_entry.php?id=$id\">" .
1433      "<IMG SRC=\"edit.gif\" ALT=\"" . translate("Edit entry") .
1434      "\" BORDER=\"0\" " .
1435      "WIDTH=\"10\" HEIGHT=\"10\">" .
1436      "</A>";
1437  if ( $can_delete && ( $readonly == "N" || $is_admin ) )
1438    $ret .= "<A HREF=\"del_entry.php?id=$id\" " .
1439      "onClick=\"return confirm('" .
1440      translate("Are you sure you want to delete this entry?") .
1441      "\\n\\n" . translate("This will delete this entry for all users.") .
1442      "');\">" .
1443      "<IMG SRC=\"delete.gif\" ALT=\"" . translate("Delete entry") .
1444      "\" BORDER=\"0\" " .
1445      "WIDTH=\"10\" HEIGHT=\"10\">" .
1446      "</A>";
1447  return $ret;
1448}
1449
1450
1451//
1452// Print all the calendar entries for the specified user for the
1453// specified date.  If we are displaying data from someone other than
1454// the logged in user, then check the access permission of the entry.
1455// params:
1456//   $date - date in YYYYMMDD format
1457//   $user - username
1458//   $hide_icons - hide icons to make printer-friendly
1459//   $is_ssi - is this being called from week_ssi.php?
1460function print_date_entries ( $date, $user, $hide_icons, $ssi ) {
1461  global $events, $readonly, $is_admin,
1462    $public_access, $public_access_can_add;
1463  $cnt = 0;
1464  $get_unapproved = ( $GLOBALS["DISPLAY_UNAPPROVED"] == "Y" );
1465  // public access events always must be approved before being displayed
1466  if ( $user == "__public__" )
1467    $get_unapproved = false;
1468
1469  $year = substr ( $date, 0, 4 );
1470  $month = substr ( $date, 4, 2 );
1471  $day = substr ( $date, 6, 2 );
1472 
1473  $dateu = mktime ( 3, 0, 0, $month, $day, $year );
1474
1475  $can_add = ( $readonly == "N" || $is_admin );
1476  if ( $public_access == "Y" && $public_access_can_add != "Y" &&
1477    $user == "__public__" )
1478    $can_add = false;
1479
1480  if ( ! $hide_icons && ! $ssi && $can_add ) {
1481    print "<A HREF=\"edit_entry.php?";
1482    if ( strcmp ( $user, $GLOBALS["login"] ) )
1483      print "user=$user&";
1484    print "date=$date\">" .
1485      "<IMG SRC=\"new.gif\" WIDTH=\"10\" HEIGHT=\"10\" ALT=\"" .
1486      translate("New Entry") . "\" BORDER=\"0\" ALIGN=\"right\">" .
1487      "</A>";
1488    $cnt++;
1489  }
1490  if ( ! $ssi ) {
1491    echo "<FONT SIZE=\"-1\"><A CLASS=\"dayofmonth\" HREF=\"day.php?";
1492    if ( strcmp ( $user, $GLOBALS["login"] ) )
1493      echo "user=$user&";
1494    echo "date=$date\">$day</A></FONT>";
1495    if ( $GLOBALS["DISPLAY_WEEKNUMBER"] == "Y" &&
1496      date ( "w", $dateu ) == $GLOBALS["WEEK_START"] ) {
1497      echo "<A HREF=\"week.php?date=$date";
1498      if ( strcmp ( $user, $GLOBALS["login"] ) )
1499        echo "&user=$user";
1500       echo "\" CLASS=\"weeknumber\">";
1501      echo "<FONT SIZE=\"-2\" CLASS=\"weeknumber\">(" .
1502        translate("Week") . " " . week_number ( $dateu ) . ")</FONT></A>";
1503    }
1504    print "<BR>\n";
1505    $cnt++;
1506  }
1507
1508  // get all the repeating events for this da…

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