New: [ task #187 ] Gerer les evenement recurrents dans les imports ical

This commit is contained in:
Laurent Destailleur 2012-01-22 02:12:11 +01:00
parent ed22c802cd
commit fb89b061ba
5 changed files with 211 additions and 89 deletions

View File

@ -24,6 +24,7 @@ For users:
- New: task #10606 : more comprehensive message error.
- New: task #11278 : Option into point of sale module to add services in list.
- New: task #11261 : Add an entry into menu called "New shipment".
- New: [ task #187 ] Gerer les evenement recurrents dans les imports ical
- New: Make option MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT available by default.
- New: Can build PDF in USLetter format or canada format (change paper size).
- New: Can export into Excel 2007 format.

View File

@ -155,11 +155,11 @@ class ical
}
/**
* Add to $this->ical array one value and key. Type is VTODO, VEVENT, VFREEBUSY, VCALENDAR ... .
* Add to $this->ical array one value and key.
*
* @param string $type Type
* @param string $key Key
* @param string $value Value
* @param string $type Type ('VTODO', 'VEVENT', 'VFREEBUSY', 'VCALENDAR'...)
* @param string $key Key ('DTSTART', ...). Note: Field is never 'DTSTART;TZID=...' because ';...' was before removed and added as another property
* @param string $value Value
* @return void
*/
function add_to_array($type, $key, $value)

View File

@ -42,9 +42,9 @@ $showbirthday = GETPOST("showbirthday","int");
$sortfield = GETPOST("sortfield");
$sortorder = GETPOST("sortorder");
$page = GETPOST("page","int");
if ($page == -1) { $page = 0 ; }
if ($page == -1) { $page = 0; }
$limit = $conf->liste_limit;
$offset = $limit * $page ;
$offset = $limit * $page;
if (! $sortorder) $sortorder="ASC";
if (! $sortfield) $sortfield="a.datec";
@ -73,9 +73,15 @@ $actioncode=GETPOST("actioncode");
$pid=GETPOST("projectid","int")?GETPOST("projectid","int"):0;
$status=GETPOST("status");
$maxprint=GETPOST("maxprint");
if (GETPOST('viewcal')) { $action='show_month'; $day=''; } // View by month
if (GETPOST('viewweek')) { $action='show_week'; $week=($week?$week:date("W")); $day=($day?$day:date("d")); } // View by week
if (GETPOST('viewday')) { $action='show_day'; $day=($day?$day:date("d")); } // View by day
if (GETPOST('viewcal')) {
$action='show_month'; $day='';
} // View by month
if (GETPOST('viewweek')) {
$action='show_week'; $week=($week?$week:date("W")); $day=($day?$day:date("d"));
} // View by week
if (GETPOST('viewday')) {
$action='show_day'; $day=($day?$day:date("d"));
} // View by day
$langs->load("other");
$langs->load("commercial");
@ -491,18 +497,18 @@ $listofextcals=array();
if (empty($conf->global->AGENDA_DISABLE_EXT) && $conf->global->AGENDA_EXT_NB > 0)
{
$i=0;
while($i < $conf->global->AGENDA_EXT_NB)
{
$i++;
$paramkey='AGENDA_EXT_SRC'.$i;
$url=$conf->global->$paramkey;
$paramkey='AGENDA_EXT_NAME'.$i;
$namecal = $conf->global->$paramkey;
$paramkey='AGENDA_EXT_COLOR'.$i;
$colorcal = $conf->global->$paramkey;
if ($url && $namecal) $listofextcals[]=array('src'=>$url,'name'=>$namecal,'color'=>$colorcal);
}
$i=0;
while($i < $conf->global->AGENDA_EXT_NB)
{
$i++;
$paramkey='AGENDA_EXT_SRC'.$i;
$url=$conf->global->$paramkey;
$paramkey='AGENDA_EXT_NAME'.$i;
$namecal = $conf->global->$paramkey;
$paramkey='AGENDA_EXT_COLOR'.$i;
$colorcal = $conf->global->$paramkey;
if ($url && $namecal) $listofextcals[]=array('src'=>$url,'name'=>$namecal,'color'=>$colorcal);
}
}
if (count($listofextcals))
@ -516,38 +522,126 @@ if (count($listofextcals))
//print "url=".$url." namecal=".$namecal." colorcal=".$colorcal;
$ical=new ical();
$ical->parse($url);
// After this $ical->cal['VEVENT'] contains array of events, $ical->cal['DAYLIGHT'] contains daylight info, $ical->cal['STANDARD'] contains non daylight info, ...
//var_dump($ical->cal); exit;
$icalevents=array();
if (is_array($ical->get_event_list())) $icalevents=array_merge($icalevents,$ical->get_event_list());
if (is_array($ical->get_freebusy_list())) $icalevents=array_merge($icalevents,$ical->get_freebusy_list());
if (is_array($ical->get_event_list())) $icalevents=array_merge($icalevents,$ical->get_event_list()); // Add $ical->cal['VEVENT']
if (is_array($ical->get_freebusy_list())) $icalevents=array_merge($icalevents,$ical->get_freebusy_list()); // Add $ical->cal['VFREEBUSY']
if (count($icalevents)>0)
{
// Duplicate all repeatable events into new entries
$moreicalevents=array();
foreach($icalevents as $icalevent)
{
if (is_array($icalevent['RRULE'])) //repeatable event
{
//if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow;
//if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=$lastdaytoshow;
$datecur=$icalevent['DTSTART']['unixtime'];
if ($icalevent['RRULE']['FREQ']=='WEEKLY')
if ($icalevent['DTSTART;VALUE=DATE']) //fullday event
{
$until=dol_stringtotime($icalevent['RRULE']['UNTIL'],1);
$datecurstart=dol_stringtotime($icalevent['DTSTART;VALUE=DATE'],1);
$datecurend=dol_stringtotime($icalevent['DTEND;VALUE=DATE'],1)-1; // We remove one second to get last second of day
}
else if (is_array($icalevent['DTSTART']) && ! empty($icalevent['DTSTART']['unixtime']))
{
$datecurstart=$icalevent['DTSTART']['unixtime'];
$datecurend=$icalevent['DTEND']['unixtime'];
if (! empty($ical->cal['DAYLIGHT']['DTSTART']) && $datecurstart)
{
//var_dump($ical->cal);
$tmpcurstart=$datecurstart;
$tmpcurend=$datecurend;
$tmpdaylightstart=dol_mktime(0,0,0,1,1,1970,1) + (int) $ical->cal['DAYLIGHT']['DTSTART'];
$tmpdaylightend=dol_mktime(0,0,0,1,1,1970,1) + (int) $ical->cal['STANDARD']['DTSTART'];
//var_dump($tmpcurstart);var_dump($tmpcurend); var_dump($ical->cal['DAYLIGHT']['DTSTART']);var_dump($ical->cal['STANDARD']['DTSTART']);
// Edit datecurstart and datecurend
if ($tmpcurstart >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) $datecurstart-=((int) $ical->cal['DAYLIGHT']['TZOFFSETTO'])*36;
else $datecurstart-=((int) $ical->cal['STANDARD']['TZOFFSETTO'])*36;
if ($tmpcurend >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) $datecurend-=((int) $ical->cal['DAYLIGHT']['TZOFFSETTO'])*36;
else $datecurend-=((int) $ical->cal['STANDARD']['TZOFFSETTO'])*36;
}
// datecurstart and datecurend are now GMT date
//var_dump($datecurstart); var_dump($datecurend); exit;
}
else
{
// Not a recongized record
dol_syslog("Found a not recognized repeatable record with unknown date start", LOG_ERR);
continue;
}
//print 'xx'.$datecurstart;exit;
$interval=(empty($icalevent['RRULE']['INTERVAL'])?1:$icalevent['RRULE']['INTERVAL']);
$until=empty($icalevent['RRULE']['UNTIL'])?0:dol_stringtotime($icalevent['RRULE']['UNTIL'],1);
$maxrepeat=empty($icalevent['RRULE']['COUNT'])?0:$icalevent['RRULE']['COUNT'];
if ($until && ($until+($datecurend-$datecurstart)) < $firstdaytoshow) continue; // We discard repeatable event that end before start date to show
if ($datecurstart > $lastdaytoshow) continue; // We discard repeatable event that start after end date to show
$numofevent=0;
while (($datecurstart <= $lastdaytoshow) && (empty($maxrepeat) || ($numofevent < $maxrepeat)))
{
if ($datecurend >= $firstdaytoshow) // We add event
{
$newevent=$icalevent;
unset($newevent['RRULE']);
if ($icalevent['DTSTART;VALUE=DATE'])
{
$newevent['DTSTART;VALUE=DATE']=dol_print_date($datecurstart,'%Y%m%d');
$newevent['DTEND;VALUE=DATE']=dol_print_date($datecurend+1,'%Y%m%d');
}
else
{
$newevent['DTSTART']=$datecurstart;
$newevent['DTEND']=$datecurend;
}
$moreicalevents[]=$newevent;
}
// Jump on next occurence
$numofevent++;
$savdatecurstart=$datecurstart;
if ($icalevent['RRULE']['FREQ']=='DAILY')
{
$datecurstart=dol_time_plus_duree($datecurstart, $interval, 'd');
$datecurend=dol_time_plus_duree($datecurend, $interval, 'd');
}
if ($icalevent['RRULE']['FREQ']=='WEEKLY')
{
$datecurstart=dol_time_plus_duree($datecurstart, $interval, 'w');
$datecurend=dol_time_plus_duree($datecurend, $interval, 'w');
}
elseif ($icalevent['RRULE']['FREQ']=='MONTHLY')
{
$datecurstart=dol_time_plus_duree($datecurstart, $interval, 'm');
$datecurend=dol_time_plus_duree($datecurend, $interval, 'm');
}
elseif ($icalevent['RRULE']['FREQ']=='YEARLY')
{
$datecurstart=dol_time_plus_duree($datecurstart, $interval, 'y');
$datecurend=dol_time_plus_duree($datecurend, $interval, 'y');
}
// Test to avoid infinite loop ($datecurstart must increase)
if ($savdatecurstart >= $datecurstart)
{
dol_syslog("Found a rule freq ".$icalevent['RRULE']['FREQ']." not managed by dolibarr code. Assume 1 week frequency.", LOG_ERR);
$datecurstart+=3600*24*7;
$datecurend+=3600*24*7;
}
}
}
}
$icalevents=array_merge($icalevents,$moreicalevents);
// Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray
foreach($icalevents as $icalevent)
{
//print $icalevent['SUMMARY'].'->'.var_dump($icalevent).'<br>';exit;
if (! empty($icalevent['RRULE'])) continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule.
// Create a new object action
$event=new ActionComm($db);
$addevent = false;
if ($icalevent['DTSTART;VALUE=DATE']) //fullday event
if ($icalevent['DTSTART;VALUE=DATE']) // fullday event
{
// For full day events, date are also GMT but they wont but converted using tz during output
$datestart=dol_stringtotime($icalevent['DTSTART;VALUE=DATE'],1);
@ -557,19 +651,12 @@ if (count($listofextcals))
$event->fulldayevent=true;
$addevent=true;
}
elseif (!is_array($icalevent['DTSTART'])) //non-repeatable and not fullday event DTSTART;TZID=Europe/Paris:20120102T100000
elseif (!is_array($icalevent['DTSTART'])) // not fullday event (DTSTART is not array)
{
$datestart=$icalevent['DTSTART'];
$dateend=$icalevent['DTEND'];
$addevent=true;
}
//elseif (is_array($icalevent['DTSTART']) && ! empty($icalevent['DTSTART']['unixtime']) && ! is_array($icalevent['RRULE']))
elseif (is_array($icalevent['DTSTART']) && ! empty($icalevent['DTSTART']['unixtime']))
{
$datestart=$icalevent['DTSTART']['unixtime'];
$dateend=$icalevent['DTEND']['unixtime'];
$addevent=true;
}
if ($addevent)
{
@ -583,9 +670,9 @@ if (count($listofextcals))
if($icalevent['SUMMARY']) $event->libelle=$icalevent['SUMMARY'];
elseif($icalevent['DESCRIPTION']) $event->libelle=dol_nl2br($icalevent['DESCRIPTION'],1);
else $event->libelle = $langs->trans("ExtSiteNoLabel");
else $event->libelle = $langs->trans("ExtSiteNoLabel");
$event->date_start_in_calendar=$event->datep;
$event->date_start_in_calendar=$event->datep;
if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar=$event->datef;
else $event->date_end_in_calendar=$event->datep;
@ -594,11 +681,15 @@ if (count($listofextcals))
if ($event->date_start_in_calendar == $event->date_end_in_calendar)
{
$event->ponctuel=1;
//print 'x'.$datestart.'-'.$dateend;exit;
}
// Add event into $eventarray if date range are ok.
if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar > $lastdaytoshow)
{
//print 'x'.$datestart.'-'.$dateend;exit;
//print 'x'.$datestart.'-'.$dateend;exit;
//print 'x'.$datestart.'-'.$dateend;exit;
// This record is out of visible range
}
else
@ -618,6 +709,7 @@ if (count($listofextcals))
$daykey=dol_mktime(0,0,0,$mois,$jour,$annee);
$daykeygmt=dol_mktime(0,0,0,$mois,$jour,$annee,true,0,false);
do
//print 'x'.$datestart.'-'.$dateend;exit;
{
//if ($event->fulldayevent) print dol_print_date($daykeygmt,'dayhour','gmt').'-'.dol_print_date($daykey,'dayhour','gmt').'-'.dol_print_date($event->date_end_in_calendar,'dayhour','gmt').' ';
$eventarray[$daykey][]=$event;
@ -796,7 +888,7 @@ else // View by day
$db->close();
/* TODO Export
print '
print '
<a href="" id="actionagenda_ical_link"><img src="'.DOL_URL_ROOT.'/theme/common/ical.gif" border="0"/></a>
<a href="" id="actionagenda_vcal_link"><img src="'.DOL_URL_ROOT.'/theme/common/vcal.gif" border="0"/></a>
<a href="" id="actionagenda_rss_link"><img src="'.DOL_URL_ROOT.'/theme/common/rss.gif" border="0"/></a>
@ -955,10 +1047,10 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa
}
else
{
if ($showinfo)
{
if ($showinfo)
{
print $langs->trans("EventOnFullDay")."<br>\n";
}
}
}
// Show title

View File

@ -31,32 +31,33 @@
*/
function get_tz_array()
{
$tzarray=array( -11=>"Pacific/Midway",
-10=>"Pacific/Fakaofo",
-9=>"America/Anchorage",
-8=>"America/Los_Angeles",
-7=>"America/Dawson_Creek",
-6=>"America/Chicago",
-5=>"America/Bogota",
-4=>"America/Anguilla",
-3=>"America/Araguaina",
-2=>"America/Noronha",
-1=>"Atlantic/Azores",
0=>"Africa/Abidjan",
1=>"Europe/Paris",
2=>"Europe/Helsinki",
3=>"Europe/Moscow",
4=>"Asia/Dubai",
5=>"Asia/Karachi",
6=>"Indian/Chagos",
7=>"Asia/Jakarta",
8=>"Asia/Hong_Kong",
9=>"Asia/Tokyo",
10=>"Australia/Sydney",
11=>"Pacific/Noumea",
12=>"Pacific/Auckland",
13=>"Pacific/Enderbury"
);
$tzarray=array(
-11=>"Pacific/Midway",
-10=>"Pacific/Fakaofo",
-9=>"America/Anchorage",
-8=>"America/Los_Angeles",
-7=>"America/Dawson_Creek",
-6=>"America/Chicago",
-5=>"America/Bogota",
-4=>"America/Anguilla",
-3=>"America/Araguaina",
-2=>"America/Noronha",
-1=>"Atlantic/Azores",
0=>"Africa/Abidjan",
1=>"Europe/Paris",
2=>"Europe/Helsinki",
3=>"Europe/Moscow",
4=>"Asia/Dubai",
5=>"Asia/Karachi",
6=>"Indian/Chagos",
7=>"Asia/Jakarta",
8=>"Asia/Hong_Kong",
9=>"Asia/Tokyo",
10=>"Australia/Sydney",
11=>"Pacific/Noumea",
12=>"Pacific/Auckland",
13=>"Pacific/Enderbury"
);
return $tzarray;
}
@ -78,17 +79,33 @@ function getCurrentTimeZone()
}
/**
* Add a delay of a timezone to a date
*
* @param timestamp $time Date timestamp
* @param string $timezone Timezone
* @return timestamp New timestamp
*/
function dol_time_plus_timezone($time,$timezone)
{
// TODO Finish function
return $time;
}
/**
* Add a delay to a date
*
* @param timestamp $time Date timestamp (or string with format YYYY-MM-DD)
* @param int $duration_value Value of delay to add
* @param int $duration_unit Unit of added delay (d, m, y)
* @param int $duration_unit Unit of added delay (d, m, y, w)
* @return timestamp New timestamp
*/
function dol_time_plus_duree($time,$duration_value,$duration_unit)
{
if ($duration_value == 0) return $time;
if ($duration_value == 0) return $time;
if ($duration_unit == 'w') return $time + (3600*24*7*$duration_value);
if ($duration_value > 0) $deltastring="+".abs($duration_value);
if ($duration_value < 0) $deltastring="-".abs($duration_value);
if ($duration_unit == 'd') { $deltastring.=" day"; }
@ -98,7 +115,7 @@ function dol_time_plus_duree($time,$duration_value,$duration_unit)
}
/** Converti les heures et minutes en secondes
/** Convert hours and minutes into seconds
*
* @param int $iHours Heures
* @param int $iMinutes Minutes
@ -208,13 +225,16 @@ function ConvertSecondToTime($iSecond,$format='all',$lengthOfDay=86400,$lengthOf
* YYYY-MM-DDTHH:MM:SSZ (RFC3339)
* DD/MM/YY or DD/MM/YYYY (this format should not be used anymore)
* DD/MM/YY HH:MM:SS or DD/MM/YYYY HH:MM:SS (this format should not be used anymore)
* @param int $gm 1=Input date is GM date, 0=Input date is local date
* 19700101020000 -> 7200 with gm=1
* @param int $gm 1 =Input date is GM date,
* 0 =Input date is local date using PHP server timezone
* -1=Input date is local date using timezone provided as third parameter
* @param string $tz Timezone to use of $gm=-1
* @return date Date
* 19700101020000 -> 7200 with gm=1
*
* @see dol_print_date, dol_mktime, dol_getdate
*/
function dol_stringtotime($string, $gm=1)
function dol_stringtotime($string, $gm=1, $tz='')
{
// Convert date with format DD/MM/YYY HH:MM:SS. This part of code should not be used.
if (preg_match('/^([0-9]+)\/([0-9]+)\/([0-9]+)\s?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i',$string,$reg))
@ -257,7 +277,12 @@ function dol_stringtotime($string, $gm=1)
$string=preg_replace('/([^0-9])/i','',$string);
$tmp=$string.'000000';
$date=dol_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4),$gm);
$date=dol_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4),($gm?1:0));
if ($gm == -1)
{
// TODO Define offset according to TZ
$date+=0;
}
return $date;
}

