diff --git a/includes/class-calendar-plus-event-rules-formatter.php b/includes/class-calendar-plus-event-rules-formatter.php index 4cc0b12..31ab4e2 100644 --- a/includes/class-calendar-plus-event-rules-formatter.php +++ b/includes/class-calendar-plus-event-rules-formatter.php @@ -5,13 +5,6 @@ public function format( $rule ); } class Calendar_Plus_Event_Rules_Formatter { - public $times; - public $dates; - public $every; - public $exclusions; - public $standard; - public $datespan; - public function __construct() { $this->times = new Calendar_Plus_Event_Rules_Times_Formatter(); $this->dates = new Calendar_Plus_Event_Rules_Dates_Formatter(); @@ -20,6 +13,8 @@ public function __construct() { $this->standard = new Calendar_Plus_Event_Rules_Standard_Formatter(); $this->datespan = new Calendar_Plus_Event_Rules_Datespan_Formatter(); + $this->formatted_date = array(); + do_action_ref_array( 'calendarp_event_rules_formatter', array( &$this ) ); } @@ -28,11 +23,18 @@ public function format_all( $rules ) { foreach ( $rules as $rule ) { if ( ! isset( $rule['rule_type'] ) ) { continue; - } + } if ( ! isset( $formatted[ $rule['rule_type'] ] ) ) { $formatted[ $rule['rule_type'] ] = array(); - } + } + + if ( isset( $formatted[ 'dates' ] ) && empty( $this->formatted_date ) ) { + if ( isset( $formatted[ 'dates' ][0] ) ) { + $this->formatted_date['from'] = new \DateTime( $formatted[ 'dates' ][0]['from'] ); + $this->formatted_date['until'] = new \DateTime( $formatted[ 'dates' ][0]['until'] ); + } + } $formatted[ $rule['rule_type'] ][] = $this->format( $rule ); } @@ -43,13 +45,14 @@ public function format_all( $rules ) { public function format( $rule ) { if ( ! isset( $rule['rule_type'] ) ) { return false; - } + } if ( property_exists( $this, $rule['rule_type'] ) ) { $classname = 'Calendar_Plus_Event_Rules_' . ucfirst( strtolower( $rule['rule_type'] ) ) . '_Formatter'; $rule_type = $rule['rule_type']; + if ( $this->$rule_type instanceof $classname ) { - return $this->$rule_type->format( $rule ); + return 'times' === $rule_type ? $this->$rule_type->format( $rule, $this->formatted_date ) : $this->$rule_type->format( $rule ); } } @@ -60,30 +63,32 @@ public function format( $rule ) { class Calendar_Plus_Event_Rules_Times_Formatter implements Calendar_Plus_Event_Rules_Formatter_Interface { - public function format( $rule ) { + public function format( $rule, $formatted_date = array() ) { if ( ! isset( $rule['from'] ) ) { return false; - } + } $from_time = self::format_single_time( $rule['from'] ); if ( ! $from_time ) { return false; - } + } if ( isset( $rule['until'] ) ) { $until_time = self::format_single_time( $rule['until'] ); } else { $until_time = false; - } + } if ( $from_time == $until_time ) { $until_time = false; - } + } if ( $until_time < $from_time ) { - $_until_time = $until_time; - $until_time = $from_time; - $from_time = $_until_time; + if ( $formatted_date['from'] === $formatted_date['until'] ) { + $_until_time = $until_time; + $until_time = $from_time; + $from_time = $_until_time; + } } return array( @@ -97,7 +102,7 @@ public static function format_single_time( $time ) { if ( ! $time ) { return false; - } + } if ( count( $time ) === 1 ) { $time_hour = substr( $time[0], 0, 2 ); @@ -108,11 +113,11 @@ public static function format_single_time( $time ) { $time = array_map( 'absint', $time ); if ( count( $time ) < 2 ) { return false; - } + } if ( $time[0] > 23 || $time[1] > 59 ) { return false; - } + } $time[0] = str_pad( $time[0], 2, '0', STR_PAD_LEFT ); $time[1] = str_pad( $time[1], 2, '0', STR_PAD_LEFT ); @@ -124,28 +129,28 @@ class Calendar_Plus_Event_Rules_Dates_Formatter implements Calendar_Plus_Event_R public function format( $rule ) { if ( ! isset( $rule['from'] ) || ! isset( $rule['until'] ) ) { return false; - } + } $from_date = explode( '-', $rule['from'] ); $until_date = explode( '-', $rule['until'] ); if ( ! $from_date || ! is_array( $from_date ) || ! $until_date || ! is_array( $until_date ) ) { return false; - } + } if ( count( $from_date ) != 3 || count( $until_date ) != 3 ) { return false; - } + } $check_from = checkdate( $from_date[1], $from_date[2], $from_date[0] ); $check_until = checkdate( $until_date[1], $until_date[2], $until_date[0] ); if ( ! $check_from || ! $check_until ) { return false; - } + } if ( $from_date > $until_date ) { return false; - } + } return array( 'from' => $rule['from'], @@ -216,23 +221,23 @@ class Calendar_Plus_Event_Rules_Exclusions_Formatter implements Calendar_Plus_Ev public function format( $rule ) { if ( empty( $rule['date'] ) ) { return false; - } + } $date = explode( '-', $rule['date'] ); if ( ! $date ) { return false; - } + } if ( count( $date ) != 3 ) { return false; - } + } $check = checkdate( $date[1], $date[2], $date[0] ); if ( ! $check ) { return false; - } + } return array( 'date' => $rule['date'] ); } @@ -248,38 +253,38 @@ public function format( $rule ) { $until_date = explode( '-', $rule['until_date'] ); if ( ! $from_date || ! is_array( $from_date ) || ! $until_date || ! is_array( $until_date ) ) { return false; - } + } if ( count( $from_date ) != 3 || count( $until_date ) != 3 ) { return false; - } + } $check_from = checkdate( $from_date[1], $from_date[2], $from_date[0] ); $check_until = checkdate( $until_date[1], $until_date[2], $until_date[0] ); if ( ! $check_from || ! $check_until ) { return false; - } + } if ( $from_date > $until_date ) { return false; - } + } if ( ! isset( $rule['until_time'] ) ) { $until_time = '23:59'; } else { $until_time = $rule['until_time']; - } + } $from_time = Calendar_Plus_Event_Rules_Times_Formatter::format_single_time( $rule['from_time'] ); if ( ! $from_time ) { return false; - } + } $until_time = Calendar_Plus_Event_Rules_Times_Formatter::format_single_time( $until_time ); if ( ! $until_time ) { $until_time = '23:59'; - } + } // switch times if event is set to finish before it begins if ( $until_time < $from_time && $rule['from_date'] === $rule['until_date'] ) { diff --git a/includes/ical/class-calendar-plus-ical-parser.php b/includes/ical/class-calendar-plus-ical-parser.php index b757206..9fef147 100644 --- a/includes/ical/class-calendar-plus-ical-parser.php +++ b/includes/ical/class-calendar-plus-ical-parser.php @@ -40,8 +40,8 @@ class Calendar_Plus_iCal_Parser { private $_import_recurring = false; /** - * Whether or not to exclude past events. - * For now only -1 is supported = exclude all events. + * Whether or not to exclude past events. + * For now only -1 is supported = exclude all events. * * @var int */ @@ -116,6 +116,7 @@ public function parse_events() { if ( ! $local_tz ) { throw new Exception( __( 'Local timezone cannot be parsed', 'calendarp' ), 'wrong-timezone' ); } + $recurring_single_events = array(); foreach ( $_events as $event ) { if ( $event->recurrence_id ) { @@ -155,13 +156,12 @@ public function parse_events() { isset( $_event->dtstart_array[0]['VALUE'] ) && $_event->dtstart_array[0]['VALUE'] === 'DATE' ) { - // Set start time to 12:00AM - $_event->dtstart .= 'T000000'; + // Set start time to begining + $_event->dtstart .= 'T'; $_event->all_day = true; - // We don't need time to be converted - $local_tz = $start_date_tz; } } + $from = self::cast_date_timezones( $_event->dtstart, $start_date_tz, $local_tz ); $end_date_tz = $calendar_tz; @@ -175,7 +175,7 @@ public function parse_events() { isset( $_event->dtend_array[0]['VALUE'] ) && $_event->dtend_array[0]['VALUE'] === 'DATE' ) { - // Set end time to 23:59:59 + // Set end time to 23:59:59. $_event->dtend .= 'T235959'; } } @@ -185,8 +185,9 @@ public function parse_events() { else { $to = $from; } + if( $this->_exlude_past === -1 ) { - + if( $to < time() && ! $_event->rrule ) { continue; } @@ -204,6 +205,7 @@ public function parse_events() { 'categories' => isset( $_event->categories ) ? array_map( 'trim', explode( ',', $_event->categories ) ) : array(), 'all_day' => ! empty( $_event->all_day ), ); + if ( $_event->rrule ) { $rules = array(); $rrule = $this->parse_rrule( $_event->rrule ); @@ -272,14 +274,9 @@ public function parse_events() { * @return DateTimeZone|null */ private function extract_timezone_from_ical_format( string $date_str ): ?DateTimeZone { - $parts = explode( '=', $date_str ); - if ( count( $parts ) > 1 ) { - $date_parts = explode( ':', $parts[1] ); - if ( $date_parts ) { - return $this->ical->timeZoneStringToDateTimeZone( $date_parts[0] ); - } - } - return null; + $datetime = $this->ical->iCalDateToDateTime( $date_str ); + + return $datetime->getTimezone() ?: new \DateTimeZone('UTC'); } @@ -536,4 +533,4 @@ private static function cast_date_timezones( $date, $from_tz, $to_tz ) { //Its not easy to get time zone based timestamp. Hack was needed. return strtotime( $date->format( 'Y-m-d H:i:s' ) ); } -} +} \ No newline at end of file