Topics

User Functions

Events

There are no upcoming events

What's New

Stories last 2 weeks

Comments last 2 weeks

No new comments

Trackbacks last 2 weeks

No new trackback comments

Links last 2 weeks

No recent new links

Downloads last 2 weeks

No new files

Welcome to Geeklog Sunday, July 31 2016 @ 01:23 am EDT

 Forum Index > Extensions > Cool Hacks New Topic Post Reply
 vCal format calendar generation.
Prev Topic Next Topic
   
Anonymous: Anon
 26/11/2003 01:28am (Read 20001 times)  
I've written some php code that will read the gl_events table and produce a vCal calendar. This means that people can subscribe to a geeklog calendar using iCal, Mozilla Calendar, Outlook, Ximian, etc.

The code is very basic but works, someone with more knowledge of php and geeklog might like to turn this into a plugin.
PHP Formatted Code
BEGIN:VCALENDAR
VERSION:2.0
<?php

/* First we connect with the database */
$dbh = mysql_pconnect("dbserver","dbuser","dbpass");

/* Next we select the database */
mysql_select_db("dbname",$dbh);

/* run the query for all events */
$query="select * from gl_events";
$result=mysql_query($query);

/* How many rows were returned ? */
$returned=mysql_num_rows($result);

/* Lets fetch them and output the vCal data */
if ($returned>0) {
        // This gets every returned row, and outputs the vCal data
        while($row=mysql_fetch_array($result)) {
                /* format event data to vCal */
                $vCalDescription = str_replace("r", "\\n", $row["description"]);
                $vCalLocation = str_replace("r", "\\n", $row["location"]);
                $vCalStart = date("Ymd\THi00", strtotime($row["datestart"]." ".$row["timestart"]) );
                $vCalEnd = date("Ymd\THi00", strtotime($row["dateend"]." ".$row["timeend"]) );

                /* output the event */
                echo("BEGIN:VEVENT\n");
                echo("SUMMARY:".$row["title"]."\n");
                echo("DESCRIPTION:".$vCalDescription."\n");
                echo("DTSTART:".$vCalStart."\n");
                echo("LOCATION:".$vCalLocation."\n");
                echo("URL;VALUE=URI:".$row["url"]."\n");
                echo("DTEND:".$vCalEnd."\n");
                echo("END:VEVENT\n");
        }

}


/* now we clean up */
mysql_free_result($result);

?>
END:VCALENDAR

 


It shouldn't be to hard to change this to produce an actual .ics file (if geeklog called this every time an event was edited it would be handy).
 
 Quote
Anonymous: Anon
 26/11/2003 01:32am  
Ooops, the forum software ate some escape chars and I forgot to put them back in. In the lines containing str_replace there should be before r.
 
 Quote
ronack
 26/11/2003 09:34am  

Full Member

Status: offline
Forum User

Registered: 27/05/2003
Posts: 612
Quote by Anon: Ooops, the forum software ate some escape chars and I forgot to put them back in. In the lines containing str_replace there should be before r.
It still removed it what should be before r.
 
Profile Email
 Quote
Anonymous: Anon
 26/11/2003 05:58pm  
Quote by ronack:It still removed it what should be before r.


Backslash, it should correctly read r (I'm not pressing preview this time since that is when it seemed to vanish).

I've written a better version of this code that produces a .ics file and updates it whenever an event is modified. I'll post it soon.
 
 Quote
Toholio
 26/11/2003 07:17pm  

Newbie

Status: offline
Forum User

Registered: 30/07/2003
Posts: 6
OK, I'm logged in now (since what I'm posting is a bit longer). Here is what I did to get the vCal generation happening automatically. This probably isn't the best way to do it but it does work (for me at least).

Create an empty file called "geeklog.ics" in your /backend folder (remember to make sure php has permission to write to it).

Then, put the following into a file called "icsgen.php" in your /admin folder.

PHP Formatted Code
<?php

$vCalOutput = "BEGIN:VCALENDAR\nVERSION:1.0\nPRODID:Geeklog\nTZ:+10\n";

/* First we connect with the database */
$dbh = mysql_pconnect("dbserver","dbuser","dbpass");

/* Next we select the database */
mysql_select_db("dbname",$dbh);

