Importing iCal calendar into MySQL database - php

I've searched through a lot of sites, but all of them do in reverse already what I've achieved , but not what I need.
I need a way to import data FROM ICAL into a MySQL database, actually just one table and a few columns in a WordPress database. But I'm ignoring WordPress (as it messed up my export) and using direct database connection.
Can any of you help me achieve this? Is importing ICAL so obviously simple that I'm thinking way too difficult?
My ICAL docs setup:
BEGIN:VCALENDAR
VERSION:2.0C
ALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-TIMEZONE:Europe/Amsterdam
BEGIN:VEVENT
DTSTART:20120113T133300
DTEND:20120223T165900
DTSTAMP:20120118T093232
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:29007/on/on
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
From "BEGIN:" to "END:" also gets repeated when a user exports multiple events. In status I've currently (will change to something else) a post ID, whether or not the event is "on"(true) meaning to be displayed (in order to preserve data of past events), and the 2nd "on" tells the front end whether an event is an all-day event (from 00:00 until 23:59).
So again the question, how could I import this, using just a few lines of code, not a plugin or some other external code, into my table in a WP database?
Thanks in advance!
P.s. -> I just made this profile, not here to leech knowledge, before I created the profile just now I've also answered questions anonymously and corrected some answers in which I spotted mistakes.

The next is not a universal tool, but may suit your needs
iCal Export/Import Tool for dhtmlxScheduler

Related

.ics export from Google calendar has wrong time

Using PHP,mysql, i am trying to export/import calendar data from/to Google calendar.
The importing (to Google) works fine. I can export data from my mysql table and create an ics file then import it into Google Calendar, using a specific timezone.
The problem is when i am exporting the data... Google changes the timezone for every event. I'll give an example.
When i am importing the data to Google Calender, a typical event looks like this:
BEGIN:VEVENT
UID:20
DTSTAMP:20160328T222128
DTSTART:20160328T033000
DTEND:20160328T043000
LOCATION:
DESCRIPTION:My description here
SUMMARY:Event number 3
END:VEVENT
The StartTime is 033000 and EndTime is 043000. Everything is fine, i see an event starting at 3:30am and ending at 4:30am.
When i am exporting my calendar from Google this event looks like this:
BEGIN:VEVENT
DTSTART:20160328T003000Z
DTEND:20160328T013000Z
DTSTAMP:20160328T194501Z
UID:20
CREATED:20160328T224357Z
DESCRIPTION:My description here
LAST-MODIFIED:20160328T194410Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Event number 3
TRANSP:OPAQUE
END:VEVENT
StartTime 003000 EndTime 013000
Both .ics files have X-WR-TIMEZONE:Europe/Athens
Why on earth is Google sending me back Zulu time, instead of what i am seeing in the calendar ?
I dont want to handle timezones. This means if a person from the Usa uploads an .ics file to the custom calendar i am making, it will insert wrong times in the database. Is it possible, Google Calendar to export exactly the hours a person sees in his calendar?
If i cant avoid this, what is the easiest way to convert this Z time into the proper time ? (the time that person sees in Google Calendar)
Thanks!
I assume that, since you are able to insert the date/times into a database, you are able to parse the format of DTSTART. If not, I recommend taking a look at sabre/vobject for a full-on iCalendar parser.
So after parsing DTSTART, make sure you parse this into a php DateTime object. This object makes it really easy to convert to different timezones:
$dt = new \DateTime($input);
$dt->setTimeZone(new DateTimeZone('Europe/Athens'));
After that, your $dt contains your start time, converted to your timezone.
Here's an example with vobject:
$cal = Sabre\VObject\Reader::read($iCalendarData);
// DTSTART property
$dtstart = $cal->VEVENT->DTSTART;
// Turn into DateTime object
$dateTime = $dtstart->getDateTime();
// Convert to your timezone
$newDateTime = $dateTime->setTimeZone('Europe/Athens');
Disclaimer: I'm the main author for vobject.

