0012300: add container owner column
authorPhilipp Schüle <p.schuele@metaways.de>
Tue, 8 Nov 2016 17:28:06 +0000 (18:28 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 16 Nov 2016 12:45:12 +0000 (13:45 +0100)
* adds "real" owner_id col
* make use of owner col (no longer get owner from acl table)
* owner -> owner_id in ContainerFilter

TODO
* allow to change owner in admin

Change-Id: Ib96d6926aab131386cd7159a750901407536ac72
Reviewed-on: http://gerrit.tine20.com/customers/3783
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
17 files changed:
tests/tine20/Addressbook/ControllerTest.php
tests/tine20/Calendar/Frontend/WebDAV/ContainerTest.php
tests/tine20/Calendar/Frontend/WebDAV/EventTest.php
tests/tine20/Tinebase/ContainerTest.php
tine20/Addressbook/Controller.php
tine20/Calendar/Controller.php
tine20/Calendar/Frontend/WebDAV/Container.php
tine20/Tasks/Controller.php
tine20/Tinebase/Container.php
tine20/Tinebase/Event.php
tine20/Tinebase/Model/Container.php
tine20/Tinebase/Model/ContainerFilter.php
tine20/Tinebase/Model/Filter/ContainerOwner.php [deleted file]
tine20/Tinebase/Model/Filter/Id.php
tine20/Tinebase/Setup/Update/Release9.php
tine20/Tinebase/Setup/setup.xml
tine20/Tinebase/User/Sql.php

index 2128d96..fa1d16b 100644 (file)
@@ -37,18 +37,6 @@ class Addressbook_ControllerTest extends PHPUnit_Framework_TestCase
     protected $_instance = NULL;
     
     /**
-     * Runs the test methods of this class.
-     *
-     * @access public
-     * @static
-     */
-    public static function main()
-    {
-        $suite  = new PHPUnit_Framework_TestSuite('Tine 2.0 Addressbook Controller Tests');
-        PHPUnit_TextUI_TestRunner::run($suite);
-    }
-
-    /**
      * Sets up the fixture.
      * This method is called before a test is executed.
      *
@@ -56,7 +44,8 @@ class Addressbook_ControllerTest extends PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->_geodata = Addressbook_Controller_Contact::getInstance()->setGeoDataForContacts(false);
+        $this->_instance = Addressbook_Controller_Contact::getInstance();
+        $this->_geodata = $this->_instance->setGeoDataForContacts(false);
         
         $personalContainer = Tinebase_Container::getInstance()->getPersonalContainer(
             Zend_Registry::get('currentAccount'), 
@@ -157,8 +146,6 @@ class Addressbook_ControllerTest extends PHPUnit_Framework_TestCase
             'note_type_id'      => 1,
             'note'              => 'phpunit test note',    
         ));
-        
-        $this->_instance = Addressbook_Controller_Contact::getInstance();
     }
 
     /**
index beb7ab2..050c152 100644 (file)
@@ -52,7 +52,12 @@ class Calendar_Frontend_WebDAV_ContainerTest extends PHPUnit_Framework_TestCase
             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(),
         )));
         
-        Tinebase_Container::getInstance()->addGrants($this->objects['initialContainer'], Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP, Tinebase_Core::getUser()->accountPrimaryGroup, array(Tinebase_Model_Grants::GRANT_READ));
+        Tinebase_Container::getInstance()->addGrants(
+            $this->objects['initialContainer'],
+            Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP,
+            Tinebase_Core::getUser()->accountPrimaryGroup,
+            array(Tinebase_Model_Grants::GRANT_READ)
+        );
 
         // rw cal agent
         $_SERVER['HTTP_USER_AGENT'] = 'CalendarStore/5.0 (1127); iCal/5.0 (1535); Mac OS X/10.7.1 (11B26)';
@@ -362,9 +367,10 @@ class Calendar_Frontend_WebDAV_ContainerTest extends PHPUnit_Framework_TestCase
         
         $shares = $container->getShares();
 
-        $this->assertEquals(3, count($shares));
+        $this->assertEquals(2, count($shares), 'should find 2 shares');
         $this->assertEquals('urn:uuid:anyone', $shares[0]['href']);
-        $this->assertEquals('urn:uuid:' . Tinebase_Core::getUser()->contact_id, $shares[2]['href']);
+        $this->assertEquals('urn:uuid:'
+            . Tinebase_Group::getInstance()->getGroupById(Tinebase_Core::getUser()->accountPrimaryGroup)->list_id, $shares[1]['href']);
     }
     
     /**
index 85e683e..8871fb7 100644 (file)
@@ -398,13 +398,13 @@ class Calendar_Frontend_WebDAV_EventTest extends Calendar_TestCase
         $egt = new Calendar_Controller_EventGrantsTests();
         $egt->setup();
         
-        $pwulfPersonalCal = $this->_getPersonasDefaultCals('sclever');
-        $pwulf = new Calendar_Model_Attender(array(
+        $scleverCalendar = $this->_getPersonasDefaultCals('sclever');
+        $sclever = new Calendar_Model_Attender(array(
             'user_type'    => Calendar_Model_Attender::USERTYPE_USER,
             'user_id'      => $this->_getPersonasContacts('sclever')->getId(),
         ));
         
-        $this->_testEventMissingAttendee($pwulfPersonalCal, $pwulf);
+        $this->_testEventMissingAttendee($scleverCalendar, $sclever);
     }
     
     /**
index faee496..9075ca8 100644 (file)
@@ -520,26 +520,26 @@ class Tinebase_ContainerTest extends PHPUnit_Framework_TestCase
     
     /**
      * get not disabled users
-     *
      */
     public function testGetNotDisabledUsers()
     {
-        $user1 = Tinebase_User::getInstance()->getUserByLoginName('jsmith');
-        $user2 = Tinebase_User::getInstance()->getUserByLoginName('pwulf');
-        
-        Tinebase_User::getInstance()->setStatus($user2, 'enabled');
+        $user = Tinebase_User::getInstance()->getUserByLoginName('jsmith');
+        Tinebase_User::getInstance()->setStatus($user, 'enabled');
         
-        $container = Tinebase_Container::getInstance()->getPersonalContainer($user1, 'Calendar', $user1, Tinebase_Model_Grants::GRANT_READ);
+        $container = Tinebase_Container::getInstance()->getPersonalContainer(
+            $user, 'Calendar', $user, Tinebase_Model_Grants::GRANT_READ
+        )->getFirstRecord();
 
-        $this->assertGreaterThan(0, count($container));
-        
-        $oldGrants = Tinebase_Container::getInstance()->getGrantsOfContainer($container->getFirstRecord()->id, TRUE);
+        $this->assertTrue($container !== null);
+        $this->assertEquals($user->getId(), $container->owner_id);
         
+        $oldGrants = Tinebase_Container::getInstance()->getGrantsOfContainer($container->id, TRUE);
+
         $newGrants = new Tinebase_Record_RecordSet('Tinebase_Model_Grants');
         $newGrants->addRecord(
             new Tinebase_Model_Grants(
                 array(
-                    'account_id'    => $user1->accountId,
+                    'account_id'    => $user->accountId,
                     'account_type'  => 'user',
                     Tinebase_Model_Grants::GRANT_READ     => true,
                     Tinebase_Model_Grants::GRANT_ADD      => true,
@@ -552,37 +552,37 @@ class Tinebase_ContainerTest extends PHPUnit_Framework_TestCase
         $newGrants->addRecord(
             new Tinebase_Model_Grants(
                 array(
-                    'account_id'    => $user2->accountId,
+                    'account_id'    => Tinebase_Core::getUser()->getId(),
                     'account_type'  => 'user',
                     Tinebase_Model_Grants::GRANT_READ     => true,
                     Tinebase_Model_Grants::GRANT_ADD      => true,
                     Tinebase_Model_Grants::GRANT_EDIT     => true,
                     Tinebase_Model_Grants::GRANT_DELETE   => true,
-                    Tinebase_Model_Grants::GRANT_ADMIN    => true
                 )
             )
         );
-        
-        Tinebase_Container::getInstance()->setGrants($container->getFirstRecord()->id, $newGrants, TRUE);
-        
-        $otherUsers = Tinebase_Container::getInstance()->getOtherUsers($user1, 'Calendar', array(
+
+        Tinebase_Container::getInstance()->setGrants($container->id, $newGrants, TRUE);
+
+        $otherUsers = Tinebase_Container::getInstance()->getOtherUsers(Tinebase_Core::getUser(), 'Calendar', array(
             Tinebase_Model_Grants::GRANT_READ
         ));
         
-        $this->assertEquals(1, $otherUsers->filter('accountId', $user2->accountId)->count());
+        $this->assertEquals(1, $otherUsers->filter('accountId', $user->accountId)->count(), 'should find jsmiths container');
         
-        Tinebase_User::getInstance()->setStatus($user2, 'disabled');
+        Tinebase_User::getInstance()->setStatus($user, 'disabled');
 
         Tinebase_Cache_PerRequest::getInstance()->reset();
 
-        $otherUsers = Tinebase_Container::getInstance()->getOtherUsers($user1, 'Calendar', array(
+        $otherUsers = Tinebase_Container::getInstance()->getOtherUsers(Tinebase_Core::getUser()->getId(), 'Calendar', array(
             Tinebase_Model_Grants::GRANT_READ
         ));
+
+        // TODO move to tear down
+        Tinebase_User::getInstance()->setStatus($user, 'enabled');
+        Tinebase_Container::getInstance()->setGrants($container->id, $oldGrants, TRUE);
         
-        Tinebase_User::getInstance()->setStatus($user2, 'enabled');
-        Tinebase_Container::getInstance()->setGrants($container->getFirstRecord()->id, $oldGrants, TRUE);
-        
-        $this->assertEquals(0, $otherUsers->filter('accountId', $user2->accountId)->count());
+        $this->assertEquals(0, $otherUsers->filter('accountId', $user->accountId)->count(), 'should not find jsmiths container');
     }
     
     /**
@@ -609,7 +609,7 @@ class Tinebase_ContainerTest extends PHPUnit_Framework_TestCase
     public function testSearchContainerByOwner()
     {
         $filter = new Tinebase_Model_ContainerFilter(array(
-            array('field' => 'owner', 'operator' => 'equals', 'value' => Tinebase_Core::getUser()->getId())
+            array('field' => 'owner_id', 'operator' => 'equals', 'value' => Tinebase_Core::getUser()->getId())
         ));
         $result = Tinebase_Container::getInstance()->search($filter);
         
index ad35cda..4788f17 100644 (file)
@@ -119,7 +119,7 @@ class Addressbook_Controller extends Tinebase_Controller_Event implements Tineba
         $newContainer = new Tinebase_Model_Container(array(
             'name'              => sprintf($translation->_("%s's personal addressbook"), $account->accountFullName),
             'type'              => Tinebase_Model_Container::TYPE_PERSONAL,
-            'owner_id'          => $_account,
+            'owner_id'          => $account->getId(),
             'backend'           => 'Sql',
             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName($this->_applicationName)->getId(),
             'model'             => 'Addressbook_Model_Contact'
index 85fd26f..1e2da39 100644 (file)
@@ -59,7 +59,7 @@ class Calendar_Controller extends Tinebase_Controller_Event implements Tinebase_
      */
     protected function _handleEvent(Tinebase_Event_Abstract $_eventObject)
     {
-        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . ' (' . __LINE__ . ') handle event of type ' . get_class($_eventObject));
+        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . ' ' . __LINE__ . ' handle event of type ' . get_class($_eventObject));
         
         switch (get_class($_eventObject)) {
             case 'Admin_Event_AddAccount':
@@ -78,16 +78,16 @@ class Calendar_Controller extends Tinebase_Controller_Event implements Tinebase_
                 break;
                 
             case 'Admin_Event_UpdateGroup':
-                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') updated group ' . $_eventObject->group->name);
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' updated group ' . $_eventObject->group->name);
                 Tinebase_ActionQueue::getInstance()->queueAction('Calendar.onUpdateGroup', $_eventObject->group->getId());
                 break;
             case 'Admin_Event_AddGroupMember':
-                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') add groupmember ' . (string) $_eventObject->userId . ' to group ' . (string) $_eventObject->groupId);
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' add groupmember ' . (string) $_eventObject->userId . ' to group ' . (string) $_eventObject->groupId);
                 Tinebase_ActionQueue::getInstance()->queueAction('Calendar.onUpdateGroup', $_eventObject->groupId);
                 break;
                 
             case 'Admin_Event_RemoveGroupMember':
-                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') removed groupmember ' . (string) $_eventObject->userId . ' from group ' . (string) $_eventObject->groupId);
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__ . ' removed groupmember ' . (string) $_eventObject->userId . ' from group ' . (string) $_eventObject->groupId);
                 Tinebase_ActionQueue::getInstance()->queueAction('Calendar.onUpdateGroup', $_eventObject->groupId);
                 break;
                 
@@ -289,7 +289,7 @@ class Calendar_Controller extends Tinebase_Controller_Event implements Tinebase_
         $newContainer = new Tinebase_Model_Container(array(
             'name'              => sprintf($translation->_("%s's personal calendar"), $account->accountFullName),
             'type'              => Tinebase_Model_Container::TYPE_PERSONAL,
-            'owner_id'          => $_account,
+            'owner_id'          => $account->getId(),
             'backend'           => Tinebase_User::SQL,
             'color'             => '#FF6600',
             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(),
@@ -311,7 +311,8 @@ class Calendar_Controller extends Tinebase_Controller_Event implements Tinebase_
      */
     protected function _handleContainerBeforeCreateEvent(Tinebase_Event_Container_BeforeCreate $_eventObject)
     {
-        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->INFO(__METHOD__ . ' (' . __LINE__ . ') about to handle Tinebase_Event_Container_BeforeCreate' );
+        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->INFO(__METHOD__ . ' ' . __LINE__
+            . ' about to handle Tinebase_Event_Container_BeforeCreate' );
         
         if ($_eventObject->container && 
             $_eventObject->container->type === Tinebase_Model_Container::TYPE_PERSONAL &&
index b72faf5..f86ce4c 100644 (file)
@@ -385,6 +385,7 @@ class Calendar_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstr
                     break;
                     
                 case 'user':
+                    // apple clients don't want own shares ...
                     if ((string)$this->_container->owner_id === (string)$grant->account_id) {
                         continue 2;
                     }
index cc07b28..ffc44d1 100644 (file)
@@ -101,7 +101,7 @@ class Tasks_Controller extends Tinebase_Controller_Event implements Tinebase_Con
         $newContainer = new Tinebase_Model_Container(array(
             'name'              => sprintf($translation->_("%s's personal tasks"), $account->accountFullName),
             'type'              => Tinebase_Model_Container::TYPE_PERSONAL,
-            'owner_id'          => $_accountId,
+            'owner_id'          => $account->getId(),
             'backend'           => 'Sql',
             'application_id'    => Tinebase_Application::getInstance()->getApplicationByName('Tasks')->getId(),
             'model'             => static::$_defaultModel
index 59e8cd1..35e64d2 100644 (file)
@@ -168,10 +168,13 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
             }
         }
         
-        if (!empty($_container->owner_id)) {
+        if (! empty($_container->owner_id)) {
             $accountId = $_container->owner_id instanceof Tinebase_Model_User ? $_container->owner_id->getId() : $_container->owner_id;
         } else {
             $accountId = (is_object(Tinebase_Core::getUser())) ? Tinebase_Core::getUser()->getId() : NULL;
+            if ($_container->type === Tinebase_Model_Container::TYPE_PERSONAL) {
+                $_container->owner_id = $accountId;
+            }
         }
         
         if($_grants === NULL || count($_grants) == 0) {
@@ -221,7 +224,10 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
         Tinebase_Timemachine_ModificationLog::setRecordMetaData($_container, 'create');
         $container = $this->create($_container);
         $this->setGrants($container->getId(), $grants, TRUE, FALSE);
-        
+
+        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::'
+            . __LINE__ . ' Created new ' . $_container->type . ' container for account id ' . $accountId);
+
         return $container;
     }
     
@@ -295,7 +301,8 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
             $split = explode('_', $_recordClass);
             switch(count($split)) {
                 case 1:
-                    if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Using application name is deprecated. Please use the classname of the model or the class itself.');
+                    if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::'
+                        . __LINE__ . ' Using application name is deprecated. Please use the classname of the model or the class itself.');
                     $ret['appName'] = $_recordClass;
                     if(! $ret['recordClass'] = Tinebase_Core::getApplicationInstance($_recordClass)->getDefaultModel()) {
                         throw new Tinebase_Exception_NotFound('A default model could not be found for application ' . $_recordClass);
@@ -335,32 +342,7 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
         
         return $this->update($container);
     }
-    
-    /**
-    * get the basic select object to fetch records from the database
-    *
-    * @param array|string $_cols columns to get, * per default
-    * @param boolean $_getDeleted get deleted records (if modlog is active)
-    * @return Zend_Db_Select
-    */
-    protected function _getSelect($_cols = '*', $_getDeleted = FALSE)
-    {
-        $select = parent::_getSelect($_cols, $_getDeleted);
-        
-        if ($_cols === '*') {
-            $select->joinLeft(
-                /* table  */ array('owner' => SQL_TABLE_PREFIX . 'container_acl'),
-                /* on     */ "{$this->_db->quoteIdentifier('owner.container_id')} = {$this->_db->quoteIdentifier('container.id')} AND ".
-                             "{$this->_db->quoteIdentifier('container.type')} = {$this->_db->quote(Tinebase_Model_Container::TYPE_PERSONAL)} AND " .
-                             "{$this->_db->quoteIdentifier('owner.account_type')} = {$this->_db->quote('user')} AND " .
-                             "{$this->_db->quoteIdentifier('owner.account_grant')} = {$this->_db->quote(Tinebase_Model_Grants::GRANT_ADMIN)}",
-                /* select */ array('owner_id' => 'account_id')
-            );
-        }
-        
-        return $select;
-    }
-    
+
     /**
      * get containers with bad names (name == uuid)
      * 
@@ -538,7 +520,7 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
             ->where("{$this->_db->quoteIdentifier('container.is_deleted')} = ?", 0, Zend_Db::INT_TYPE);
 
         if ($type == Tinebase_Model_Container::TYPE_PERSONAL) {
-            $select->where("{$this->_db->quoteIdentifier('owner.account_id')} = ?", $ownerId);
+            $select->where("{$this->_db->quoteIdentifier('owner_id')} = ?", $ownerId);
         }
         
         $stmt = $this->_db->query('/*' . __FUNCTION__ . '*/' . $select);
@@ -590,28 +572,22 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
         }
         
         $select = $this->_db->select()
-            ->distinct()
-            ->from(array('owner' => SQL_TABLE_PREFIX . 'container_acl'), array())
+            ->distinct() // TODO needed?
+            ->from(array('container' => SQL_TABLE_PREFIX . 'container'))
             ->join(array(
-                /* table  */ 'user' => SQL_TABLE_PREFIX . 'container_acl'), 
-                /* on     */ "{$this->_db->quoteIdentifier('owner.container_id')} = {$this->_db->quoteIdentifier('user.container_id')}",
+                /* table  */ 'container_acl' => SQL_TABLE_PREFIX . 'container_acl'),
+                /* on     */ "{$this->_db->quoteIdentifier('container.id')} = {$this->_db->quoteIdentifier('container_acl.container_id')}",
                 /* select */ array()
             )
-            ->join(array(
-                /* table  */ 'container' => SQL_TABLE_PREFIX . 'container'), 
-                /* on     */ "{$this->_db->quoteIdentifier('owner.container_id')} = {$this->_db->quoteIdentifier('container.id')}"
-            )
-            
-            ->where("{$this->_db->quoteIdentifier('owner.account_id')} = ?", $ownerId)
-            ->where("{$this->_db->quoteIdentifier('owner.account_grant')} = ?", Tinebase_Model_Grants::GRANT_ADMIN)
-            
+
             ->where("{$this->_db->quoteIdentifier('container.application_id')} = ?", $application->getId())
             ->where("{$this->_db->quoteIdentifier('container.type')} = ?", Tinebase_Model_Container::TYPE_PERSONAL)
             ->where("{$this->_db->quoteIdentifier('container.is_deleted')} = ?", 0, Zend_Db::INT_TYPE)
-            
+            ->where("{$this->_db->quoteIdentifier('container.owner_id')} = ?", $ownerId)
+
             ->order('container.name');
             
-        $this->addGrantsSql($select, $accountId, $grant, 'user');
+        $this->addGrantsSql($select, $accountId, $grant);
         
         if ($meta['recordClass']) {
             $select->where("{$this->_db->quoteIdentifier('container.model')} = ?", $meta['recordClass']);
@@ -686,7 +662,7 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
      * @param  Zend_Db_Select    $_select
      * @param  String            $_accountId
      * @param  Array|String      $_grant
-     * @param  String            $_aclTableName
+     * @param  String            $_aclTableName (deprecated)
      * @param  bool              $_andGrants
      * @return void
      */
@@ -921,48 +897,26 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
             // continue...
         }
 
-        // first grab all container ids ...
         $select = $this->_db->select()
-            ->distinct()
-            ->from(array('container_acl' => SQL_TABLE_PREFIX . 'container_acl'), array())
+            ->from(array('container' => SQL_TABLE_PREFIX . 'container'), array('owner_id'))
             ->join(array(
-                /* table  */ 'container' => SQL_TABLE_PREFIX . 'container'), 
+                /* table  */ 'container_acl' => SQL_TABLE_PREFIX . 'container_acl'),
                 /* on     */ "{$this->_db->quoteIdentifier('container_acl.container_id')} = {$this->_db->quoteIdentifier('container.id')}",
                 /* select */ array('container_id' => 'container.id')
             )
-            ->where("{$this->_db->quoteIdentifier('container.application_id')} = ?", $application->getId())
-            ->where("{$this->_db->quoteIdentifier('container.type')} = ?", Tinebase_Model_Container::TYPE_PERSONAL)
-            ->where("{$this->_db->quoteIdentifier('container.is_deleted')} = ?", 0, Zend_Db::INT_TYPE);
-
-        $this->addGrantsSql($select, $accountId, $grant, 'container_acl', $_andGrants, __CLASS__ . '::addGrantsSqlCallback');
-
-        $stmt = $this->_db->query('/*' . __FUNCTION__ . '*/' . $select);
-        $containerIds = $stmt->fetchAll(Zend_Db::FETCH_COLUMN);
-        
-        // no container ids found / can stop here
-        if (empty($containerIds)) {
-            return $containerIds;
-        }
-        
-        // ... now get the owners of the containers 
-        $select = $this->_db->select()
-            ->distinct()
-            ->from(array('container_acl' => SQL_TABLE_PREFIX . 'container_acl'), array('account_id'))
-            ->join(array(
-                /* table  */ 'container' => SQL_TABLE_PREFIX . 'container'), 
-                /* on     */ "{$this->_db->quoteIdentifier('container_acl.container_id')} = {$this->_db->quoteIdentifier('container.id')}",
-                /* select */ array()
-            )
             ->join(array(
                 /* table  */ 'accounts' => SQL_TABLE_PREFIX . 'accounts'),
-                /* on     */ "{$this->_db->quoteIdentifier('container_acl.account_id')} = {$this->_db->quoteIdentifier('accounts.id')}",
+                /* on     */ "{$this->_db->quoteIdentifier('container.owner_id')} = {$this->_db->quoteIdentifier('accounts.id')}",
                 /* select */ array()
             )
-            ->where("{$this->_db->quoteIdentifier('container.id')} IN (?)", $containerIds)
-            ->where("{$this->_db->quoteIdentifier('container_acl.account_id')} != ?", $accountId)
-            ->where("{$this->_db->quoteIdentifier('container_acl.account_grant')} = ?", Tinebase_Model_Grants::GRANT_ADMIN)
+            ->where("{$this->_db->quoteIdentifier('container.application_id')} = ?", $application->getId())
+            ->where("{$this->_db->quoteIdentifier('container.type')} = ?", Tinebase_Model_Container::TYPE_PERSONAL)
+            ->where("{$this->_db->quoteIdentifier('container.is_deleted')} = ?", 0, Zend_Db::INT_TYPE)
+            ->where("{$this->_db->quoteIdentifier('container.owner_id')} != ?", $accountId)
             ->where("{$this->_db->quoteIdentifier('accounts.status')} = ?", 'enabled');
-            
+
+        $this->addGrantsSql($select, $accountId, $grant, 'container_acl', $_andGrants, __CLASS__ . '::addGrantsSqlCallback');
+
         $stmt = $this->_db->query('/*' . __FUNCTION__ . '*/' . $select);
         $accountIds = $stmt->fetchAll(Zend_Db::FETCH_COLUMN);
 
@@ -1016,38 +970,26 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
         }
         
         $select = $this->_db->select()
-            ->from(array('owner' => SQL_TABLE_PREFIX . 'container_acl'), array('account_id'))
+            ->from(array('container' => SQL_TABLE_PREFIX . 'container'), array('owner_id'))
             ->join(array(
-                /* table  */ 'user' => SQL_TABLE_PREFIX . 'container_acl'), 
-                /* on     */ "{$this->_db->quoteIdentifier('owner.container_id')} = {$this->_db->quoteIdentifier('user.container_id')}",
+                /* table  */ 'container_acl' => SQL_TABLE_PREFIX . 'container_acl'),
+                /* on     */ "{$this->_db->quoteIdentifier('container.id')} = {$this->_db->quoteIdentifier('container_acl.container_id')}",
                 /* select */ array()
             )
             ->join(array(
-                /* table  */ 'container' => SQL_TABLE_PREFIX . 'container'), 
-                /* on     */ "{$this->_db->quoteIdentifier('owner.container_id')} = {$this->_db->quoteIdentifier('container.id')}"
-            )
-            ->join(array(
                 /* table  */ 'accounts' => SQL_TABLE_PREFIX . 'accounts'),
-                /* on     */ "{$this->_db->quoteIdentifier('owner.account_id')} = {$this->_db->quoteIdentifier('accounts.id')}",
+                /* on     */ "{$this->_db->quoteIdentifier('container.owner_id')} = {$this->_db->quoteIdentifier('accounts.id')}",
                 /* select */ array()
             )
-            #->join(array(
-            #    /* table  */ 'contacts' => SQL_TABLE_PREFIX . 'addressbook'),
-            #    /* on     */ "{$this->_db->quoteIdentifier('owner.account_id')} = {$this->_db->quoteIdentifier('contacts.account_id')}",
-            #    /* select */ array()
-            #)
-            ->where("{$this->_db->quoteIdentifier('owner.account_id')} != ?", $accountId)
-            ->where("{$this->_db->quoteIdentifier('owner.account_grant')} = ?", Tinebase_Model_Grants::GRANT_ADMIN)
-            
             ->where("{$this->_db->quoteIdentifier('container.application_id')} = ?", $application->getId())
             ->where("{$this->_db->quoteIdentifier('container.type')} = ?", Tinebase_Model_Container::TYPE_PERSONAL)
             ->where("{$this->_db->quoteIdentifier('container.is_deleted')} = ?", 0, Zend_Db::INT_TYPE)
             ->where("{$this->_db->quoteIdentifier('accounts.status')} = ?", 'enabled')
             
             ->order('accounts.display_name')
-            ->group('owner.account_id');
+            ->group('owner_id');
         
-        $this->addGrantsSql($select, $accountId, $grant, 'user');
+        $this->addGrantsSql($select, $accountId, $grant);
         
         Tinebase_Backend_Sql_Abstract::traitGroup($select);
         
@@ -1586,6 +1528,10 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
                 . ' Only personal containers have an owner.');
             return FALSE;
         }