View File

@ -825,9 +825,9 @@ function dol_format_address($object)
/**
* Output date in a string format according to outputlangs (or langs if not defined).
* Return charset is always UTF-8, except if encodetoouput is defined. In this cas charset is output charset
* Return charset is always UTF-8, except if encodetoouput is defined. In this case charset is output charset
*
* @param timestamp $time GM Timestamps date (or deprecated strings 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS')
* @param timestamp $time GM Timestamps date
* @param string $format Output date format
* "%d %b %Y",
* "%d/%m/%Y %H:%M",
@ -973,9 +973,12 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e
/**
* Return an array with date info
* Return an array with locale date info.
* PHP getdate is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows
*
* WARNING: This function always use PHP server timezone to return locale informations.
* Usage must be avoid.
*
* @param timestamp $timestamp Timestamp
* @param boolean $fast Fast mode
* @return array Array of informations
@ -1000,6 +1003,7 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e
* 'yday' => floor($secsInYear/$_day_power),
* 'leap' => $leaf,
* 'ndays' => $ndays
* @see dol_print_date, dol_stringtotime, dol_mktime
*/
function dol_getdate($timestamp,$fast=false)
{
@ -1030,17 +1034,17 @@ function dolibarr_mktime($hour,$minute,$second,$month,$day,$year,$gm=false,$chec
* Replace function mktime not available under Windows if year < 1970
* PHP mktime is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows
*
* @param int $hour Hour (can be -1 for undefined)
* @param int $minute Minute (can be -1 for undefined)
* @param int $second Second (can be -1 for undefined)
* @param int $month Month (1 to 12)
* @param int $day Day (1 to 31)
* @param int $year Year
* @param int $gm 1=Input informations are GMT values, otherwise local to server TZ
* @param int $check 0=No check on parameters (Can use day 32, etc...)
* @param int $isdst Dayling saving time
* @return timestamp Date as a timestamp, '' if error
* @see dol_print_date, dol_stringtotime
* @param int $hour Hour (can be -1 for undefined)
* @param int $minute Minute (can be -1 for undefined)
* @param int $second Second (can be -1 for undefined)
* @param int $month Month (1 to 12)
* @param int $day Day (1 to 31)
* @param int $year Year
* @param int $gm 1=Input informations are GMT values, otherwise local to server TZ
* @param int $check 0=No check on parameters (Can use day 32, etc...)
* @param int $isdst Dayling saving time
* @return timestamp Date as a timestamp, '' if error
* @see dol_print_date, dol_stringtotime, dol_getdate
*/
function dol_mktime($hour,$minute,$second,$month,$day,$year,$gm=false,$check=1,$isdst=true)
{