0011470: Tine 2.0 creates additional container when importing
authorCornelius Weiß <c.weiss@metaways.de>
Fri, 4 Nov 2016 15:21:59 +0000 (16:21 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Mon, 14 Nov 2016 09:48:23 +0000 (10:48 +0100)
appointments

* 0012294: improve/cleanup scheduledImports
* fix forceUpdateExisting
* fix unittests
* remove unused options
* rework options handling
* remove import_export_definition fragments

Change-Id: I4a552093f444ddef8d1632210bd9bc67b322908b
Reviewed-on: http://gerrit.tine20.com/customers/3738
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Calendar/Import/ICalTest.php
tests/tine20/Tinebase/ScheduledImportTest.php
tine20/Calendar/Frontend/Json.php
tine20/Calendar/Import/CalDAV.php
tine20/Calendar/Import/Ical.php
tine20/Tinebase/Controller/ScheduledImport.php
tine20/Tinebase/Model/Import.php

index e6b0872..a80755f 100644 (file)
@@ -29,29 +29,17 @@ class Calendar_Import_ICalTest extends Calendar_TestCase
     /**
      * test simple import from file into a not existing container
      * 
-     *  - the calendar should be created
+     *  - should not work
+     *  - auto container creation should be done elsewhere!
      */
-    public function testSimpleImportIntoNewContainer()
+    public function testSimpleImportIntoNonExistingContainer()
     {
         $importer = new Calendar_Import_Ical(array(
             'container_id' => 'unittest_not_existing',
         ));
 
+        $this->setExpectedException('Tinebase_Exception_InvalidArgument');
         $result = $importer->importFile(dirname(__FILE__) . '/files/simple.ics');
-
-        $importedContainerId = Tinebase_Container::getInstance()->getContainerByName(
-                    'Calendar',
-                    'unittest_not_existing',
-                    Tinebase_Model_Container::TYPE_PERSONAL,
-                    Tinebase_Core::getUser()->getId()
-                )->getId();
-
-        $events = Calendar_Controller_Event::getInstance()->search(new Calendar_Model_EventFilter(array(
-            array('field' => 'container_id', 'operator' => 'equals', 'value' => $importedContainerId)
-        )), NULL);
-        
-        $this->assertEquals($importedContainerId, Tinebase_Container::getInstance()->getContainerById($importedContainerId)->getId());
-        $this->assertEquals(6, $events->count(), 'events was not imported');
     }
     
     /**
index 97e985a..54e46ce 100644 (file)
@@ -38,94 +38,64 @@ class Tinebase_ScheduledImportTest extends TestCase
     /**
      * Test create a scheduled import
      */
-    public function createScheduledImport($source = 'http://localhost/test.ics')
+    public function createScheduledImport($source = '')
     {
-        $id = Tinebase_Record_Abstract::generateUID();
+        $source = $source ?: __DIR__ . '/../Calendar/Import/files/lightning.ics';
+
         $import = new Tinebase_Model_Import(
             array(
-                'id'                => $id,
                 'user_id'           => $this->_originalTestUser->getId(),
                 'interval'          => Tinebase_Model_Import::INTERVAL_HOURLY,
                 'model'             => Calendar_Controller::getInstance()->getDefaultModel(),
                 'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(),
-                'container_id'      => $this->_testCalendar->getId(),
                 'sourcetype'        => Tinebase_Model_Import::SOURCETYPE_REMOTE,
                 'source'            => $source,
-                'options'           => json_encode(array(
-                    'forceUpdateExisting' => TRUE,
-                    'import_defintion' => NULL,
-                    'plugin' => 'Calendar_Import_Ical'
-                ))
-            )
+                'options'           => array(
+                    'forceUpdateExisting'   => TRUE,
+                    'importFileByScheduler' => TRUE,
+                    'plugin'                => 'Calendar_Import_Ical',
+                    'container_id'          => $this->_testCalendar->getId(),
+                )
+            ), true
         );
         
         $record = $this->_uit->create($import);
 
-        $this->assertEquals(Calendar_Controller::getInstance()->getDefaultModel(), $this->_uit->get($id)->model);
+        $this->assertEquals(Calendar_Controller::getInstance()->getDefaultModel(), $this->_uit->get($record->getId())->model);
 
         return $record;
     }
     
     /**
      * testNextScheduledImport
-     *
-     * TODO this should run without the need for internet access to http://www.schulferien.org
-     *      maybe we should put the file into the local filesystem
      */
     public function testNextScheduledImport()
     {
-        $this->markTestSkipped('FIXME: use local ics file for this test / see TODO in doc block');
-
-        $icsUri = 'http://www.schulferien.org/iCal/Ferien/icals/Ferien_Hamburg_2014.ics';
-        $client = new Zend_Http_Client($icsUri);
-        try {
-            $client->request()->getBody();
-        } catch (Exception $e) {
-            $this->markTestSkipped('no access to ' . $icsUri);
-        }
-
         $cc = Calendar_Controller_Event::getInstance();
         $filter = new Calendar_Model_EventFilter(array(
             array('field' => 'container_id', 'operator' => 'equals', 'value' => $this->_testCalendar->getId()),
         ));
-        
-        $all = $cc->search($filter);
-        
-        $this->assertEquals(0, $all->count());
-        
-        $now = Tinebase_DateTime::now()->subHour(1);
-        
-        $record = $this->createScheduledImport($icsUri);
-        
-        // assert setting timestamp to start value
-        $this->assertEquals($now->format('YMDHi'), $record->timestamp->format('YMDHi'));
-        
-        $record = $this->_uit->runNextScheduledImport();
 
-        $this->assertTrue($record !== null, 'import did not run');
-        
-        // assert updating timestamp after successful run
-        $now->addHour(1);
-        $this->assertEquals($now->format('YMDHi'), $record->timestamp->format('YMDHi'));
-        
+        $record = $this->createScheduledImport();
+        $this->_uit->runNextScheduledImport();
+
         $all = $cc->search($filter);
         $seq = $all->getFirstRecord()->seq;
+
         // assert all events have been imported
-        $this->assertEquals(7, $all->count());
+        $this->assertEquals(1, $all->count());
         
         // this must not be run, the interval is not exceed
         $this->_uit->runNextScheduledImport();
         $all = $cc->search($filter);
         $this->assertEquals($seq, $all->getFirstRecord()->seq);
-        
-        // setting manual timestamp to force run again
-        $record->timestamp = $record->timestamp->subHour(1)->subSecond(1);
-        
-        $this->_uit->update($record);
-        
-        $this->_uit->runNextScheduledImport();
+
+        $record = $this->_uit->get($record->getId());
+        $this->_uit->doScheduledImport($record);
+
         $all = $cc->search($filter);
-        $this->assertEquals(7, $all->count());
+        $this->assertEquals(1, $all->count());
+        $this->assertGreaterThan($seq, $all->getFirstRecord()->seq);
     }
 
     /**
index 7a0a7e6..4733ef1 100644 (file)
@@ -176,31 +176,19 @@ class Calendar_Frontend_Json extends Tinebase_Frontend_Json_Abstract
                 $plugin = 'Calendar_Import_Ical';
         }
 
-        $credentialCache = Tinebase_Auth_CredentialCache::getInstance();
-        $credentials = $credentialCache->cacheCredentials(
-            $importOptions['username'],
-            $importOptions['password'],
-            null,
-            /* persist */       true,
-            /* valid until */   Tinebase_DateTime::now()->addYear(100)
-        );
-
-        $record = Tinebase_Controller_ScheduledImport::getInstance()->createRemoteImportEvent(array(
+        $record = Tinebase_Controller_ScheduledImport::getInstance()->create( new Tinebase_Model_Import(array(
             'source'            => $remoteUrl,
+            'sourcetype'        => Tinebase_Model_Import::SOURCETYPE_REMOTE,
             'interval'          => $interval,
             'options'           => array_replace($importOptions, array(
                 'plugin' => $plugin,
                 'importFileByScheduler' => $importOptions['sourceType'] != 'remote_caldav',
-                'cid' => $credentials->getId(),
-                'ckey' => $credentials->key
             )),
             'model'             => 'Calendar_Model_Event',
-            'user_id'           => Tinebase_Core::getUser()->getId(),
             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(),
-        ));
+        ), true));
 
         $result = $this->_recordToJson($record);
