Merge branch '2014.11' into 2014.11-develop
authorPhilipp Schüle <p.schuele@metaways.de>
Thu, 5 Nov 2015 10:14:02 +0000 (11:14 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 5 Nov 2015 10:14:02 +0000 (11:14 +0100)
1  2 
tine20/Tinebase/Container.php
tine20/Tinebase/Relation/Backend/Sql.php

@@@ -574,7 -574,7 +574,7 @@@ class Tinebase_Container extends Tineba
       * @return  Tinebase_Record_RecordSet of subtype Tinebase_Model_Container
       * @throws  Tinebase_Exception_NotFound
       */
 -    public function getPersonalContainer($_accountId, $_recordClass, $_owner, $_grant, $_ignoreACL = false)
 +    public function getPersonalContainer($_accountId, $_recordClass, $_owner, $_grant = Tinebase_Model_Grants::GRANT_READ, $_ignoreACL = false)
      {
          $meta = $this->_resolveRecordClassArgument($_recordClass);
          
          
          $stmt = $this->_db->query('/*' . __FUNCTION__ . '*/' . $select);
          $containersData = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
 -        
 +
          // if no containers where found, maybe something went wrong when creating the initial folder
          // let's check if the controller of the application has a function to create the needed folders
 -        if (empty($containersData) and $accountId === $ownerId) {
 -            $application = Tinebase_Core::getApplicationInstance($application->name);
 -            
 -            if ($application instanceof Tinebase_Container_Interface) {
 +        if (empty($containersData) && $accountId === $ownerId) {
 +            $application = Tinebase_Core::getApplicationInstance($meta['appName']);
 +
 +            if ($application instanceof Tinebase_Container_Interface && method_exists($application, 'createPersonalFolder')) {
                  return $application->createPersonalFolder($accountId);
 +            } else if ($meta['recordClass']) {
 +                $containersData = array($this->createDefaultContainer($meta['recordClass'], $meta['appName'], $accountId));
              }
          }
  
          $containers = new Tinebase_Record_RecordSet('Tinebase_Model_Container', $containersData, TRUE);
 -        
 +
          $this->saveInClassCache(__FUNCTION__, $classCacheId, $containers);
  
          return $containers;
      }
 +
 +    /**
 +     * create default container for a user
 +     *
 +     * @param string $recordClass
 +     * @param string $applicationName
 +     * @param Tinebase_Model_User|string $account
 +     * @param string $containerName
 +     * @return Tinebase_Model_Container
 +     * @throws Tinebase_Exception_AccessDenied
 +     * @throws Tinebase_Exception_InvalidArgument
 +     * @throws Tinebase_Exception_NotFound
 +     *
 +     * @todo add record name to container name?
 +     */
 +    public function createDefaultContainer($recordClass, $applicationName, $account, $containerName = null)
 +    {
 +        if (! $account instanceof Tinebase_Model_User) {
 +            $account = Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $account);
 +        }
 +
 +        Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
 +            . ' Creating new default container ' . $containerName . ' for '
 +            . $account->accountFullName . ' for model ' . $recordClass);
 +
 +        if (! $containerName) {
 +            $translation = Tinebase_Translation::getTranslation('Tinebase');
 +            $containerName = sprintf($translation->_("%s's personal container"), $account->accountFullName);
 +        }
 +
 +        $container = $this->addContainer(new Tinebase_Model_Container(array(
 +            'name'              => $containerName,
 +            'type'              => Tinebase_Model_Container::TYPE_PERSONAL,
 +            'owner_id'          => $account->getId(),
 +            'backend'           => 'Sql',
 +            'model'             => $recordClass,
 +            'application_id'    => Tinebase_Application::getInstance()->getApplicationByName($applicationName)->getId()
 +        )));
 +
 +        return $container;
 +    }
      
      /**
       * appends container_acl sql 
          $db = $_select->getAdapter();
          
          $grants = is_array($_grant) ? $_grant : array($_grant);
 -        
 -
  
          $groupMemberships   = Tinebase_Group::getInstance()->getGroupMemberships($accountId);
          
              } catch (Tinebase_Exception $te) {
                  Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Default container not found (' . $te->getMessage() . ')');
                  // default may be gone -> remove default adb pref
 -                $appPref = Tinebase_Core::getPreference($this->_applicationName);
 +                $appPref = Tinebase_Core::getPreference($meta['appName']);
                  if ($appPref) {
                      $appPref->deleteUserPref($defaultContainerPreferenceName);
                  }
              }
          }
          
 -        $account = ($accountId !== NULL) ? Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $accountId) : Tinebase_Core::getUser();
 +        $account = ($accountId !== NULL)
 +            ? Tinebase_User::getInstance()->getUserByPropertyFromSqlBackend('accountId', $accountId)
 +            : Tinebase_Core::getUser();
          $result = $this->getPersonalContainer($account, $recordClass, $account, Tinebase_Model_Grants::GRANT_ADD)->getFirstRecord();
          
          if ($result === NULL) {
 -            Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ 
 -                . ' Creating new default container for ' . $account->accountFullName . ' in application ' . $meta['appName']);
 -            
 -            $translation = Tinebase_Translation::getTranslation($meta['appName']);
 -            $result = $this->addContainer(new Tinebase_Model_Container(array(
 -                'name'              => sprintf($translation->_("%s's personal container"), $account->accountFullName),
 -                'type'              => Tinebase_Model_Container::TYPE_PERSONAL,
 -                'owner_id'          => $account->getId(),
 -                'backend'           => 'Sql',
 -                'model'             => $meta['recordClass'],
 -                'application_id'    => Tinebase_Application::getInstance()->getApplicationByName($meta['appName'])->getId() 
 -            )));
 +            $result = $this->createDefaultContainer($recordClass, $meta['appName'], $accountId);
          }
          
          if ($defaultContainerPreferenceName !== NULL) {
          
          $tm = Tinebase_TransactionManager::getInstance();   
          $myTransactionId = $tm->startTransaction(Tinebase_Core::getDb());
 -        
 +
 +        Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
 +            . ' Deleting container id ' . $containerId . ' ...');
 +
          $deletedContainer = NULL;
          
          try {
      {
          // set records belonging to this container to deleted
          $model = $container->model;
 -        if ($model) {
 -            $controller = Tinebase_Core::getApplicationInstance($model);
 -            $filterName = $model . 'Filter';
 -            if($_ignoreAcl === TRUE && method_exists($controller, 'doContainerACLChecks')) {
 -                $acl = $controller->doContainerACLChecks(FALSE);
 -            }
 -            if ($controller && class_exists($filterName)) {
 -                $filter = new $filterName(array(
 -                    array(
 -                        'field'    => 'container_id',
 -                        'operator' => 'equals',
 -                        'value'    => intval($container->id)
 -                    ),
 -                    array(
 -                        'field'    => 'is_deleted',
 -                        'operator' => 'equals',
 -                        'value'    => 0
 -                    )),
 -                    'AND');
 -                $controller::getInstance()->deleteByFilter($filter);
 -            }
 -            if ($_ignoreAcl === TRUE && method_exists($controller, 'doContainerACLChecks')) {
 -                $controller->doContainerACLChecks($acl);
 -            }
 +
 +        if (empty($model)) {
 +            Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
 +                . ' No container model defined');
 +            return;
 +        }
 +
 +        Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
 +            . ' Deleting container contents ...');
 +
 +        $controller = Tinebase_Core::getApplicationInstance($model);
 +        $filterName = $model . 'Filter';
 +
 +        if ($_ignoreAcl === TRUE && method_exists($controller, 'doContainerACLChecks')) {
 +            $acl = $controller->doContainerACLChecks(FALSE);
 +        }
 +        if ($controller && class_exists($filterName)) {
 +            $filter = new $filterName(array(
 +                array(
 +                    'field'    => 'container_id',
 +                    'operator' => 'equals',
 +                    'value'    => intval($container->id)
 +                ),
 +                array(
 +                    'field'    => 'is_deleted',
 +                    'operator' => 'equals',
 +                    'value'    => 0
 +                )),
 +                'AND');
 +            $controller::getInstance()->deleteByFilter($filter);
 +        }
 +
 +        if ($_ignoreAcl === TRUE && method_exists($controller, 'doContainerACLChecks')) {
 +            $controller->doContainerACLChecks($acl);
          }
      }
      
       * create a new system container
       * - by default user group gets READ grant
       * - by default admin group gets all grants
+      *
+      * NOTE: this should never be called in user land and only in admin/setup contexts
       * 
       * @param Tinebase_Model_Application|string $application app record, app id or app name
       * @param string $name
      {
          $application = ($application instanceof Tinebase_Model_Application) ? $application : Tinebase_Application::getInstance()->getApplicationById($application);
          if ($model === null) {
-             $controller = Tinebase_Core::getApplicationInstance($application->name);
+             $controller = Tinebase_Core::getApplicationInstance($application->name, /* $_modelName = */ '', /* $_ignoreACL = */ true);
              $model = $controller->getDefaultModel();
          }
          
@@@ -42,13 -42,6 +42,13 @@@ class Tinebase_Relation_Backend_Sql ext
       * @var Tinebase_Db_Table
       */
      protected $_dbTable;
 +
 +    /**
 +     * Table name without prefix
 +     *
 +     * @var string
 +     */
 +    protected $_tableName = 'relations';
      
      /**
       * constructor
      {
          $this->_db = Tinebase_Core::getDb();
          $this->_dbCommand = Tinebase_Backend_Sql_Command::factory($this->_db);
 +        $this->_tablePrefix = $this->_db->table_prefix;
          
          // temporary on the fly creation of table
          $this->_dbTable = new Tinebase_Db_Table(array(
 -            'name' => SQL_TABLE_PREFIX . 'relations',
 +            'name' => $this->_tablePrefix . 'relations',
              'primary' => 'id'
          ));
 +
      }
      
      /**
       */
      public function removeApplication($applicationName)
      {
-         $tableName = $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . 'relations');
+         $tableName = SQL_TABLE_PREFIX . 'relations';
  
          $select = $this->_db->select()->from($tableName)->columns('rel_id')
              ->where($this->_db->quoteIdentifier('own_model') . ' LIKE ?', $applicationName . '_%');