/* run the query for all events */
$query="select * from gl_events";
$result=mysql_query($query);

/* How many rows were returned ? */
$returned=mysql_num_rows($result);

/* Lets fetch them and output the vCal data */
if ($returned>0) {
        // This gets every returned row, and puts each in a hash
        while($row=mysql_fetch_array($result)) {
                /* format event data to vCal */
                $vCalDescription = str_replace("\r", "\\n", $row["description"]);
                $vCalLocation = str_replace("\r", "\\n", $row["location"]);
                $vCalStart = date("Ymd\THi00", strtotime($row["datestart"]." ".$row["timestart"]) );
                $vCalEnd = date("Ymd\THi00", strtotime($row["dateend"]." ".$row["timeend"]) );

                /* output the event */
                $vCalOutput = $vCalOutput."BEGIN:VEVENT\n";
                $vCalOutput = $vCalOutput."SUMMARY:".$row["title"]."\n";
                $vCalOutput = $vCalOutput."DESCRIPTION:".$vCalDescription."\n";
                $vCalOutput = $vCalOutput."DTSTART:".$vCalStart."\n";
                $vCalOutput = $vCalOutput."LOCATION:".$vCalLocation."\n";
                $vCalOutput = $vCalOutput."URL;VALUE=URI:".$row["url"]."\n";
                $vCalOutput = $vCalOutput."DTEND:".$vCalEnd."\n";
                $vCalOutput = $vCalOutput."END:VEVENT\n";
        }

}


/* now we clean up */
mysql_free_result($result);

$vCalOutput = $vCalOutput."END:VCALENDAR";

/* echo($vCalOutput); */

$icsfile=fopen('../backend/geeklog.ics','w');
fputs($icsfile, $vCalOutput);
fclose($icsfile);

?>





 


Then open up event.php in the /admin folder and add the following code in the function saveevent just after the line beginning "DB_save($_TABLES['events']" and again just after "DB_delete($_TABLES['personal_events']" (its near the end of the file)
PHP Formatted Code
/* PATCH FOR vCal GENERATION */
include("icsgen.php");
/* END vCal PATCH */




 


Thats it, edit or delete something in your calendar and the ics file should be updated (but you can always run icsgen.php yourself if you want).

Be sure to let me know if the .ics file isn't compatible with any software that it should be (Outlook is the one most likely to choke)
 
Profile Email
 Quote
michaelaskew
 23/01/2004 12:45am  

Newbie


Status: offline
Forum User

Registered: 02/09/2002
Posts: 7

Very neat hack Tohollo! I've been contemplating trying something like this but you've gone and done it. Actually, what I'd really like to see is a way to import ical/vcal files so that I don't have to use the web interface to keep things up to date, and also so I can create calendar events "offline" or even on my cell phone (which sync's with my iBook, which could then upload changes to Geeklog, which site user's could be subscribed to....)


This project has code which parses an ical file and displays a page, but I've looked at their parser and it doesn't look very reusable.

 
Profile Email
 Quote
wrdickson
 08/03/2004 03:29pm  

Newbie

Status: offline
Forum User

Registered: 08/03/2004
Posts: 6
I've been doing some gradual munging of this nifty thing to make it work a little better for me. Figured I'd post the differences I've added. I'm new to PHP, so forgive me if I've done something stupid:

I replaced his first $vCalOutput line with the following:

PHP Formatted Code
$vCalOutput = "BEGIN:VCALENDAR\n" .
              "VERSION:2.0\n" .
              "X-WR-CALNAME:VCOS\n" .
              "PRODID:-//Geeklog//Version 1.3.8//EN\n" .
              "X-WR-TIMEZONE:US/Pacific\n" .
              "CALSCALE:GREGORIAN\n" .
              "METHOD:PUBLISH\n" .
              "BEGIN:VTIMEZONE\n" .
              "TZID:US/Pacific\n" .
              "LAST-MODIFIED:" . date("Ymd\THi00\Z") . "\n" .
              "BEGIN:STANDARD\n" .
              "DTSTART:20021027T090000\n" .
              "TZOFFSETTO:-0800\n" .
              "TZOFFSETFROM:+0000\n" .
              "TZNAME:PST\n" .
              "END:STANDARD\n" .
              "BEGIN:DAYLIGHT\n" .
              "DTSTART:20030406T010000\n" .
              "TZOFFSETTO:-0700\n" .
              "TZOFFSETFROM:-0800\n" .
              "TZNAME:PDT\n" .
              "END:DAYLIGHT\n" .
              "BEGIN:STANDARD\n" .
              "DTSTART:20031026T020000\n" .
              "TZOFFSETTO:-0800\n" .
              "TZOFFSETFROM:-0700\n" .
              "TZNAME:PST\n" .
              "END:STANDARD\n" .
              "BEGIN:DAYLIGHT\n" .
              "DTSTART:20040404T010000\n" .
              "TZOFFSETTO:-0700\n" .
              "TZOFFSETFROM:-0800\n" .
              "TZNAME:PDT\n" .
              "END:DAYLIGHT\n" .
              "END:VTIMEZONE\n";
 


This helps make the file more useful to an iPod's calendar sync function, which seems to really want the timezone info. Obviously, it'd be smarter to generate the timezone info from Geeklog's timezone setting, but I haven't got around to that.

This replaces the output code (it's not very different):

PHP Formatted Code
/* Lets fetch them and output the vCal data */
if ($returned>0) {
        // This gets every returned row, and puts each in a hash
        while($row=mysql_fetch_array($result)) {
                /* format event data to vCal */
                $vCalDescription = str_replace("\r", "\\n", $row["description"]);
                $vCalLocation = str_replace("\r", "\\n", $row["location"]);
                if ($row["allday"]) {
                        $vCalStart = date("Ymd", strtotime($row["datestart"]));
                        $vCalEnd = date("Ymd", strtotime($row["dateend"]));
                } else {
                        $vCalStart = date("Ymd\THi00", strtotime($row["datestart"]." ".$row["timestart"]) );
                    $vCalEnd = date("Ymd\THi00", strtotime($row["dateend"]." ".$row["timeend"]) );
                                }

                /* output the event */
               
                if (!$row["allday"]) {
                        $vCalOutput = $vCalOutput."BEGIN:VEVENT\n";
                        $vCalOutput = $vCalOutput."SUMMARY:".$row["title"]."\n";
                        $vCalOutput = $vCalOutput."DESCRIPTION:".$vCalDescription."\n";
                    $vCalOutput = $vCalOutput."DTSTART;TZID=US/Pacific:".$vCalStart."\n";
                    $vCalOutput = $vCalOutput."LOCATION:".$vCalLocation."\n";
                    $vCalOutput = $vCalOutput."URL;VALUE=URI:".$row["url"]."\n";
                        $vCalOutput = $vCalOutput."DTEND:".$vCalEnd."\n";
                            $vCalOutput = $vCalOutput."END:VEVENT\n";
                        } else {
                                $dayinc = 1;
                                while ($vCalStart <= $vCalEnd) {
                                $vCalOutput = $vCalOutput."BEGIN:VEVENT\n";
                                $vCalOutput = $vCalOutput."SUMMARY:".$row["title"]."\n";
                                $vCalOutput = $vCalOutput."DESCRIPTION:".$vCalDescription."\n";
                                    $vCalOutput = $vCalOutput."DTSTART;TZID=US/Pacific:".$vCalStart."\n";
                                    $vCalOutput = $vCalOutput."LOCATION:".$vCalLocation."\n";
                            $vCalOutput = $vCalOutput."URL;VALUE=URI:".$row["url"]."\n";
                                    $vCalOutput = $vCalOutput."END:VEVENT\n";
                                    $vCalYear = $vCalStart[0] . $vCalStart[1] . $vCalStart[2] . $vCalStart[3];
                                    $vCalMonth = $vCalStart[4] . $vCalStart[5];
                                    $vCalDay = $vCalStart[6] . $vCalStart[7];
                                    $nextday = mktime(0, 0, 0, $vCalMonth, $vCalDay + 1, $vCalYear);
                                    $vCalStart = date("Ymd", $nextday);
                                }
                        }
        }

}
 


Two significant changes: first, timezone info is included for events (again, to help with iPod syncing). Second, in the original, a multiday event would appear as one very long event spanning all the hours on your calendar for the days in question. Now, if the event is marked "all day event," it will instead appear as one (or more if necessary) all-day events on the syncing calendar.
 
Profile Email Website
 Quote
wrdickson
 16/03/2004 12:32am  

Newbie

Status: offline
Forum User

Registered: 08/03/2004
Posts: 6
Anybody managed to produce vCal output that Outlook will read properly, with multiple events? Both mine and Toholio's original code seem to generate files that iCal can read just fine. Mine fixes timezone issues and the iPod can read it fine. But Outlook can only read the first event in a multi-event file.

It appears that Outlook can only export single events; does it perhaps simply not understand files with multiple events?
 
Profile Email Website
 Quote
Toholio
 16/03/2004 07:50pm  

Newbie

Status: offline
Forum User

Registered: 30/07/2003
Posts: 6
Quote by wrdickson: Anybody managed to produce vCal output that Outlook will read properly, with multiple events?


I think this is a problem with Outlook. A person using my calendar feed and the latest version of Outlook (2003?) was able to import all the events but older versions seem to read the first one and then stop.

The person who was able to import the calendar was still without any decent way to update it. Loading the vCal file again just gives duplicates.
 
Profile Email
 Quote
Toholio
 16/03/2004 07:56pm  

Newbie

Status: offline
Forum User

Registered: 30/07/2003
Posts: 6
Quote by michaelaskew:Actually, what I'd really like to see is a way to import ical/vcal files...This project has code which parses an ical file and displays a page, but I've looked at their parser and it doesn't look very reusable.


Importing vCal files would be a pain because you'd have to check to see if events were already in the database (unless you don't mind overwriting them, in which case the process would be much simpler).