iCalendar exclude date range

I am working on school timetables system and currently developing a PHP script that would allow exporting the data in iCalendar (.ics) format. The target use-case of exporting the data would be importing it into Google Calendar.
Since there are holidays inbetween the semesters in our school (specified by start and end date), what would be the best way to exclude the holidays from the iCalendar recurrence rule (RRULE)?. Keep in mind that there can be many different schedules in one export.
I did try using EXDATE;VALUE=DATE:YYYYMMDD,YYYYMMDD,YYYYMMDD... with all holiday days, but Google Calendar didn't exclude the dates, probably because schedules also have time attached and therefore they don't match.
I'll also provide the data in iCalendar format with one of the events, with holiday days excluded one by one (the one that didn't work)
BEGIN:VCALENDAR
PRODID:-//Gregor Eesmaa/NONSGML Poska timetables//ET
VERSION:2.0
METHOD:PUBLISH
BEGIN:VEVENT
UID:schedule-1442#jpg.tartu.ee
SUMMARY:French
DESCRIPTION:
LOCATION:Room 210
DTSTART:20151215T123000Z
DTEND:20151215T134500Z
RRULE:FREQ=WEEKLY;UNTIL=20160211;INTERVAL=1;BYDAY=TU
EXDATE;VALUE=DATE:20151223,20151224,20151225,20151226,20151227,20151228,20151229,20151230,20151231,20160101,20160102,20160103,20160104,20160105,20160106,20160107,20160108,20160109,20160110,20160319,20160320,20160321,20160322,20160323,20160324,20160325,20160326,20160327,20160415,20160416,20160417,20160418,20160607,20160608,20160609,20160610,20160611,20160612,20160613,20160614,20160615,20160616,20160617,20160618,20160619,20160620,20160621,20160622,20160623,20160624,20160625,20160626,20160627,20160628,20160629,20160630,20160701,20160702,20160703,20160704,20160705,20160706,20160707,20160708,20160709,20160710,20160711,20160712,20160713,20160714,20160715,20160716,20160717,20160718,20160719,20160720,20160721,20160722,20160723,20160724,20160725,20160726,20160727,20160728,20160729,20160730,20160731,20160801,20160802,20160803,20160804,20160805,20160806,20160807,20160808,20160809,20160810,20160811,20160812,20160813,20160814,20160815,20160816,20160817,20160818,20160819,20160820,20160821,20160822,20160823,20160824,20160825,20160826,20160827,20160828,20160829,20160830,20160831
LAST-MODIFIED:20160102T123758Z
DTSTAMP:20160107T232137Z
END:VEVENT
END:VCALENDAR
If DTSTART is a date-time value then EXDATEs must also be date-times. I propose you append T123000Z to each of your EXDATEs to make them actually point to valid instance starts. They will then get correctly excluded.
Based on this other SO issue, it seems you're not setting any excluded date in EXDATE. EXDATE can be set to DATE, based on the RFC 5545 specificaiton.
Based on the answer on the other issue, your EXDATE should have been
EXDATE:20151223,20151224,20151225,20151226,20151227,20151228,20151229,20151230,20151231,20160101,20160102,20160103,20160104,20160105,20160106,20160107,20160108,20160109,20160110,20160319,20160320,20160321,20160322,20160323,20160324,20160325,20160326,20160327,20160415,20160416,20160417,20160418,20160607,20160608,20160609,20160610,20160611,20160612,20160613,20160614,20160615,20160616,20160617,20160618,20160619,20160620,20160621,20160622,20160623,20160624,20160625,20160626,20160627,20160628,20160629,20160630,20160701,20160702,20160703,20160704,20160705,20160706,20160707,20160708,20160709,20160710,20160711,20160712,20160713,20160714,20160715,20160716,20160717,20160718,20160719,20160720,20160721,20160722,20160723,20160724,20160725,20160726,20160727,20160728,20160729,20160730,20160731,20160801,20160802,20160803,20160804,20160805,20160806,20160807,20160808,20160809,20160810,20160811,20160812,20160813,20160814,20160815,20160816,20160817,20160818,20160819,20160820,20160821,20160822,20160823,20160824,20160825,20160826,20160827,20160828,20160829,20160830,20160831
Hope this helps!
I posted this question looking for a solution that would exclude whole ranges. After careful consideration, I decided to do this properly, by excluding only the date-times where the event would actually take place. This decreased the file size of the export three fold.
I also added timezone information as recommended for using RRULE. Now the French lesson event would look like this:
BEGIN:VEVENT
UID:schedule-1442#jpg.tartu.ee
SUMMARY:French
DESCRIPTION:
LOCATION:Room 210
DTSTART;TZID=Europe/Tallinn:20151215T143000
DTEND;TZID=Europe/Tallinn:20151215T154500
RRULE:FREQ=WEEKLY;UNTIL=20160211;INTERVAL=1;BYDAY=TU
EXDATE;TZID=Europe/Tallinn:20151229T143000,20160105T143000
CREATED:20160102T123758Z
LAST-MODIFIED:20160102T123758Z
DTSTAMP:20160108T115122Z
END:VEVENT

