<?php
/******************************************************************************/
/* class_calendar.php: Gregorian calendar to easily create calendars. */
/* Copyright (C) 2005 Ken Stanley <phpclasses@kennethpaul.com> */
/* */
/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Lesser General Public */
/* License as published by the Free Software Foundation; either */
/* version 2.1 of the License, or (at your option) any later version. */
/* */
/* This library is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
/* Lesser General Public License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public */
/* License along with this library; if not, write to the Free Software */
/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/******************************************************************************/
class calendar {
var $pad_dates = FALSE; /* Convert numbers like 1 to 01 */
var $min_year = 0; /* Minimum year before it rolls over */
var $max_year = 0; /* Maximum year before it rolls over */
var $start_monday = 0; /* Start the week with Monday (0: no; 1: yes) */
var $language = "en"; /* Two-letter country code to determine language
of calendar */
var $has_sqlite = FALSE; /* Whether there is support for SQLite */
/*
* Name: calendar() [class constructor]
* Params: string database_filename
* Returns: void
* Description: Sets up connection to SQLite database_filename, and if
* necessary, it will create the database first (first run).
* You MUST create a subdirectory and chown it to your
* webserver's user:group! After doing that, you MUST make
* the file writeable by the webserver (e.g. chmod 666 <file>).
* Not doing this will generate a read/write error.
*/
function calendar($_calendar_language = 'en', $_calendar_db_file = 'db/calendar.sdb') {
if (!extension_loaded('sqlite')) {
/*
* This method of loading the sqlite.so/php_sqlite.dll is for
* easy interoperability to all versions of PHP
*/
if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) {
$extension = "php_sqlite.dll";
} else {
$extension = "sqlite.so";
}
if (@dl($extension)) {
$this->has_sqlite = TRUE;
} else {
$this->has_sqlite = FALSE;
}
} else {
$this->has_sqlite = TRUE;
}
if (!is_writable($_calendar_db_file)) {
$this->has_sqlite = FALSE;
}
if (!file_exists('class_sqlite.php')) {
$this->has_sqlite = FALSE;
}
/*
* If there is no SQLite support then we don't need to bother
* trying to open or set up any kind of database. Checks like
* this will be throughout the class to ensure smooth operation.
*/
if ($this->has_sqlite) {
include_once('class_sqlite.php');
$this->sqlite = new sqlite($_calendar_db_file);
if (!$this->sqlite->table_exists('events')) {
/*
* Setting PRAGMA auto_vaccum will optimize the size of the database
* after deletions, without having to always call the VACCUM statement.
* This has to be set before creating the table, or nothing will happen.
*/
$this->sqlite->query("PRAGMA auto_vacuum = 1");
/*
* Database schema (for the curious):
* events (
* id INTEGER PRIMARY KEY AUTOINCREMENT,
* month INTEGER NOT NULL,
* day INTEGER NOT NULL,
* year INTEGER NOT NULL,
* event TEXT NOT NULL,
* added INTEGER NOT NULL
* );
*/
$_calendar_sql = "CREATE TABLE events(";
$_calendar_sql .= "id INTEGER PRIMARY KEY,";
$_calendar_sql .= "month INTEGER,";
$_calendar_sql .= "day INTEGER,";
$_calendar_sql .= "year INTEGER,";
$_calendar_sql .= "event TEXT,";
$_calendar_sql .= "added INTEGER)";
$this->sqlite->query($_calendar_sql);
}
}
/* Language Support */
$this->language = $_calendar_language;
/* Begin Translation: English */
$this->languages['en']['day'][] = "Sunday";
$this->languages['en']['day'][] = "Monday";
$this->languages['en']['day'][] = "Tuesday";
$this->languages['en']['day'][] = "Wednesday";
$this->languages['en']['day'][] = "Thursday";
$this->languages['en']['day'][] = "Friday";
$this->languages['en']['day'][] = "Saturday";
$this->languages['en']['month'][] = "January";
$this->languages['en']['month'][] = "February";
$this->languages['en']['month'][] = "March";
$this->languages['en']['month'][] = "April";
$this->languages['en']['month'][] = "May";
$this->languages['en']['month'][] = "June";
$this->languages['en']['month'][] = "July";
$this->languages['en']['month'][] = "August";
$this->languages['en']['month'][] = "September";
$this->languages['en']['month'][] = "October";
$this->languages['en']['month'][] = "November";
$this->languages['en']['month'][] = "December";
if ($_calendar_language == "en") {
$this->start_monday = 0;
setlocale(LC_TIME, 'en_US');
}
/* End Translation: English */
/* Begin Translation: Hungarian */
$this->languages['hu']['day'][] = "Vasárnap";
$this->languages['hu']['day'][] = "Hétfő";
$this->languages['hu']['day'][] = "Kedd";
$this->languages['hu']['day'][] = "Szerda";
$this->languages['hu']['day'][] = "Csütörtök";
$this->languages['hu']['day'][] = "Péntek";
$this->languages['hu']['day'][] = "Szombat";
$this->languages['hu']['month'][] = "Január";
$this->languages['hu']['month'][] = "Február";
$this->languages['hu']['month'][] = "Március";
$this->languages['hu']['month'][] = "Április";
$this->languages['hu']['month'][] = "Május";
$this->languages['hu']['month'][] = "Június";
$this->languages['hu']['month'][] = "Július";
$this->languages['hu']['month'][] = "Augusztus";
$this->languages['hu']['month'][] = "Szeptember";
$this->languages['hu']['month'][] = "Október";
$this->languages['hu']['month'][] = "November";
$this->languages['hu']['month'][] = "December";
if ($_calendar_language == "hu") {
$this->start_monday = 1;
setlocale(LC_TIME, 'hu_HU');
}
/* End Translation: Hungarian */
/* Begin Translation: Spanish */
$this->languages['es']['day'][] = "Lunes";
$this->languages['es']['day'][] = "Martes";
$this->languages['es']['day'][] = "Miércoles";
$this->languages['es']['day'][] = "Jueves";
$this->languages['es']['day'][] = "Viernes";
$this->languages['es']['day'][] = "Sábado";
$this->languages['es']['day'][] = "Domingo";
$this->languages['es']['month'][] = "Enero";
$this->languages['es']['month'][] = "Febrero";
$this->languages['es']['month'][] = "Marzo";
$this->languages['es']['month'][] = "Abril";
$this->languages['es']['month'][] = "Mayo";
$this->languages['es']['month'][] = "Junio";
$this->languages['es']['month'][] = "Julio";
$this->languages['es']['month'][] = "Agosto";
$this->languages['es']['month'][] = "Septiembre";
$this->languages['es']['month'][] = "Octubre";
$this->languages['es']['month'][] = "Noviembre";
$this->languages['es']['month'][] = "Diciembre";
if ($_calendar_language == "es") {
$this->start_monday = 1;
setlocale(LC_TIME, 'es_ES');
}
/* End Translation: Spanish */
/* Start Translation: French */
$this->languages['fr']['day'][] = "Dimanche";
$this->languages['fr']['day'][] = "Lundi";
$this->languages['fr']['day'][] = "Mardi";
$this->languages['fr']['day'][] = "Mercredi";
$this->languages['fr']['day'][] = "Jeudi";
$this->languages['fr']['day'][] = "Vendredi";
$this->languages['fr']['day'][] = "Samedi";
$this->languages['fr']['month'][] = "Janvier";
$this->languages['fr']['month'][] = "Février";
$this->languages['fr']['month'][] = "Mars";
$this->languages['fr']['month'][] = "Avril";
$this->languages['fr']['month'][] = "Mai";
$this->languages['fr']['month'][] = "Juin";
$this->languages['fr']['month'][] = "Juillet";
$this->languages['fr']['month'][] = "Aoűt";
$this->languages['fr']['month'][] = "Septembre";
$this->languages['fr']['month'][] = "Octobre";
$this->languages['fr']['month'][] = "Novembre";
$this->languages['fr']['month'][] = "Décembre";
if ($_calendar_language == "fr") {
$this->start_monday = 1;
setlocale(LC_TIME, 'fr_FR');
}
/* End Translation: French */
/* Start Translation: German */
$this->languages['de']['day'][] = "Sonntag";
$this->languages['de']['day'][] = "Montag";
$this->languages['de']['day'][] = "Dienstag";
$this->languages['de']['day'][] = "Mittwoch";
$this->languages['de']['day'][] = "Donnerstag";
$this->languages['de']['day'][] = "Freitag";
$this->languages['de']['day'][] = "Samstag";
$this->languages['de']['month'][] = "Januar";
$this->languages['de']['month'][] = "Februar";
$this->languages['de']['month'][] = "März";
$this->languages['de']['month'][] = "April";
$this->languages['de']['month'][] = "Mai";
$this->languages['de']['month'][] = "Juni";
$this->languages['de']['month'][] = "Juli";
$this->languages['de']['month'][] = "August";
$this->languages['de']['month'][] = "September";
$this->languages['de']['month'][] = "Oktober";
$this->languages['de']['month'][] = "November";
$this->languages['de']['month'][] = "Dezember";
if ($_calendar_language == "de") {
$this->start_monday = 1;
setlocale(LC_TIME, 'de_DE');
}
/* End Translation: German */
/* Start Translation: Italian */
$this->languages['it']['day'][] = "Lunedě";
$this->languages['it']['day'][] = "Martedě";
$this->languages['it']['day'][] = "Mercoledě";
$this->languages['it']['day'][] = "Giovedě";
$this->languages['it']['day'][] = "Venerdě";
$this->languages['it']['day'][] = "Sabato";
$this->languages['it']['day'][] = "Domenica";
$this->languages['it']['month'][] = "Gennaio";
$this->languages['it']['month'][] = "Febbraio";
$this->languages['it']['month'][] = "Marzo";
$this->languages['it']['month'][] = "Aprile";
$this->languages['it']['month'][] = "Maggio";
$this->languages['it']['month'][] = "Giugno";
$this->languages['it']['month'][] = "Luglio";
$this->languages['it']['month'][] = "Agosto";
$this->languages['it']['month'][] = "Settembre";
$this->languages['it']['month'][] = "Ottobre";
$this->languages['it']['month'][] = "Novembre";
$this->languages['it']['month'][] = "Dicembre";
if ($_calendar_language == "it") {
$this->start_monday = 1;
setlocale(LC_TIME, 'it_IT');
}
/* End Translation: Italian */
}
/*
* Name: date()
* Params: int time
* Returns: string date
* Description: Works just like PHP's date() function, but is locale
* friendly.
*/
function date($_date_format, $_date_time) {
$_date_hour = date("G", $_date_time);
$_date_minute = date("i", $_date_time);
$_date_second = date("s", $_date_time);
$_date_month = date("n", $_date_time);
$_date_day = date("j", $_date_time);
$_date_year = date("Y", $_date_time);
return strftime(
$_date_format,
mktime(
$_date_hour,
$_date_minute,
$_date_second,
$_date_month,
$_date_day,
$_date_year
)
);
}
/* Name: get_month()
* Params: int month, int year
* Returns: array()
* Description: Returns a multi-dimension array containing
* the calendar month. The first layer of the
* array are the weeks, and the second layer
* are the days:
*
* week 1: sun, mon, tue, wed, thu, fri, sat
* week 2: sun, mon, tue, wed, thu, fri, sat
* week 3: sun, mon, tue, wed, thu, fri, sat
* week 4: sun, mon, tue, wed, thu, fri, sat
* week 5: sun, mon, tue, wed, thu, fri, sat
* week 6: sun, mon, tue, wed, thu, fri, sat
*
* This is for easy user-formatting. See README
* for example code.
*/
function get_month($_get_month_month, $_get_month_year) {
$_get_month_array = array_pad(array(), 6, array_pad(array(), 7, 0));
$_get_month_days = $this->month_length($_get_month_month, $_get_month_year);
$k = $this->get_day($_get_month_month, 1, $_get_month_year);
for ($i = 1, $j = 0; $i <= $_get_month_days; $i += 1) {
if ($k > 6) {
$j += 1;
$k = 0;
}
if ($this->pad_dates) {
$_get_month_array[$j][$k] = str_pad($i, 2, '0', STR_PAD_LEFT);
} else {
$_get_month_array[$j][$k] = $i;
}
$k += 1;
}
return $_get_month_array;
}
/*
* Name: get_day()
* Params: int month, int day, int year
* Returns: int
* Description: Returns the day of the week for the given
* date as a number between 0-6:
*
* 0 = Sunday/Monday
* 1 = Monday/Tuesday
* 2 = Tuesday/Wednesday
* 3 = Wednesday/Thursday
* 4 = Thursday/Friday
* 5 = Friday/Saturday
* 6 = Saturday/Sunday
*/
function get_day($_get_day_month, $_get_day_day, $_get_day_year) {
$_get_day_adj1 = (int)((14 - $_get_day_month) / 12);
$_get_day_adj2 = $_get_day_year - $_get_day_adj1;
$_get_day_adj3 = $_get_day_month + (12 * $_get_day_adj1) - 2;
$_get_day_result = $_get_day_day + $_get_day_adj2 + (int)($_get_day_adj2 / 4);
$_get_day_result -= (int)($_get_day_adj2 / 100);
$_get_day_result += (int)($_get_day_adj2 / 400);
$_get_day_result += (int)((31 * $_get_day_adj3) / 12);
$_get_day_result = (7 + $_get_day_result - $this->start_monday) % 7;
return $_get_day_result;
}
/*
* Name: day_name()
* Params: int day, int short
* Returns: string
* Description: Converts the numerical format of month (0-6) into
* human-readable format. You can control the
* size of the name by passing either a 1 (Full),
* 2 (First 3 letters), or 3 (First letter only)
* as the second parameter.
*/
function day_name($_day_name_day, $_day_name_short = 0) {
$_day_name_day = ($this->start_monday + $_day_name_day) % 7;
$_day_name_result = $this->languages[$this->language]['day'][$_day_name_day];
switch ($_day_name_short) {
case 1:
/* Shortened to the first three letters */
return substr($_day_name_result, 0, 3);
break;
case 2:
/* Shortened to the first letter only */
return substr($_day_name_result, 0, 1);
break;
case 0:
default:
return $_day_name_result;
break;
}
}
/*
* Name: month_name()
* Params: int month, int short
* Returns: string
* Description: Converts the numerical format of month (1-12)
* into human-readable format. You can control the
* size of the name by passing either a 1 (Full),
* 2 (First 3 letters), or 3 (First letter only)
* as the second parameter.
*/
function month_name($_month_name_month, $_month_name_short = 0) {
$_month_name_month -= 1;
$_month_name_result = $this->languages[$this->language]['month'][$_month_name_month];
switch ($_month_name_short) {
case 1:
/* Shortened to the first three letters */
return substr($_month_name_result, 0, 3);
break;
case 2:
/* Shortened to the first letter only */
return substr($_month_name_result, 0, 1);
break;
case 0:
default:
return $_month_name_result;
break;
}
}
/*
* Name: is_leap()
* Params: string year
* Returns: bool
* Description: Returns either TRUE or FALSE depending
* on whether a year is a leap year or not.
*/
function is_leap($_is_leap_year) {
if (($_is_leap_year % 4) == 0) {
if (($_is_leap_year % 100) == 0) {
if (($_is_leap_year % 400) == 0) {
return TRUE;
} else {
return FALSE;
}
} else {
return TRUE;
}
} else {
return FALSE;
}
}
/*
* Name: month_length()
* Params: int month, int year
* Returns: int
* Description: Returns the length of given month for
* given year.
*/
function month_length($_month_length_month, $_month_length_year) {
switch ($_month_length_month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
$_month_length_length = 31;
break;
case 2:
if ($this->is_leap($_month_length_year)) {
$_month_length_length = 29;
} else {
$_month_length_length = 28;
}
break;
case 4:
case 6:
case 9:
case 11:
$_month_length_length = 30;
break;
default:
$_month_length_length = 0;
}
return $_month_length_length;
}
/*
* Name: valid_date()
* Params: int month, int day, int year
* Returns: void
* Description: This function takes care to ensure the
* validity of the date given. E.g. -1/01/2005
* would be converted to 12/01/2004, and 13/01/2005
* would be converted to 01/01/2006.
*/
function valid_date(&$_valid_date_month, &$_valid_date_day, &$_valid_date_year) {
/*
* NOTE: If you were to try 01/60/2005 without these passes, you would
* get most unexpected results (i.e. 02/29/2005 for a NON-LEAP YEAR!)
*/
/* Pass 1: Convert the month to something legit (1-12) */
$this->valid_month($_valid_date_month, $_valid_date_year);
/* Pass 1: Convert the day to something legit (1-{28,29,30,31}) */
$this->valid_day($_valid_date_month, $_valid_date_day, $_valid_date_year);
/* Pass 1: Convert the year to within acceptable limits */
if (isset($this->min_year) && is_numeric($this->min_year) && ($this->min_year > 0)) {
if (isset($this->max_year) && is_numeric($this->max_year) && ($this->max_year > 0)) {
$this->valid_year($_valid_date_year);
}
}
/* Pass 2: Since the days changed, the month may need to be changed again. */
$this->valid_month($_valid_date_month, $_valid_date_year);
/* Pass 2: The month may have changed again, so we need to do this. */
$this->valid_day($_valid_date_month, $_valid_date_day, $_valid_date_year);
/* Pass 2: Convert the year to within acceptable limits */
if (isset($this->min_year) && is_numeric($this->min_year) && ($this->min_year > 0)) {
if (isset($this->max_year) && is_numeric($this->max_year) && ($this->max_year > 0)) {
$this->valid_year($_valid_date_year);
}
}
}
/*
* Name: valid_month()
* Params: int month, int year
* Returns: void
* Description: Used in valid_date to roll over the month so it
* stays within 1-12 constraints.
*/
function valid_month(&$_valid_month_month, &$_valid_month_year) {
while ($_valid_month_month > 12) {
$_valid_month_month -= 12;
$_valid_month_year += 1;
}
while ($_valid_month_month < 1) {
$_valid_month_month += 12;
$_valid_month_year -= 1;
}
}
/*
* Name: valid_day()
* Params: int month, int day, int year
* Returns: void
* Description: Used in valid_date to roll over the day so it
* stays within 1-(whatever the last day is)
* constraints.
*/
function valid_day(&$_valid_day_month, &$_valid_day_day, &$_valid_day_year) {
$_valid_day_month_length = $this->month_length(
$_valid_day_month,
$_valid_day_year
);
while ($_valid_day_day > $_valid_day_month_length) {
$_valid_day_month_length = $this->month_length(
$_valid_day_month,
$_valid_day_year
);
$_valid_day_day -= $_valid_day_month_length;
$_valid_day_month += 1;
}
while ($_valid_day_day < 1) {
$_valid_day_month_length = $this->month_length(
$_valid_day_month,
$_valid_day_year
);
$_valid_day_day += $_valid_day_month_length;
$_valid_day_month -= 1;
}
}
/*
* Name: valid_year()
* Params: int year
* Returns: void
* Description: Used in valid_date to roll over the year so it
* stays within user-specified constraints.
*
* NOTE: This function is COMPLETELY optional. To
* disable it's use, DO NOT SET $this->min_year or
* $this->max_year!!!!
*/
function valid_year(&$_valid_year_year) {
if (isset($this->min_year) && is_numeric($this->min_year) && ($this->min_year > 0)) {
if (isset($this->max_year) && is_numeric($this->max_year) && ($this->max_year > 0)) {
while ($_valid_year_year > $this->max_year) {
$_valid_year_year -= ($this->max_year - $this->min_year) + 1;
}
while ($_valid_year_year < $this->min_year) {
$_valid_year_year += ($this->max_year - $this->min_year) + 1;
}
}
}
}
/*
* Name: add_event()
* Params: int month, int day, int year, mixed string
* Returns: bool TRUE/FALSE
* Description: Adds an event for given month/day/year to the SQLite database.
*/
function add_event($_add_event_month, $_add_event_day, $_add_event_year, $_add_event_event) {
if ($this->sqlite) {
$_add_event_sql = "INSERT INTO events ";
$_add_event_sql .= "(id, month, day, year, event, added) VALUES (";
$_add_event_sql .= "NULL, ";
$_add_event_sql .= "$_add_event_month, ";
$_add_event_sql .= "$_add_event_day, ";
$_add_event_sql .= "$_add_event_year, ";
$_add_event_sql .= "'" . sqlite_escape_string($_add_event_event) . "', ";
$_add_event_sql .= time() . ")";
return $this->sqlite->query($_add_event_sql);
} else {
return FALSE;
}
}
/*
* Name: del_event()
* Params: int id
* Returns: bool TRUE/FALSE
* Description: Removes an event from the database by given id.
*/
function del_event($_del_event_id) {
if ($this->has_sqlite) {
$_del_event_sql = "DELETE FROM events ";
$_del_event_sql .= "WHERE id=$_del_event_id";
return $this->sqlite->query($_del_event_sql);
} else {
return FALSE;
}
}
/*
* Name: get_event()
* Params: int month, int day, int year
* Returns: mixed event
* Description: Retrieves an event for the given month/day/year from the database.
*/
function get_events($_get_events_month, $_get_events_day, $_get_events_year) {
if ($this->has_sqlite) {
$_get_events_sql = "SELECT * FROM events ";
$_get_events_sql .= "WHERE month=$_get_events_month AND ";
$_get_events_sql .= "day=$_get_events_day AND ";
$_get_events_sql .= "year=$_get_events_year";
$_get_events_result = $this->sqlite->fetch_assoc($_get_events_sql);
if (sizeof($_get_events_result) > 0) {
return $_get_events_result;
} else {
return FALSE;
}
} else {
return FALSE;
}
}
/*
* Name: num_events()
* Params: int month, int day, int year
* Returns: int rows or bool FALSE
* Description: Returns the number of events for given month/day/year.
*/
function num_events($_num_events_month, $_num_events_day, $_num_events_year) {
if ($this->has_sqlite) {
$_num_events_sql = "SELECT COUNT(*) as count FROM events ";
$_num_events_sql .= "WHERE month=$_num_events_month AND ";
$_num_events_sql .= "day=$_num_events_day AND ";
$_num_events_sql .= "year=$_num_events_year";
$_num_events_result = $this->sqlite->fetch_assoc($_num_events_sql);
if (sizeof($_num_events_result) > 0) {
return $_num_events_result[0]['count'];
} else {
return FALSE;
}
} else {
return FALSE;
}
}
}
?>
|