ryan Posted December 23, 2011 Share Posted December 23, 2011 Given a Google Calendar XML feed URL, this module will pull it, cache it, and let you foreach() it or render it. Download at: https://github.com/r.../MarkupLoadGCal USAGE The MarkupLoadRSS module is used from your template files. To use it, you get a copy of the module, tell it what URL to load from (with the load method), and then execute a find() query with a selector string. It works basically the same as a $pages->find("selector string"). <?php $cal = $modules->get("MarkupLoadGCal"); $cal->load('http://calendar XML feed'); $items = $cal->find('from=2011-12-1, to=2011-12-31'); foreach($items as $item) echo "<p>{$item->title}</p>"; To get a Google calendar URL, you would go into your (or another) calendar on Google and click to the calendar's settings. At the bottom of the screen, you will see a section called "Calendar Address" with XML, ICAL, and HTML. Copy the XML address, and use that with this module. If you just want one to test with, use the one from my examples below: http://www.google.co...com/public/full Note: you must use the 'full' not 'basic' calendar from Google Calendar. You can identify if you've got the right one because it will end with 'full' rather than 'basic', as in the URL above. Selector Properties The selector properties you may provide to find() are: from: Starting date in any common date/time format (or unix timestamp). to: Ending date in any common date/time format (or unix timestamp). keywords: Keyword(s) to search for in the Google calendar events. limit: Max number of items to load (default = 100). sort: May be 'date', '-date', 'modified' or '-modified'. html: Set to '0' if you don't want the event description in HTML. The find() method will return the found items. You can then foreach() these items to generate your output. A render() method is also included with the items which provides some default output, if you want it. Calendar Item (Event) Properties Each calendar item has the following properties: title: The title of the event description: Detailed description of the event (in HTML, unless disabled) location: Where the event will take place author: Author of this item from: Timestamp of when the event begins to: Timestamp of when the event ends dateFrom: Formatted date string of when the event begins dateTo: Formatted date string of when the event ends See the module file for additional configuration options. EXAMPLES Example #1: Simplest example <?php // get the calendar module $cal = $modules->get("MarkupLoadGCal"); // set the feed URL: may be any google calendar XML feed URL $cal->load('http://www.google.com/calendar/feeds/3icgo6ucgvsf6bi5orld9moqqc%40group.calendar.google.com/public/full'); // find all items for December, 2011 $items = $cal->find('from=2011-12-1, to=2011-12-31'); // render items using built-in rendering echo $items->render(); Example #2: Rendering your own items <?php $cal = $modules->get("MarkupLoadGCal"); $cal->load('http://www.google.com/calendar/feeds/3icgo6ucgvsf6bi5orld9moqqc%40group.calendar.google.com/public/full'); $items = $cal->find('from=2011-12-1, to=2011-12-31'); foreach($items as $item) { echo " <h2>{$item->title}</h2> <p> <b>Date From:</b> {$item->dateFrom} (Timestamp: {$item->from}) <br /> <b>Date To:</b> {$item->dateTo} (Timestamp: {$item->to}) <br /> <b>Location:</b> {$item->location} <br /> <b>Author:</b> {$item->author} </p> {$item->description} "; } Example #3: Finding Keywords <?php $cal = $modules->get("MarkupLoadGCal"); $cal->load('http://www.google.com/calendar/feeds/3icgo6ucgvsf6bi5orld9moqqc%40group.calendar.google.com/public/full'); $items = $cal->find("from=Aug 1 2011, to=Dec 1 2011, keywords=Eddie Owen"); echo $items->render(); ADDITIONAL INFO Options See the module's class file (MarkupLoadGCal) for a description of all options in the comments of the $options and $markup arrays at the top of the class file. Handling Errors If an error occurred when loading the feed, the $cal will have an 'error' property populated with a message of what error occurred: <?php $items = $cal->find("..."); if(empty($items) && $cal->error) { // an error occurred echo "Error! " . $cal->error; } $items will be blank if an error occurs, but it will always be of the same type, so it's up to you whether you want to detect errors. If you don't, then your calendar output will just indicate that nothing was found. Cache By default your calendar queries are cached for an hour. You can change the cache time by setting the $cal->cache property to the number of seconds you want it to cache. --- Edit: Added note that you must use the 'full' google calendar feed rather than the 'basic' one. 5 Link to comment Share on other sites More sharing options...
Soma Posted December 23, 2011 Share Posted December 23, 2011 Ryan is on fire! I'm sure this will be very useful. So many new things to try out. Thanks for this module! Link to comment Share on other sites More sharing options...
Soma Posted December 24, 2011 Share Posted December 24, 2011 I'm just trying to get this working. I'm not sure if I'm doing it correctly, but I get nothing but a warning. 6 times a waring like: Warning: MarkupLoadGCal::makeCalendarItem() [markuploadgcal.makecalendaritem]: Node no longer exists in /Applications/XAMPP/xamppfiles/htdocs/pw2.ch/site/modules/MarkupLoadGCal/MarkupLoadGCal.module on line 334 ... then error: Fatal error: Cannot break/continue 1 level in /Applications/XAMPP/xamppfiles/htdocs/pw2.ch/site/modules/MarkupLoadGCal/MarkupLoadGCal.module on line 340 I'm using this code: $cal = $modules->get("MarkupLoadGCal"); $cal->load('https://www.google.com/calendar/feeds/ph.urlich%40gmail.com/public/basic'); $items = $cal->find('from=2011-12-1, to=2012-01-31'); foreach($items as $item) { echo " <h2>{$item->title}</h2> <p> <b>Date From:</b> {$item->dateFrom} (Timestamp: {$item->from}) <br /> <b>Date To:</b> {$item->dateTo} (Timestamp: {$item->to}) <br /> <b>Location:</b> {$item->location} <br /> <b>Author:</b> {$item->author} </p> {$item->description} "; } When I use your example xml url it works. But the ones I get are also different... https://www.google.com/calendar/feeds/ph.urlich%40gmail.com/public/basic Link to comment Share on other sites More sharing options...
ryan Posted December 24, 2011 Author Share Posted December 24, 2011 Sorry I missed this in the instructions (will update later) bit this module currently requires the 'full' not 'basic' calendar. So you'd need to replace basic with full in your URL. It looks to me like your full has read access disabled. Try with the example feed if you want. Link to comment Share on other sites More sharing options...
Jan Romero Posted February 9, 2012 Share Posted February 9, 2012 I get the same error when I try to $cal->find() a month that has an event spanning into it: Error Cannot break/continue 1 level (line 340 Events that continue beyond the loaded timespan are fine. That line goes as follows, and, judging from the comment, I don't want that functionality anyways, so I commented it out. Now my output looks good, although I'm not very comfortable with messing with the code... // filter out events that started before the requested time // these will be multi-day events that span into the requested time if($from && $a->from < $from) continue; The point in my code that throws the error: $items = $Calendar->find("from=$year-$month-1, to=$year-$month-$numdays, sort=date"); Otherwise everything is going super swell, thanks a lot for ProcessWire! Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2012 Author Share Posted February 9, 2012 Jan, thanks for letting me know about the error. Do you have a calendar URL I could test with to reproduce it? Feel free to PM to me if it's something you don't want to post publicly. I'll be happy to fix this and update the source code. Link to comment Share on other sites More sharing options...
Hani Posted February 23, 2012 Share Posted February 23, 2012 Thanks for this module, Ryan! For anyone using this module and has recurring events on their calendars, you're going to want to add one line of code to the makeCalendar() function if it isn't behaving as you expect. (Recurring events' behavior is wonky in the sorted order. I didn't look too hard to find a pattern.) Anyway, right before the following line: $url = rtrim($url, '?&'); Add the following: $url .= 'singleevents=true&'; This will render recurring events as single events in the XML feed. Come to think of it, It may be good to make this change in the module anyway since it doesn't have any negative effects on single events. Link to comment Share on other sites More sharing options...
ryan Posted February 24, 2012 Author Share Posted February 24, 2012 Thanks Hani, I have updated the module to add a new 'recurring' option which is set to true by default (and translates to singleevents=true' in the URL). Link to comment Share on other sites More sharing options...
Hani Posted February 28, 2012 Share Posted February 28, 2012 Great idea, Ryan! Even better than my static fix! Thanks! Link to comment Share on other sites More sharing options...
ffub Posted September 20, 2012 Share Posted September 20, 2012 Hiya, I'm using this module on a couple of sites now, but most notably on the site for my climbing club: http://nlmc.co.uk/meets/ The previous events list is getting pretty long and I was wondering how complicated it would be to add pagination? Stephen Link to comment Share on other sites More sharing options...
ryan Posted September 20, 2012 Author Share Posted September 20, 2012 It's meant to be paginated within date ranges using the dateFrom() and dateTo() methods that you can call. Here's an example that uses the Google Calendar Loader and paginates by month/year: http://washingtonwaldorf.org/calendar/ $month = $input->get->month ? (int) $input->get->month : date('n'); $year = $input->get->year ? (int) $input->get->year : date('Y'); $dateFrom = strtotime("$year-$month-01 00:00"); $dateTo = strtotime("+1 month", $dateFrom)-1; $cal = $modules->get('MarkupLoadGCal'); $cal->dateFrom($dateFrom)->dateTo($dateTo); $cal->load('your-gcal-email@domain.com'); echo "<h1>" . date('F Y', $dateFrom) . "</h1>"; // i.e. September 2012 foreach($cal as $item) { // output your items } Link to comment Share on other sites More sharing options...
renobird Posted October 1, 2012 Share Posted October 1, 2012 Hi Ryan, Does this currently allow for multiple feeds? I have a "master" calendar that has a lot of individual calendars. Link to comment Share on other sites More sharing options...
ryan Posted October 2, 2012 Author Share Posted October 2, 2012 I've been away from this for a bit, but I don't recall there being reference to multiple feeds outside of what you send to the $cal->load(...) call. But of course, you can create as many instances of the module, and load as many feeds as you want, using that method. Link to comment Share on other sites More sharing options...
renobird Posted October 2, 2012 Share Posted October 2, 2012 Thanks Ryan, I was hoping to transition to using Google Calendar as a way to manage all our calendars (and there are a lot). I tested it some today, and Google Calendar isn't going to provide all the functionality we need. However, it is well suited for some of our more specialized calendars that are essentially a list of dates — in which case this module will be perfect. 1 Link to comment Share on other sites More sharing options...
ojohnsen Posted December 5, 2012 Share Posted December 5, 2012 I have been getting this message when using gcal and the items->render() method. The feed works when entered staight into a browser. Any ideas? Unable to load GCal XML feed at http://www.google.com/calendar/feeds/www.google.com%2Fcalendar%2Ffeeds%2Fggn1dqqha77gc0ullk27uuh2s0%2540group.calendar.google.com%2Fpublic%2Ffull/public/full?start-min=2012-12-01T00%3A00%3A00-05%3A00&start-max=2012-12-31T00%3A00%3A00-05%3A00&orderby=starttime&sortorder=ascending&max-results=100&singleevents=true: Link to comment Share on other sites More sharing options...
ryan Posted December 5, 2012 Author Share Posted December 5, 2012 Two possibilities I can think of: 1. Your PHP installation doesn't have allow_url_fopen enabled. You can check this by viewing your phpinfo. My guess is this might be the case? 2. The calendar URL isn't public and requires authentication. Meaning you've got to be logged into your gmail or something in order to view it. This one would be easy to test, as you could log-out of any google services and try it (or just post the URL here or by PM to me). Link to comment Share on other sites More sharing options...
ojohnsen Posted December 6, 2012 Share Posted December 6, 2012 Ryan, Thank you for the heads up on the allow_url_fopen. That is the problem. I added the following code to the loadXMLData method. $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $xmlData= curl_exec($ch); curl_close($ch); //$xmlData = @file_get_contents($url); This retrieved the xml data, sort of. The makeCalendar method does too much to the url to make it work properly. However, if you change the code to this - $xmlData = $this->loadXmlData($calendarID); in the makeCalendar method. then it renders out the calendar. I think though this will eliminate the features of the start-min, start-max, order by, etc. Perhaps you have some more insight into how we could get this to work properly using curl? Olen 1 Link to comment Share on other sites More sharing options...
ryan Posted December 6, 2012 Author Share Posted December 6, 2012 I haven't actually ever used CURL other than copy/paste from examples, so don't know what the proper method is to make it behave the way we'd want. I've always avoided CURL just because the examples always look so darn cryptic. But PW now comes with a WireHttp class that uses sockets and should give us an independent way of handling this stuff that doesn't rely upon allow_url_fopen or CURL. Actually, it attempts to use allow_url_fopen, but if the option isn't there, it falls back to using sockets. Meaning, it should work anywhere. The equivalent of your CURL example would be this: $http = new WireHttp(); $data = $http->get($url); // for a GET request // ...or... $data = $http->post($url); // for a POST request Should any GET or POST vars need to be included, then they must be passed in an array as the second parameter: $vars = array('foo' => 'bar'); $data = $http->get($url, $vars); 1 Link to comment Share on other sites More sharing options...
Marty Walker Posted December 18, 2013 Share Posted December 18, 2013 Hi, Does anyone know if Google have changed anything with their XML feeds. I can't get this to work at all. My code is from the simple example: <?php // get the calendar module $cal = $modules->get("MarkupLoadGCal"); // set the feed URL: may be any google calendar XML feed URL $cal->load('https://www.google.com/calendar/feeds/3q20e8nef1robstuplq5knc394%40group.calendar.google.com/public/basic'); // find all items for December, 2013 $items = $cal->find('from=2013-12-1, to=2013-12-31'); // render items using built-in rendering echo $items->render(); The only error I get is: Error: Cannot break/continue 1 level (line 342 of /Users/martin/Sites/mumble/_html/site/modules/MarkupLoadGCal/MarkupLoadGCal.module) Link to comment Share on other sites More sharing options...
ryan Posted December 28, 2013 Author Share Posted December 28, 2013 That actually looks like a bug in this module. The error message is correct, as there's a "continue" in the middle of the function (not sure what I was thinking–I must have converted a loop to a function and not hit a date that would trigger the line). I'm not in the office where I can fix it, but I think it should be safe to just comment out or remove that line. Link to comment Share on other sites More sharing options...
adrian Posted April 10, 2014 Share Posted April 10, 2014 (edited) Hey Ryan, Just went to use this module and that break/continue error is still happening. I'll submit an issue on Github too. EDIT: Apparently I submitted an issue already - 3 months ago! Edited April 10, 2014 by adrian 1 Link to comment Share on other sites More sharing options...
adrian Posted April 10, 2014 Share Posted April 10, 2014 In case anyone is wanting to access the item link or summary, you just need to add these to the makeCalendarItem function. $a->link = $this->cleanText($item->link['href']); $a->summary = $this->cleanText($item->summary); and edit the __construct function appropriately. 3 Link to comment Share on other sites More sharing options...
FL0RIAN Posted May 12, 2014 Share Posted May 12, 2014 Hi! $cal->dateFormat = "D, d.m.Y"; How do i get this date format in german language? My result ist only i. e. "Tue, 13.05.2014". Thanks. Link to comment Share on other sites More sharing options...
adrian Posted May 12, 2014 Share Posted May 12, 2014 (edited) Haven't needed this myself, but from the PHP date page: "To format dates in other languages, you should use the setlocale() and strftime() functions instead of date()." EDIT: Given the way this module uses dateFormat, it might not be possible easily without hacking the core of the module. Perhaps it would be better to implement a new way of defining the date format in the module by using strftime instead of date here: https://github.com/ryancramerdesign/MarkupLoadGCal/blob/master/MarkupLoadGCal.module#L351 If you have the time and skills this should be pretty easy and might be a nice pull request for enhancing the module. Perhaps someone more language savvy will chime in too. Edited May 12, 2014 by adrian Link to comment Share on other sites More sharing options...
Martijn Geerts Posted May 12, 2014 Share Posted May 12, 2014 Don't forget to set setlocale(LC_ALL, 'de_DE'); when using strftime() Is that de_DE correct for German? 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now