Merge branch 'pu/2013.10-caldav' into 2014.09
authorPhilipp Schüle <p.schuele@metaways.de>
Mon, 22 Sep 2014 09:27:47 +0000 (11:27 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Mon, 22 Sep 2014 09:27:47 +0000 (11:27 +0200)
16 files changed:
tests/tine20/Addressbook/AllTests.php
tests/tine20/Addressbook/CliTest.php
tests/tine20/Calendar/Frontend/iMIPTest.php
tests/tine20/TestCase.php
tine20/Addressbook/Frontend/Cli.php
tine20/Addressbook/Frontend/WebDAV/Contact.php
tine20/Calendar/Controller/Event.php
tine20/Calendar/Controller/MSEventFacade.php
tine20/Calendar/Frontend/WebDAV/Container.php
tine20/Calendar/Import/CalDav/Client.php
tine20/Calendar/Model/Attender.php
tine20/Calendar/Model/iMIP.php
tine20/Calendar/js/iMIPDetailsPanel.js
tine20/Tinebase/Import/CalDav/Client.php
tine20/Tinebase/Model/Container.php
tine20/Tinebase/WebDav/PrincipalBackend.php

index 5dcab9b..35e2474 100644 (file)
@@ -4,7 +4,7 @@
  * 
  * @package     Addressbook
  * @license     http://www.gnu.org/licenses/agpl.html
- * @copyright   Copyright (c) 2008 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2008-2014 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Lars Kneschke <l.kneschke@metaways.de>
  */
 
  */
 require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'TestHelper.php';
 
-if (! defined('PHPUnit_MAIN_METHOD')) {
-    define('PHPUnit_MAIN_METHOD', 'Addressbook_AllTests::main');
-}
-
 class Addressbook_AllTests
 {
     public static function main ()
@@ -42,7 +38,3 @@ class Addressbook_AllTests
         return $suite;
     }
 }
-
-if (PHPUnit_MAIN_METHOD == 'Addressbook_AllTests::main') {
-    Addressbook_AllTests::main();
-}
index 20dc5e5..a3803ab 100644 (file)
@@ -4,19 +4,14 @@
  * 
  * @package     Addressbook
  * @license     http://www.gnu.org/licenses/agpl.html
- * @copyright   Copyright (c) 2010-2013 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2010-2014 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Philipp Schüle <p.schuele@metaways.de>
  */
 
 /**
- * Test helper
- */
-require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'TestHelper.php';
-
-/**
  * Test class for Addressbook_Frontend_Cli
  */
