326 lines
12 KiB
Diff
326 lines
12 KiB
Diff
|
--- Date/Recurrence.php.orig 2012-07-10 19:54:48.000000000 +0200
|
||
|
+++ Date/Recurrence.php 2012-07-10 19:55:38.000000000 +0200
|
||
|
@@ -95,6 +95,20 @@
|
||
|
public $recurData = null;
|
||
|
|
||
|
/**
|
||
|
+ * BYDAY recurrence number
|
||
|
+ *
|
||
|
+ * @var integer
|
||
|
+ */
|
||
|
+ public $recurNthDay = null;
|
||
|
+
|
||
|
+ /**
|
||
|
+ * BYMONTH recurrence data
|
||
|
+ *
|
||
|
+ * @var array
|
||
|
+ */
|
||
|
+ public $recurMonths = array();
|
||
|
+
|
||
|
+ /**
|
||
|
* All the exceptions from recurrence for this event.
|
||
|
*
|
||
|
* @var array
|
||
|
@@ -157,6 +171,44 @@
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
+ *
|
||
|
+ * @param integer $nthDay The nth weekday of month to repeat events on
|
||
|
+ */
|
||
|
+ public function setRecurNthWeekday($nth)
|
||
|
+ {
|
||
|
+ $this->recurNthDay = (int)$nth;
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ *
|
||
|
+ * @return integer The nth weekday of month to repeat events.
|
||
|
+ */
|
||
|
+ public function getRecurNthWeekday()
|
||
|
+ {
|
||
|
+ return isset($this->recurNthDay) ? $this->recurNthDay : ceil($this->start->mday / 7);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Specifies the months for yearly (weekday) recurrence
|
||
|
+ *
|
||
|
+ * @param array $months List of months (integers) this event recurs on.
|
||
|
+ */
|
||
|
+ function setRecurByMonth($months)
|
||
|
+ {
|
||
|
+ $this->recurMonths = (array)$months;
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Returns a list of months this yearly event recurs on
|
||
|
+ *
|
||
|
+ * @return array List of months (integers) this event recurs on.
|
||
|
+ */
|
||
|
+ function getRecurByMonth()
|
||
|
+ {
|
||
|
+ return $this->recurMonths;
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
* Returns the days this event recurs on.
|
||
|
*
|
||
|
* @return integer A mask consisting of Horde_Date::MASK_* constants
|
||
|
@@ -546,8 +598,13 @@
|
||
|
$estart = clone $this->start;
|
||
|
|
||
|
// What day of the week, and week of the month, do we recur on?
|
||
|
- $nth = ceil($this->start->mday / 7);
|
||
|
- $weekday = $estart->dayOfWeek();
|
||
|
+ if (isset($this->recurNthDay)) {
|
||
|
+ $nth = $this->recurNthDay;
|
||
|
+ $weekday = log($this->recurData, 2);
|
||
|
+ } else {
|
||
|
+ $nth = ceil($this->start->mday / 7);
|
||
|
+ $weekday = $estart->dayOfWeek();
|
||
|
+ }
|
||
|
|
||
|
// Adjust $estart to be the first candidate.
|
||
|
$offset = ($after->month - $estart->month) + ($after->year - $estart->year) * 12;
|
||
|
@@ -660,8 +717,13 @@
|
||
|
$estart = clone $this->start;
|
||
|
|
||
|
// What day of the week, and week of the month, do we recur on?
|
||
|
- $nth = ceil($this->start->mday / 7);
|
||
|
- $weekday = $estart->dayOfWeek();
|
||
|
+ if (isset($this->recurNthDay)) {
|
||
|
+ $nth = $this->recurNthDay;
|
||
|
+ $weekday = log($this->recurData, 2);
|
||
|
+ } else {
|
||
|
+ $nth = ceil($this->start->mday / 7);
|
||
|
+ $weekday = $estart->dayOfWeek();
|
||
|
+ }
|
||
|
|
||
|
// Adjust $estart to be the first candidate.
|
||
|
$offset = floor(($after->year - $estart->year + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval;
|
||
|
@@ -894,15 +956,6 @@
|
||
|
case 'W':
|
||
|
$this->setRecurType(self::RECUR_WEEKLY);
|
||
|
if (!empty($remainder)) {
|
||
|
- $maskdays = array(
|
||
|
- 'SU' => Horde_Date::MASK_SUNDAY,
|
||
|
- 'MO' => Horde_Date::MASK_MONDAY,
|
||
|
- 'TU' => Horde_Date::MASK_TUESDAY,
|
||
|
- 'WE' => Horde_Date::MASK_WEDNESDAY,
|
||
|
- 'TH' => Horde_Date::MASK_THURSDAY,
|
||
|
- 'FR' => Horde_Date::MASK_FRIDAY,
|
||
|
- 'SA' => Horde_Date::MASK_SATURDAY,
|
||
|
- );
|
||
|
$mask = 0;
|
||
|
while (preg_match('/^ ?[A-Z]{2} ?/', $remainder, $matches)) {
|
||
|
$day = trim($matches[0]);
|
||
|
@@ -953,7 +1006,10 @@
|
||
|
list($year, $month, $mday) = sscanf($remainder, '%04d%02d%02d');
|
||
|
$this->setRecurEnd(new Horde_Date(array('year' => $year,
|
||
|
'month' => $month,
|
||
|
- 'mday' => $mday)));
|
||
|
+ 'mday' => $mday,
|
||
|
+ 'hour' => 23,
|
||
|
+ 'min' => 59,
|
||
|
+ 'sec' => 59)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
@@ -1049,6 +1105,16 @@
|
||
|
// Always default the recurInterval to 1.
|
||
|
$this->setRecurInterval(isset($rdata['INTERVAL']) ? $rdata['INTERVAL'] : 1);
|
||
|
|
||
|
+ $maskdays = array(
|
||
|
+ 'SU' => Horde_Date::MASK_SUNDAY,
|
||
|
+ 'MO' => Horde_Date::MASK_MONDAY,
|
||
|
+ 'TU' => Horde_Date::MASK_TUESDAY,
|
||
|
+ 'WE' => Horde_Date::MASK_WEDNESDAY,
|
||
|
+ 'TH' => Horde_Date::MASK_THURSDAY,
|
||
|
+ 'FR' => Horde_Date::MASK_FRIDAY,
|
||
|
+ 'SA' => Horde_Date::MASK_SATURDAY,
|
||
|
+ );
|
||
|
+
|
||
|
switch (Horde_String::upper($rdata['FREQ'])) {
|
||
|
case 'DAILY':
|
||
|
$this->setRecurType(self::RECUR_DAILY);
|
||
|
@@ -1057,15 +1123,6 @@
|
||
|
case 'WEEKLY':
|
||
|
$this->setRecurType(self::RECUR_WEEKLY);
|
||
|
if (isset($rdata['BYDAY'])) {
|
||
|
- $maskdays = array(
|
||
|
- 'SU' => Horde_Date::MASK_SUNDAY,
|
||
|
- 'MO' => Horde_Date::MASK_MONDAY,
|
||
|
- 'TU' => Horde_Date::MASK_TUESDAY,
|
||
|
- 'WE' => Horde_Date::MASK_WEDNESDAY,
|
||
|
- 'TH' => Horde_Date::MASK_THURSDAY,
|
||
|
- 'FR' => Horde_Date::MASK_FRIDAY,
|
||
|
- 'SA' => Horde_Date::MASK_SATURDAY,
|
||
|
- );
|
||
|
$days = explode(',', $rdata['BYDAY']);
|
||
|
$mask = 0;
|
||
|
foreach ($days as $day) {
|
||
|
@@ -1090,6 +1147,10 @@
|
||
|
case 'MONTHLY':
|
||
|
if (isset($rdata['BYDAY'])) {
|
||
|
$this->setRecurType(self::RECUR_MONTHLY_WEEKDAY);
|
||
|
+ if (preg_match('/(-?[1-4])([A-Z]+)/', $rdata['BYDAY'], $m)) {
|
||
|
+ $this->setRecurOnDay($maskdays[$m[2]]);
|
||
|
+ $this->setRecurNthWeekday($m[1]);
|
||
|
+ }
|
||
|
} else {
|
||
|
$this->setRecurType(self::RECUR_MONTHLY_DATE);
|
||
|
}
|
||
|
@@ -1100,6 +1161,14 @@
|
||
|
$this->setRecurType(self::RECUR_YEARLY_DAY);
|
||
|
} elseif (isset($rdata['BYDAY'])) {
|
||
|
$this->setRecurType(self::RECUR_YEARLY_WEEKDAY);
|
||
|
+ if (preg_match('/(-?[1-4])([A-Z]+)/', $rdata['BYDAY'], $m)) {
|
||
|
+ $this->setRecurOnDay($maskdays[$m[2]]);
|
||
|
+ $this->setRecurNthWeekday($m[1]);
|
||
|
+ }
|
||
|
+ if ($rdata['BYMONTH']) {
|
||
|
+ $months = explode(',', $rdata['BYMONTH']);
|
||
|
+ $this->setRecurByMonth($months);
|
||
|
+ }
|
||
|
} else {
|
||
|
$this->setRecurType(self::RECUR_YEARLY_DATE);
|
||
|
}
|
||
|
@@ -1163,13 +1232,19 @@
|
||
|
break;
|
||
|
|
||
|
case self::RECUR_MONTHLY_WEEKDAY:
|
||
|
- $nth_weekday = (int)($this->start->mday / 7);
|
||
|
- if (($this->start->mday % 7) > 0) {
|
||
|
- $nth_weekday++;
|
||
|
+ if (isset($this->recurNthDay)) {
|
||
|
+ $nth_weekday = $this->recurNthDay;
|
||
|
+ $day_of_week = log($this->recurData, 2);
|
||
|
+ } else {
|
||
|
+ $day_of_week = $this->start->dayOfWeek();
|
||
|
+ $nth_weekday = (int)($this->start->mday / 7);
|
||
|
+ if (($this->start->mday % 7) > 0) {
|
||
|
+ $nth_weekday++;
|
||
|
+ }
|
||
|
}
|
||
|
$vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
|
||
|
$rrule = 'FREQ=MONTHLY;INTERVAL=' . $this->recurInterval
|
||
|
- . ';BYDAY=' . $nth_weekday . $vcaldays[$this->start->dayOfWeek()];
|
||
|
+ . ';BYDAY=' . $nth_weekday . $vcaldays[$day_of_week];
|
||
|
break;
|
||
|
|
||
|
case self::RECUR_YEARLY_DATE:
|
||
|
@@ -1182,15 +1257,22 @@
|
||
|
break;
|
||
|
|
||
|
case self::RECUR_YEARLY_WEEKDAY:
|
||
|
- $nth_weekday = (int)($this->start->mday / 7);
|
||
|
- if (($this->start->mday % 7) > 0) {
|
||
|
- $nth_weekday++;
|
||
|
- }
|
||
|
+ if (isset($this->recurNthDay)) {
|
||
|
+ $nth_weekday = $this->recurNthDay;
|
||
|
+ $day_of_week = log($this->recurData, 2);
|
||
|
+ } else {
|
||
|
+ $day_of_week = $this->start->dayOfWeek();
|
||
|
+ $nth_weekday = (int)($this->start->mday / 7);
|
||
|
+ if (($this->start->mday % 7) > 0) {
|
||
|
+ $nth_weekday++;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ $months = !empty($this->recurMonths) ? join(',', $this->recurMonths) : $this->start->month;
|
||
|
$vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
|
||
|
$rrule = 'FREQ=YEARLY;INTERVAL=' . $this->recurInterval
|
||
|
. ';BYDAY='
|
||
|
. $nth_weekday
|
||
|
- . $vcaldays[$this->start->dayOfWeek()]
|
||
|
+ . $vcaldays[$day_of_week]
|
||
|
. ';BYMONTH=' . $this->start->month;
|
||
|
break;
|
||
|
}
|
||
|
@@ -1223,6 +1305,21 @@
|
||
|
|
||
|
$this->setRecurInterval((int)$hash['interval']);
|
||
|
|
||
|
+ $month2number = array(
|
||
|
+ 'january' => 1,
|
||
|
+ 'february' => 2,
|
||
|
+ 'march' => 3,
|
||
|
+ 'april' => 4,
|
||
|
+ 'may' => 5,
|
||
|
+ 'june' => 6,
|
||
|
+ 'july' => 7,
|
||
|
+ 'august' => 8,
|
||
|
+ 'september' => 9,
|
||
|
+ 'october' => 10,
|
||
|
+ 'november' => 11,
|
||
|
+ 'december' => 12,
|
||
|
+ );
|
||
|
+
|
||
|
$parse_day = false;
|
||
|
$set_daymask = false;
|
||
|
$update_month = false;
|
||
|
@@ -1255,11 +1352,9 @@
|
||
|
|
||
|
case 'weekday':
|
||
|
$this->setRecurType(self::RECUR_MONTHLY_WEEKDAY);
|
||
|
- $nth_weekday = (int)$hash['daynumber'];
|
||
|
- $hash['daynumber'] = 1;
|
||
|
+ $this->setRecurNthWeekday($hash['daynumber']);
|
||
|
$parse_day = true;
|
||
|
- $update_daynumber = true;
|
||
|
- $update_weekday = true;
|
||
|
+ $set_daymask = true;
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
@@ -1297,12 +1392,13 @@
|
||
|
}
|
||
|
|
||
|
$this->setRecurType(self::RECUR_YEARLY_WEEKDAY);
|
||
|
- $nth_weekday = (int)$hash['daynumber'];
|
||
|
- $hash['daynumber'] = 1;
|
||
|
+ $this->setRecurNthWeekday($hash['daynumber']);
|
||
|
$parse_day = true;
|
||
|
- $update_month = true;
|
||
|
- $update_daynumber = true;
|
||
|
- $update_weekday = true;
|
||
|
+ $set_daymask = true;
|
||
|
+
|
||
|
+ if ($hash['month'] && isset($month2number[$hash['month']])) {
|
||
|
+ $this->setRecurByMonth($month2number[$hash['month']]);
|
||
|
+ }
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
@@ -1368,21 +1464,6 @@
|
||
|
|
||
|
if ($update_month || $update_daynumber || $update_weekday) {
|
||
|
if ($update_month) {
|
||
|
- $month2number = array(
|
||
|
- 'january' => 1,
|
||
|
- 'february' => 2,
|
||
|
- 'march' => 3,
|
||
|
- 'april' => 4,
|
||
|
- 'may' => 5,
|
||
|
- 'june' => 6,
|
||
|
- 'july' => 7,
|
||
|
- 'august' => 8,
|
||
|
- 'september' => 9,
|
||
|
- 'october' => 10,
|
||
|
- 'november' => 11,
|
||
|
- 'december' => 12,
|
||
|
- );
|
||
|
-
|
||
|
if (isset($month2number[$hash['month']])) {
|
||
|
$this->start->month = $month2number[$hash['month']];
|
||
|
}
|
||
|
@@ -1398,7 +1479,7 @@
|
||
|
}
|
||
|
|
||
|
if ($update_weekday) {
|
||
|
- $this->start->setNthWeekday($last_found_day, $nth_weekday);
|
||
|
+ $this->setNthWeekday($nth_weekday);
|
||
|
}
|
||
|
}
|
||
|
|