From 8c7c0c1eb217e97c4379d5168843c50514d9cb84 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 4 May 2016 17:15:18 +0000 Subject: [PATCH] reading holidays now from Mozilla holiday calendars, or a custom iCal URL --- api/src/CalDAV/IcalIterator.php | 6 +- calendar/inc/class.calendar_bo.inc.php | 21 +- calendar/inc/class.calendar_holidays.inc.php | 220 ++++++++ calendar/inc/class.calendar_hooks.inc.php | 1 - calendar/inc/class.calendar_ical.inc.php | 10 +- calendar/inc/class.calendar_ui.inc.php | 1 - calendar/inc/class.calendar_uiviews.inc.php | 2 +- calendar/inc/class.holidaycalc.inc.php | 34 -- calendar/inc/class.holidaycalc_JP.inc.php | 159 ------ calendar/inc/class.holidaycalc_US.inc.php | 111 ---- calendar/inc/class.sbox.inc.php | 395 ------------- calendar/inc/class.soholiday.inc.php | 213 ------- calendar/inc/class.uiholiday.inc.php | 530 ------------------ calendar/lang/egw_de.lang | 11 +- calendar/lang/egw_en.lang | 11 +- calendar/setup/ical_holiday_urls.json | 72 +++ calendar/setup/setup.inc.php | 3 +- calendar/setup/tables_current.inc.php | 16 - calendar/setup/tables_update.inc.php | 8 + calendar/templates/default/config.xet | 17 +- calendar/templates/default/csv_import.tpl | 72 --- calendar/templates/default/delete_common.tpl | 16 - calendar/templates/default/event_widget.tpl | 40 -- .../templates/default/form_button_script.tpl | 12 - calendar/templates/default/holiday.tpl | 34 -- calendar/templates/default/locales.tpl | 62 -- .../templates/default/preference_acl_row.tpl | 11 - .../templates/default/preference_colspan.tpl | 10 - 28 files changed, 330 insertions(+), 1768 deletions(-) create mode 100644 calendar/inc/class.calendar_holidays.inc.php delete mode 100755 calendar/inc/class.holidaycalc.inc.php delete mode 100755 calendar/inc/class.holidaycalc_JP.inc.php delete mode 100755 calendar/inc/class.holidaycalc_US.inc.php delete mode 100644 calendar/inc/class.sbox.inc.php delete mode 100755 calendar/inc/class.soholiday.inc.php delete mode 100755 calendar/inc/class.uiholiday.inc.php create mode 100644 calendar/setup/ical_holiday_urls.json delete mode 100644 calendar/templates/default/csv_import.tpl delete mode 100755 calendar/templates/default/delete_common.tpl delete mode 100644 calendar/templates/default/event_widget.tpl delete mode 100755 calendar/templates/default/form_button_script.tpl delete mode 100755 calendar/templates/default/holiday.tpl delete mode 100755 calendar/templates/default/locales.tpl delete mode 100755 calendar/templates/default/preference_acl_row.tpl delete mode 100755 calendar/templates/default/preference_colspan.tpl diff --git a/api/src/CalDAV/IcalIterator.php b/api/src/CalDAV/IcalIterator.php index 9eeffce8ec..4408f34cad 100644 --- a/api/src/CalDAV/IcalIterator.php +++ b/api/src/CalDAV/IcalIterator.php @@ -104,8 +104,9 @@ class IcalIterator extends Horde_Icalendar implements \Iterator * @param string $charset =null * @param callback $callback =null callback to call with component in current() method, if returning false, item get's ignored * @param array $callback_params =array() further parameters for the callback, 1. parameter is component + * @param boolean $add_container =false true, add container / $this as last parameter to callback */ - public function __construct($ical_file,$base='VCALENDAR',$charset=null,$callback=null,array $callback_params=array()) + public function __construct($ical_file,$base='VCALENDAR',$charset=null,$callback=null,array $callback_params=array(), $add_container=false) { // call parent constructor parent::__construct(); @@ -115,6 +116,7 @@ class IcalIterator extends Horde_Icalendar implements \Iterator if (is_callable($callback)) { $this->callback = $callback; + if ($add_container) $callback_params[] = $this; $this->callback_params = $callback_params; } if (is_string($ical_file)) @@ -274,7 +276,7 @@ class IcalIterator extends Horde_Icalendar implements \Iterator */ public function rewind() { - fseek($this->ical_file,0,SEEK_SET); + @fseek($this->ical_file,0,SEEK_SET); // advance to begin of container while(($line = $this->read_line()) && substr($line,0,6+strlen($this->base)) !== 'BEGIN:'.$this->base) diff --git a/calendar/inc/class.calendar_bo.inc.php b/calendar/inc/class.calendar_bo.inc.php index cec93c440f..0993985d47 100644 --- a/calendar/inc/class.calendar_bo.inc.php +++ b/calendar/inc/class.calendar_bo.inc.php @@ -184,10 +184,6 @@ class calendar_bo * @var array $cached_holidays holidays plus birthdays (gets cached in the session for performance reasons) */ var $cached_holidays; - /** - * @var boholiday - */ - var $holidays; /** * Instance of the socal class * @@ -1744,14 +1740,11 @@ class calendar_bo * * @param int $year =0 year, defaults to 0 = current year * @return array indexed with Ymd of array of holidays. A holiday is an array with the following fields: - * index: numerical unique id - * locale: string, 2-char short for the nation * name: string + * title: optional string with description * day: numerical day in month * month: numerical month * occurence: numerical year or 0 for every year - * dow: day of week, 0=sunday, .., 6= saturday - * observande_rule: boolean */ function read_holidays($year=0) { @@ -1763,12 +1756,10 @@ class calendar_bo } if (!isset($this->cached_holidays[$year])) { - if (!is_object($this->holidays)) - { - $this->holidays = CreateObject('calendar.boholiday'); - } - $this->holidays->prepare_read_holidays($year); - $this->cached_holidays[$year] = $this->holidays->read_holiday(); + $this->cached_holidays[$year] = calendar_holidays::read( + !empty($GLOBALS['egw_info']['server']['ical_holiday_url']) ? + $GLOBALS['egw_info']['server']['ical_holiday_url'] : + $GLOBALS['egw_info']['user']['preferences']['common']['country'], $year); // search for birthdays if ($GLOBALS['egw_info']['server']['hide_birthdays'] != 'yes') @@ -1813,7 +1804,7 @@ class calendar_bo } } // store holidays and birthdays in the session - $this->cached_holidays = Api\Cache::setSession('calendar', 'holidays', $this->cached_holidays); + Api\Cache::setSession('calendar', 'holidays', $this->cached_holidays); } if ((int) $this->debug >= 2 || $this->debug == 'read_holidays') { diff --git a/calendar/inc/class.calendar_holidays.inc.php b/calendar/inc/class.calendar_holidays.inc.php new file mode 100644 index 0000000000..0b465cf5d6 --- /dev/null +++ b/calendar/inc/class.calendar_holidays.inc.php @@ -0,0 +1,220 @@ + + * @copyright (c) 2016 by RalfBecker-At-outdoor-training.de + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @version $Id$ + */ + +use EGroupware\Api; + +/** + * Calendar holidays + * + * Holidays are read from: + * - a given iCal URL or + * - json file with 2-digit iso country-code: URL pairs is read from https://community.egroupware.org or + * - json file is read from /calendar/setup/ical_holiday_urls.json + * + * Holidays are cached on tree or instance level, later for custom urls. + * As fetching and parsing iCal files is expensive, we always render them + * from previous (requested) year until next 5 years. + */ +class calendar_holidays +{ + const URL_CACHE_TIME = 864000; + const URL_FAIL_CACHE_TIME = 300; + const EGW_HOLIDAY_URL = 'https://community.egroupware.org/egw'; + const HOLIDAY_PATH = '/calendar/setup/ical_holiday_urls.json'; + const HOLIDAY_CACHE_TIME = 864000; + + /** + * Read holidays for given country/url and year + * + * @param string $country 2-digit iso country code or URL + * @param int $year =null default current year + * @return array of Ymd => array of array with values for keys 'occurence','month','day','name', (commented out) 'title' + */ + public static function read($country, $year=null) + { + if (!$year) $year = (int)Api\DateTime::to('now', 'Y'); + $level = self::is_url($country) ? Api\Cache::INSTANCE : Api\Cache::TREE; + + $holidays = Api\Cache::getCache($level, __CLASS__, $country.':'.$year); + + // if we dont find holidays in cache, we render from previous year until next 5 years + if (!isset($holidays) && ($years = self::render($country, $year-1, $year+5))) + { + foreach($years as $y => $data) + { + Api\Cache::setCache($level, __CLASS__, $country.':'.$y, $data, self::HOLIDAY_CACHE_TIME); + } + $holidays = $years[$year]; + } + return (array)$holidays; + } + + /** + * Fetch holiday iCal and convert it to usual holiday format + * + * @param string $country 2-digit iso country code or URL + * @param int $year =null default current year + * @param int $until_year =null default, fetch only one year, if given result is indexed additional by year + * @return array of Ymd => array of array with values for keys 'occurence','month','day','name', (commented out) 'title' + */ + public static function render($country, $year=null, $until_year=null) + { + if (!$year) $year = (int)Api\DateTime::to('now', 'Y'); + $end_year = $until_year && $year < $until_year ? $until_year : $year; + + $starttime = microtime(true); + if (!($holidays = self::fetch($country))) + { + return array(); + } + $years = array(); + foreach($holidays as $event) + { + $start = new Api\DateTime($event['start']); + $end = new Api\DateTime($event['end']); + if ($start->format('Y') > $end_year) continue; + if ($end->format('Y') < $year && !$event['recur_type']) continue; + + // recuring events + if ($event['recur_type']) + { + // calendar_rrule limits no enddate, to 5 years + if (!$event['recur_enddate']) $event['recur_enddate'] = (1+$end_year).'0101'; + + $rrule = calendar_rrule::event2rrule($event); + if ($rrule->enddate && $rrule->enddate->format('Y') < $year) continue; + + foreach($rrule as $rtime) + { + if (($y = (int)$rtime->format('Y')) < $year) continue; + if ($y > $end_year) break; + + $ymd = (int)$rtime->format('Ymd'); + $years[$y][(string)$ymd][] = array( + 'day' => $ymd % 100, + 'month' => ($ymd / 100) % 100, + 'occurence' => $y, + 'name' => $event['title'], + //'title' => $event['description'], + ); + } + } + else + { + $end_ymd = (int)$end->format('Ymd'); + while(($ymd = (int)$start->format('Ymd')) <= $end_ymd) + { + $y = (int)$start->format('Y'); + $years[$y][(string)$ymd][] = array( + 'day' => $ymd % 100, + 'month' => ($ymd / 100) % 100, + 'occurence' => $y, + 'name' => $event['title'], + //'title' => $event['description'], + ); + $start->add('1day'); + } + } + } + foreach($years as $y => &$data) + { + ksort($data); + } + error_log(__METHOD__."('$country', $year, $end_year) took ". number_format(microtime(true)-$starttime, 3).'s to fetch '.count(call_user_func_array('array_merge', $years)).' events'); + unset($starttime); + + return $until_year ? $years : $years[$year]; + } + + protected static function is_url($url) + { + return $url[0] == '/' || strpos($url, '://') !== false; + } + + /** + * Fetch iCal for given country + * + * @param string $country 2-digit iso country code or URL + * @return array|Iterator parsed events + */ + protected static function fetch($country) + { + if (!($url = self::is_url($country) ? $country : self::ical_url($country))) + { + error_log("No holiday iCal for '$country'!"); + return array(); + } + if (!($f = fopen($url, 'r'))) + { + error_log("Can NOT open holiday iCal '$url' for country '$country'!"); + return array(); + } + $parser = new calendar_ical(); + if (!($icals = $parser->icaltoegw($f))) + { + error_log("Error parsing holiday iCal '$url' for country '$country'!"); + return array(); + } + return $icals; + } + + /** + * Get iCal url for holidays of given country + * + * We first try to fetch urls from https://community.egroupware.org and if that fails we use the local one. + * + * @param string $country + * @return string|boolean|null string with url, false if we cant load urls, NULL if $country is not included + */ + protected static function ical_url($country) + { + $urls = Api\Cache::getTree(__CLASS__, 'ical_holiday_urls'); + + if (!isset($urls)) + { + $ctx = stream_context_create(array( + 'http'=> array( + 'timeout' => 1, + ) + )); + if (!($json = file_get_contents(self::EGW_HOLIDAY_URL.self::HOLIDAY_PATH, false, $ctx))) + { + $json = file_get_contents(EGW_SERVER_ROOT.self::HOLIDAY_PATH); + } + if (!$json || !($urls = json_decode($json, true))) + { + error_log(__METHOD__."() cant read ical_holiday_urls.json!"); + $urls = false; + } + Api\Cache::setTree(__CLASS__, 'ical_holiday_urls', $urls, $urls ? self::URL_CACHE_TIME : self::URL_FAIL_CACHE_TIME); + } + return $urls[$country]; + } +} + +// some tests when url is called direct +if (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] == __FILE__) +{ + $GLOBALS['egw_info'] = array( + 'flags' => array( + 'currentapp' => 'login', + ) + ); + include('../../header.inc.php'); + + $country = !empty($_GET['country']) && preg_match('/^[A-Z]{2}$/i', $_GET['country']) ? strtoupper($_GET['country']) : 'DE'; + $year = !empty($_GET['year']) && (int)$_GET['year'] > 2000 ? (int)$_GET['year'] : (int)date('Y'); + $year_until = !empty($_GET['year_until']) && (int)$_GET['year_until'] >= $year ? (int)$_GET['year_until'] : $year; + + Api\Header\Content::type('holidays-'.$country.'.txt', 'text/plain', 0, true, false); + print_r(calendar_holidays::render($country, $year, $year_until)); +} diff --git a/calendar/inc/class.calendar_hooks.inc.php b/calendar/inc/class.calendar_hooks.inc.php index da049485e8..b1184a1a85 100644 --- a/calendar/inc/class.calendar_hooks.inc.php +++ b/calendar/inc/class.calendar_hooks.inc.php @@ -86,7 +86,6 @@ class calendar_hooks $file = Array( 'Site Configuration' => Egw::link('/index.php','menuaction=admin.admin_config.index&appname=calendar&ajax=true'), 'Custom fields' => Egw::link('/index.php','menuaction=admin.customfields.index&appname=calendar'), - 'Calendar Holiday Management' => Egw::link('/index.php','menuaction=calendar.uiholiday.admin'), 'Global Categories' => Egw::link('/index.php','menuaction=admin.admin_categories.index&appname=calendar'), 'Category ACL' => Egw::link('/index.php','menuaction=calendar.calendar_uiforms.cat_acl'), 'Update timezones' => Egw::link('/index.php','menuaction=calendar.calendar_timezones.update'), diff --git a/calendar/inc/class.calendar_ical.inc.php b/calendar/inc/class.calendar_ical.inc.php index 0112f87cba..72cd3c7a59 100644 --- a/calendar/inc/class.calendar_ical.inc.php +++ b/calendar/inc/class.calendar_ical.inc.php @@ -2249,7 +2249,9 @@ class calendar_ical extends calendar_boupdate // we use Api\CalDAV\IcalIterator only on resources, as calling importVCal() accesses single events like an array (eg. $events[0]) if (is_resource($_vcalData)) { - return new Api\CalDAV\IcalIterator($_vcalData,'VCALENDAR',$charset,array($this,'_ical2egw_callback'),array($this->tzid,$principalURL)); + return new Api\CalDAV\IcalIterator($_vcalData, 'VCALENDAR', $charset, + // true = add container as last parameter to callback parameters + array($this, '_ical2egw_callback'), array($this->tzid, $principalURL), true); } if ($this->tzid) @@ -2335,6 +2337,12 @@ class calendar_ical extends calendar_boupdate error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.'() '.get_class($component)." found\n",3,$this->logfile); } + // eg. Mozilla holiday calendars contain only a X-WR-TIMEZONE on vCalendar component + if (!$tzid && $container && ($tz = $container->getAttributeDefault('X-WR-TIMEZONE'))) + { + $tzid = $tz; + } + if (!is_a($component, 'Horde_Icalendar_Vevent') || !($event = $this->vevent2egw($component, $container ? $container->getAttributeDefault('VERSION', '2.0') : '2.0', $this->supportedFields, $principalURL, null, $container))) diff --git a/calendar/inc/class.calendar_ui.inc.php b/calendar/inc/class.calendar_ui.inc.php index 3d40658fff..8c4def8d7e 100644 --- a/calendar/inc/class.calendar_ui.inc.php +++ b/calendar/inc/class.calendar_ui.inc.php @@ -520,7 +520,6 @@ class calendar_ui $file = Array( 'Configuration'=>Egw::link('/index.php','menuaction=admin.admin_config.index&appname=calendar&ajax=true'), 'Custom Fields'=>Egw::link('/index.php','menuaction=admin.customfields.index&appname=calendar'), - 'Holiday Management'=>Egw::link('/index.php','menuaction=calendar.uiholiday.admin'), 'Global Categories' =>Egw::link('/index.php','menuaction=admin.admin_categories.index&appname=calendar'), ); $GLOBALS['egw']->framework->sidebox($appname,lang('Admin'),$file,'admin'); diff --git a/calendar/inc/class.calendar_uiviews.inc.php b/calendar/inc/class.calendar_uiviews.inc.php index c3046ddbc5..2233a8a6b2 100644 --- a/calendar/inc/class.calendar_uiviews.inc.php +++ b/calendar/inc/class.calendar_uiviews.inc.php @@ -158,7 +158,7 @@ class calendar_uiviews extends calendar_ui 'daywise' => True, 'use_so_events' => $this->test === 'true', ); - $this->holidays = $this->bo->read_holidays($this->year); +// $this->holidays = $this->bo->read_holidays($this->year); $this->check_owners_access(); diff --git a/calendar/inc/class.holidaycalc.inc.php b/calendar/inc/class.holidaycalc.inc.php deleted file mode 100755 index 0583aafa27..0000000000 --- a/calendar/inc/class.holidaycalc.inc.php +++ /dev/null @@ -1,34 +0,0 @@ - * - * http://www.itheart.com * - * -------------------------------------------- * - * This program is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 2 of the License, or (at your * - * option) any later version. * - \**************************************************************************/ - - /* $Id$ */ - - if (empty($GLOBALS['egw_info']['user']['preferences']['common']['country']) || - strlen($GLOBALS['egw_info']['user']['preferences']['common']['country']) > 2) - { - $rule = 'US'; - } - else - { - $rule = $GLOBALS['egw_info']['user']['preferences']['common']['country']; - } - - $calc_include = EGW_INCLUDE_ROOT.'/calendar/inc/class.holidaycalc_'.$rule.'.inc.php'; - if(@file_exists($calc_include)) - { - include($calc_include); - } - else - { - include(EGW_INCLUDE_ROOT.'/calendar/inc/class.holidaycalc_US.inc.php'); - } diff --git a/calendar/inc/class.holidaycalc_JP.inc.php b/calendar/inc/class.holidaycalc_JP.inc.php deleted file mode 100755 index 14278dc27b..0000000000 --- a/calendar/inc/class.holidaycalc_JP.inc.php +++ /dev/null @@ -1,159 +0,0 @@ - * - * http://www.itheart.com * - * -------------------------------------------- * - * This program is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 2 of the License, or (at your * - * option) any later version. * - \**************************************************************************/ - - /* $Id$ */ - - /** - * Calculations for calendar JP holidays - * - * @package calendar - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - */ - class holidaycalc - { - function calculate_date($holiday, &$holidays, $year) - { - static $cached_month; - static $cached_day; - static $cached_observance_rule; - - if ($holiday['day'] == 0 && $holiday['dow'] != 0 && $holiday['occurence'] != 0) - { - $dow = $GLOBALS['egw']->datetime->day_of_week($year, $holiday['month'], 1); - $dayshift = (($holiday['dow'] + 7) - $dow) % 7; - $day = ($holiday['occurence'] - 1) * 7 + $dayshift + 1; - - // Happy monday law. - if ($holiday['month'] == 1) - { - if ($year < 2000) - { - $day = 15; - } - } - elseif ($holiday['month'] == 7) - { - if ($year < 2003) - { - $day = 20; - } - } - elseif ($holiday['month'] == 9) - { - if ($year < 2003) - { - $day = 15; - } - } - elseif ($holiday['month'] == 10) - { - if ($year < 2000) - { - $day = 10; - } - } - } - elseif ($holiday['day'] == 0 && $holiday['dow'] == 0 && $holiday['occurence'] == 0) - { - // For the next generation. - // over 2151, please set $factor... - if ($holiday['month'] == 3) - { - // for Vernal Equinox - if ($year >= 1980 && $year <= 2099) - { - $factor = 20.8431; - } - elseif ($year >= 2100 && $year <= 2150) - { - $factor = 21.851; - } - } - elseif ($holiday['month'] == 9) - { - // for Autumnal Equinox - if ($year >= 1980 && $year <= 2099) - { - $factor = 23.2488; - } - elseif ($year >= 2100 && $year <= 2150) - { - $factor = 24.2488; - } - } - - $day = (int)($factor + 0.242194 * ($year - 1980) - - (int)(($year - 1980) / 4)); - } - else - { - // normal holiday - $day = $holiday['day']; - } - - if ($year >= 1985 && $holiday['month'] == $cached_month && $day == $cached_day + 2 && $cached_observance_rule == True && $holiday['observance_rule'] == True) - { - $pdow = $GLOBALS['egw']->datetime->day_of_week($year,$holiday['month'],$day-1); - if ($pdow != 0) - { - $addcnt = count($holidays) + 1; - $holidays[$addcnt]['locale'] = $holiday['locale']; - if ($pdow == 1) - { - $holidays[$addcnt]['name'] = lang('overlap holiday'); - } - else - { - $holidays[$addcnt]['name'] = lang('people holiday'); - } - $holidays[$addcnt]['day'] = $day - 1; - $holidays[$addcnt]['month'] = $holiday['month']; - $holidays[$addcnt]['occurence'] = 0; - $holidays[$addcnt]['dow'] = 0; - $holidays[$addcnt]['date'] = mktime(0,0,0,$holiday['month'],$day-1,$year); - $holidays[$addcnt]['observance_rule'] = 0; - } - } - - $cached_month = $holiday['month']; - $cached_day = $day; - $cached_observance_rule = $holiday['observance_rule']; - - if ($year >= 1985 && $holiday['month'] == 5 && $day == 3) - { - ; - } - elseif ($holiday['observance_rule'] == True) - { - $dow = $GLOBALS['egw']->datetime->day_of_week($year,$holiday['month'],$day); - // This now calulates Observed holidays and creates a new entry for them. - if($dow == 0) - { - $addcnt = count($holidays) + 1; - $holidays[$addcnt]['locale'] = $holiday['locale']; - $holidays[$addcnt]['name'] = lang('overlap holiday'); - $holidays[$addcnt]['day'] = $day + 1; - $holidays[$addcnt]['month'] = $holiday['month']; - $holidays[$addcnt]['occurence'] = $holiday['occurence']; - $holidays[$addcnt]['dow'] = $holiday['dow']; - $holidays[$addcnt]['date'] = mktime(0,0,0,$holiday['month'],$day+1,$year); - $holidays[$addcnt]['observance_rule'] = 0; - } - } - - $date = mktime(0,0,0,$holiday['month'],$day,$year); - - return $date; - } - } -?> diff --git a/calendar/inc/class.holidaycalc_US.inc.php b/calendar/inc/class.holidaycalc_US.inc.php deleted file mode 100755 index c7c0c1afa7..0000000000 --- a/calendar/inc/class.holidaycalc_US.inc.php +++ /dev/null @@ -1,111 +0,0 @@ - * - * http://www.itheart.com * - * -------------------------------------------- * - * This program is free software; you can redistribute it and/or modify it * - * under the terms of the GNU General Public License as published by the * - * Free Software Foundation; either version 2 of the License, or (at your * - * option) any later version. * - \**************************************************************************/ - - /* $Id$ */ - - /** - * Calculations for calendar US and other holidays - * - * @package calendar - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - */ - class holidaycalc - { - function add($holiday,&$holidays,$year,$day_offset=0) - { - if ($day_offset) - { - $holiday['name'] .= ' (Observed)'; - } - $holiday['date'] = mktime(0,0,0,$holiday['month'],$holiday['day']+$day_offset,$year); - foreach(array('day'=>'d','month'=>'m','occurence'=>'Y') as $key => $frmt) - { - $holiday[$key] = date($frmt,$holiday['date']); - } - $holiday['obervance_rule'] = 0; - - $holidays[]= $holiday; - - //echo "