-class Addressbook_CliTest extends PHPUnit_Framework_TestCase
+class Addressbook_CliTest extends TestCase
 {
     /**
      * Backend
@@ -26,17 +21,10 @@ class Addressbook_CliTest extends PHPUnit_Framework_TestCase
     protected $_cli;
     
     /**
-     * Runs the test methods of this class.
-     *
-     * @access public
-     * @static
+     * @var Tinebase_Model_Container
      */
-    public static function main()
-    {
-        $suite  = new PHPUnit_Framework_TestSuite('Tine 2.0 Addressbook Cli Tests');
-        PHPUnit_TextUI_TestRunner::run($suite);
-    }
-
+    protected $_container = null;
+    
     /**
      * Sets up the fixture.
      * This method is called before a test is executed.
@@ -45,20 +33,10 @@ class Addressbook_CliTest extends PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
+        parent::setUp();
+        
         $this->_cli = new Addressbook_Frontend_Cli();
-        $this->_container = Addressbook_Controller_Contact::getInstance()->getDefaultAddressbook();
-        $this->_originalGrants = Tinebase_Container::getInstance()->getGrantsOfContainer($this->_container);
-    }
-
-    /**
-     * Tears down the fixture
-     * This method is called after a test is executed.
-     *
-     * @access protected
-     */
-    protected function tearDown()
-    {
-        Tinebase_Container::getInstance()->setGrants($this->_container, $this->_originalGrants, TRUE);
+        $this->_container = $this->_getTestContainer('Addressbook');
     }
     
     /**
@@ -81,7 +59,7 @@ class Addressbook_CliTest extends PHPUnit_Framework_TestCase
      */
     public function testSetContainerGrantsWithFilterAndOverwrite()
     {
-        $nameFilter = Tinebase_Core::getUser()->accountLastName;
+        $nameFilter = $this->_container->name;
         $filter = new Tinebase_Model_ContainerFilter(array(
             array('field' => 'application_id', 'operator' => 'equals', 
                 'value' => Tinebase_Application::getInstance()->getApplicationByName('Addressbook')->getId()),
@@ -120,4 +98,32 @@ class Addressbook_CliTest extends PHPUnit_Framework_TestCase
         
         return $out;
     }
+    
+    /**
+     * testRemoveAutogeneratedContacts
+     * 
+     * @see 0010257: add cli function for deleting autogenerated contacts
+     */
+    public function testRemoveAutogeneratedContacts()
+    {
+        if (! Tinebase_Application::getInstance()->isInstalled('Calendar')) {
+            $this->markTestSkipped('only works with Calendar app');
+        }
+        
+        $attenderEmail = 'test@external.org';
+        $attenderData = array(
+            'email' => $attenderEmail
+        );
+        Calendar_Model_Attender::resolveEmailToContact($attenderData);
+        
+        $opts = new Zend_Console_Getopt('abp:');
+        $opts->setArguments(array());
+        $this->_cli->removeAutogeneratedContacts($opts);
+        
+        $filter = new Addressbook_Model_ContactFilter(array(
+            array('field' => 'email', 'operator' => 'equals', 'value' => $attenderEmail)
+        ));
+        $result = Addressbook_Controller_Contact::getInstance()->search($filter);
+        $this->assertEquals(0, count($result), 'should not find autogenerated contact any more: ' . print_r($result->toArray(), true));
+    }
 }
index db395cc..4a372bd 100644 (file)
@@ -311,8 +311,7 @@ class Calendar_Frontend_iMIPTest extends TestCase
         
         // assert REPLY message to organizer only
         $smtpConfig = Tinebase_Config::getInstance()->get(Tinebase_Config::SMTP);
-        $mailer = Calendar_Controller_EventNotificationsTests::getMailer();
-        if ($mailer instanceof Zend_Mail_Transport_Array || (isset($smtpConfig->from) && ! empty($smtpConfig->from))) {
+        if (isset($smtpConfig->from) && ! empty($smtpConfig->from)) {
             $messages = Calendar_Controller_EventNotificationsTests::getMessages();
             $this->assertEquals(1, count($messages), 'exactly one mail should be send');
             $this->assertTrue(in_array('l.kneschke@caldav.org', $messages[0]->getRecipients()), 'organizer is not a receipient');
@@ -502,7 +501,7 @@ class Calendar_Frontend_iMIPTest extends TestCase
         
         $this->assertEquals(3, count($updatedEvent->attendee));
         $this->assertEquals(Calendar_Model_Attender::STATUS_ACCEPTED, $updatedExternalAttendee->status, 'status not updated');
-    
+        
         // TEST ACCEPTABLE NON RECENT REPLY
         $updatedExternalAttendee->status = Calendar_Model_Attender::STATUS_NEEDSACTION;
         Calendar_Controller_Event::getInstance()->attenderStatusUpdate($updatedEvent, $updatedExternalAttendee, $updatedExternalAttendee->status_authkey);
@@ -519,11 +518,20 @@ class Calendar_Frontend_iMIPTest extends TestCase
         
         $this->assertEquals(3, count($updatedEvent->attendee));
         $this->assertEquals(Calendar_Model_Attender::STATUS_ACCEPTED, $updatedExternalAttendee->status, 'status not updated');
-    
+        
+        // check if attendee are resolved
+        $existingEvent = $iMIP->getExistingEvent();
+        $this->assertTrue($iMIP->existing_event->attendee instanceof Tinebase_Record_RecordSet);
+        $this->assertEquals(3, count($iMIP->existing_event->attendee));
+        
         // TEST NON ACCEPTABLE NON RECENT REPLY
-        $this->setExpectedException('Calendar_Exception_iMIP', 'iMIP preconditions failed: RECENT');
         $iMIP->preconditionsChecked = false;
-        $this->_iMIPFrontend->autoProcess($iMIP);
+        try {
+            $this->_iMIPFrontend->autoProcess($iMIP);
+            $this->fail('autoProcess should throw Calendar_Exception_iMIP');
+        } catch (Calendar_Exception_iMIP $cei) {
+            $this->assertContains('iMIP preconditions failed: RECENT', $cei->getMessage());
+        }
     }
 
     /**
index 9f7af30..8310941 100644 (file)
@@ -224,11 +224,11 @@ abstract class TestCase extends PHPUnit_Framework_TestCase
     protected function _getTestContainer($applicationName)
     {
         return Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array(
-        'name'           => 'PHPUnit test container',
-        'type'           => Tinebase_Model_Container::TYPE_PERSONAL,
-        'owner_id'       => Tinebase_Core::getUser(),
-        'backend'        => 'Sql',
-        'application_id' => Tinebase_Application::getInstance()->getApplicationByName($applicationName)->getId()
+            'name'           => 'PHPUnit test container',
+            'type'           => Tinebase_Model_Container::TYPE_PERSONAL,
+            'owner_id'       => Tinebase_Core::getUser(),
+            'backend'        => 'Sql',
+            'application_id' => Tinebase_Application::getInstance()->getApplicationByName($applicationName)->getId()
         ), true));
     }
     
index 36b51ab..aad16ce 100644 (file)
@@ -136,4 +136,44 @@ class Addressbook_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
             }
         }
     }
+
+    /**
+     * remove autogenerated contacts
+     * 
+     * @param Zend_Console_Getopt $opts
+     * 
+     * @todo use OR filter for different locales
+     */
+    public function removeAutogeneratedContacts($opts)
+    {
+        if (! Tinebase_Application::getInstance()->isInstalled('Calendar')) {
+            throw new Addressbook_Exception('Calendar application not installed');
+        }
+        
+        $params = $this->_parseArgs($opts);
+        
+        $languages = isset($params['languages']) ? $params['languages'] : array('en', 'de');
+        
+        $contactBackend = new Addressbook_Backend_Sql();
+        
+        foreach ($languages as $language) {
+            $locale = new Zend_Locale($language);
+            
+            $translation = Tinebase_Translation::getTranslation('Calendar', $locale);
+            // search all contacts with note "This contact has been automatically added by the system as an event attender"
+            $noteFilter = new Addressbook_Model_ContactFilter(array(
+                array('field' => 'note', 'operator' => 'equals', 'value' => 
+                    $translation->_('This contact has been automatically added by the system as an event attender')),
+            ));
+            $contactIdsToDelete = $contactBackend->search($noteFilter, null, Tinebase_Backend_Sql_Abstract::IDCOL);
+            
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
+                    . " About to delete " . count($contactIdsToDelete) . ' contacts ...');
+            
+            $number = $contactBackend->delete($contactIdsToDelete);
+            
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
+                    . " Deleted " . $number . ' autogenerated contacts for language ' . $language);
+        }
+    }
 }
