Skip to content

Instantly share code, notes, and snippets.

@stas
Created May 8, 2010 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stas/394205 to your computer and use it in GitHub Desktop.
Save stas/394205 to your computer and use it in GitHub Desktop.
<?php
/**
* iCalParser implements a basic parser for .ics files.
* This class is a fork of TigerCRM parser class.
* Improved by Stas Sușcov (stas_at_nerd_dot_ro), May 2010.
* - Better handling of summmaries and descriptions
* - Sanitization and proper handling of parsed content
* - Code optimizations
* - Inline docs
*
* <code>
* <?php
*
* include( "ical.class.php" );
* $vcal = new iCalParser( "icalfile.ics" );
* var_dump( $vcal );
*
* ?>
* </code>
*
* @package icalparser
* @since 1.0.3
* @copyright (c) TigerCRM, under GPL compatible VPL licence
* @link http://trac.vtiger.com/svn/vtiger/vtigercrm/branches/5.2.0/modules/Calendar/iCal/ical-parser-class.php
*/
class iCalParser {
/**
* Filename of the source file
* @access public
*/
var $filename;
/**
* Content of the file
* @access public
*/
var $file_contents;
/**
* Resulted vevents parsed from file
* @access public
*/
var $events;
/**
* Resulted vtodos parsed from file
* @access public
*/
var $todos;
/**
* Here be errors saved
* @access private
*/
var $errors;
/**
* Constructor method. Parses the $filename and populates $entries
* @access public
* @param string $filename the filename to read from
*/
public function iCalParser( $filename, $load_contents = false ) {
if( !file_exists( $filename ) ) {
$this->log( "File doesn't exist." );
return;
}
$this->filename = $filename;
$this->file_contents = file_get_contents( $this->filename );
$this->read();
if( !$load_contents )
unset( $this->file_contents );
}
/**
* Function reads the $filename for vevent and vtodo entries
* @access private
*/
private function read() {
preg_match_all( '/BEGIN:VEVENT.*?END:VEVENT/si', $this->file_contents, $events, PREG_PATTERN_ORDER );
preg_match_all( '/BEGIN:VTODO.*?END:VTODO/si', $this->file_contents, $todos, PREG_PATTERN_ORDER );
// parse vevent entries
$this->events = $this->parse( $events );
// parse vtodo entries
$this->todos = $this->parse( $todos );
}
/**
* Function parses for vevents or vtodos
* @access private
* @param array $to_parse Array of strings to parse
*/
private function parse( $to_parse, $limit = 2 ) {
$results = null;
for ( $i = 0; $i < count( $to_parse[0] ); $i++ ) {
$tmpbyline = explode( "\r\n", $to_parse[0][$i] );
$begin = false;
$key = NULL;
for( $l = 0; $l < count( $tmpbyline); $l++ ) {
$item = $tmpbyline[$l];
$tmpholderarray = explode( ":", $item, $limit );
if ( isset( $tmpholderarray ) && count( $tmpholderarray ) >1 ) {
if( $tmpholderarray[0] == "DESCRIPTION" || $tmpholderarray[0] == "SUMMARY" ) {
$ll = $l + 1;
while( $tmpbyline[$ll][0] == ' ' ) {
$tmpholderarray[1] .= trim( $tmpbyline[$ll] );
$tmpbyline[$ll] = '';
$ll++;
}
$tmpholderarray[1] = $this->sanitize( $tmpholderarray[1] );
$result[$tmpholderarray[0]] = $tmpholderarray[1];
} else if( $tmpholderarray[0]=='BEGIN' ){
if( $begin==false ){
$begin = true;
$result['type']=$tmpholderarray[1];
} else {
$result[$tmpholderarray[1]]=array();
$key = $tmpholderarray[1];
}
} else if( $tmpholderarray[0]=='END' ){
if( !empty( $key ) ){
$key = NULL;
}
} else {
if( !empty( $key ) ){
$result[$key][$tmpholderarray[0]] = stripslashes( $tmpholderarray[1] );
} else {
$result[$tmpholderarray[0]] = stripslashes( $tmpholderarray[1] );
}
}
}
}
$results[] = $result;
unset( $result );
}
return $results;
}
/**
* Sanitization rules
* @access private
* @param string $str String to be sanitized
*/
private function sanitize( $str ) {
$str = str_replace( array( "\\n", "\\r" ), "\n", $str );
$str = stripslashes( $str );
return $str;
}
/**
* Simple error logger
* @access public
* @param string $message
*/
public function log( $message ) {
$this->errors[] = $message;
}
}
?>
<html>
<head>
</head>
<body>
<pre>
<?php
include("iCalParser.class.php");
$vcal = new iCalParser("basic.ics");
var_dump($vcal);
?>
</pre>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment