PHP-Code:
<?php if (!defined('TL_ROOT')) die('You can not access this file directly!');
/**
* @copyright Helmut Schottmüller 2009
* @author Helmut Schottmüller <typolight@aurealis.de>
* @package CalendarImport
* @license LGPL
*/
/**
* Class CalendarImport
*
* Provide methods to handle import and export of member data.
* @copyright Helmut Schottmüller 2009
* @author Helmut Schottmüller <typolight@aurealis.de>
* @package Controller
*/
class CalendarImport extends Backend
{
protected $blnSave = true;
protected $cal;
public function getAllEvents($arrEvents, $arrCalendars, $intStart, $intEnd)
{
$arrCalendars = $this->Database->prepare("SELECT * FROM tl_calendar WHERE id IN (" . join($arrCalendars, ',') . ") AND ical_source = ?")
->execute('1')
->fetchAllAssoc();
foreach ($arrCalendars as $calendar)
{
$this->importCalendarWithID($calendar['id']);
}
return $arrEvents;
}
public function importFromURL(DataContainer $dc)
{
$this->importCalendarWithID($dc->id);
}
protected function importCalendarWithID($id)
{
$arrCalendar = $this->Database->prepare("SELECT * FROM tl_calendar WHERE id = ?")
->executeUncached($id)
->fetchAssoc();
if ($arrCalendar['ical_source'])
{
if (time() - $arrCalendar['tstamp'] > $arrCalendar['ical_cache'])
{
// create new from ical file
$this->import('CalendarImport');
$startDate = (strlen($arrCalendar['ical_source_start'])) ? new Date($arrCalendar['ical_source_start'], $GLOBALS['TL_CONFIG']['dateFormat']) : new Date(time(), $GLOBALS['TL_CONFIG']['dateFormat']);
$endDate = (strlen($arrCalendar['ical_source_end'])) ? new Date($arrCalendar['ical_source_end'], $GLOBALS['TL_CONFIG']['dateFormat']) : new Date(time()+365*24*3600, $GLOBALS['TL_CONFIG']['dateFormat']);
$tz = array($arrCalendar['ical_timezone'], $arrCalendar['ical_timezone']);
$this->CalendarImport->importFromWebICS($arrCalendar['ical_url'], $startDate, $endDate, $tz);
}
}
}
public function importFromWebICS($url, $startDate, $endDate, $timezone)
{
require_once(TL_ROOT . '/plugins/iCalcreator/iCalcreator.class.php' );
$this->cal = new vcalendar();
$this->cal->setConfig('ical_' . $this->id, 'aurealis.de');
$this->cal->setProperty('method', 'PUBLISH');
$this->cal->setProperty( "x-wr-calname", $this->strTitle);
$this->cal->setProperty( "X-WR-CALDESC", $this->strTitle);
/* start parse of local file */
$this->cal->setConfig('url', $url);
$this->cal->parse();
$tz = $this->cal->getProperty('X-WR-TIMEZONE');
if (!is_array($tz) || strlen($tz[1]) == 0)
{
$tz = $timezone;
}
$this->importFromICS($startDate, $endDate, false, $tz, true);
}
protected function importFromICSFile($filename, DataContainer $dc, $startDate, $endDate, $correctTimezone = null, $manualTZ = null, $deleteCalendar = false)
{
require_once(TL_ROOT . '/plugins/iCalcreator/iCalcreator.class.php' );
$this->cal = new vcalendar();
$this->cal->setConfig('ical_' . $this->id, 'aurealis.de');
$this->cal->setProperty('method', 'PUBLISH');
$this->cal->setProperty( "x-wr-calname", $this->strTitle);
$this->cal->setProperty( "X-WR-CALDESC", $this->strTitle);
/* start parse of local file */
$this->cal->setConfig('directory', TL_ROOT . '/' . dirname($filename));
$this->cal->setConfig('filename', basename($filename));
$this->cal->parse();
$tz = $this->cal->getProperty('X-WR-TIMEZONE');
if (is_array($tz) && strlen($tz[1]) && strcmp($tz[1], $GLOBALS['TL_CONFIG']['timeZone']) != 0)
{
if ($correctTimezone === null)
{
return $this->getConfirmationForm($dc, $filename, $startDate->date, $endDate->date, $tz[1], $GLOBALS['TL_CONFIG']['timeZone'], $deleteCalendar);
}
} else if (!is_array($tz) || strlen($tz[1]) == 0)
{
if ($manualTZ === null)
{
return $this->getConfirmationForm($dc, $filename, $startDate->date, $endDate->date, $tz[1], $GLOBALS['TL_CONFIG']['timeZone'], $deleteCalendar);
}
}
if (strlen($manualTZ))
{
$tz[1] = $manualTZ;
}
$this->importFromICS($startDate, $endDate, $correctTimezone, $tz, $deleteCalendar);
$this->redirect(str_replace('&key=import', '', $this->Environment->request));
}
protected function importFromICS($startDate, $endDate, $correctTimezone = null, $tz, $deleteCalendar = false)
{
$this->cal->sort();
$this->loadDataContainer('tl_calendar_events');
$fields = $this->Database->listFields('tl_calendar_events');
$arrFields = array();
$defaultFields = array();
foreach ($fields as $fieldarr)
{
if (strcmp($fieldarr['name'], 'id') != 0) $defaultFields[$fieldarr['name']] = '';
}
// Get all default values for new entries
foreach ($GLOBALS['TL_DCA']['tl_calendar_events']['fields'] as $k=>$v)
{
if (isset($v['default']))
{
$defaultFields[$k] = is_array($v['default']) ? serialize($v['default']) : $v['default'];
}
}
$this->import('BackendUser', 'User');
$foundevents = array();
if ($deleteCalendar && $this->Input->get('id'))
{
$objDelete = $this->Database->prepare("DELETE FROM tl_calendar_events WHERE pid = ?")
->execute($this->Input->get('id'));
}
$eventArray = $this->cal->selectComponents(date('Y', $startDate->tstamp),date('m', $startDate->tstamp),date('d', $startDate->tstamp),date('Y', $endDate->tstamp),date('m', $endDate->tstamp),date('d', $endDate->tstamp),'vevent');
if (is_array($eventArray))
{
foreach( $eventArray as $year => $yearArray)
{
foreach ($yearArray as $month => $monthArray)
{
foreach( $monthArray as $day => $dailyEventsArray )
{
foreach( $dailyEventsArray as $vevent )
{
$arrFields = $defaultFields;
$currddate = $vevent->getProperty( 'x-current-dtstart' );
// if member of a recurrence set,
// returns array( 'x-current-dtstart', <DATE>)
// <DATE> = (string) date("Y-m-d [H:i:s][timezone/UTC offset]")
$dtstartraw = $vevent->getProperty( 'dtstart' , false, true);
$dtstart = $dtstartraw['value'];
$dtendraw = $vevent->getProperty( 'dtend', false, true);
$dtend = $dtendraw['value'];
$rrule = $vevent->getProperty( 'rrule' );
$summary = $vevent->getProperty( 'summary' );
$descriptionraw = $vevent->getProperty( 'description' , false, true);
$description = $descriptionraw['value'];
$location = $vevent->getProperty( 'location' );
$uid = $vevent->getProperty( 'UID' );
$fixend = (!array_key_exists('hour', $dtend)) ? 24*60*60 : 0;
$arrFields['tstamp'] = time();
$arrFields['pid'] = $this->Input->get('id');
$arrFields['published'] = 1;
$arrFields['author'] = ($this->User->id) ? $this->User->id : 0;
// set values from vevent
$arrFields['title'] = $summary;
$cleanedup = (strlen($description)) ? $description : $summary;
$cleanedup = preg_replace("/[\\r](\\\\)n(\\t){0,1}/ims", "", $cleanedup);
$cleanedup = preg_replace("/[\\r\\n]/ims", "", $cleanedup);
$cleanedup = str_replace("\\n", "<br />", $cleanedup);
$arrFields['details'] = '<p>' . $cleanedup . '</p>';
if (strlen($location)) $arrFields['details'] =
'<p><strong>' . $GLOBALS['TL_LANG']['MSC']['location'] . ':</strong> ' . $location . "</p>" . $arrFields['details'];
$timezone = (array_key_exists('TZID', $dtstartraw['params'])) ? $dtstartraw['params']['TZID'] : 'UTC';
@ini_set('date.timezone', $timezone);
@date_default_timezone_set($timezone);
$arrFields['startDate'] = mktime(0,0,0,$dtstart['month'], $dtstart['day'], $dtstart['year']);
$arrFields['addTime'] = (array_key_exists('hour', $dtstart)) ? 1 : '';
$arrFields['startTime'] = mktime($dtstart['hour'],$dtstart['min'],$dtstart['sec'],$dtstart['month'], $dtstart['day'], $dtstart['year']);
$timezone = (array_key_exists('TZID', $dtendraw['params'])) ? $dtendraw['params']['TZID'] : (($correctTimezone) ? $tz[1] : 'UTC');
@ini_set('date.timezone', $timezone);
@date_default_timezone_set($timezone);
$arrFields['endDate'] = mktime(0,0,0,$dtend['month'], $dtend['day'], $dtend['year']);
$arrFields['endTime'] = mktime($dtend['hour'],$dtend['min'],$dtend['sec'],$dtend['month'], $dtend['day'], $dtend['year']);
if ($correctTimezone)
{
@ini_set('date.timezone', $GLOBALS['TL_CONFIG']['timeZone']);
@date_default_timezone_set($GLOBALS['TL_CONFIG']['timeZone']);
$newStartTime = mktime($dtstart['hour'],$dtstart['min'],$dtstart['sec'],$dtstart['month'], $dtstart['day'], $dtstart['year']);
$diff = $arrFields['startTime'] - $newStartTime;
$arrFields['startTime'] -= $diff;
$arrFields['startDate'] -= $diff;
}
if ($correctTimezone)
{
@ini_set('date.timezone', $GLOBALS['TL_CONFIG']['timeZone']);
@date_default_timezone_set($GLOBALS['TL_CONFIG']['timeZone']);
$newEndTime = mktime($dtend['hour'],$dtend['min'],$dtend['sec'],$dtend['month'], $dtend['day'], $dtend['year']);
$diff = $arrFields['endTime'] - $newEndTime;
$arrFields['endTime'] -= $diff;
$arrFields['endDate'] -= $diff;
}
$arrFields['endDate'] -= $fixend;
$arrFields['endTime'] -= $fixend;
if (is_array($rrule))
{
$arrFields['recurring'] = 1;
$arrFields['recurrences'] = (array_key_exists('count', $rrule)) ? $rrule['count'] : 0;
$repeatEach = array();
switch ($rrule['FREQ'])
{
case 'DAILY':
$repeatEach['unit'] = 'days';
break;
case 'WEEKLY':
$repeatEach['unit'] = 'weeks';
break;
case 'MONTHLY':
$repeatEach['unit'] = 'months';
break;
case 'YEARLY':
$repeatEach['unit'] = 'years';
break;
}
$repeatEach['value'] = $rrule['INTERVAL'];
$arrFields['repeatEach'] = serialize($repeatEach);
$arrFields['repeatEnd'] = $arrFields['endTime'];
}
$foundevents[$uid]++;
if ($foundevents[$uid] <= 1)
{
$objInsertStmt = $this->Database->prepare("INSERT INTO tl_calendar_events %s")
->set($arrFields)
->execute();
if ($objInsertStmt->affectedRows)
{
$insertID = $objInsertStmt->insertId;
// Add a log entry
$this->log('A new entry in table "tl_calendar_events" has been created (ID: '.$insertID.')', 'CAlendarImport importFromICS()', TL_GENERAL);
$alias = $this->generateAlias("", $insertID);
$objUpdateStmt = $this->Database->prepare("UPDATE tl_calendar_events SET alias = ? WHERE id = ?")
->execute($alias, $insertID);
}
}
}
}
}
}
}
}
/**
* Autogenerate a event alias if it has not been set yet
* @param mixed
* @param object
* @return string
*/
public function generateAlias($varValue, $id)
{
$autoAlias = false;
// Generate alias if there is none
if (!strlen($varValue))
{
$objTitle = $this->Database->prepare("SELECT title FROM tl_calendar_events WHERE id=?")
->limit(1)
->execute($id);
$autoAlias = true;
$varValue = standardize($objTitle->title);
}
$objAlias = $this->Database->prepare("SELECT id FROM tl_calendar_events WHERE alias=?")
->executeUncached($varValue);
// Check whether the news alias exists
if ($objAlias->numRows > 1 && !$autoAlias)
{
throw new Exception(sprintf($GLOBALS['TL_LANG']['ERR']['aliasExists'], $varValue));
}
// Add ID to alias
if ($objAlias->numRows && $autoAlias)
{
$varValue .= '.' . $id;
}
return $varValue;
}
public function getConfirmationForm(DataContainer $dc, $icssource, $startDate, $endDate, $tzimport, $tzsystem, $deleteCalendar)
{
$this->Template = new BackendTemplate('be_import_calendar_confirmation');
if (strlen($tzimport))
{
$this->Template->confirmationText = sprintf(
$GLOBALS['TL_LANG']['tl_calendar_events']['confirmationTimezone'],
$tzsystem,
$tzimport
);
$this->Template->correctTimezone = $this->getCorrectTimezoneWidget();
}
else
{
$this->Template->confirmationText = sprintf(
$GLOBALS['TL_LANG']['tl_calendar_events']['confirmationMissingTZ'],
$tzsystem
);
$this->Template->timezone = $this->getTimezoneWidget($tzsystem);
}
$this->Template->startDate = $startDate;
$this->Template->endDate = $endDate;
$this->Template->icssource = $icssource;
$this->Template->deleteCalendar = $deleteCalendar;
$this->Template->hrefBack = ampersand(str_replace('&key=import', '', $this->Environment->request));
$this->Template->goBack = $GLOBALS['TL_LANG']['MSC']['goBack'];
$this->Template->headline = $GLOBALS['TL_LANG']['MSC']['import_calendar'][0];
$this->Template->request = ampersand($this->Environment->request, ENCODE_AMPERSANDS);
$this->Template->submit = specialchars($GLOBALS['TL_LANG']['tl_calendar_events']['proceed'][0]);
return $this->Template->parse();
}
public function importCalendar(DataContainer $dc)
{
if ($this->Input->get('key') != 'import')
{
return '';
}
$this->loadLanguageFile("tl_calendar_events");
$this->Template = new BackendTemplate('be_import_calendar');
$this->Template->icssource = $this->getFileTreeWidget();
$year = date('Y', time());
$tstamp = mktime(0,0,0,1,1,$year);
$defaultStartDate = date($GLOBALS['TL_CONFIG']['dateFormat'], $tstamp);
$tstamp = mktime(0,0,0,12,31,$year);
$defaultEndDate = date($GLOBALS['TL_CONFIG']['dateFormat'], $tstamp);
$this->Template->startDate = $this->getStartDateWidget($defaultStartDate);
$this->Template->endDate = $this->getEndDateWidget($defaultEndDate);
$this->Template->deleteCalendar = $this->getDeleteWidget();
$this->Template->hrefBack = ampersand(str_replace('&key=import', '', $this->Environment->request));
$this->Template->goBack = $GLOBALS['TL_LANG']['MSC']['goBack'];
$this->Template->headline = $GLOBALS['TL_LANG']['MSC']['import_calendar'][0];
$this->Template->request = ampersand($this->Environment->request, ENCODE_AMPERSANDS);
$this->Template->submit = specialchars($GLOBALS['TL_LANG']['tl_calendar_events']['import'][0]);
// Create import form
if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar' && $this->blnSave)
{
$startDate = new Date($this->Template->startDate->value, $GLOBALS['TL_CONFIG']['dateFormat']);
$endDate = new Date($this->Template->endDate->value, $GLOBALS['TL_CONFIG']['dateFormat']);
$filename = $this->Template->icssource->value;
$deleteCalendar = $this->Template->deleteCalendar->value;
if (strlen($filename)) $this->importFromICSFile($filename, $dc, $startDate, $endDate, null, null, $deleteCalendar);
}
else if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar_confirmation' && $this->blnSave)
{
$startDate = new Date($this->Input->post('startDate'), $GLOBALS['TL_CONFIG']['dateFormat']);
$endDate = new Date($this->Input->post('endDate'), $GLOBALS['TL_CONFIG']['dateFormat']);
$filename = $this->Input->post('icssource');
$deleteCalendar = $this->Input->post('deleteCalendar');
if (strlen($this->Input->post('timezone')))
{
$timezone = $this->Input->post('timezone');
$correctTimezone = null;
}
else
{
$timezone = null;
$correctTimezone = ($this->Input->post('correctTimezone')) ? true : false;
}
$this->importFromICSFile($filename, $dc, $startDate, $endDate, $correctTimezone, $timezone, $deleteCalendar);
}
return $this->Template->parse();
}
/**
* Return the file tree widget as object
* @param mixed
* @return object
*/
protected function getFileTreeWidget($value=null)
{
$widget = new FileTree();
$widget->id = 'icssource';
$widget->name = 'icssource';
$widget->strTable = 'tl_calendar_events';
$widget->strField = 'icssource';
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['icssource']['eval']['fieldType'] = 'radio';
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['icssource']['eval']['files'] = true;
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['icssource']['eval']['filesOnly'] = true;
$GLOBALS['TL_DCA']['tl_calendar_events']['fields']['icssource']['eval']['extensions'] = 'ics';
$widget->value = $value;
$widget->label = $GLOBALS['TL_LANG']['tl_calendar_events']['icssource'][0];
if ($GLOBALS['TL_CONFIG']['showHelp'] && strlen($GLOBALS['TL_LANG']['tl_calendar_events']['icssource'][1]))
{
$widget->help = $GLOBALS['TL_LANG']['tl_calendar_events']['icssource'][1];
}
// Valiate input
if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar')
{
$widget->validate();
if ($widget->hasErrors())
{
$this->blnSave = false;
}
}
return $widget;
}
/**
* Return the start date widget as object
* @param mixed
* @return object
*/
protected function getStartDateWidget($value=null)
{
$widget = new TextField();
$widget->id = 'startDate';
$widget->name = 'startDate';
$widget->mandatory = true;
$widget->required = true;
$widget->maxlength = 10;
$widget->rgxp = 'date';
$widget->datepicker = sprintf($this->getDatePickerString(), 'ctrl_startDate');
$widget->value = $value;
$widget->label = $GLOBALS['TL_LANG']['tl_calendar_events']['importStartDate'][0];
if ($GLOBALS['TL_CONFIG']['showHelp'] && strlen($GLOBALS['TL_LANG']['tl_calendar_events']['importStartDate'][1]))
{
$widget->help = $GLOBALS['TL_LANG']['tl_calendar_events']['importStartDate'][1];
}
// Valiate input
if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar')
{
$widget->validate();
if ($widget->hasErrors())
{
$this->blnSave = false;
}
}
return $widget;
}
/**
* Return the end date widget as object
* @param mixed
* @return object
*/
protected function getEndDateWidget($value=null)
{
$widget = new TextField();
$widget->id = 'endDate';
$widget->name = 'endDate';
$widget->mandatory = false;
$widget->maxlength = 10;
$widget->rgxp = 'date';
$widget->datepicker = sprintf($this->getDatePickerString(), 'ctrl_endDate');
$widget->value = $value;
$widget->label = $GLOBALS['TL_LANG']['tl_calendar_events']['importEndDate'][0];
if ($GLOBALS['TL_CONFIG']['showHelp'] && strlen($GLOBALS['TL_LANG']['tl_calendar_events']['importEndDate'][1]))
{
$widget->help = $GLOBALS['TL_LANG']['tl_calendar_events']['importEndDate'][1];
}
// Valiate input
if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar')
{
$widget->validate();
if ($widget->hasErrors())
{
$this->blnSave = false;
}
}
return $widget;
}
/**
* Return the delete calendar widget as object
* @param mixed
* @return object
*/
protected function getDeleteWidget($value=null)
{
$widget = new CheckBox();
$widget->id = 'deleteCalendar';
$widget->name = 'deleteCalendar';
$widget->mandatory = false;
$widget->options = array(array('value' => '1', 'label' => $GLOBALS['TL_LANG']['tl_calendar_events']['importDeleteCalendar'][0]));
$widget->value = $value;
if ($GLOBALS['TL_CONFIG']['showHelp'] && strlen($GLOBALS['TL_LANG']['tl_calendar_events']['importDeleteCalendar'][1]))
{
$widget->help = $GLOBALS['TL_LANG']['tl_calendar_events']['importDeleteCalendar'][1];
}
// Valiate input
if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar')
{
$widget->validate();
if ($widget->hasErrors())
{
$this->blnSave = false;
}
}
return $widget;
}
/**
* Return the correct timezone widget as object
* @param mixed
* @return object
*/
protected function getCorrectTimezoneWidget($value=null)
{
$widget = new CheckBox();
$widget->id = 'correctTimezone';
$widget->name = 'correctTimezone';
$widget->value = $value;
$widget->options = array(array('value'=>1, 'label'=>$GLOBALS['TL_LANG']['tl_calendar_events']['correctTimezone'][0]));
if ($GLOBALS['TL_CONFIG']['showHelp'] && strlen($GLOBALS['TL_LANG']['tl_calendar_events']['correctTimezone'][1]))
{
$widget->help = $GLOBALS['TL_LANG']['tl_calendar_events']['correctTimezone'][1];
}
// Valiate input
if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar_confirmation')
{
$widget->validate();
if ($widget->hasErrors())
{
$this->blnSave = false;
}
}
return $widget;
}
/**
* Return the status widget as object
* @param mixed
* @return object
*/
protected function getTimezoneWidget($value=null)
{
$widget = new SelectMenu();
$widget->id = 'timezone';
$widget->name = 'timezone';
$widget->mandatory = true;
$widget->value = $value;
$widget->label = $GLOBALS['TL_LANG']['tl_calendar_events']['timezone'][0];
if ($GLOBALS['TL_CONFIG']['showHelp'] && strlen($GLOBALS['TL_LANG']['tl_calendar_events']['timezone'][1]))
{
$widget->help = $GLOBALS['TL_LANG']['tl_calendar_events']['timezone'][1];
}
$arrOptions = array();
foreach ($this->getTimezones() as $name => $zone)
{
if (!array_key_exists($name, $arrOptions)) $arrOptions[$name] = array();
foreach ($zone as $tz)
{
$arrOptions[$name][] = array('value'=>$tz, 'label'=>$tz);
}
}
$widget->options = $arrOptions;
// Valiate input
if ($this->Input->post('FORM_SUBMIT') == 'tl_import_calendar_confirmation')
{
$widget->validate();
if ($widget->hasErrors())
{
$this->blnSave = false;
}
}
return $widget;
}
}
Lesezeichen