+
+        if ($_container->owner_id) {
+            return $_container->owner_id;
+        }
         
         $grants = (! $_container->account_grants) ? $this->getGrantsOfContainer($_container, true) : $_container->account_grants;
         
@@ -1614,6 +1560,8 @@ class Tinebase_Container extends Tinebase_Backend_Sql_Abstract
      * @param $_container
      * @throws Tinebase_Exception_Record_NotAllowed
      * @throws Tinebase_Exception_UnexpectedValue
+     *
+     * @deprecated: could be removed because we have an owner property and could have multiple admins for a personal container now
      */
     public function checkContainerOwner(Tinebase_Model_Container $_container)
     {
index eecd932..f687d96 100644 (file)
@@ -46,15 +46,17 @@ class Tinebase_Event
                 continue;
             }
             if($controller instanceof Tinebase_Event_Interface) {
-                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') calling eventhandler for event ' . get_class($_eventObject) . ' of application ' . (string) $application);
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' '
+                    . __LINE__ . ' calling eventhandler for event ' . get_class($_eventObject) . ' of application ' . (string) $application);
                 try {
                     $controller->handleEvent($_eventObject);
                 } catch (Exception $e) {
-                    if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) Tinebase_Core::getLogger()->notice(__METHOD__ . ' (' . __LINE__ . ') ' 
-                        . (string) $application . ' threw an exception: '
+                    if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) Tinebase_Core::getLogger()->notice(__METHOD__ . ' '
+                        . __LINE__ . ' ' . (string) $application . ' threw an exception: '
                         . $e->getMessage()
                     );