-        Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . 'container_id:'  .  print_r($result['container_id'], true));
 
         return $result;
     }
index 8c91cb5..80927e5 100644 (file)
@@ -29,21 +29,47 @@ class Calendar_Import_CalDAV extends Tinebase_Import_Abstract
          */
         'updateExisting'        => true,
         /**
-         * updates exiting events if sequence number is higher
+         * update exiting events even if imported sequence number isn't higher
          * @var boolean
          */
         'forceUpdateExisting'   => false,
         /**
+         * ?
+         */
+        'allowDuplicateEvents'  => false,
+        /**
          * container the events should be imported in
          * @var string
          */
-        'container_id'     => null,
-        
+        'container_id'          => null,
+        /**
+         * url of calDAV service
+         * @var string
+         */
+        'url'                   => null,
         /**
-         * Model to be used for import
+         * username for calDAV service
          * @var string
          */
-        'model' => 'Calendar_Model_Event'
+        'username'              => null,
+        /**
+         * password for calDAV service
+         * @var string
+         */
+        'password'              => null,
+        /**
+         * credential cache id instead of username/password
+         * @var string
+         */
+        'cid'                   => null,
+        /**
+         * credential cache key instead of username/password
+         * @var string
+         */
+        'ckey'                  => null,
+
+        'model'                 => 'Calendar_Model_Event',
+
     );
     
     protected $_calDAVClient = null;