index d262366..fef2ff9 100644 (file)
@@ -80,7 +80,12 @@ class Addressbook_Frontend_WebDAV_Contact extends Sabre\DAV\File implements Sabr
         $id = strlen($id) > 40 ? sha1($id) : $id;
         $contact->setId($id);
         
-        $contact = Addressbook_Controller_Contact::getInstance()->create($contact, false);
+        try {
+            $contact = Addressbook_Controller_Contact::getInstance()->create($contact, false);
+        } catch (Tinebase_Exception_AccessDenied $tead) {
+            Tinebase_Exception::log($tead);
+            throw new DAV\Exception\Forbidden('Access denied');
+        }
         
         $card = new self($container, $contact);
         
@@ -101,11 +106,15 @@ class Addressbook_Frontend_WebDAV_Contact extends Sabre\DAV\File implements Sabr
         sleep(1);
         
         // (re) fetch contact as tree move does not refresh src node before delete
-        // check if we are still in the same container, if not -> it is a MOVE 
-        $contact = Addressbook_Controller_Contact::getInstance()->get($this->_contact);
-        
-        if ($contact->container_id == $this->_container->getId()) {
-            Addressbook_Controller_Contact::getInstance()->delete($contact);
+        // check if we are still in the same container, if not -> it is a MOVE
+        try {
+            $contact = Addressbook_Controller_Contact::getInstance()->get($this->_contact);
+            if ($contact->container_id == $this->_container->getId()) {
+                Addressbook_Controller_Contact::getInstance()->delete($contact);
+            }
+        } catch (Tinebase_Exception_AccessDenied $tead) {
+            Tinebase_Exception::log($tead);
+            throw new DAV\Exception\Forbidden('Access denied');
         }
     }
     