-                    if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' (' . __LINE__ . ') ' . $e->getTraceAsString());
+                    if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' '
+                        . __LINE__ . ' ' . $e->getTraceAsString());
                 }
             }
         }
@@ -64,12 +66,12 @@ class Tinebase_Event
             if (@class_exists('CustomEventHooks')) {
                 $methods = get_class_methods('CustomEventHooks');
                 if (in_array('handleEvent', (array)$methods)) {
-                    Tinebase_Core::getLogger()->info(__METHOD__ . ' (' . __LINE__ . ') ' . ' about to process user defined event hook for '. get_class($_eventObject));
+                    Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__ . ' ' . ' about to process user defined event hook for '. get_class($_eventObject));
                     CustomEventHooks::handleEvent($_eventObject);
                 }
             }
         } catch (Exception $e) {
-            Tinebase_Core::getLogger()->info(__METHOD__ . ' (' . __LINE__ . ') ' . ' failed to process user defined event hook with message: ' . $e);
+            Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__ . ' ' . ' failed to process user defined event hook with message: ' . $e);
         }
         
         unset(self::$events[get_class($_eventObject)][$_eventObject->getId()]);
index 26d4ed2..c3e3173 100644 (file)
@@ -55,10 +55,10 @@ class Tinebase_Model_Container extends Tinebase_Record_Abstract
      * @var string
      */
     protected $_application = 'Tinebase';