@@ -81,38 +107,20 @@ class Calendar_Import_CalDAV extends Tinebase_Import_Abstract
      */
     public function import($_resource = NULL, $_clientRecordData = array())
     {
-        $_resource['options'] = Zend_Json::decode($_resource['options']);
-        
-        $credentials = new Tinebase_Model_CredentialCache(array(
-            'id'    => $_resource['options']['cid'],
-            'key'   => $_resource['options']['ckey']
-        ));
-        Tinebase_Auth_CredentialCache::getInstance()->getCachedCredentials($credentials);
-        
-        $uri = $this->_splitUri($_resource['remoteUrl']);
+        $container = Tinebase_Container::getInstance()->getContainerById($this->_options['container_id']);
+
+        $uri = $this->_splitUri($this->_options['url']);
         
         $caldavClientOptions = array(
             'baseUri' => $uri['host'],
             'calenderUri' => $uri['path'],
-            'userName' => $credentials->username,
-            'password' => $credentials->password,
-            'allowDuplicateEvents' => isset($_resource['options']['allowDuplicateEvents']) ? $_resource['options']['allowDuplicateEvents'] : false,
+            'userName' => $this->_options['username'],
+            'password' => $this->_options['password'],
+            'allowDuplicateEvents' => $this->_options['allowDuplicateEvents'],
         );
         
-        Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
-            . ' Trying to get calendar container Name:' . $_resource['options']['container_id']);
-        $container = Tinebase_Container::getInstance()->getContainerById($this->_getImportCalendarByName($_resource['options']['container_id']));
-        
-        if ($container === false) {
-            throw new Tinebase_Exception('Could not import, aborting ..');
-            return false;
-        }
-        
-        $credentialCache = Tinebase_Auth_CredentialCache::getInstance()->cacheCredentials($credentials->username, $credentials->password);
-        Tinebase_Core::set(Tinebase_Core::USERCREDENTIALCACHE, $credentialCache);
-        
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
-            Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' Trigger CalDAV client with URI ' . $_resource['remoteUrl']);
+            Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' Trigger CalDAV client with URI ' . $this->_options['url']);
         }
         
         $this->_calDAVClient = new Calendar_Import_CalDav_Client($caldavClientOptions, 'Generic', $container->name);
@@ -120,56 +128,4 @@ class Calendar_Import_CalDAV extends Tinebase_Import_Abstract
         $this->_calDAVClient->getDecorator()->initCalendarImport();
         $this->_calDAVClient->updateAllCalendarData();
     }