@@ -252,7 +261,12 @@ class Addressbook_Frontend_WebDAV_Contact extends Sabre\DAV\File implements Sabr
             Addressbook_Convert_Contact_VCard_Abstract::OPTION_USE_SERVER_MODLOG => true,
         ));
         
-        $this->_contact = Addressbook_Controller_Contact::getInstance()->update($contact, false);
+        try {
+            $this->_contact = Addressbook_Controller_Contact::getInstance()->update($contact, false);
+        } catch (Tinebase_Exception_AccessDenied $tead) {
+            Tinebase_Exception::log($tead);
+            throw new DAV\Exception\Forbidden('Access denied');
+        }
         $this->_vcard   = null;
         
         return $this->getETag();
@@ -282,7 +296,12 @@ class Addressbook_Frontend_WebDAV_Contact extends Sabre\DAV\File implements Sabr
             $id = ($pos = strpos($this->_contact, '.')) === false ? $this->_contact : substr($this->_contact, 0, $pos);
             $id = strlen($id) > 40 ? sha1($id) : $id;
             
-            $this->_contact = Addressbook_Controller_Contact::getInstance()->get($id);
+            try {
+                $this->_contact = Addressbook_Controller_Contact::getInstance()->get($id);
+            } catch (Tinebase_Exception_AccessDenied $tead) {
+                Tinebase_Exception::log($tead);
+                throw new DAV\Exception\Forbidden('Access denied');
+            }
         }
         
         return $this->_contact;
index cb60ac0..c559bbe 100644 (file)
@@ -465,7 +465,9 @@ class Calendar_Controller_Event extends Tinebase_Controller_Record_Abstract impl
             $sendNotifications = $this->sendNotifications(FALSE);
             
             $event = $this->get($_record->getId());
-            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ .' Going to update the following event. rawdata: ' . print_r($event->toArray(), true));
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
+                    .' Going to update the following event. rawdata: ' . print_r($event->toArray(), true));
+            
             //NOTE we check via get(full rights) here whereas _updateACLCheck later checks limited rights from search
             if ($this->_doContainerACLChecks === FALSE || $event->hasGrant(Tinebase_Model_Grants::GRANT_EDIT)) {
                 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " updating event: {$_record->id} (range: {$range})");
index 703d529..312a8b6 100644 (file)
@@ -323,7 +323,6 @@ class Calendar_Controller_MSEventFacade implements Tinebase_Controller_Record_In
         
         $this->_eventController->delete($migration['toDelete']->getId());
         
-        
         // NOTE: we need to exclude the toCreate exdates here to not confuse computations in createRecurException!
         $_event->exdate = array_diff($exceptions->getOriginalDtStart(), $migration['toCreate']->getOriginalDtStart());
         $updatedBaseEvent = $this->_eventController->update($_event, $_checkBusyConflicts);
@@ -345,6 +344,10 @@ class Calendar_Controller_MSEventFacade implements Tinebase_Controller_Record_In
             $this->_prepareException($updatedBaseEvent, $exception);
             $this->_addStatusAuthkeyForOwnAttender($exception);
             
+            // skip concurrency check here by setting the seq of the current record
+            $currentException = $currentPersistentExceptions->getById($exception->getId());
+            $exception->seq = $currentException->seq;
+            
             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
                 . ' Updating exception: ' . print_r($exception->toArray(), TRUE));
             $this->_eventController->update($exception, $_checkBusyConflicts);
