/** * import the data * * @param stream $_resource * @param array $_clientRecordData * @return array : * 'results' => Tinebase_Record_RecordSet, // for dryrun only * 'totalcount' => int, * 'failcount' => int, * 'duplicatecount' => int, */ public function import($_resource = NULL, $_clientRecordData = array()) { // force correct line ends require_once 'StreamFilter/StringReplace.php'; $filter = stream_filter_append($_resource, 'str.replace', STREAM_FILTER_READ, array('search' => '/(?<!\\r)\\n/', 'replace' => "\r\n", 'searchIsRegExp' => TRUE)); if (!$this->_options['importContainerId']) { throw new Tinebase_Exception_InvalidArgument('you need to define a importContainerId'); } $icalData = stream_get_contents($_resource); $parser = new qCal_Parser(); try { $ical = $parser->parse($icalData); } catch (Exception $e) { // rethrow a mal formated ics $isce = new Calendar_Exception_IcalParser(); $isce->setParseError($e); throw $isce; } $events = $this->_importResult['results'] = $this->_getEvents($ical); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Got ' . count($events) . ' events for import.'); } // print_r($events->toArray()); // set container $events->container_id = $this->_options['importContainerId']; $cc = Calendar_Controller_Event::getInstance(); $sendNotifications = $cc->sendNotifications(FALSE); // search uid's and remove already existing -> only in import cal? $existingEvents = $cc->search(new Calendar_Model_EventFilter(array(array('field' => 'container_id', 'operator' => 'equals', 'value' => $this->_options['importContainerId']), array('field' => 'uid', 'operator' => 'in', 'value' => array_unique($events->uid)))), NULL); // insert one by one in a single transaction $existingEvents->addIndices(array('uid')); foreach ($events as $event) { $existingEvent = $existingEvents->find('uid', $event->uid); try { if (!$existingEvent) { $cc->create($event, FALSE); $this->_importResult['totalcount'] += 1; } else { if ($this->_options['forceUpdateExisting'] || $this->_options['updateExisting'] && $event->seq > $existingEvent->seq) { $event->id = $existingEvent->getId(); $event->last_modified_time = clone $existingEvent->last_modified_time; $cc->update($event, FALSE); $this->_importResult['totalcount'] += 1; } else { $this->_importResult['duplicatecount'] += 1; } } } catch (Exception $e) { $this->_importResult['failcount'] += 1; } } $cc->sendNotifications($sendNotifications); return $this->_importResult; }
/** * import the data * * @param stream $_resource * @param array $_clientRecordData * @return array : * 'results' => Tinebase_Record_RecordSet, // for dryrun only * 'totalcount' => int, * 'failcount' => int, * 'duplicatecount' => int, * * @throws Calendar_Exception_IcalParser * * @see 0008334: use vcalendar converter for ics import */ public function import($_resource = NULL, $_clientRecordData = array()) { $this->_initImportResult(); if (!$this->_options['container_id']) { throw new Tinebase_Exception_InvalidArgument('you need to define a container_id'); } $converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC); if (isset($this->_options['onlyBasicData'])) { $converter->setOptions(array('onlyBasicData' => $this->_options['onlyBasicData'])); } try { $events = $converter->toTine20RecordSet($_resource); } catch (Exception $e) { Tinebase_Exception::log($e); $isce = new Calendar_Exception_IcalParser('Can not parse ics file: ' . $e->getMessage()); $isce->setParseError($e); throw $isce; } try { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' ' . ' Trying to find container with ID ' . print_r($this->_options['container_id'], true)); } $container = Tinebase_Container::getInstance()->getContainerById($this->_options['container_id']); } catch (Tinebase_Exception_InvalidArgument $e) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' ' . ' Could not found container with Id ' . print_r($this->_options['container_id'], true) . ' assuming this is a container name.'); } $container = new Tinebase_Model_Container(array('name' => $this->_options['container_id'], 'type' => Tinebase_Model_Container::TYPE_PERSONAL, 'backend' => Tinebase_User::SQL, 'color' => '#ffffff', 'application_id' => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(), 'owner_id' => Tinebase_Core::getUser()->getId(), 'model' => 'Calendar_Model_Event')); $container = Tinebase_Container::getInstance()->addContainer($container); } try { $this->_options['container_id'] = $container->getId(); } catch (Exception $ex) { throw new Tinebase_Exception_NotFound('Could not find container by ID: ' . $this->_options['container_id']); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' ' . ' Import into calendar: ' . print_r($this->_options['container_id'], true)); } $cc = Calendar_Controller_MSEventFacade::getInstance(); $sendNotifications = Calendar_Controller_Event::getInstance()->sendNotifications(FALSE); // search uid's and remove already existing -> only in import cal? $existingEventsFilter = new Calendar_Model_EventFilter(array(array('field' => 'container_id', 'operator' => 'equals', 'value' => $this->_options['container_id']), array('field' => 'uid', 'operator' => 'in', 'value' => array_unique($events->uid)))); $existingEvents = $cc->search($existingEventsFilter); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' ' . ' Found ' . count($existingEvents) . ' existing events'); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . ' ' . __LINE__ . ' ' . ' Filter: ' . print_r($existingEventsFilter->toArray(), true)); } // insert one by one in a single transaction $existingEvents->addIndices(array('uid')); foreach ($events as $event) { $existingEvent = $existingEvents->find('uid', $event->uid); try { if (!$existingEvent) { $event->container_id = $this->_options['container_id']; $event = $cc->create($event, FALSE); $this->_importResult['totalcount'] += 1; $this->_importResult['results']->addRecord($event); } else { if ($this->_options['forceUpdateExisting'] || $this->_options['updateExisting'] && $event->seq > $existingEvent->seq) { $event->id = $existingEvent->getId(); $event->last_modified_time = $existingEvent->last_modified_time instanceof Tinebase_DateTime ? clone $existingEvent->last_modified_time : NULL; $cc->update($event, FALSE); $this->_importResult['results']->addRecord($event); $this->_importResult['totalcount'] += 1; } else { $this->_importResult['duplicatecount'] += 1; } } } catch (Exception $e) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . ' ' . __LINE__ . ' Import failed for Event ' . $event->summary); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' ' . print_r($event->toArray(), TRUE)); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' ' . $e); } $this->_importResult['failcount'] += 1; } } Calendar_Controller_Event::getInstance()->sendNotifications($sendNotifications); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' ' . ' totalcount: ' . $this->_importResult['totalcount'] . ' / duplicates: ' . $this->_importResult['duplicatecount'] . ' / fails: ' . $this->_importResult['failcount']); } return $this->_importResult; }