holidaycalc::add(,,$year,,$day_offset)=".print_r($holiday,True)."

"; - } - - function calculate_date($holiday, &$holidays, $year) - { - //echo "

holidaycalc::calculate_date(".print_r($holiday,True).",,$year,)

"; - - if($holiday['day'] == 0 && $holiday['occurence'] != 0) - { - if($holiday['occurence'] != 99) - { - $dow = $GLOBALS['egw']->datetime->day_of_week($year,$holiday['month'],1); - $day = (((7 * $holiday['occurence']) - 6) + ((($holiday['dow'] + 7) - $dow) % 7)); - $day += ($day < 1 ? 7 : 0); - - // Sometimes the 5th occurance of a weekday (ie the 5th monday) - // can spill over to the next month. This prevents that. - $ld = $GLOBALS['egw']->datetime->days_in_month($holiday['month'],$year); - if ($day > $ld) - { - return; - } - } - else - { - $ld = $GLOBALS['egw']->datetime->days_in_month($holiday['month'],$year); - $dow = $GLOBALS['egw']->datetime->day_of_week($year,$holiday['month'],$ld); - $day = $ld - (($dow + 7) - $holiday['dow']) % 7 ; - } - } - else - { - $day = $holiday['day']; - if($holiday['observance_rule'] == True) - { - $dow = $GLOBALS['egw']->datetime->day_of_week($year,$holiday['month'],$day); - // This now calulates Observed holidays and creates a new entry for them. - - // 0 = sundays are observed on monday (+1), 6 = saturdays are observed on fridays (-1) - if($dow == 0 || $dow == 6) - { - $this->add($holiday,$holidays,$year,$dow == 0 ? 1 : -1); - } - if ($holiday['month'] == 1 && $day == 1) - { - $dow = $GLOBALS['egw']->datetime->day_of_week($year+1,$holiday['month'],$day); - // checking if next year's newyear might be observed in this year - if ($dow == 6) - { - $this->add($holiday,$holidays,$year+1,-1); - } - // add the next years newyear, to show it in a week- or month-view - $this->add($holiday,$holidays,$year+1); - } - // checking if last year's new year's eve might be observed in this year - if ($holiday['month'] == 12 && $day == 31) - { - $dow = $GLOBALS['egw']->datetime->day_of_week($year-1,$holiday['month'],$day); - if ($dow == 0) - { - $this->add($holiday,$holidays,$year-1,1); - } - // add the last years new year's eve, to show it in a week- or month-view - $this->add($holiday,$holidays,$year-1); - } - } - } - $date = mktime(0,0,0,$holiday['month'],$day,$year); - - return $date; - } - } -?> diff --git a/calendar/inc/class.sbox.inc.php b/calendar/inc/class.sbox.inc.php deleted file mode 100644 index 477e53c166..0000000000 --- a/calendar/inc/class.sbox.inc.php +++ /dev/null @@ -1,395 +0,0 @@ - * - * Class for creating predefines select boxes * - * Copyright (C) 2000, 2001 Dan Kuykendall * - * -------------------------------------------------------------------------* - * This library is part of the eGroupWare API * - * ------------------------------------------------------------------------ * - * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - \**************************************************************************/ - /* $Id: class.sbox.inc.php 15449 2004-06-15 08:16:07Z ralfbecker $ */ - - class sbox - { - var $monthnames = array( - '', - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December' - ); - - var $weekdays = array( - '', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - 'Sunday' - ); - - function sbox() - { - if (!$this->country_array) - { - $this->country_array = EGroupware\Api\Country::countries(true); - } - } - - function hour_formated_text($name, $selected = 0) - { - $s = '"; - - return $s; - } - - function hour_text($name, $selected = 0) - { - $s = '"; - - return $s; - } - - // I would like to add a increment feature - function sec_minute_text($name, $selected = 0) - { - $s = '"; - return $s; - } - - function ap_text($name,$selected) - { - $selected = strtolower($selected); - $t[$selected] = " selected"; - $s = ''; - return $s; - } - - function full_time($hour_name,$hour_selected,$min_name,$min_selected,$sec_name,$sec_selected,$ap_name,$ap_selected) - { - // This needs to be changed to support there time format preferences - $s = $this->hour_text($hour_name,$hour_selected) - . $this->sec_minute_text($min_name,$min_selected) - . $this->sec_minute_text($sec_name,$sec_selected) - . $this->ap_text($ap_name,$ap_selected); - return $s; - } - - function getWeekdays($name, $selected=0) - { - $out = ''; - for($i=0;$iweekdays);$i++) - { - $out .= ''."\n"; - } - return ''."\n"; - } - - function nr2weekday($selected = 0) - { - for($i=0;$iweekdays);$i++) - { - if ($selected > 0 && $selected == $i) - { - return lang($this->weekdays[$i]); - } - } - } - - function getMonthText($name, $selected=0) - { - $out = ''; - $c_monthnames = count($this->monthnames); - for($i=0;$i<$c_monthnames;$i++) - { - $out .= ''."\n"; - } - return ''."\n"; - } - - function getDays($name, $selected=0) - { - $out = ''; - - for($i=0;$i<32;$i++) - { - $out .= ''."\n"; - } - return ''."\n"; - } - - function getYears($name, $selected = 0, $startYear = 0, $endyear = 0) - { - if (!$startYear) - { - $startYear = date('Y') - 5; - } - if ($selected && $startYear > $selected) $startYear = $selected; - - if (!$endyear) - { - $endyear = date('Y') + 6; - } - if ($selected && $endYear < $selected) $endYear = $selected; - - $out = ''."\n"; - - return $out; - } - - function getPercentage($name, $selected=0) - { - $out = "\n"; - - for(reset($arr);current($arr);next($arr)) - { - $out .= '