index 8a5e55b..823a9dd 100644 (file)
@@ -102,7 +102,7 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
                 'field'    => 'period', 
                 'operator'  => 'within', 
                 'value'     => array(
-                    'from'  => Tinebase_DateTime::now()->subWeek(4),
+                    'from'  => Tinebase_DateTime::now()->subMonth($this->_getMaxPeriodFrom()),
                     'until' => Tinebase_DateTime::now()->addYear(4)
                 )
             )
@@ -122,6 +122,9 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
             $filter->addFilter($skipPersonalFilter);
         }
         
+        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) 
+            Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Event filter: ' . print_r($filter->toArray(), true));
+        
         /**
          * see http://forge.tine20.org/mantisbt/view.php?id=5122
          * we must use action 'sync' and not 'get' as
@@ -240,7 +243,7 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
         // @see 0009162: CalDAV Performance issues for many events
         // create default time-range end in 4 years from now and 2 months back (configurable) if no filter was set by client
         if ($periodFrom === null) {
-            $periodFrom = Tinebase_DateTime::now()->subMonth(Calendar_Config::getInstance()->get(Calendar_Config::MAX_FILTER_PERIOD_CALDAV, 2));
+            $periodFrom = Tinebase_DateTime::now()->subMonth($this->_getMaxPeriodFrom());
         }
         if ($periodUntil === null) {
             $periodUntil = Tinebase_DateTime::now()->addYear(4);
@@ -267,6 +270,16 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
     }
     
     /**
+     * get max period (from) in months (default: 2)
+     * 
+     * @return integer
+     */
+    protected function _getMaxPeriodFrom()
+    {
+        return Calendar_Config::getInstance()->get(Calendar_Config::MAX_FILTER_PERIOD_CALDAV, 2);
+    }
+    
+    /**
      * (non-PHPdoc)
      * @see \Sabre\CalDAV\IShareableCalendar::getShares()
      */
index 2b26499..a6d7603 100644 (file)
@@ -34,6 +34,13 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
     protected $_uuidPrefix = '';
     
     /**
+     * record backend
+     * 
+     * @var Tinebase_Backend_Sql_Abstract
+     */
+    protected $_recordBackend = null;
+    
+    /**
      * skip those ics
      * 
      * TODO move to config
@@ -86,12 +93,18 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         
         $flavor = 'Calendar_Import_CalDav_Decorator_' . $flavor;
         $this->decorator = new $flavor($this);
+        $this->_recordBackend = Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->getBackend();
     }
     
     public function findAllCalendars()
     {
         if ('' == $this->calendarHomeSet && ! $this->findCalendarHomeSet())
+        {
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__
+                    . ' No calendar home set for user ' . $this->userName);
+            
             return false;
+        }
         
         //issue with follow location in curl!?!?
         if ($this->calendarHomeSet[strlen($this->calendarHomeSet)-1] !== '/')
@@ -237,9 +250,16 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         }
     }
     
+    /**
+     * import all calendars
+     * 
+     * @return boolean
+     */
     public function importAllCalendars()
     {
         if (count($this->calendars) < 1 && ! $this->findAllCalendars()) {
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__ 
+                . 'No calendars for user ' . $this->userName);
             return false;
         }
         
@@ -265,11 +285,60 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
             $this->decorator->setCalendarProperties($container, $this->calendars[$calUri]);
             
             $grants = $this->getCalendarGrants($calUri);