-    
+
     /**
      * list of zend inputfilter
-     * 
+     *
      * this filter get used when validating user generated content with Zend_Input_Filter
      *
      * @var array
@@ -66,10 +66,10 @@ class Tinebase_Model_Container extends Tinebase_Record_Abstract
     protected $_filters = array(
         'name'              => 'StringTrim'
     );
-    
+
     /**
      * list of zend validator
-     * 
+     *
      * this validators get used when validating user generated content with Zend_Input_Filter
      *
      * @var array
@@ -82,14 +82,14 @@ class Tinebase_Model_Container extends Tinebase_Record_Abstract
         'color'             => array('allowEmpty' => true, array('regex', '/^#[0-9a-fA-F]{6}$/')),
         'application_id'    => array('Alnum', 'presence' => 'required'),
         'account_grants'    => array('allowEmpty' => true), // non persistent
-        'owner_id'          => array('allowEmpty' => true), // non persistent + only set for personal folders
+        'owner_id'          => array('allowEmpty' => true),
         'path'              => array('allowEmpty' => true), // non persistent
         'model'             => array('allowEmpty' => true),
         'uuid'              => array('allowEmpty' => true),
-        
+
     // only gets updated in increaseContentSequence() + readonly in normal record context
         'content_seq'       => array('allowEmpty' => true),
-    
+
     // modlog fields
         'created_by'             => array('allowEmpty' => true),
         'creation_time'          => array('allowEmpty' => true),
@@ -100,7 +100,7 @@ class Tinebase_Model_Container extends Tinebase_Record_Abstract
         'deleted_by'             => array('allowEmpty' => true),
         'seq'                    => array('allowEmpty' => true),
     );
-    
+
     /**
      * datetime fields
      *
index 9751ed0..2362dda 100644 (file)
@@ -44,7 +44,7 @@ class Tinebase_Model_ContainerFilter extends Tinebase_Model_Filter_FilterGroup
         'name'              => array('filter' => 'Tinebase_Model_Filter_Text'),
         'type'              => array('filter' => 'Tinebase_Model_Filter_Text'),
         'query'             => array('filter' => 'Tinebase_Model_Filter_Query', 'options' => array('fields' => array('name'))),
-        'owner'             => array('filter' => 'Tinebase_Model_Filter_ContainerOwner'),
+        'owner_id'          => array('filter' => 'Tinebase_Model_Filter_Id'),
         'model'             => array('filter' => 'Tinebase_Model_Filter_Text'),
         'uuid'              => array('filter' => 'Tinebase_Model_Filter_Text'),
     );
diff --git a/tine20/Tinebase/Model/Filter/ContainerOwner.php b/tine20/Tinebase/Model/Filter/ContainerOwner.php
deleted file mode 100644 (file)
index 177bbb0..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
- * Tine 2.0
- * 
- * @package     Tinebase
- * @subpackage  Filter
- * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
- * @copyright   Copyright (c) 2011 Metaways Infosystems GmbH (http://www.metaways.de)
- * @author      Philipp Schüle <p.schuele@metaways.de>
- */
-
-/**
- * Tinebase_Model_Filter_ContainerOwner
- * 
- * filters by container owner
- * 
- * @package     Tinebase
- * @subpackage  Filter
- */
-class Tinebase_Model_Filter_ContainerOwner extends Tinebase_Model_Filter_Abstract
-{
-    /**
-     * @var array list of allowed operators
-     */
-    protected $_operators = array(
-        0 => 'equals',
-    );
-    
-    /**
-     * appends sql to given select statement
-     *
-     * @param  Zend_Db_Select                    $_select
-     * @param  Tinebase_Backend_Sql_Abstract     $_backend
-     * @throws Tinebase_Exception_NotFound
-     */
-    public function appendFilterSql($_select, $_backend)
-    {
-        $db = $_backend->getAdapter();
-        $correlationName = Tinebase_Record_Abstract::generateUID() . $this->_value . 'owner';
-        // use only last 30 chars (oracle column name limit)
-        $correlationName = substr($correlationName, -30);
-        
-        $_select->joinLeft(
-            /* table  */ array($correlationName => SQL_TABLE_PREFIX . 'container_acl'), 
-            /* on     */ $db->quoteIdentifier("{$correlationName}.container_id") . " = " . $db->quoteIdentifier("container.id"),
-            /* select */ array()
-        );
-        
-        // only personal containers have an owner!
-        $_select->where("{$db->quoteIdentifier('container.type')} = ?", Tinebase_Model_Container::TYPE_PERSONAL);
-        
-        // assure admin grant
-        $_select->where($db->quoteIdentifier("{$correlationName}.account_id") . " = " . $db->quote($this->_value) . ' AND ' .
-            $db->quoteIdentifier("{$correlationName}.account_grant") . " = ?", Tinebase_Model_Grants::GRANT_ADMIN);
-    }
-}
index f417439..f91f10f 100644 (file)
@@ -26,7 +26,8 @@ class Tinebase_Model_Filter_Id extends Tinebase_Model_Filter_Abstract
         'equals',
         'not',
         'in',