-    
-    /**
-     * Return container id of newly created container for import
-     * 
-     *  - the given container name is not allowed to exist
-     * 
-     * @param type $containerName
-     * @return boolean
-     * @throws Tinebase_Exception_InvalidArgument
-     */
-    protected function _getImportCalendarByName ($containerName)
-    {
-        Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
-            . ' Get calendar by name for CalDAV import. Name:' . $containerName);
-
-        $filter = new Tinebase_Model_ContainerFilter(array(
-            array(
-                'field' => 'name', 
-                'operator' => 'equals', 
-                'value' => $containerName
-            ),
-            array(
-                'field' => 'application_id',
-                'operator' => 'equals',
-                'value' => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId()
-            )
-        ));
-        $search = Tinebase_Container::getInstance()->search($filter);
-
-        if ($search->count() > 0) {
-            Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
-                . ' Calendar already exists ' . $containerName . ' ID: ' . $search->getFirstRecord()->getId());
-            return $search->getFirstRecord()->getId();
-        }
-            
-        $container = new Tinebase_Model_Container(array(
-            'name'              => $containerName,
-            'type'              => Tinebase_Model_Container::TYPE_PERSONAL,
-            'backend'           => Tinebase_User::SQL,
-            'color'             => '#ff0000',
-            'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(),
-            'owner_id'          => Tinebase_Core::getUser()->getId(),
-            'model'             => 'Calendar_Model_Event',
-        ));
-
-        $container = Tinebase_Container::getInstance()->addContainer($container);
-
-        Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
-            . ' Added calendar ' . $containerName . ' with ID: ' . $container->getId());
-
-        return $container->getId();
-    }
-}
+ }
index 8cb3f81..c4d65dd 100644 (file)
@@ -16,8 +16,6 @@
  * 
  * @package     Calendar
  * @subpackage  Import
- * 
- * @see for german holidays http://www.sunbird-kalender.de/extension/kalender/
  */
 class Calendar_Import_Ical extends Tinebase_Import_Abstract
 {
@@ -33,7 +31,7 @@ class Calendar_Import_Ical extends Tinebase_Import_Abstract
          */
         'updateExisting'        => TRUE,
         /**
-         * updates exiting events if sequence number is higher
+         * update exiting events even if imported sequence number isn't higher
          * @var boolean
          */
         'forceUpdateExisting'   => FALSE,
@@ -45,19 +43,14 @@ class Calendar_Import_Ical extends Tinebase_Import_Abstract
          * container the events should be imported in
          * @var string
          */
-        'container_id'     => NULL,
-        
-        /**
-         * Model to be used for import
-         * @var string
-         */
-        'model' => 'Calendar_Model_Event',
-        
+        'container_id'          => NULL,
         /**
          * import only basic data (i.e. without attendee, alarms, uid, ...)
          * @var string
          */
         'onlyBasicData'         => NULL,
+
+        'model'                 => 'Calendar_Model_Event',
     );
     
     /**
@@ -90,11 +83,13 @@ class Calendar_Import_Ical extends Tinebase_Import_Abstract
     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');
-        }
-        
+
+        // make sure container exists
+        $container = Tinebase_Container::getInstance()->getContainerById($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));
+
         $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']));
@@ -108,37 +103,7 @@ class Calendar_Import_Ical extends Tinebase_Import_Abstract
             $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);
         
@@ -165,9 +130,10 @@ class Calendar_Import_Ical extends Tinebase_Import_Abstract
                     $this->_importResult['totalcount'] += 1;
                     $this->_importResult['results']->addRecord($event);
                 } else if ($this->_options['forceUpdateExisting'] || ($this->_options['updateExisting'] && $event->seq > $existingEvent->seq)) {
+                    $event->container_id = $this->_options['container_id'];
                     $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);
+                    $event = $cc->update($event, FALSE);
                     $this->_importResult['results']->addRecord($event);
                     $this->_importResult['totalcount'] += 1;
                 } else {
index 036fff4..a2593b5 100644 (file)
@@ -65,7 +65,7 @@ class Tinebase_Controller_ScheduledImport extends Tinebase_Controller_Record_Abs
     public function runNextScheduledImport()
     {
         if ($record = $this->_getNextScheduledImport()) {
-            return $this->_doScheduledImport($record)->toArray();
+            return $this->doScheduledImport($record)->toArray();
         }
         
         return NULL;
@@ -168,116 +168,110 @@ class Tinebase_Controller_ScheduledImport extends Tinebase_Controller_Record_Abs
     
     /**
      * Execute scheduled import
+     *
      * @param Tinebase_Model_Import $record
      * @return Tinebase_Model_Import
      */
-    protected function _doScheduledImport(Tinebase_Model_Import $record)
+    public function doScheduledImport(Tinebase_Model_Import $record)
     {
         $currentUser = Tinebase_Core::getUser();
         // set user who created the import job
         $importUser = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $record->user_id, 'Tinebase_Model_FullUser');
         Tinebase_Core::set(Tinebase_Core::USER, $importUser);