+            $this->_assureAdminGrantForOwner($container, $grants);
+            $this->_removeSyncGrantIfContainerEmpty($container, $grants);
             Tinebase_Container::getInstance()->setGrants($container->getId(), $grants, TRUE, FALSE);
         }
     }
     
     /**
+     * container owner needs admin grant
+     * 
+     * @param Tinebase_Model_Container $container
+     * @param Tinebase_Record_RecordSet $grants
+     */
+    protected function _assureAdminGrantForOwner($container, $grants)
+    {
+        $currentAccountId = Tinebase_Core::getUser()->getId();
+        foreach ($grants as $grant) {
+            if ($grant->account_id === $currentAccountId && $container->created_by === $currentAccountId && ! $grant->{Tinebase_Model_Grants::GRANT_ADMIN}) {
+                if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__
+                        . ' Set ADMIN grant for container creator');
+                $grant->{Tinebase_Model_Grants::GRANT_ADMIN} = true;
+            }
+        }
+    }
+    
+    /**
+     * remove container sync grant if empty
+     *
+     * @param Tinebase_Model_Container $container
+     * @param Tinebase_Record_RecordSet $grants
+     */
+    protected function _removeSyncGrantIfContainerEmpty($container, $grants)
+    {
+        if (/* creation_time is less than 1 hour ago */ $container->creation_time->addHour(1)->compare(Tinebase_DateTime::now()) === 1) {
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
+                    . ' Do not remove sync grant on initial import - ignore new calendars');
+            return;
+        }
+        
+        $etags = $this->_recordBackend->getEtagsForContainerId($container->getId());
+        if (count($etags)) {
+            // we found records - container not empty
+            return; 
+        }
+        
+        foreach ($grants as $grant) {
+            if ($grant->{Tinebase_Model_Grants::GRANT_SYNC}) {
+                if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__
+                        . ' Removing SYNC grant for empty ' . $this->appName . ' container ' . $container->name . ' (account: ' . $grant->account_id . ')');
+                $grant->{Tinebase_Model_Grants::GRANT_SYNC} = false;
+            }
+        }
+    }
+    
+    /**
      * decide which calendar to use as default calendar
      * if there is a remote default calendar, use that. If not, use the first we find
      * 
@@ -322,10 +391,8 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
                 . ' Looking for updates in ' . count($this->calendarICSs). ' calendars ...');
         
-        $recordBackend = Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->getBackend();
-        
         foreach ($this->calendarICSs as $calUri => $calICSs) {
-            $updateResult = $this->updateCalendar($calUri, $calICSs, $recordBackend);
+            $updateResult = $this->updateCalendar($calUri, $calICSs);
             if (count($updateResult['ics']) > 0) {
                 $newICSs[$calUri] = $updateResult['ics'];
             }
@@ -362,9 +429,8 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
      * 
      * @param string $calUri
      * @param array $calICSs
-     * @param Tinebase_Backend_Sql $recordBackend
      */
-    protected function updateCalendar($calUri, $calICSs, $recordBackend)
+    protected function updateCalendar($calUri, $calICSs)
     {
         $updateResult = array(
             'ics'       => array(),
@@ -378,7 +444,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         // get current tine20 id/etags of records
         $defaultCalendarsName = $this->_getDefaultCalendarsName();
         $container = $this->findContainerForCalendar($calUri, $this->calendars[$calUri]['displayname'], $defaultCalendarsName);
-        $containerEtags = $recordBackend->getEtagsForContainerId($container->getId());
+        $containerEtags = $this->_recordBackend->getEtagsForContainerId($container->getId());
         $otherComponentIds = $this->_getOtherComponentIds($container);
         
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' '
@@ -417,7 +483,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
                 
             } else {
                 try {
-                    $recordBackend->checkETag($data['id'], $data['etag']);
+                    $this->_recordBackend->checkETag($data['id'], $data['etag']);
                     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' '
                             . ' Ignoring delegated event from another container/organizer: ' . $data['id']);
                     continue;
@@ -636,18 +702,12 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
                     }
                 }
                 
-                $this->_setEtags($etags);
+                $this->_recordBackend->setETags($etags);
             } while($start < $max);
         }
         return true;
     }
     