Google Calendar Feed

I am trying to add a Google calendar to a website I'm making that the client will be able to update themselves. I found this: http://mikeclaffey.com/google-calendar-into-html/ which has been quite helpful, but I am a bit stuck.
The website I am building is using PHP template and the page contents is contained within the $content variable. Here is the link I'm working on: http://victoriasawyer.com/AmosTheTransparent.
The calendar feed is the top one of the two lists of Tour Dates. I would like the top one to look similar to the bottom one. The same would be ideal but not necessary.
The biggest issue I'm having is with the start date and time. In the title of the event I would like just the date to show (preferably like 10/03/14) not the time. I have figured out how to display just the time separately without issue. Is there some way to change the date format?
The other issue I'm having is the order that the events are appearing. I would like the events to show with the soonest one first in the list and the furthest one last in the list. I added the additional parameters as instructed in the tutorial (orderby=starttime and sortorder=ascending) but they do not display correctly.
The url I am using is: https://www.google.com/calendar/feeds/qmfadhgtq2kmabsi3dlb456v98%40group.calendar.google.com/public/full?orderby=starttime&sortorder=ascending&futureevents=true&alt=json. Is there something I can adjust or add to fix the order?
Any help will be much appreciated (even if you can recommend an alternative. It just needs to be customizable, and so far this seems to be the best option I have found).
You can use PHP's DateTime class like this:
$date = new DateTime('Sun Nov 16 2014 00:30:00 GMT+0000');
echo $date->format('Y-m-d');
You can then use the predefined formats in PHP which are listed here to format it into whatever style you like.
echo $date->format('d/m');
echo $date->format('d/m/Y');

Dynamic .ics from php not updating in Google Calendar