-        
-        $importer = $record->getOption('plugin');
-        
-        $options = array(
-            'container_id' => $record->container_id,
-            // legacy
-            'importContainerId' => $record->container_id,
-        );
-        
-        if ($record->getOption('importFileByScheduler') === true) {
-            $toImport = $this->_getFileToImport($record->source);
-        } else {
-            $toImport = array(
-                'remoteUrl'    => $record->source,
-                'container_id' => $record->container_id,
-                'options'      => $record->options
-            );
+
+        // handle options
+        $options = Zend_Json::decode($record->options);
+        $options['url'] = $record->source;
+
+        if (isset($options['cid']) && isset($options['ckey'])) {
+            $credentials = new Tinebase_Model_CredentialCache($options);
+            Tinebase_Auth_CredentialCache::getInstance()->getCachedCredentials($credentials);
+
+            $options['username'] = $credentials->username;
+            $options['password'] = $credentials->password;
         }
-        
-        if ($toImport) {
-            try {
-                $importer = new $importer($options);
-                $importer->import($toImport);
-            } catch (Exception $e) {
-                if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
-                    Tinebase_Core::getLogger()->notice(__METHOD__ . ' ' . __LINE__
-                        . ' Import failed.');
-                }
-                // TODO log failure message in import record
-                Tinebase_Exception::log($e);
-            }
 
-            $record->timestamp = Tinebase_DateTime::now();
+        $importer = $record->getOption('plugin');
+        $resource = $record->getOption('importFileByScheduler') ? $this->_getFileToImport($options['url']) : null;
 
-            // update record
-            $record = $this->update($record);
-            
-        } else {
+        try {
+            $importer = new $importer($options);
+            $importer->import($resource);
+        } catch (Exception $e) {
             if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
-                Tinebase_Core::getLogger()->notice(__METHOD__ . ' ' . __LINE__ . ' The source could not be loaded: "' . $record->source . '"');
+                Tinebase_Core::getLogger()->notice(__METHOD__ . ' ' . __LINE__
+                    . ' Import failed.');
             }
+            // TODO log failure message in import record
+            Tinebase_Exception::log($e);
         }
-        
+
+        $record->timestamp = Tinebase_DateTime::now();
+        $record = $this->update($record);
+
         Tinebase_Core::set(Tinebase_Core::USER, $currentUser);
-        
+
         return $record;
     }
-    
+
     /**
-     * Creates a remote import for events
-     * 
-     * @param string $remoteUrl
-     * @param string $interval
-     * @param array $importOptions
-     * @throws Calendar_Exception_InvalidUrl
-     * @return Tinebase_Record_Interface
+     * add one record
+     *
+     * @param   Tinebase_Model_Import $import
+     * @param   boolean $duplicateCheck
+     * @return  Tinebase_Model_Import
+     * @throws  Tinebase_Exception_AccessDenied
      */