-    protected function _setEtags($etags)
-    {
-        $recordBackend = Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->getBackend();
-        $recordBackend->setETags($etags);
-    }
-    
     /**
      * get Tine 2.0 group for given principal (by display name)
      * - result is cached for 1 week
index 5fc2f5b..47cd378 100644 (file)
@@ -442,7 +442,8 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
         )));
         
         if (count($contacts) > 0) {
-            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " found # of contacts " . count($contacts));
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+                    . " Found # of contacts " . count($contacts));
             $result = $contacts->getFirstRecord();
         
         } else if ($_implicitAddMissingContacts === TRUE) {
@@ -458,7 +459,8 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
                 'n_family'    => (isset($_attenderData['lastName']) && ! empty($_attenderData['lastName'])) ? $_attenderData['lastName'] : $email,
                 'n_given'     => (isset($_attenderData['firstName'])) ? $_attenderData['firstName'] : '',
             );
-            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " add new contact " . print_r($contactData, true));
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+                    . " Ádd new contact " . print_r($contactData, true));
             $contact = new Addressbook_Model_Contact($contactData);
             $result = Addressbook_Controller_Contact::getInstance()->create($contact, FALSE);
         } else {
index 585c302..b808eae 100644 (file)
@@ -196,6 +196,7 @@ class Calendar_Model_iMIP extends Tinebase_Record_Abstract
     {
         if ($_refetch || ! $this->existing_event instanceof Calendar_Model_Event) {
             $this->existing_event = Calendar_Controller_MSEventFacade::getInstance()->lookupExistingEvent($this->getEvent());
+            Calendar_Model_Attender::resolveAttendee($this->existing_event['attendee']);
         }
         
         return $this->existing_event;
index e90c9d1..af52c29 100644 (file)
@@ -178,8 +178,10 @@ Tine.Calendar.iMIPDetailsPanel = Ext.extend(Tine.Calendar.EventDetailsPanel, {
             preconditions = this.iMIPrecord.get('preconditions'),
             method = this.iMIPrecord.get('method'),
             event = this.iMIPrecord.get('event'),
-            existingEvent = this.iMIPrecord.get('existing_event'),
-            myAttenderRecord = event.getMyAttenderRecord(),
+            existingEvent = this.iMIPrecord.get('existing_event') ? Tine.Calendar.backend.recordReader({
+                responseText: Ext.util.JSON.encode(this.iMIPrecord.get('existing_event'))
+            }) : null,
+            myAttenderRecord = existingEvent ? existingEvent.getMyAttenderRecord() : event.getMyAttenderRecord(),
             myAttenderstatus = myAttenderRecord ? myAttenderRecord.get('status') : null;
             
         // show container from existing event if exists
@@ -247,13 +249,7 @@ Tine.Calendar.iMIPDetailsPanel = Ext.extend(Tine.Calendar.EventDetailsPanel, {
         singleRecordPanel.setVisible(true);
         singleRecordPanel.setHeight(150);
         
-        if (existingEvent) {
-            this.record = Tine.Calendar.backend.recordReader({
-                responseText: Ext.util.JSON.encode(existingEvent)
-            });
-        } else {
-            this.record = event;
-        }
+        this.record = existingEvent && ! preconditions ? existingEvent : event;
         singleRecordPanel.loadRecord(this.record);
     }
 });
index 4a84ac6..9dfa69c 100644 (file)
@@ -117,7 +117,7 @@ class Tinebase_Import_CalDav_Client extends \Sabre\DAV\Client
             $credentialCache = Tinebase_Auth_CredentialCache::getInstance()->cacheCredentials($this->userName, $this->password);
             Tinebase_Core::set(Tinebase_Core::USERCREDENTIALCACHE, $credentialCache);
         } catch (Tinebase_Exception_NotFound $e) {
-            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' can\'t find tine20 user: ' . $this->userName);
+            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Can\'t find tine20 user: ' . $this->userName);
             return null;
         }
         
@@ -141,7 +141,7 @@ class Tinebase_Import_CalDav_Client extends \Sabre\DAV\Client
                     unset($users[$username]);
                 }
             } catch (Tinebase_Exception $te) {
-                // TODO should use better exception (Not_Authenticatied, ...)
+                // TODO should use better exception (Not_Authenticated, ...)
                 if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) Tinebase_Core::getLogger()->notice(__METHOD__ . ' ' . __LINE__
                         . ' Skipping ' . $username);
                 unset($users[$username]);
@@ -159,6 +159,8 @@ class Tinebase_Import_CalDav_Client extends \Sabre\DAV\Client
     public function findCalendarHomeSet()
     {
         if ('' == $this->currentUserPrincipal && ! $this->findCurrentUserPrincipal(/* tries = */ 3)) {
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__
+                    . ' No principal found for user ' . $this->userName);
             return false;
         }
         $cacheId = convertCacheId('findCalendarHomeSet' . $this->userName);
