Merge branch '2016.11' into 2016.11-develop
authorPhilipp Schüle <p.schuele@metaways.de>
Wed, 12 Jul 2017 09:05:53 +0000 (11:05 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 12 Jul 2017 09:05:53 +0000 (11:05 +0200)
Change-Id: If1d630ec5059f759772dfa1598b34423b3e99151

1  2 
tests/tine20/Tinebase/Frontend/CliTest.php
tine20/Calendar/Backend/Sql.php
tine20/Calendar/Convert/Event/VCalendar/Abstract.php
tine20/Tinebase/Backend/Sql/Abstract.php
tine20/Tinebase/Frontend/Cli.php
tine20/Tinebase/User.php
tine20/Tinebase/User/Abstract.php

Simple merge
@@@ -367,16 -411,8 +381,16 @@@ class Tinebase_Frontend_Cli extends Tin
          if (! $message) {
              throw new Tinebase_Exception_InvalidArgument('mandatory parameter "message" is missing');
          }
 -        
 -        Tinebase_ActionQueue::getInstance()->executeAction($message);
 +
 +        if (null === ($job = json_decode($message, true))) {
 +            throw new Tinebase_Exception_InvalidArgument('parameter "message" can not be json decoded');
 +        }
 +
 +        if (isset($job['account_id'])) {
 +            Tinebase_Core::set(Tinebase_Core::USER, Tinebase_User::getInstance()->getFullUserById($job['account_id']));
 +        }
-         
++
 +        Tinebase_ActionQueue::getInstance()->executeAction($job);
          
          return TRUE;
      }
      }
  
      /**
-     
 +     * recalculates the revision sizes and then the folder sizes
 +     *
 +     * @return int
 +     */
 +    public function fileSystemSizeRecalculation()
 +    {
 +        if (! $this->_checkAdminRight()) {
 +            return -1;
 +        }
 +
 +        Tinebase_FileSystem::getInstance()->recalculateRevisionSize();
 +
 +        Tinebase_FileSystem::getInstance()->recalculateFolderSize();
 +
 +        return 0;
 +    }
 +
 +    /**
 +     * checks if there are not yet indexed file objects and adds them to the index synchronously
 +     * that means this can be very time consuming
 +     *
 +     * @return int
 +     */
 +    public function fileSystemCheckIndexing()
 +    {
 +
 +        if (! $this->_checkAdminRight()) {
 +            return -1;
 +        }
 +
 +        Tinebase_FileSystem::getInstance()->checkIndexing();
 +
 +        return 0;
 +    }