You could always replace the Geeklog calendar with phpiCal but then you wouldn't have a web interface (not such a problem if you are the only person contributing to the calendar).

I might write a script to import vCal info into Geeklog but I don't have the time to produce a version that wouldn't obliterate whatever used to be in the gl_events table.
 
Profile Email
 Quote
Anonymous: djbeta
 08/09/2005 12:51am  

This is a little off the topic of this thread... but I'm hoping someone here might have an idea of how to approach this...

I would like to take a multi-event mac-version calendar export (ical generates an .ics file)
and convert it to a format that Outlook can import.

Can anyone tell me how I can either do this or point me in the right direction so that I can learn how to do this ?

Thanks,
Steven

 
 Quote
trampoline
 02/03/2007 02:17pm  

Full Member

Status: offline
Forum User

Registered: 24/02/2006
Posts: 392
Is anyone having success with this ?
Also is there anyway to IMPORT a whole calendar or calendar events into the geeklog calendar ?
 
Profile Email
 Quote
jcz
 18/05/2007 11:29pm  

Chatty

Status: offline
Forum User

Registered: 29/01/2002
Posts: 39
I'd really like to use this hack.

Where do I stick

/* PATCH FOR vCal GENERATION */
include("icsgen.php"Wink;
/* END vCal PATCH */

in GL the event.php file for version 1.4.1?

 
Profile Email Website
 Quote
jmucchiello
 19/05/2007 01:01am  

Full Member

Status: offline
Forum User

Registered: 29/08/2005
Posts: 985
I would say you should search /public_html/admin/plugins/calendar/index.php and /plugins/calendar/functions.inc for all occurrences of the COM_rdfUpToDateCheck function and call it there.

That example code is very ugly. Someone should update it to use Geeklog functions to access the database.
 
Profile Email
 Quote
Anonymous: swninetails
 29/05/2007 05:47pm  
Along the lines of outlook and the ical/vcal format does anyone know how to indicate a specific calendar to import an ical/vcal object into. For instance I have created a format whch outlook can read in but it always places the event into my calendar and I need the event placed into the sales team calendar which is a shared calendar.
 
 Quote
Content generated in: 1.54 seconds New Topic Post Reply
 All times are EDT. The time is now 01:23 am.
Normal Topic Normal Topic
Sticky Topic Sticky Topic
Locked Topic Locked Topic
New Post New Post
Sticky Topic W/ New Post Sticky Topic W/ New Post
Locked Topic W/ New Post Locked Topic W/ New Post
View Anonymous Posts 
Able to post 
Filtered HTML Allowed 
Censored Content