<?php

###############################################################################
###############################################################################
##
##	ical.php
##
##	icalendar export of PostCalendar data
##
##	Author:		Eric Germann
##	Version:	0.1
##	Date:		01-03-04
##	Contact:	ekgermann at cctec.com
##
##	ical.php is an icalendar export library for PostCalendar.  Put it
##	in the root of your PostNuke site.  The parameters are as follows:
##
##	date		one day export formatted as MM/DD/YYYY (i.e. 01/04/2004)
##	start		beginning day export formatted as above
##	end		ending dayexport formatted as above
##	eid		a specific PostCalendar Event ID (use with date to get a
##			specific event on a specific day.
##	type		inline (default) or attach.  Outlook 2000 can only do one 
##			event inline.  However, you can save multiple events and 
##			import the file and it will work.  This will override
##			that behavior.
##	debug		set to 1 to turn on debugging, which shows the ICS file
##			as HTML, not an x-vCalendar type.
##	category	allows you to match a specific PostCalendar Event Category
##
###############################################################################
###############################################################################

  include 'includes/pnAPI.php';
  pnInit();

  # $sitename = pnConfigGetVar ('sitename');
  $sitename = getenv ('SERVER_NAME');
  $now = date ("m/d/Y");

  # control whether debug and extendedinfo flags are allowed
  $debugallowed = 0;
  $extendedinfoallowed = 1;

  
  # Clean up the dates and force the format to be correct
  if ($start == '') 
    { $start = date ("m/d/Y"); } 
  else 
    { $start = date ("m/d/Y", strtotime ($start)); };
  if ($end == '') 
    { $end = date ("m/d/Y"); }
  else
    { $end = date ("m/d/Y", strtotime ($end)); }
  if ($date != "") { $start = date ("m/d/Y", strtotime ($date)); $end = $start; };

  if (!$debug)
    {
      $filename = mktime () . ".ics";
      header ("Content-Type: text/calendar");
      if (($type == "") || ($type == "inline"))
	{
      	  header ("Content-Disposition: inline; filename=$filename");
	}
      else
	{
      	  header ("Content-Disposition: attachment; filename=$filename");
	}
    }

  if ($debug) { echo ("<PRE>"); }

  pnModAPILoad ('PostCalendar', 'user');
  $events = pnModAPIFunc ('PostCalendar', 'user', 'pcGetEvents', array ('start' => $start, 'end' => $end));

  # sort the events by start date and time, sevent has the sorted list
  $sevents = array ();
  foreach ($events as $cdate => $event)
    {
      # $event has event array for $cdate day
      # sort the event array and store back in $sevent with $cdate as the index
      usort ($event, "eventdatecmp");
      $sevents [$cdate] = array ();
      $sevents [$cdate] = $event;
    }      
  reset ($sevents);

  echo "BEGIN:VCALENDAR\n";
  echo "VERSION:2.0\n";
  echo "METHOD:PUBLISH\n";
  echo "PRODID:-//CCTec/PostCalendar 4.0.0 iCal export//EN\n";

  foreach ($sevents as $cdate => $event)
    {
      # $cdate has the events actual date
      # $event has the event array for $cdate day
      foreach ($event as $item)
	{
	  # Allow a selection by unique eventid and/or category
	  if (($item [eid] == $eid || $eid == "") &&
	      ($item [catname] == $category || $category == ""))
	    {
	      # slurp out the fields to make it more convenient
  	      $starttime	= $item [startTime];
	      $duration		= $item [duration];
	      $title		= $item [title];
	      $summary		= $item [title];
	      $description	= str_replace ("<br />", "\N", $item [desc]);
	      $evcategory	= $item [catname];
	      $location		= $item [location];
	      $uid 		= $item [eid] . "--" .  strtotime ($item [time]) . "@$sitename";
	      $url		= $item [website];
	      $peid		= $item [eid];

	      # this block of code cleans up encodings such as &#113; in the
	      # email addresses.  These were escaped on store by postcalendar
	      # and I'm too lazy to figure out a regexp to fix it.
	      # it builds two arrays with search and replace and then calls
	      # str_replace once to translate everything over.
	      $email = $item [contemail];
	      for ($i = 1; $i <= 127; $i++)
		{
		  $srch [$i] = sprintf ("&#%03.3d;", $i);
		  $repl [$i] = chr ($i);
		}
	      $item [contemail] = str_replace ($srch, $repl, $item [contemail]);
	      $email = str_replace ($srch, $repl, $email);
	      $organizer = $email;
	
	      # indent the original description so VEVENT doesn't blow up on DESCRIPTION
	      $description = preg_replace ('!^!m', str_repeat (' ', 2), $description);

	      # Build the event description text.
	      $evtdesc = $description . "\N\N\n" . 
	        "  For more information:\N\n" . 
	        "  Contact: " . $item [contname] . "\N\n" .
		"  Phone: " . $item [conttel] . "\N\n" .
		"  Email: " . $email . "\N\n" .
		"  URL: " . $item [website] . "\N\n".
		"  Location: " . $item [location] . "\N\n" .
		"  Street Addr 1: " . $item [street1] . "\N\n" .
		"  Street Addr 2: " . $item [street2] . "\N\n" .
		"  City, ST ZIP: " . $item [city] . "," . $item [state] . " " . $item [postal] .
		"  \N\n";

	      # Build the ALTREP line as a link to the actual calendar
	      $altrep = "http://$sitename/index.php?" .
		"module=PostCalendar&" .
		"func=view&" .
		"Date=" . date ("Ymd", strtotime ($cdate)) . "&" .
		"tplview=&" .
		"viewtype=details&" . 
		"eid=$peid&" . 
		"print=1";

	      # output the vCard/iCal VEVENT object
	      echo "BEGIN:VEVENT\n";
	      if ($organizer <> "")
		{
	          echo "ORGANIZER:MAILTO:$organizer\n";
	          echo "CONTACT:MAILTO:$organizer\n";
		}
	      if ($url <> "") {  echo "URL:$url\n"; };

	      echo "SUMMARY:$summary\n";
	      echo "DESCRIPTION:$evtdesc";
	      echo "UID:$uid\n";
	      echo "CATEGORIES:$evcategory\n";
	      echo "LOCATION:$location\n";
	      echo "TRANSP:OPAQUE\n";
	      echo "CLASS:CONFIDENTIAL\n";
	      echo "DTSTAMP:" . gmdate ("Ymd") . "T" . gmdate ("His") . "Z\n";

	      # format up the date/time into ical format for output
	      # build the normal date/time string ...
	      $evtstr = $cdate . " ". $item [startTime];
	      # convert it to unix time ...
	      $evttime = strtotime ($evtstr);
	      # add duration to get the end time ...
	      $evtend = $evttime + $duration;

	      # format it for output
	      $startdate = gmdate ("Ymd", $evttime) . "T" . gmdate ("His", $evttime) ."Z";
	      echo "DTSTART:$startdate\n";

	      $enddate = gmdate ("Ymd", $evtend) . "T" . gmdate ("His", $evtend) . "Z";
	      echo "DTEND:$enddate\n";

	      # bury a serialized php structure in the COMMENT field.
	      if (($extendedinfo == 1) && ($extendedinfoallowed == 1))
		{
	          $extinfo [url]			= $altrep;
	          $extinfo [date]			= gmdate ("Ymd", $evttime);
	          $extinfo [eid]			= $peid;
	          $extinfo [eventtime]			= $evttime;
	          $extinfo [icallink]			= "http://$sitename/ical.php?eid=$peid&date=" . date ("Ymd", strtotime ($cdate));
		  $extinfo [evtstartunixtime]		= $evttime;
		  $extinfo [evtendunixtime]		= $evtend;

	          foreach ($item as $key => $data)
		    { $extinfo [$key] = $item [$key]; };

	          echo "COMMENT:" . serialize ($extinfo) . "\n";
		}

	      echo "END:VEVENT\n";
	    }
        }
    }
  echo "END:VCALENDAR\n";

  if ($debug && $debugallowed) { echo "<P><HR WIDTH=100%><P>Original Events are <P>"; print_r ($events); };
  if ($debug && $debugallowed) { echo "<P><HR WIDTH=100%><P>Sorted Events are <P>\n"; print_r ($sevents); };

###############################################################################

function eventdatecmp ($a, $b)
  {
    if ($a [startTime] < $b [startTime]) return -1;
    elseif ($a [startTime] > $b [startTime]) return 1;
  }

###############################################################################

?>