index 36f1853..9ed21f1 100644 (file)
@@ -202,7 +202,7 @@ class Tinebase_Model_Container extends Tinebase_Record_Abstract
                 }
             }
             if (! $this->owner_id) {
-                throw new Exception('could not find container admin');
+                throw new Tinebase_Exception_NotFound('Could not find container admin');
             }
         }
         
index 9280bd7..b080edd 100644 (file)
@@ -48,13 +48,7 @@ class Tinebase_WebDav_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend
                 break;
                 
             case self::PREFIX_USERS:
-                $filter = new Addressbook_Model_ContactFilter(array(
-                    array(
-                        'field'     => 'type',
-                        'operator'  => 'equals',
-                        'value'     => Addressbook_Model_Contact::CONTACTTYPE_USER
-                    )
-                ));
+                $filter = $this->_getContactFilterForUserContact();
                 
                 $contacts = Addressbook_Controller_Contact::getInstance()->search($filter);
                 
@@ -143,18 +137,7 @@ class Tinebase_WebDav_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend
                     $principal = $this->_contactForSharedPrincipal();
                     
                 } else {
-                    $filter = new Addressbook_Model_ContactFilter(array(
-                        array(
-                            'field'     => 'type',
-                            'operator'  => 'equals',
-                            'value'     => Addressbook_Model_Contact::CONTACTTYPE_USER
-                        ),
-                        array(
-                            'field'     => 'id',
-                            'operator'  => 'equals',
-                            'value'     => $id
-                        ),
-                    ));
+                    $filter = $this->_getContactFilterForUserContact($id);
                     
                     $contact = Addressbook_Controller_Contact::getInstance()->search($filter)->getFirstRecord();
                     
@@ -172,6 +155,31 @@ class Tinebase_WebDav_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend
     }
     
     /**
+     * get contact filter
+     * 
+     * @param string $id
+     * @return Addressbook_Model_ContactFilter
+     */
+    protected function _getContactFilterForUserContact($id = null)
+    {
+        $filterData = array(array(
+            'field'     => 'type',
+            'operator'  => 'equals',
+            'value'     => Addressbook_Model_Contact::CONTACTTYPE_USER
+        ));
+        
+        if ($id !== null) {
+            $filterData[] = array(
+                'field'     => 'id',
+                'operator'  => 'equals',
+                'value'     => $id
+            );
+        }
+        
+        return new Addressbook_Model_ContactFilter($filterData);
+    }
+    
+    /**
      * (non-PHPdoc)
      * @see Sabre\DAVACL\IPrincipalBackend::getGroupMemberSet()
      */
@@ -217,18 +225,7 @@ class Tinebase_WebDav_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend
                     }
                     
                 } else {
-                    $filter = new Addressbook_Model_ContactFilter(array(
-                        array(
-                            'field'     => 'type',
-                            'operator'  => 'equals',
-                            'value'     => Addressbook_Model_Contact::CONTACTTYPE_USER
-                        ),
-                        array(
-                            'field'     => 'id',
-                            'operator'  => 'equals',
-                            'value'     => $id
-                        ),
-                    ));
+                    $filter = $this->_getContactFilterForUserContact($id);
                     
                     $contact = Addressbook_Controller_Contact::getInstance()->search($filter)->getFirstRecord();
                     
@@ -429,13 +426,7 @@ class Tinebase_WebDav_PrincipalBackend implements \Sabre\DAVACL\PrincipalBackend
                 break;
                 
             case self::PREFIX_USERS:
-                $filter = new Addressbook_Model_ContactFilter(array(
-                    array(
-                        'field'     => 'type',
-                        'operator'  => 'equals',
-                        'value'     => Addressbook_Model_Contact::CONTACTTYPE_USER
-                    )
-                ));
+                $filter = $this->_getContactFilterForUserContact();
                 
                 if (!empty($searchProperties['{http://calendarserver.org/ns/}search-token'])) {
                     $filter->addFilter($filter->createFilter(array(