-        'notin'
+        'notin',
+        'isnull',
     );
     
     /**
@@ -36,7 +37,8 @@ class Tinebase_Model_Filter_Id extends Tinebase_Model_Filter_Abstract
         'equals'     => array('sqlop' => ' = ?'   ),
         'not'        => array('sqlop' => ' != ?'  ),
         'in'         => array('sqlop' => ' IN (?)'),
-        'notin'      => array('sqlop' => ' NOT IN (?)')
+        'notin'      => array('sqlop' => ' NOT IN (?)'),
+        'isnull'     => array('sqlop' => ' IS NULL'),
     );
     
     /**
@@ -60,7 +62,7 @@ class Tinebase_Model_Filter_Id extends Tinebase_Model_Filter_Abstract
              // prevent sql error
              if ($this->_operator == 'in' || $this->_operator == 'equals') {
                  if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
-                     . ' Empty value with "in" operator (model: ' 
+                     . ' Empty value with "' . $this->_operator . '"" operator (model: '
                      . (isset($this->_options['modelName']) ? $this->_options['modelName'] : 'unknown / no modelName defined in filter options'). ')');
                  $_select->where('1=0');
              }
index b4134de..0a0a1d7 100644 (file)
@@ -57,4 +57,74 @@ class Tinebase_Setup_Update_Release9 extends Setup_Update_Abstract
         $update8->update_14();
         $this->setApplicationVersion('Tinebase', '9.4');
     }
+
+    /**
+     * update to 9.9
+     *
+     * @see 0012300: add container owner column
+     */
+    public function update_4()
+    {
+        if ($this->getTableVersion('container') < 10) {
+            $declaration = new Setup_Backend_Schema_Field_Xml(
+            '<field>
+                <name>owner_id</name>
+                <type>text</type>
+                <length>40</length>
+                <notnull>false</notnull>
+            </field>
+            ');
+            $this->_backend->addCol('container', $declaration);
+
+            $declaration = new Setup_Backend_Schema_Index_Xml('
+                <index>
+                    <name>owner_id</name>
+                    <field>
+                        <name>owner_id</name>
+                    </field>
+                </index>
+            ');
+
+            $this->_backend->addIndex('container', $declaration);
+            $this->setTableVersion('relations', '8');
+        }
+        $this->setTableVersion('container', '10');
+
+        //Tinebase_Core::getCache()->clean();
+        $this->_setContainerOwners();
+
+        $this->setApplicationVersion('Tinebase', '9.5');
+    }
+
+    /**
+     * write owner to all personal containers
+     */
+    protected function _setContainerOwners()
+    {
+        $filter = new Tinebase_Model_ContainerFilter(array(
+            array('field' => 'type', 'operator' => 'equals', 'value' => Tinebase_Model_Container::TYPE_PERSONAL),
+            array('field' => 'owner_id', 'operator' => 'isnull', 'value' => ''),
+        ));
+        $count = 0;
+        $paging = new Tinebase_Model_Pagination(array(
+            'start' => 0,
+            'limit' => 100,
+        ));
+        $containers = Tinebase_Container::getInstance()->search($filter, $paging);
+        while (count($containers) > 0) {
+            foreach ($containers as $container) {
+                $ownerId = Tinebase_Container::getInstance()->getContainerOwner($container);
+                if ($ownerId) {
+                    $container->owner_id = $ownerId;
+                    Tinebase_Container::getInstance()->update($container);
+                    $count++;
+                }
+            }
+            $paging->start += $paging->limit;
+            $containers = Tinebase_Container::getInstance()->search($filter, $paging);
+        }
+
+        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
+            . ' Set owner for ' . $count . ' containers.');
+    }
 }
