format( 'Ymd\THis\Z' ); $dtstart = $start_utc->setTimezone( $utc )->format( 'Ymd\THis\Z' ); $dtend = $end_utc->setTimezone( $utc )->format( 'Ymd\THis\Z' ); $lines = [ 'BEGIN:VCALENDAR', 'VERSION:2.0', 'PRODID:-//Bookline//EN', 'CALSCALE:GREGORIAN', 'METHOD:PUBLISH', 'BEGIN:VEVENT', 'UID:' . $this->escape( $uid ), 'DTSTAMP:' . $stamp, 'DTSTART:' . $dtstart, 'DTEND:' . $dtend, 'SUMMARY:' . $this->escape( $summary ), 'DESCRIPTION:' . $this->escape( $description ), ]; if ( null !== $location && '' !== $location ) { $lines[] = 'LOCATION:' . $this->escape( $location ); } if ( null !== $organizer && '' !== $organizer ) { $lines[] = 'ORGANIZER:mailto:' . $this->escape( $organizer ); } $lines[] = 'END:VEVENT'; $lines[] = 'END:VCALENDAR'; return implode( "\r\n", $lines ) . "\r\n"; } /** * Escape ICS text values. * * @param string $value Raw. */ private function escape( string $value ): string { $value = str_replace( [ '\\', ';', ',', "\n", "\r" ], [ '\\\\', '\\;', '\\,', "\\n", '' ], $value ); return $value; } }