I have been trying to create a .ics page in php which is to be added to Google Calendar via "Add by URL" in order for me to retrieve events from a database and present them in the calendar.
I have searched around a while on SO and found another post which was very helpful in getting started, but I have now hit a snag which doesn't seem to affect those with similar code. Post can be found here.
So, my problem is that I cannot seem to get the Google Calendar to update my page, as if it has cached the page within the calendar. So when I add another VEVENT to the page it does not update the calendar.
When creating the file it generates the correct format for an *.ics file. Format shown below.
If I go directly to the page I do get prompted to download the file, which works to import into GC, and if I add the same code to a different page, for instance changing the pages name from cal.php to cal2.php, will make GC read all of the events whilst when I simply add the same URL as before it does not pick up on any changes made to the file.
Anyone have any idea to why this isn't updating?
Others who have had similar problems have solved this by adding a UID to their VEVENT, which did not solve this anything for me...
Format generated
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:17d88c861131ec62f18835cdd4eb7d0c#yourhost.test
DTSTAMP:20110901T092002Z
DTSTART:20110925T170000Z
DTEND:20110928T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
BEGIN:VEVENT
UID:00813115d1a2d21447eb11ded3ba9020#yourhost.test
DTSTAMP:20110901T092002Z
DTSTART:20110929T170000Z
DTEND:20110930T035959Z
SUMMARY:Camping Trip
END:VEVENT
BEGIN:VEVENT
UID:1f18d85fe516d684536129ed066e7d4f#yourhost.test
DTSTAMP:20110901T092002Z
DTSTART:20110914T170000Z
DTEND:20110915T035959Z
SUMMARY:Testing new Event
END:VEVENT
END:VCALENDAR
Code used
<?php
header("Content-Type: text/Calendar");
header("Content-Disposition: inline; filename=\"calendar.ics\"");
echo "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)) . "#yourhost.test
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:20110925T170000Z
DTEND:20110928T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)) . "#yourhost.test
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:20110929T170000Z
DTEND:20110930T035959Z
SUMMARY:Camping Trip
END:VEVENT
BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)) . "#yourhost.test
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:20110914T170000Z
DTEND:20110915T035959Z
SUMMARY:Testing new Event
END:VEVENT
END:VCALENDAR";
?>
csanyigabor is correct. Also you must ensure that the UID's are the same so that the application will match the events.
This question and answer here deals with cancelations, but the principle is the same
How to cancel an calendar event using ics files?
I think you should use the SEQUENCE attribute in VEVENT and it should increases after every change.
#csanyigabor is right and so is #anmari, but a few other tips I picked up. When you are building your ICS file, like anmari said, make sure your UID's are consistent every time your feed is sync'd. I had made it create a hash based on some text provided by the user (bad, bad idea. Shame on myself 5 years ago when I built it).
If you go here -> https://www.rfc-editor.org/rfc/rfc5545 (and a few updated points here -> https://www.rfc-editor.org/rfc/rfc7986 ) it gives some great outlines on stuff that's helpful. Specifically 3.8.7.4. Sequence Number and it outlines what should be criteria for a new sequence.
Description: When a calendar component is created, its sequence
number is 0. It is monotonically incremented by the "Organizer's"
CUA each time the "Organizer" makes a significant revision to the
calendar component.
Also helpful is what it says about UID in 3.8.4.7. Unique Identifier
Description: The "UID" itself MUST be a globally unique identifier.
The generator of the identifier MUST guarantee that the identifier
is unique. There are several algorithms that can be used to
accomplish this. A good method to assure uniqueness is to put the
domain name or a domain literal IP address of the host on which
the identifier was created on the right-hand side of an "#", and
on the left-hand side, put a combination of the current calendar
date and time of day (i.e., formatted in as a DATE-TIME value)
along with some other currently unique (perhaps sequential)
identifier available on the system (for example, a process id
number). Using a DATE-TIME value on the left-hand side and a
domain name or domain literal on the right-hand side makes it
possible to guarantee uniqueness since no two hosts should be
using the same domain name or IP address at the same time. Though
other algorithms will work, it is RECOMMENDED that the right-hand
side contain some domain identifier (either of the host itself or
otherwise) such that the generator of the message identifier can
guarantee the uniqueness of the left-hand side within the scope of
that domain.
Example: The following is an example of this property:
UID:19960401T080045Z-4000F192713-0052#host1.com

How to create a Calendar in Php?

How can I create a calendar in PHP?
Today should be in bold. How could it be coded?
You can try dhtml Calendar, or maybe Yahoo UI's Calendar.
PHP: date should give you everything you need.
Then, format everything in a table.
Firstly, start by capturing your requirements (should it handle month browsing, should it show a week at a time, etc.) - this should let you derive a functional spec of sorts, which should guide you when actually writing the component/page/application
If you mean: "how to show a date picker on your web page from PHP", the answer is to use some default JavaScript library for it. E.g. Dojo or jQuery.

Categories