I have a 'Subscribed Calendar' on my iPhone which fetches calendar events in the iCalendar format from a URL. The calendar works fine except it does not show the following event, is there a reason why? All other events show fine. I'm thinking there's maybe a problem with the way the event is formatted/syntax but I can't seem to find anything that may be causing it.
BEGIN:VEVENT SUMMARY:Meet with tenant DESCRIPTION:Notes: Meter readings\, SoC images\, post box key\, finalise Let Procedure.\nLocation: Apartment X X Woodland Road\, Bebington\, Wirral\, CHXX XXX\nEmployee: Michael Le Brocq\nStatus: Confirmed\nOriginally Arranged: 07/09/16 12:18:43 by Lucy Christian\nLast Updated: 12/09/16 15:57:05 by Michael Le Brocq\n UID:2432 STATUS:CONFIRMED DTSTART:20160914T160000 DTEND:20160914T151500 LAST-MODIFIED:20160912T155705 LOCATION:Apartment 5 20 Woodland Road\, Bebington\, Wirral\, CH42 4NT END:VEVENT
Code used to generate calendar events;
<?php
require_once('../inc/app_top_cron.php');
if (!empty($_GET)) {
// define and escape each GET as a variable
foreach ($_GET as $key => $value) {
if (!empty($value)) {
${$key} = mysqli_real_escape_string($con, PrepareInput($value));
}
}
}
// company details
$company_details_query = mysqli_query($con, "SELECT company_id, company_trading_name FROM company WHERE company_token = '" . $company . "' LIMIT 1") or die(mysql_error());
$company_details = mysqli_fetch_array( $company_details_query );
// the iCal date format. Note the Z on the end indicates a UTC timestamp.
define('DATE_ICAL', 'Ymd\THis');
// max line length is 75 chars. New line is \\r\n
$output = "BEGIN:VCALENDAR
METHOD:PUBLISH
VERSION:2.0
PRODID:-//Property Software//Calendar//EN
CALSCALE:GREGORIAN
X-WR-CALNAME:" . $company_details['company_trading_name'] . " Calendar" . "
\r\n";
$sql = "SELECT ce.*, ces.calendar_event_status_name
FROM calendar_event ce
INNER JOIN calendar_event_status ces
on ce.calendar_event_status = ces.calendar_event_status_id
WHERE ce.calendar_event_company_id = '" . $company_details['company_id'] . "'";
$calendar_event_query = mysqli_query($con, $sql) or die(mysql_error());
while($row = mysqli_fetch_array( $calendar_event_query )) {
$calendar_event_subject = str_replace(",","\,", $row['calendar_event_subject']);
$calendar_event_description = str_replace(",","\,", $row['calendar_event_description']);
$calendar_event_description = str_replace("\r\n","\\n", $calendar_event_description);
$calendar_event_location = str_replace(",","\,", $row['calendar_event_location']);
// loop through events
$output .=
"BEGIN:VEVENT
SUMMARY:" . $calendar_event_subject . "
DESCRIPTION:" . $calendar_event_description . "
UID:" . $row["calendar_event_id"] . "
STATUS:" . $row["calendar_event_status_name"] . "
DTSTART:" . date(DATE_ICAL, strtotime($row["calendar_event_start"])) . "
DTEND:" . date(DATE_ICAL, strtotime($row["calendar_event_end"])) . "
LAST-MODIFIED:" . date(DATE_ICAL, strtotime($row["calendar_event_date_updated"])) . "
LOCATION:" . $calendar_event_location . "
END:VEVENT
";
}
// close calendar
$output .= "END:VCALENDAR";
echo $output;
mysqli_close($con);
?>
This:
$calendar_event_description = str_replace("\r\n","\\n", $calendar_event_description);
You're taking \r\n
(carriage return + newline) and turning them into a literal \
character, followed by an n
. That's not a new line (one byte/character), it's TWO bytes/characters, and has no special meaning to anything.
And as per my comments above, don't do multiline string building/concatenating. it makes for hard-to-read and hard-to-follow debugging. Use a heredoc instead:
$output = <<<EOL
BEGIN:VEVENT
SUMMARY: {$calendar_event_subject}
DESCRIPTION: {$calendar_event_description}
UID: {$row["calendar_event_id"]}
etc...
EOL;
Note the lack of any "
or .
- making for a much more compact and easy-to-follow code block. If you need to change the line breaks afterwards, because your system uses something different than what your code editor is embedding, you can do that with a simple str_replace() after finishing building the string.