++
 +    /**
       * repair a table
       * 
       * @param Zend_Console_Getopt $opts
          return 0;
      }
  
+     /**
+      * show user report (number of enabled, disabled, ... users)
+      *
+      * TODO add system user count
+      * TODO use twig?
+      */
+     public function userReport()
+     {
+         if (! $this->_checkAdminRight()) {
+             return 2;
+         }
+         $translation = Tinebase_Translation::getTranslation('Tinebase');
+         $userStatus = array(
+             'total' => array(),
+             Tinebase_Model_User::ACCOUNT_STATUS_ENABLED => array(/* 'showUserNames' => true, 'showClients' => true */),
+             Tinebase_Model_User::ACCOUNT_STATUS_DISABLED => array(),
+             Tinebase_Model_User::ACCOUNT_STATUS_BLOCKED => array(),
+             Tinebase_Model_User::ACCOUNT_STATUS_EXPIRED => array(),
+             //'system' => array(),
+             'lastmonth' => array('lastMonths' => 1, 'showUserNames' => true, 'showClients' => true),
+             'last 3 months' => array('lastMonths' => 3),
+         );
+         foreach ($userStatus as $status => $options) {
+             switch ($status) {
+                 case 'lastmonth':
+                 case 'last 3 months':
+                     $userCount = Tinebase_User::getInstance()->getActiveUserCount($options['lastMonths']);
+                     $text = $translation->_("Number of distinct users") . " (" . $status . "): " . $userCount . "\n";
+                     break;
+                 case 'system':
+                     $text = "TODO add me\n";
+                     break;
+                 default:
+                     $userCount = Tinebase_User::getInstance()->getUserCount($status);
+                     $text = $translation->_("Number of users") . " (" . $status . "): " . $userCount . "\n";
+             }
+             echo $text;
+             if (isset($options['showUserNames']) && $options['showUserNames']
+                 && in_array($status, array('lastmonth', 'last 3 months'))
+                 && isset($options['lastMonths'])
+             ) {
+                 // TODO allow this for other status
+                 echo $translation->_("  User Accounts:\n");
+                 $userIds = Tinebase_User::getInstance()->getActiveUserIds($options['lastMonths']);
+                 foreach ($userIds as $userId) {
+                     $user = Tinebase_User::getInstance()->getUserByProperty('accountId', $userId, 'Tinebase_Model_FullUser');
+                     echo "  * " . $user->accountLoginName . ' / ' . $user->accountDisplayName . "\n";
+                     if (isset($options['showClients']) && $options['showClients']) {
+                         $userClients = Tinebase_AccessLog::getInstance()->getUserClients($user, $options['lastMonths']);
+                         echo "    Clients: \n";
+                         foreach ($userClients as $client) {
+                             echo "     - $client\n";
+                         }
+                         echo "\n";
+                     }
+                 }
+             }
+             echo "\n";
+         }
+         return 0;
+     }
++
 +    public function createFullTextIndex()
 +    {
 +        if (! $this->_checkAdminRight()) {
 +            return -1;
 +        }
 +
 +        $setupBackend = Setup_Backend_Factory::factory();
 +        if (!$setupBackend->supports('mysql >= 5.6.4')) {
 +            return -2;
 +        }
 +
 +        $failures = array();
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>note</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>note</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('addressbook', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'addressbook';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('cal_events', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'cal_events';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('metacrm_lead', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'metacrm_lead';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('events_event', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'events_event';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('projects_project', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'projects_project';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('sales_contracts', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'sales_contracts';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('sales_products', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'sales_products';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('sales_customers', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'sales_customers';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('sales_suppliers', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'sales_suppliers';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('sales_purchase_invoices', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'sales_purchase_invoices';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('sales_sales_invoices', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'sales_sales_invoices';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('sales_offers', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'sales_offers';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('tasks', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'tasks';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('timetracker_timesheet', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'timetracker_timesheet';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('timetracker_timeaccount', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'timetracker_timeaccount';
 +        }
 +
 +        try {
 +            if ($setupBackend->tableExists('path')) {
 +                $declaration = new Setup_Backend_Schema_Index_Xml('
 +                    <index>
 +                        <name>path</name>
 +                        <fulltext>true</fulltext>
 +                        <field>
 +                            <name>path</name>
 +                        </field>
 +                    </index>
 +                ');
 +                $setupBackend->addIndex('path', $declaration);
 +            }
 +        } catch (Exception $e) {
 +            $failures[] = 'path';
 +        }
 +
 +        try {
 +            if ($setupBackend->tableExists('path')) {
 +                $declaration = new Setup_Backend_Schema_Index_Xml('
 +                    <index>
 +                        <name>shadow_path</name>
 +                        <fulltext>true</fulltext>
 +                        <field>
 +                            <name>shadow_path</name>
 +                        </field>
 +                    </index>
 +                ');
 +                $setupBackend->addIndex('path', $declaration);
 +            }
 +        } catch (Exception $e) {
 +            $failures[] = 'shadow_path';
 +        }
 +
 +        try {
 +            if (!$setupBackend->tableExists('path')) {
 +                $declaration = new Setup_Backend_Schema_Table_Xml('<table>
 +                    <name>path</name>
 +                    <version>2</version>
 +                    <requirements>
 +                        <required>mysql >= 5.6.4</required>
 +                    </requirements>
 +                    <declaration>
 +                        <field>
 +                            <name>id</name>
 +                            <type>text</type>
 +                            <length>40</length>
 +                            <notnull>true</notnull>
 +                        </field>
 +                        <field>
 +                            <name>path</name>
 +                            <type>text</type>
 +                            <length>65535</length>
 +                            <notnull>true</notnull>
 +                        </field>
 +                        <field>
 +                            <name>shadow_path</name>
 +                            <type>text</type>
 +                            <length>65535</length>
 +                            <notnull>true</notnull>
 +                        </field>
 +                        <field>
 +                            <name>creation_time</name>
 +                            <type>datetime</type>
 +                        </field>
 +                        <index>
 +                            <name>id</name>
 +                            <primary>true</primary>
 +                            <field>
 +                                <name>id</name>
 +                            </field>
 +                        </index>
 +                        <index>
 +                        <name>path</name>
 +                            <fulltext>true</fulltext>
 +                            <field>
 +                                <name>path</name>
 +                            </field>
 +                        </index>
 +                        <index>
 +                            <name>shadow_path</name>
 +                            <fulltext>true</fulltext>
 +                            <field>
 +                                <name>shadow_path</name>
 +                            </field>
 +                        </index>
 +                    </declaration>
 +                </table>');
 +
 +                $tmp = new Setup_Update_Abstract($setupBackend);
 +                $tmp->createTable('path', $declaration, 'Tinebase', 2);
 +
 +                $setupUser = Setup_Update_Abstract::getSetupFromConfigOrCreateOnTheFly();
 +                if ($setupUser) {
 +                    Tinebase_Core::set(Tinebase_Core::USER, $setupUser);
 +                    Tinebase_Controller::getInstance()->rebuildPaths();
 +                } else {
 +                    if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
 +                        Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__
 +                            . ' Could not find valid setupuser. Skipping rebuildPaths: you might need to run this manually.');
 +                    }
 +                }
 +            }
 +        } catch (Exception $e) {
 +            $failures[] = 'create path';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>text_data</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>text_data</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('external_fulltext', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'external_fulltext';
 +        }
 +
 +        try {
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('tree_fileobjects', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'tree_fileobjects';
 +        }
 +
 +        try {
 +            try {
 +                $setupBackend->dropIndex('tags', 'description');
 +            } catch (Exception $e) {
 +                // Ignore, if there is no index, we can just go on and create one.
 +            }
 +            $declaration = new Setup_Backend_Schema_Index_Xml('
 +                <index>
 +                    <name>description</name>
 +                    <fulltext>true</fulltext>
 +                    <field>
 +                        <name>description</name>
 +                    </field>
 +                </index>
 +            ');
 +            $setupBackend->addIndex('tags', $declaration);
 +        } catch (Exception $e) {
 +            $failures[] = 'tags';
 +        }
 +
 +        if (count($failures) > 0) {
 +            echo PHP_EOL . 'failures: ' . join(' ', $failures);
 +        }
 +
 +        echo PHP_EOL . 'done' . PHP_EOL . PHP_EOL;
 +    }
  }
@@@ -50,19 -50,7 +50,19 @@@ class Tinebase_User implements Tinebase
       *
       */
      const DEFAULT_ADMIN_GROUP_NAME_KEY = 'defaultAdminGroupName';
 -    
 +
 +    /**
 +     * Do the user sync with the options as configured in the config.
 +     * see Tinebase_Config:: TODO put key here
 +     * for details and default behavior
 +     */
 +    const SYNC_WITH_CONFIG_OPTIONS = 'sync_with_config_options';
 +
 +    /**
 +     * Key under which the default replication group name setting will be stored/retrieved
 +     */
 +    const DEFAULT_REPLICATION_GROUP_NAME_KEY = 'defaultReplicationGroupName';
-     
++
      protected static $_contact2UserMapping = array(
          'n_family'      => 'accountLastName',
          'n_given'       => 'accountFirstName',
          if (! $hookResult) {
              return null;
          }
 -        
 +
 +
          if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' 
              . print_r($user->toArray(), TRUE));
 -        
 +
 +        $oldContainerAcl = Addressbook_Controller_Contact::getInstance()->doContainerACLChecks(false);
 +        $oldRequestContext = Addressbook_Controller_Contact::getInstance()->getRequestContext();
 +
 +        $requestContext = array();
 +        if (!isset($options['syncContactPhoto']) || !$options['syncContactPhoto']) {
 +            $requestContext[Addressbook_Controller_Contact::CONTEXT_NO_SYNC_PHOTO] = true;
 +        }
 +        if (!isset($options['syncContactData']) || !$options['syncContactData']) {
 +            $requestContext[Addressbook_Controller_Contact::CONTEXT_NO_SYNC_CONTACT_DATA] = true;
 +        }
 +        Addressbook_Controller_Contact::getInstance()->setRequestContext($requestContext);
-         
++
          self::getPrimaryGroupForUser($user);
  
          try {
          
          return $result;
      }
--    
 -    /**
 -     * create contact in addressbook
 -     * 
 -     * @param Tinebase_Model_FullUser $user
 -     * @return Addressbook_Model_Contact|null
 -     */
 -    public static function createContactForSyncedUser($user)
 -    {
 -        if (! Tinebase_Application::getInstance()->isInstalled('Addressbook')) {
 -            return null;
 -        }
 -        
 -        $contact = self::_user2Contact($user);
 -        
 -        // add modlog info
 -        Tinebase_Timemachine_ModificationLog::setRecordMetaData($contact, 'create');
 -        
 -        $addressbook = Addressbook_Backend_Factory::factory(Addressbook_Backend_Factory::SQL);
 -        $contact = $addressbook->create($contact);
 -        
 -        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
 -            . " Added contact " . $contact->n_given);
 -        
 -        $user->contact_id = $contact->getId();
 -        return $contact;
 -    }
 -    
      /**
       * sync user data to contact
       * 
              // use accountFullName overwrites contact n_fn
              $contact->n_fn = $user->accountFullName;
          }
 -        
 +
 +        $contact->account_id = $user->getId();
-         
++
          return $contact;
      }
      
       * 
       * @param array $options
       */
 -    public static function syncUsers($options)
 +    public static function syncUsers($options = array())
      {
 -        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ 
 -            .' Start synchronizing users with options ' . print_r($options, true));
 +        if (isset($options[self::SYNC_WITH_CONFIG_OPTIONS]) && $options[self::SYNC_WITH_CONFIG_OPTIONS]) {
 +            $syncOptions = Tinebase_Config::getInstance()->get(Tinebase_Config::USERBACKEND)->{Tinebase_Config::SYNCOPTIONS};
 +            if (!isset($options['deleteUsers'])) {
 +                $options['deleteUsers'] = $syncOptions->{Tinebase_Config::SYNC_DELETED_USER};
 +            }
 +            if (!isset($options['syncContactPhoto'])) {
 +                $options['syncContactPhoto'] = $syncOptions->{Tinebase_Config::SYNC_USER_CONTACT_PHOTO};
 +            }
 +            if (!isset($options['syncContactData'])) {
 +                $options['syncContactData'] = $syncOptions->{Tinebase_Config::SYNC_USER_CONTACT_DATA};
 +            }
 +        }
 +
-         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ 
++        if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
 +            . ' Start synchronizing users with options ' . print_r($options, true));
 +
 +        /** TODO replace this with something more generic, like interface "syncable" */
 +        if (! Tinebase_User::getInstance() instanceof Tinebase_User_Ldap) {
 +            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
 +                . ' User backend is not instanceof Tinebase_User_Ldap, nothing to sync');
 +            return;
 +        }
          
          $users = Tinebase_User::getInstance()->getUsersFromSyncBackend(NULL, NULL, 'ASC', NULL, NULL, 'Tinebase_Model_FullUser');
          
          if (! isset($_options['adminPassword']) || ! isset($_options['adminLoginName'])) {
              throw new Tinebase_Exception_InvalidArgument('Admin password and login name have to be set when creating initial account.', 503);
          }
 -        
 +
 +        $addressBookController = Addressbook_Controller_Contact::getInstance();
 +
 +        // make sure we have a setup user:
 +        // remove plugin, create setup user if required, register it again
 +        Tinebase_User::getInstance()->removePlugin($addressBookController);
 +        $setupUser = Setup_Update_Abstract::getSetupFromConfigOrCreateOnTheFly();
 +        if (! Tinebase_Core::getUser() instanceof Tinebase_Model_User) {
 +            Tinebase_Core::set(Tinebase_Core::USER, $setupUser);
 +        }
 +
 +        // create the replication user
 +        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Creating new replication user.');
 +
 +        $replicationUser = static::createSystemUser('replicationuser', Tinebase_Group::getInstance()->getDefaultReplicationGroup());
 +        if (null !== $replicationUser) {
 +            $replicationMasterConf = Tinebase_Config::getInstance()->get(Tinebase_Config::REPLICATION_MASTER);
 +            if (empty(($password = $replicationMasterConf->{Tinebase_Config::REPLICATION_USER_PASSWORD}))) {
 +                $password = Tinebase_Record_Abstract::generateUID(12);
 +            }
 +            Tinebase_User::getInstance()->setPassword($replicationUser, $password);
 +        }
 +
 +
 +        Tinebase_User::getInstance()->registerPlugin($addressBookController);
 +
 +
 +        $oldAcl = $addressBookController->doContainerACLChecks(false);
 +        $oldRequestContext = $addressBookController->getRequestContext();
 +        $requestContext = array(
 +            Addressbook_Controller_Contact::CONTEXT_ALLOW_CREATE_USER => true,
 +            Addressbook_Controller_Contact::CONTEXT_NO_ACCOUNT_UPDATE => true,
 +        );
 +        $addressBookController->setRequestContext($requestContext);
 +
 +
-         
++
          $adminLoginName     = $_options['adminLoginName'];
          $adminPassword      = $_options['adminPassword'];
          $adminFirstName     = isset($_options['adminFirstName'])    ? $_options['adminFirstName'] : 'Tine 2.0';
Simple merge