index 7b54ade..a38e3be 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <application>
     <name>Tinebase</name>
-    <version>9.4</version>
+    <version>9.5</version>
     <tables>
         <table>
             <name>applications</name>
         </table>
         <table>
             <name>container</name>
-            <version>9</version>
+            <version>10</version>
             <declaration>
                 <field>
                     <name>id</name>
                     <notnull>false</notnull>
                 </field>
                 <field>
+                    <name>owner_id</name>
+                    <type>text</type>
+                    <length>40</length>
+                    <notnull>false</notnull>
+                </field>
+                <field>
                     <name>color</name>
                     <type>text</type>
                     <length>7</length>
                     </field>
                 </index>
                 <index>
+                    <name>owner_id</name>
+                    <field>
+                        <name>owner_id</name>
+                    </field>
+                </index>
+                <index>
                     <name>container::application_id--applications::id</name>
                     <field>
                         <name>application_id</name>
index a0dc54c..de36fa5 100644 (file)
@@ -605,7 +605,10 @@ class Tinebase_User_Sql extends Tinebase_User_Abstract
         $where = array(
             $this->_db->quoteInto($this->_db->quoteIdentifier('id') . ' = ?', $accountId)
         );
-        
+
+        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->INFO(__METHOD__ . ' ' . __LINE__
+            . ' ' . $_status . ' user with id ' . $accountId);
+
         $result = $accountsTable->update($accountData, $where);
         
         return $result;