| Server IP : 180.180.241.3 / Your IP : 216.73.216.35 Web Server : Microsoft-IIS/7.5 System : Windows NT NETWORK-NHRC 6.1 build 7601 (Windows Server 2008 R2 Standard Edition Service Pack 1) i586 User : IUSR ( 0) PHP Version : 5.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/AppServ/www/news/components/com_jevents/libraries/ |
Upload File : |
<?php
/**
* JEvents Component for Joomla 1.5.x
*
* @version $Id: iCalRRule.php 1400 2009-03-30 08:45:17Z geraint $
* @package JEvents
* @copyright Copyright (C) 2008-2009 GWE Systems Ltd, 2006-2008 JEvents Project Group
* @license GNU/GPLv2, see http://www.gnu.org/licenses/gpl-2.0.html
* @link http://www.jevents.net
*/
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
class iCalRRule extends JTable {
/** @var int Primary key */
var $rr_id = null;
/**
* This holds the raw data as an array
*
* @var array
*/
var $data;
var $freq;
// array of exception dates
var $_exdate = array();
/**
* Null Constructor
*/
function iCalRRule( &$db ) {
parent::__construct( '#__jevents_rrule', 'rr_id', $db );
}
/**
* Pseudo Constructor
*
* @param iCal Entry parsed from ICS file as an array $ice
* @return n/a
*/
function iCalRRuleFromDB($icalrowAsArray){
$db =& JFactory::getDBO();
$temp = new iCalRRule($db);
$temp->data = $icalrowAsArray;
// Should really test count
$temp->processField2("freq","YEARLY");
$temp->processField2("count",999999);
$temp->processField2("rinterval",1);
//interval ios a mysql reserved word
$temp->_interval = $temp->rinterval;
$temp->processField2("until","");
$temp->processField2("untilraw","");
$temp->processField2("bysecond","");
$temp->processField2("byminute","");
$temp->processField2("byhour","");
$temp->processField2("byday","");
$temp->processField2("bymonthday","");
$temp->processField2("byyearday","");
$temp->processField2("byweekno","");
$temp->processField2("bymonth","");
$temp->processField2("bysetpos","");
$temp->processField2("wkst","");
return $temp;
}
function processField2($field,$default){
$this->$field = array_key_exists(strtolower($field),$this->data)?$this->data[strtolower($field)]:$default;
}
/**
* Pseudo Constructor
*
* @param iCal Entry parsed from ICS file as an array $ice
* @return n/a
*/
function iCalRRuleFromData($rrule){
$db =& JFactory::getDBO();
$temp = new iCalRRule($db);
$temp->data = $rrule;
$temp->freq = $temp->data['FREQ'];
// Should really test count
$temp->processField("count",99999);
$temp->processField("interval",1);
//interval ios a mysql reserved word
$temp->rinterval = $temp->interval;
$temp->_interval = $temp->interval;
unset($temp->interval);
$temp->processField("until","");
$temp->processField("untilraw","");
$temp->processField("bysecond","");
$temp->processField("byminute","");
$temp->processField("byhour","");
$temp->processField("byday","");
$temp->processField("bymonthday","");
$temp->processField("byyearday","");
$temp->processField("byweekno","");
$temp->processField("bymonth","");
$temp->processField("bysetpos","");
$temp->processField("wkst","");
return $temp;
}
function processField($field,$default){
$this->$field = array_key_exists(strtoupper($field),$this->data)?$this->data[strtoupper($field)]:$default;
}
/**
* Creates a repeat if not an exception date returns 1 anyway
*
* @param unknown_type $start
* @param unknown_type $end
* @return unknown
*/
function _makeRepeat($start,$end){
if (!isset($this->_repetitions)) $this->_repetitions = array();
$db =& JFactory::getDBO();
$repeat = new iCalRepetition($db);
$repeat->eventid = $this->eventid;
// TODO CHECK THIS logic
$repeat->startrepeat = strftime('%Y-%m-%d %H:%M:%S',$start);
// iCal for whole day uses 00:00:00 on the next day JEvents uses 23:59:59 on the same day
list ($h,$m,$s) = explode(":",strftime("%H:%M:%S",$end));
if (($h+$m+$s)==0) {
// $repeat->endrepeat = strftime('%Y-%m-%d 23:59:59',($end-86400));
$repeat->endrepeat = strftime('%Y-%m-%d 23:59:59',$end);
}
else {
$repeat->endrepeat = strftime('%Y-%m-%d %H:%M:%S',$end);
}
$repeat->duplicatecheck = md5($repeat->eventid . $start );
// Double check its not in the list of exception dates
foreach ($this->_exdate as $exdate) {
// compare based on YYYYMMDD since exceptions are(normally) whole day, "EXDATE;VALUE=DATE"
if (strftime('%Y%m%d', $exdate) == strftime('%Y%m%d', $start)) {
// return 0;
// exceptions count
return 1;
}
}
$this->_repetitions[] = $repeat;
return 1;
}
function _afterUntil($testDate){
if (strlen($this->until)==0) return false;
if (!isset($this->_untilMidnight)) {
list ($d,$m,$y) = explode(":",strftime("%d:%m:%Y",$this->until));
$this->_untilMidnight = mktime(23,59,59,$m,$d,$y);
}
if (strlen($this->until)>0 && $testDate>intval($this->_untilMidnight)) {
return true;
}
else return false;
}
/**
* sort the by days string for negative values so that we start at the beginning of the month/start date
*
* @param unknown_type $days
* @param unknown_type $currentMonthStart
* @param unknown_type $dtstart
*/
function sortByDays(&$days,$currentMonthStart,$dtstart){
if (count($days)==0) return;
// only sort negative values
if (strpos($days[0],"-")===false) return;
static $weekdayMap=array("SU"=>0,"MO"=>1,"TU"=>2,"WE"=>3,"TH"=>4,"FR"=>5,"SA"=>6);
static $weekdayReverseMap=array("SU","MO","TU","WE","TH","FR","SA");
list ($currentMonth,$currentYear) = explode(":",strftime("%m:%Y",$currentMonthStart));
list ($startMonth,$startYear) = explode(":",strftime("%m:%Y",$dtstart));
if ($startMonth==$currentMonth && $startYear==$currentYear){
$startdate = $dtstart;
}
else {
$startdate = $currentMonthStart;
}
$startWD = strftime("%w",$startdate);
$sorteddays = array();
// start from week -6 and go forward (overkill I know)
for ($w=-6;$w<0;$w++){
// now loop over the week starting at the appropriate day fo the week
for ($i=0;$i<7;$i++){
$wd = ($startWD+$i)%7;
$check = strval($w).$weekdayReverseMap[$wd];
if (in_array($check,$days)) $sorteddays[]=$check;
}
}
$days = $sorteddays;
}
/**
* Technically this is very complicated
* see http://www.w3.org/2002/12/cal/rfc2445 ad search for "BYxxx rule parts modify the recurrence in some manner"
*
* Priority to 'analysis' should therefore be (??)
*
* FREQ=YEARLY
* BYMONTH
* BYWEEKNO
* BYYEARDAY
* FREQ=MONTHLY ??
* BYMONTHDAY
* FREQ=WEEKLY ??
* BYDAY
* FREQ=DAILY ??
* BYHOUR, BYMINUTE, BYSECOND
* BYSETPOS
*
* INTERVAL always applies to FREQ
*
* So if I go over step in freq units adding the BYMONTH to YEARLY etc.
* then restricting DAILY with BYMONTH (do an excessive loop in this situation and test if the rules hols
* until I get some better logic)
*/
/**
* Generates repetition from vevent & rrule data from scratch
* The result can then be saved to the database
*/
function getRepetitions($dtstart,$dtend,$duration,$recreate=false,$exdate=array()) {
// put exdate into somewhere that I can get from _makerepeat
$this->_exdate = $exdate;
echo "getRepetitions doesnt yet deal with Short months and 31st or leap years/week 53<br/>";
if ($dtend==0 && $duration>0){
$dtend=$dtstart+$duration;
}
if (!$recreate && isset($this->_repetitions)) return $this->_repetitions;
$this->_repetitions = array();
if (!isset($this->eventid)) {
echo "no eventid set in generateRepetitions<br/>";
return $this->_repetitions;
}
if ($this->count==1){
echo "count=1 returing<br/>";
$this->_makeRepeat($dtstart,$dtend);
return $this->_repetitions;
}
//list ($h,$min,$s,$d,$m,$y) = explode(":",strftime("%H:%M:%S:%d:%m:%Y",$end));
list ($startHour,$startMin,$startSecond,$startDay,$startMonth,$startYear,$startWD)
= explode(":",strftime("0%H:0%M:0%S:%d:%m:%Y:%w",$dtstart));
echo "$startHour,$startMin,$startSecond,$startDay,$startMonth,$startYear,$startWD,$dtstart<br/>";
$dtstartMidnight = mktime(0,0,0,$startMonth,$startDay,$startYear);
list ($endDay,$endMonth,$endYear,$endWD) = explode(":",strftime("%d:%m:%Y:%w",$dtend));
$duration = $dtend-$dtstart;
static $weekdayMap=array("SU"=>0,"MO"=>1,"TU"=>2,"WE"=>3,"TH"=>4,"FR"=>5,"SA"=>6);
static $weekdayReverseMap=array("SU","MO","TU","WE","TH","FR","SA");
static $dailySecs = 86400;
static $weeklySecs = 604800;
// TODO implement byyearday
// TODO do full leap year audit e.g. YEARLY repeats
echo "freq = ".$this->freq."<br/>";
switch ($this->freq) {
case "YEARLY":
// TODO the code doesn't yet deal with multiple bymonths
if ($this->bymonth=="") $this->bymonth=$startMonth;
//if ($this->byday=="") $this->byday=$weekdayReverseMap[$startWD];
// If I have byday and bymonthday then the two considions must be met
$weekdays = array();
if ($this->byday!=""){
foreach (explode(",",$this->byday) as $bday) {
$weekdays[]=$weekdayMap[$bday];
}
}
if ($this->byyearday!=""){
echo "byyearday <br/>";
$days = explode(",",$this->byyearday);
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
$currentYearStart = mktime(0,0,0,1,1,$startYear);
// do the current month first
while ($countRepeats < $this->count && !$this->_afterUntil($currentYearStart)) {
$currentYear = strftime("%Y",$currentYearStart);
$currentYearDays = date("L",$currentYearStart)?366:365;
foreach ($days as $day) {
if ($countRepeats >= $this->count || $this->_afterUntil($start)) return $this->_repetitions;
// TODO I am assuming all + or all -ve
$details=array();
preg_match("/(\+|-?)(\d*)/",$day,$details);
list($temp,$plusminus,$daynumber) = $details;
if (strlen($plusminus)==0) $plusminus="+";
// do not go over year end
if ($daynumber>$currentYearDays) continue;
if ($plusminus=="+"){
$targetStart = mktime($startHour,$startMin,$startSecond,12,31,$currentYear-1);
$targetStart = strtotime("+$daynumber days",$targetStart);
}
else {
$targetStart = mktime($startHour,$startMin,$startSecond,1,1,$currentYear+1);
$targetStart = strtotime("-$daynumber days",$targetStart);
}
$targetEnd = $targetStart+$duration;
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
// double check for byday constraints
if ($this->byday!=""){
if (!in_array(strftime("%w",$targetStart),$weekdays)){
continue;
}
}
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
}
}
// now ago to the start of next year
if ($currentYear+$this->rinterval>2036) return $this->_repetitions;
$currentYearStart = mktime(0,0,0,1,1,$currentYear+$this->rinterval);
}
}
// assume for now that its an anniversary of the start month only!
// TODO relzs this assumption !!
else if ($this->bymonthday!="") {
echo "bymonthday".$this->bymonthday." <br/>";
$days = explode(",",$this->bymonthday);
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
$currentMonthStart = mktime(0,0,0,$startMonth,1,$startYear);
// do the current month first
while ($countRepeats < $this->count && !$this->_afterUntil($currentMonthStart)) {
list ($currentMonth,$currentYear) = explode(":",strftime("%m:%Y",$currentMonthStart));
$currentMonthDays = date("t",$currentMonthStart);
foreach ($days as $day) {
if ($countRepeats >= $this->count || $this->_afterUntil($start)) return $this->_repetitions;
// Assume no negative bymonthday values
// TODO relax this assumption
// do not go over month end
if ($day>$currentMonthDays) continue;
$targetStart = mktime($startHour,$startMin,$startSecond,$currentMonth,$day,$currentYear);
$targetEnd = $targetStart+$duration;
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
// double check for byday constraints
if ($this->byday!=""){
if (!in_array(strftime("%w",$targetStart),$weekdays)){
continue;
}
}
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
}
}
// now ago to the start of next month
if ($currentYear+$this->rinterval>2036) return $this->_repetitions;
$currentMonthStart = mktime(0,0,0,$currentMonth,1,$currentYear+$this->rinterval);
}
}
// annual repeats of the start date - TODO check this
else if ($this->byday=="") {
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
while ($countRepeats < $this->count && !$this->_afterUntil($start)) {
$countRepeats+=$this->_makeRepeat($start,$end);
$currentYear = strftime("%Y",$start);
list ($h,$min,$s,$d,$m,$y) = explode(":",strftime("%H:%M:%S:%d:%m:%Y",$start));
if (($currentYear+$this->rinterval)>=2037) break;
$start = strtotime("+".$this->rinterval." years",$start);
$end = strtotime("+".$this->rinterval." years",$end);
}
}
else {
$days = explode(",",$this->byday);
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
// do the current month first
while ($countRepeats < $this->count && !$this->_afterUntil($start)) {
$currentMonth = strftime("%m",$start);
foreach ($days as $day) {
if ($countRepeats >= $this->count || $this->_afterUntil($start)) {
return $this->_repetitions;
}
$details=array();
preg_match("/(\+|-?)(\d?)(.+)/",$day,$details);
if (count($details)!=4) {
echo "<br/><br/><b>PROBLEMS with $day</b><br/><br/>";
return $this->_repetitions;
}
else {
list($temp,$plusminus,$weeknumber,$dayname) = $details;
if (strlen($plusminus)==0) $plusminus="+";
if (strlen($weeknumber)==0) $weeknumber=1;
// always check for dtstart (nothing is allowed earlier)
if ($plusminus=="-") {
//echo "count back $weeknumber weeks on $dayname<br/>";
list ($startDay,$startMonth,$startYear,$startWD) = explode(":",strftime("%d:%m:%Y:%w",$start));
$startLast = date("t",$start);
$monthEnd = mktime(0,0,0,$startMonth,$startLast,$startYear);
$meWD = strftime("%w",$monthEnd );
$adjustment = $startLast - (7+$meWD-$weekdayMap[$dayname])%7;
$targetstartDay = $adjustment - ($weeknumber-1)*7;
$targetendDay = $targetstartDay + $endDay-$startDay;
list ($h,$min,$s,$d,$m,$y) = explode(":",strftime("%H:%M:%S:%d:%m:%Y",$start));
$testStart = mktime($h,$min,$s,$m,$targetstartDay,$y);
if ($currentMonth==strftime("%m",$testStart)){
$targetStart = $testStart;
$targetEnd = $targetStart + $duration;
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
}
}
}
else {
//echo "count forward $weeknumber weeks on $dayname<br/>";
list ($startDay,$startMonth,$startYear,$startWD) = explode(":",strftime("%d:%m:%Y:%w",$start));
$monthStart = mktime(0,0,0,$startMonth,1,$startYear);
$msWD = strftime("%w",$monthStart );
$adjustment = 1 + (7+$weekdayMap[$dayname]-$msWD)%7;
$targetstartDay = $adjustment+($weeknumber-1)*7;
$targetendDay = $targetstartDay + $endDay-$startDay;
list ($h,$min,$s,$d,$m,$y) = explode(":",strftime("%H:%M:%S:%d:%m:%Y",$start));
$testStart = mktime($h,$min,$s,$m,$targetstartDay,$y);
if ($currentMonth==strftime("%m",$testStart)){
$targetStart = $testStart;
$targetEnd = $targetStart + $duration;
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
}
}
}
}
}
// now ago to the start of the next month
$start = $targetStart;
$end = $targetEnd;
list ($h,$min,$s,$d,$m,$y) = explode(":",strftime("%H:%M:%S:%d:%m:%Y",$start));
if (($y+$this->rinterval+$m/12)>2036) return $this->_repetitions;
$start = mktime($h,$min,$s,$m,1,$y+$this->rinterval);
$end = $start + $duration;
}
}
return $this->_repetitions;
break;
case "MONTHLY":
if ($this->bymonthday=="" && $this->byday==""){
$this->bymonthday=$startDay;
}
if ($this->bymonthday!="") {
echo "bymonthday".$this->bymonthday." <br/>";
// if not byday then by monthday
$days = explode(",",$this->bymonthday);
// If I have byday and bymonthday then the two considions must be met
$weekdays = array();
if ($this->byday!=""){
foreach (explode(",",$this->byday) as $bday) {
$weekdays[]=$weekdayMap[$bday];
}
}
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
$currentMonthStart = mktime(0,0,0,$startMonth,1,$startYear);
// do the current month first
while ($countRepeats < $this->count && !$this->_afterUntil($currentMonthStart)) {
echo $countRepeats ." ".$this->count." ".$currentMonthStart."<br/>";
list ($currentMonth,$currentYear) = explode(":",strftime("%m:%Y",$currentMonthStart));
$currentMonthDays = date("t",$currentMonthStart);
foreach ($days as $day) {
if ($countRepeats >= $this->count || $this->_afterUntil($start)) return $this->_repetitions;
$details=array();
preg_match("/(\+|-?)(\d+)/",$day,$details);
if (count($details)!=3) {
echo "<br/><br/><b>PROBLEMS with $day</b><br/><br/>";
return $this->_repetitions;
}
else {
list($temp,$plusminus,$daynumber) = $details;
if (strlen($plusminus)==0) $plusminus="+";
if (strlen($daynumber)==0) $daynumber=$startDay;
// always check for dtstart (nothing is allowed earlier)
if ($plusminus=="-") {
// must not go before start of month etc.
if ($daynumber>$currentMonthDays) continue;
echo "I need to check negative bymonth days <br/>";
$targetStart = mktime($startHour,$startMin,$startSecond,$currentMonth,$currentMonthDays+1-$daynumber,$currentYear);
$targetEnd = $targetStart+$duration;
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
}
}
else {
echo "$daynumber $currentMonthDays bd=".$this->byday." <br/>";
// must not go over end month etc.
if ($daynumber>$currentMonthDays) continue;
echo "$startHour,$startMin,$startSecond,$currentMonth,$daynumber,$currentYear<br/>";
$targetStart = mktime($startHour,$startMin,$startSecond,$currentMonth,$daynumber,$currentYear);
$targetEnd = $targetStart+$duration;
echo "$targetStart $targetEnd $dtstartMidnight<br/>";
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
// double check for byday constraints
if ($this->byday!=""){
if (!in_array(strftime("%w",$targetStart),$weekdays)){
continue;
}
}
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
echo "countrepeats = $countRepeats<br/>";
}
}
}
}
// now ago to the start of next month
if (($currentYear+($currentMonth+$this->rinterval)/12)>2036) return $this->_repetitions;
$currentMonthStart = mktime(0,0,0,$currentMonth+$this->rinterval,1,$currentYear);
}
}
// This is byday
else {
$days = explode(",",$this->byday);
// TODO I should also iterate over week number if this is used
//$weeknumbers = explode(",",$this->byweekno);
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
$currentMonthStart = mktime(0,0,0,$startMonth,1,$startYear);
// do the current month first
while ($countRepeats < $this->count && !$this->_afterUntil($currentMonthStart)) {
list ($currentMonth,$currentYear,$currentMonthStartWD) = explode(":",strftime("%m:%Y:%w",$currentMonthStart));
$currentMonthDays = date("t",$currentMonthStart);
$this->sortByDays($days,$currentMonthStart,$dtstart);
foreach ($days as $day) {
if ($countRepeats >= $this->count || $this->_afterUntil($start)) {
return $this->_repetitions;
}
$details=array();
preg_match("/(\+|-?)(\d?)(.+)/",$day,$details);
if (count($details)!=4) {
echo "<br/><br/><b>PROBLEMS with $day</b><br/><br/>";
return $this->_repetitions;
}
else {
list($temp,$plusminus,$weeknumber,$dayname) = $details;
if (strlen($plusminus)==0) $plusminus="+";
if (strlen($weeknumber)==0) $weeknumber=1;
$multiplier = $plusminus=="+"?1:-1;
// always check for dtstart (nothing is allowed earlier)
if ($plusminus=="-") {
//echo "count back $weeknumber weeks on $dayname<br/>";
$startLast = date("t",$currentMonthStart);
$currentMonthEndWD = ($startLast - 1 + $currentMonthStartWD)%7;
$adjustment = $startLast - (7+$currentMonthEndWD-$weekdayMap[$dayname])%7;
$targetstartDay = $adjustment - ($weeknumber-1)*7;
}
else {
//echo "count forward $weeknumber weeks on $dayname<br/>";
$adjustment = 1 + (7+$weekdayMap[$dayname]-$currentMonthStartWD)%7;
$targetstartDay = $adjustment+($weeknumber-1)*7;
}
$targetStart = mktime($startHour,$startMin,$startSecond,$currentMonth,$targetstartDay,$currentYear);
if ($currentMonth==strftime("%m",$targetStart)){
$targetEnd = $targetStart + $duration;
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
}
}
}
}
// now go to the start of next month
if (($currentYear+($currentMonth+$this->rinterval)/12)>2036) return $this->_repetitions;
$currentMonthStart = mktime(0,0,0,$currentMonth+$this->rinterval,1,$currentYear);
}
}
return $this->_repetitions;
break;
case "WEEKLY":
$days = explode(",",$this->byday);
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
$currentWeekDay = strftime("%w",$start);
// Go to the zero day of the first week (even if this is in the past)
// this will be the base from which we count the weeks and weekdays
$currentWeekStart = strtotime("-$currentWeekDay days",$start);
while ($countRepeats < $this->count && !$this->_afterUntil($currentWeekStart)) {
list ($currentDay,$currentMonth,$currentYear) = explode(":",strftime("%d:%m:%Y",$currentWeekStart));
foreach ($days as $day) {
if ($countRepeats >= $this->count || $this->_afterUntil($start)) {
return $this->_repetitions;
}
$details=array();
preg_match("/(\+|-?)(\d?)(.+)/",$day,$details);
if (count($details)!=4) {
echo "<br/><br/><b>PROBLEMS with $day</b><br/><br/>";
return $this->_repetitions;
}
else {
list($temp,$plusminus,$daynumber,$dayname) = $details;
if (strlen($plusminus)==0) $plusminus="+";
// this is not relevant for weekly recurrence ?!?!?
//if (strlen($daynumber)==0) $daynumber=1;
$multiplier = $plusminus=="+"?1:-1;
if ($plusminus=="-") {
// TODO find out if I ever have this situation?
// It would seem meaningless
}
else {
//echo "count forward $daynumber days on $dayname<br/>";
$targetstartDay = $currentDay+$weekdayMap[$dayname];
}
$targetStart = mktime($startHour,$startMin,$startSecond,$currentMonth,$targetstartDay,$currentYear);
$targetEnd = $targetStart + $duration;
if ($countRepeats >= $this->count) {
return $this->_repetitions;
}
if ($targetStart>=$dtstartMidnight && !$this->_afterUntil($targetStart)){
$countRepeats+=$this->_makeRepeat($targetStart,$targetEnd);
}
}
}
// now go to the start of next week
if ($currentYear+($currentMonth/12)>2036) return $this->_repetitions;
$currentWeekStart = strtotime("+".($this->rinterval)." weeks",$currentWeekStart);
}
return $this->_repetitions;
break;
case "DAILY":
$start = $dtstart;
$end = $dtend;
$countRepeats = 0;
$startYear = strftime("%Y",$start);
while ($startYear<2027 && $countRepeats < $this->count && !$this->_afterUntil($start)) {
$countRepeats+=$this->_makeRepeat($start,$end);
$start = strtotime("+".$this->rinterval." days",$start);
$end = strtotime("+".$this->rinterval." days",$end);
$startYear = strftime("%Y",$start);
}
return $this->_repetitions;
break;
default:
echo "UNKNOWN TYPE<br/>";
return $this->_repetitions;
break;
}
}
function dumpData(){
echo "Freq : $this->freq <br/>";
echo "Interval : ".$this->data['INTERVAL']."<br/>";
switch ($this->freq) {
case "YEARLY":
echo "By Month : ".$this->data['BYMONTH']."<br/>";
break;
case "MONTHLY":
echo "By Day : ".$this->data['BYDAY']."<br/>";
$days = explode(",",$this->data['BYDAY']);
foreach ($days as $day) {
$details=array();
preg_match("/(\+|-?)(\d?)(.+)/",$day,$details);
if (count($details)!=4) echo "<br/><br/><b>PROBLEMS with $day</b><br/><br/>";
else {
if (strlen($details[1])==0) $details[1]="+";
echo "Event repeat details<br/>";
if ($details[1]=="-") echo "count back $details[2] weeks on $details[3]<br/>";
else echo "count forward $details[2] weeks on $details[3]<br/>";
// Note if no number given then EVERY specified day!!
}
}
break;
case "WEEKLY":
echo "By Day : ".$this->data['BYDAY']."<br/>";
$days = explode(",",$this->data['BYDAY']);
foreach ($days as $day) {
$details=array();
preg_match("/(\+|-?)(\d?)(.+)/",$day,$details);
if (count($details)!=4) echo "<br/><br/><b>PROBLEMS with $day</b><br/><br/>";
else {
if (strlen($details[1])==0) $details[1]="+";
echo "Event repeat details<br/>";
if ($details[1]=="-") echo "count back $details[2] weeks on $details[3]<br/>";
else echo "count forward $details[2] weeks on $details[3]<br/>";
// Note if no number given then EVERY specified day!!
}
}
break;
default:
echo "UNKNOWN TYPE<br/>";
break;
}
// Doesnt yet deal with INTERVAL, UNTIL or COUNT
print_r($this->data);
echo "<hr/>";
}
function checkDate($test, $start, $end){
if ($test>=$start && $test<=$end) return true;
else return false;
}
function eventInPeriod($startDate,$endDate, $start, $end){
// stupid verison to start that scans through EVERY single day!!!
$checkDate = $startDate;
while ($checkDate<=$endDate){
if ($this->checkDate($checkDate,$start,$end)) return true;
$checkDate+=24*60*60;
}
return false;
}
function isDuplicate(){
$sql = "SELECT rr_id from #__jevents_rrule as rr WHERE rr.eventid = '".$this->eventid."'";
$this->_db->setQuery($sql);
$matches = $this->_db->loadObjectList();
if (count($matches)>0 && isset($matches[0]->rr_id)) {
return $matches[0]->rr_id;
}
return false;
}
}