static function validate_recurrence_rule_data(&$simple, &$errors) { // If no recurrence is enabled, just return NULL if (!isset($simple['enable'])) { return NULL; } // Otherwise, create the recurrence rule. $recur = new CalendarRecurRule(); // Interval if (isset($simple['interval'])) { $interval = $simple['interval']; if (is_numeric($interval)) { $recur->SetInterval((int) $interval); } else { $errors[] = array('field' => 'interval', 'text' => "Non-numeric interval: {$interval}"); } } // Frequency dependent if (isset($simple['freq'])) { switch ($simple['freq']) { case 'daily': $recur->SetFrequency('daily'); break; case 'weekly': $recur->SetFrequency('weekly'); if (isset($simple['weekly_byday']) && is_array($simple['weekly_byday'])) { foreach ($simple['weekly_byday'] as $day => $dummy) { if (is_numeric($day) && $day >= 0 && $day < 7) { $recur->SetByDay($day); } } } break; case 'monthly': $recur->SetFrequency('monthly'); if (isset($simple['monthly_method'])) { switch ($simple['monthly_method']) { case 'monthday': if (isset($simple['monthly_monthday']) && is_array($simple['monthly_monthday'])) { $monthday =& $simple['monthly_monthday']; $monthday_fail = false; if (!isset($monthday['monthday']) || !is_numeric($monthday['monthday'])) { $monthday_fail = true; $errors[] = array('field' => 'monthly_monthday', 'text' => 'Invalid monthly day.'); } elseif ($monthday['monthday'] < -31 || $monthday['monthday'] > 31 || !$monthday['monthday']) { $monthday_fail = true; $errors[] = array('field' => 'monthly_monthday', 'text' => 'Monthly day out of range'); } if (!$monthday_fail) { $recur->SetByMonthDay((int) $monthday['monthday']); } } break; case 'weekday': if (isset($simple['monthly_weekday']) && is_array($simple['monthly_weekday'])) { $weekday =& $simple['monthly_weekday']; $weekday_fail = false; if (!isset($weekday['day'])) { $weekday_fail = true; $errors[] = array('field' => 'monthly_weekday', 'text' => 'Invalid monthly day.'); } else { $days_split = split(',', $weekday['day']); $monthly_weekday_days = array(); foreach ($days_split as $day) { if (!is_numeric($day) || $day < 0 || $day > 6) { $weekday_fail = true; } else { $monthly_weekday_days[] = (int) $day; } } if ($weekday_fail) { $errors[] = array('field' => 'monthly_weekday', 'text' => 'Monthly day(s) out of range'); } } if (!isset($weekday['week']) || !is_numeric($weekday['week'])) { $weekday_fail = true; $errors[] = array('field' => 'monthly_weekday', 'text' => 'Invalid monthly week.'); } elseif ($weekday['week'] < -5 || $weekday['week'] > 5 || !$weekday['week']) { $weekday_fail = true; $errors[] = array('field' => 'monthly_weekday', 'text' => 'Monthly week out of range'); } if (!$weekday_fail) { if (count($monthly_weekday_days) == 1) { $recur->SetByDay($monthly_weekday_days[0], (int) $weekday['week']); } else { foreach ($monthly_weekday_days as $day) { $recur->SetByDay($day); } $recur->SetBySetPos((int) $weekday['week']); } } } break; } } break; case 'yearly': $recur->SetFrequency('yearly'); if (isset($simple['yearly_method'])) { switch ($simple['yearly_method']) { case 'monthday': if (isset($simple['yearly_monthday']) && is_array($simple['yearly_monthday'])) { $monthday =& $simple['yearly_monthday']; $monthday_fail = false; if (!isset($monthday['monthday']) || !is_numeric($monthday['monthday'])) { $monthday_fail = true; $errors[] = array('field' => 'yearly_monthday', 'text' => 'Invalid yearly day.'); } elseif ($monthday['monthday'] < -31 || $monthday['monthday'] > 31 || !$monthday['monthday']) { $monthday_fail = true; $errors[] = array('field' => 'yearly_monthday', 'text' => 'yearly day out of range'); } if (!isset($monthday['month']) || !is_numeric($monthday['month'])) { $monthday_fail = true; $errors[] = array('field' => 'yearly_monthday', 'text' => 'Invalid yearly month.'); } elseif ($monthday['month'] < 1 || $monthday['month'] > 12) { $monthday_fail = true; $errors[] = array('field' => 'yearly_monthday', 'text' => 'yearly month out of range'); } if (!$monthday_fail) { $recur->SetByMonthDay((int) $monthday['monthday']); $recur->SetByMonth((int) $monthday['month']); } } break; case 'weekday': if (isset($simple['yearly_weekday']) && is_array($simple['yearly_weekday'])) { $weekday =& $simple['yearly_weekday']; $weekday_fail = false; if (!isset($weekday['week']) || !is_numeric($weekday['week'])) { $weekday_fail = true; $errors[] = array('field' => 'yearly_weekday', 'text' => 'Invalid yearly week.'); } elseif ($weekday['week'] < -5 || $weekday['week'] > 5 || !$weekday['week']) { $weekday_fail = true; $errors[] = array('field' => 'yearly_weekday', 'text' => 'yearly week out of range'); } if (!isset($weekday['day']) || !is_numeric($weekday['day'])) { $weekday_fail = true; $errors[] = array('field' => 'yearly_weekday', 'text' => 'Invalid yearly day.'); } elseif ($weekday['day'] < 0 || $weekday['day'] > 6) { $weekday_fail = true; $errors[] = array('field' => 'yearly_weekday', 'text' => 'yearly day out of range'); } if (!isset($weekday['month']) || !is_numeric($weekday['month'])) { $weekday_fail = true; $errors[] = array('field' => 'yearly_monthday', 'text' => 'Invalid yearly month.'); } elseif ($weekday['month'] < 1 || $weekday['month'] > 12) { $weekday_fail = true; $errors[] = array('field' => 'yearly_monthday', 'text' => 'yearly month out of range'); } if (!$weekday_fail) { // use monthly with bymonth and byday /// @note jh559: using monthly frequency here doesn't work coz yearly interval would be wrong // $recur->SetFrequency('monthly'); // $recur->SetByMonth((int)$weekday['month']); // $recur->SetByDay((int)$weekday['day'], (int)$weekday['week']); // use yearly with bymonth and bysetpos $recur->SetByDay((int) $weekday['day'], (int) $weekday['week']); $recur->SetByMonth((int) $weekday['month']); //$recur->SetBySetpos((int)$weekday['week']); } } break; case 'yearday': if (isset($simple['yearly_yearday']) && is_array($simple['yearly_yearday'])) { $yearday =& $simple['yearly_yearday']; if (!isset($yearday['yearday']) || !is_numeric($yearday['yearday'])) { $errors[] = array('field' => 'yearly_yearday', 'text' => 'Invalid yearly day of year.'); } elseif ($yearday['yearday'] < -365 || $yearday['yearday'] > 365 || !$yearday['yearday']) { $errors[] = array('field' => 'yearly_weekday', 'text' => 'yearly day of year out of range'); } else { $recur->SetByYearday((int) $yearday['yearday']); } } break; } } break; default: $errors[] = array('field' => 'freq', 'text' => 'Unrecognised frequency'); break; } } else { $errors[] = array('text' => 'Recurrence frequency missing'); } // Range if (isset($simple['range_method'])) { switch ($simple['range_method']) { case 'count': if (isset($simple['count']) && is_numeric($simple['count'])) { if ($simple['count'] > 0) { $recur->SetCount((int) $simple['count']); } else { $recur->SetCount(1); $errors[] = array('field' => 'count', 'text' => 'Occurrence count should be positive and non-zero'); } } else { $recur->SetCount(10); $errors[] = array('field' => 'count', 'text' => 'Non-numeric occurrence count'); } break; case 'until': if (isset($simple['until']) && is_array($simple['until'])) { $until =& $simple['until']; $until_fail = false; if (!isset($until['year']) || !is_numeric($until['year'])) { $until_fail = true; $errors[] = array('field' => 'until', 'text' => 'Invalid until year'); } elseif ($until['year'] < 2000 || $until['year'] > 2100) { $until_fail = true; $errors[] = array('field' => 'until', 'text' => 'Until year out of range'); } if (!isset($until['month']) || !is_numeric($until['month'])) { $until_fail = true; $errors[] = array('field' => 'until', 'text' => 'Invalid until month'); } elseif ($until['month'] < 1 || $until['month'] > 12) { $until_fail = true; $errors[] = array('field' => 'until', 'text' => 'Until month out of range'); } if (!isset($until['monthday']) || !is_numeric($until['monthday'])) { $until_fail = true; $errors[] = array('field' => 'until', 'text' => 'Invalid until day of month'); } elseif ($until['monthday'] < 1 || $until['monthday'] > 31) { $until_fail = true; $errors[] = array('field' => 'until', 'text' => 'Year out of range'); } if (!$until_fail) { $until_date = mktime(23, 59, 59, (int) $until['month'], (int) $until['monthday'], (int) $until['year']); $recur->SetUntil($until_date); } } else { $errors[] = array('field' => 'until', 'text' => 'Invalid until date'); } break; } } return $recur; }