-    public function createRemoteImportEvent($data)
+    public function create(Tinebase_Record_Interface $import, $duplicateCheck = true)
     {
-        $possibleIntervals = array(
-            Tinebase_Model_Import::INTERVAL_DAILY,
-            Tinebase_Model_Import::INTERVAL_HOURLY,
-            Tinebase_Model_Import::INTERVAL_ONCE,
-            Tinebase_Model_Import::INTERVAL_WEEKLY
-        );
-        
-        if (! in_array($data['interval'], $possibleIntervals)) {
-            $data['interval'] = Tinebase_Model_Import::INTERVAL_ONCE;
+        // handle credentials
+        if ($import->getOption('password')) {
+            $credentialCache = Tinebase_Auth_CredentialCache::getInstance();
+            $credentials = $credentialCache->cacheCredentials(
+                $import->getOption('username'),
+                $import->getOption('password'),
+                /* key */           null,
+                /* persist */       true,
+                /* valid until */   Tinebase_DateTime::now()->addYear(100)
+            );
+
+            $import->deleteOption('password');
+            $import->deleteOption('username');
+
+            $import->setOption('cid', $credentials->getId());
+            $import->setOption('ckey', $credentials->key);
         }
-        
-        // find container or create a new one
-        $containerId = $data['options']['container_id'];
-        
+
+        // options over own field
+        $containerId = $import->getOption('container_id') ?: $import->container_id;
+
+        // handle container
         try {
             $container = Tinebase_Container::getInstance()->getContainerById($containerId);
         } catch (Tinebase_Exception_InvalidArgument $e) {
             $container = new Tinebase_Model_Container(array(
-                'name'              => $data['options']['container_id'],
+                'name'              => $containerId,
                 'type'              => Tinebase_Model_Container::TYPE_PERSONAL,
                 'backend'           => Tinebase_User::SQL,
-                'color'             => '#ffffff',
-                'application_id'    => $data['application_id'],
-                'owner_id'          => $data['user_id'],
-                'model'             => $data['model'],
+                'color'             => '#ff0000',
+                'application_id'    => $import->application_id,
+                'owner_id'          => $import->user_id,
+                'model'             => $import->model,
             ));
 
             $container = Tinebase_Container::getInstance()->addContainer($container);
         }
-        
-        $data['options'] = json_encode(array_replace(array(
-            'forceUpdateExisting' => TRUE,
-            'import_defintion' => NULL,
-        ), $data['options']));
-        
-        $record = new Tinebase_Model_Import(array_replace(array(
-            'id'                => Tinebase_Record_Abstract::generateUID(),
-            'user_id'           => Tinebase_Core::getUser()->getId(),
-            'sourcetype'        => Tinebase_Model_Import::SOURCETYPE_REMOTE,
-            'container_id'      => $container->getId(),
-        ), $data));
-        
-        return $this->create($record);
+
+        $import->setOption('container_id', $container->getId());
+        $import->container_id = $container->getId();
+        $import->user_id = $import->user_id ?: Tinebase_Core::getUser()->getId();
+
+        // @TODO TBD
+        $import->setOption('forceUpdateExisting', true);
+
+        // @TODO fix schema so column id has 40 chars only
+        $import->setId(Tinebase_Record_Abstract::generateUID());
+
+        return parent::create($import, $duplicateCheck);
     }
 }
index f64c2db..c370425 100644 (file)
@@ -80,13 +80,17 @@ class Tinebase_Model_Import extends Tinebase_Record_Abstract
         'model'              => array('presence' => 'required'),
         'application_id'     => array('presence' => 'required'),
         'synctoken'          => array('allowEmpty' => true),
-        'interval'           => array('allowEmpty' => false, array(
-            'InArray', array(Tinebase_Model_Import::INTERVAL_DAILY,
-                Tinebase_Model_Import::INTERVAL_HOURLY,
+        'interval'           => array(
+            Zend_Filter_Input::ALLOW_EMPTY => false,
+            array('InArray', array(
                 Tinebase_Model_Import::INTERVAL_ONCE,
-                Tinebase_Model_Import::INTERVAL_WEEKLY)
-            )
+                Tinebase_Model_Import::INTERVAL_DAILY,
+                Tinebase_Model_Import::INTERVAL_HOURLY,
+                Tinebase_Model_Import::INTERVAL_WEEKLY
+            )),
+            Zend_Filter_Input::DEFAULT_VALUE => Tinebase_Model_Import::INTERVAL_ONCE,
         ),
+        // NOTE: if container_id is also in options, options should win
         'container_id'       => array('presence' => 'required'),
         'sourcetype'         => array('presence' => 'required'),
         'options'            => array('allowEmpty' => true),
@@ -139,7 +143,21 @@ class Tinebase_Model_Import extends Tinebase_Record_Abstract
         $options = $this->options ? Zend_Json::decode($this->options) : array();
         return isset($options[$_key]) ? $options[$_key] : NULL;
     }
-    
+
+    /**
+     * gets an option
+     *
+     * @param  string $_key
+     * @return scalar|array of scalar
+     */
+    public function deleteOption($_key)
+    {
+        $options = $this->options ? Zend_Json::decode($this->options) : array();
+        unset($options[$_key]);
+
+        $this->options = Zend_Json::encode($options);
+    }
+
     /**
      * sets the record related properties from user generated input.
      *
@@ -150,6 +168,10 @@ class Tinebase_Model_Import extends Tinebase_Record_Abstract
      */
     public function setFromArray(array $_data)
     {
+        if (isset($_data['options']) && is_array($_data['options'])) {
+            $_data['options'] = Zend_Json::encode($_data['options']);
+        }
+
         parent::setFromArray($_data);
         $timestamp = Tinebase_DateTime::now();