0013236: Use filepicker for filemanager relations
[tine20] / tine20 / Setup / Frontend / Cli.php
1 <?php
2 /**
3  * Tine 2.0
4  * @package     Tinebase
5  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
6  * @author      Philipp Schüle <p.schuele@metaways.de>
7  * @copyright   Copyright (c) 2008-2012 Metaways Infosystems GmbH (http://www.metaways.de)
8  * 
9  * @todo        add ext check again
10  */
11
12 /**
13  * cli server
14  *
15  * This class handles all requests from cli scripts
16  *
17  * @package     Tinebase
18  */
19 class Setup_Frontend_Cli
20 {
21     /**
22      * the internal name of the application
23      *
24      * @var string
25      */
26     protected $_appname = 'Setup';
27
28     /**
29      * authentication
30      *
31      * @param string $_username
32      * @param string $_password
33      * 
34      * @return boolean
35      */
36     public function authenticate($_username, $_password)
37     {
38         return false;
39     }
40     
41     /**
42      * handle request (call -ApplicationName-_Cli.-MethodName- or -ApplicationName-_Cli.getHelp)
43      *
44      * @param Zend_Console_Getopt $_opts
45      * @param boolean $exitAfterHandle
46      * @return void
47      */
48     public function handle(Zend_Console_Getopt $_opts, $exitAfterHandle = true)
49     {
50         Setup_Core::set(Setup_Core::USER, 'setupuser');
51
52         $result = 0;
53         if (isset($_opts->install)) {
54             $this->_install($_opts);
55         } elseif(isset($_opts->update)) {
56             $result = $this->_update($_opts);
57         } elseif(isset($_opts->uninstall)) {
58             $this->_uninstall($_opts);
59         } elseif(isset($_opts->install_dump)) {
60             $this->_installDump($_opts);
61         } elseif(isset($_opts->list)) {
62             $result = $this->_listInstalled();
63         } elseif(isset($_opts->sync_accounts_from_ldap)) {
64             $this->_importAccounts($_opts);
65         } elseif(isset($_opts->sync_passwords_from_ldap)) {
66             $this->_syncPasswords($_opts);
67         } elseif(isset($_opts->egw14import)) {
68             $this->_egw14Import($_opts);
69         } elseif(isset($_opts->check_requirements)) {
70             $this->_checkRequirements($_opts);
71         } elseif(isset($_opts->setconfig)) {
72             $this->_setConfig($_opts);
73         } elseif(isset($_opts->create_admin)) {
74             $this->_createAdminUser($_opts);
75         } elseif(isset($_opts->getconfig)) {
76             $this->_getConfig($_opts);
77         } elseif(isset($_opts->reset_demodata)) {
78             $this->_resetDemodata($_opts);
79         } elseif(isset($_opts->updateAllImportExportDefinitions)) {
80             $this->_updateAllImportExportDefinitions($_opts);
81         } elseif(isset($_opts->backup)) {
82             $this->_backup($_opts);
83         } elseif(isset($_opts->restore)) {
84             $this->_restore($_opts);
85         } elseif(isset($_opts->compare)) {
86             $this->_compare($_opts);
87         }
88         
89         if ($exitAfterHandle) {
90             exit($result);
91         }
92     }
93     
94     /**
95      * install new applications
96      *
97      * @param Zend_Console_Getopt $_opts
98      */
99     protected function _install(Zend_Console_Getopt $_opts)
100     {
101         $controller = Setup_Controller::getInstance();
102         
103         if($_opts->install === true) {
104             $applications = $controller->getInstallableApplications();
105             $applications = array_keys($applications);
106         } else {
107             $applications = array();
108             $applicationNames = explode(',', $_opts->install);
109             foreach($applicationNames as $applicationName) {
110                 $applicationName = ucfirst(trim($applicationName));
111                 try {
112                     $controller->getSetupXml($applicationName);
113                     $applications[] = $applicationName;
114                 } catch (Setup_Exception_NotFound $e) {
115                     echo "Application $applicationName not found! Skipped...\n";
116                 }
117             }
118         }
119         
120         $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
121         $this->_promptRemainingOptions($applications, $options);
122         
123         $controller->installApplications($applications, $options);
124         
125         if ((isset($options['acceptedTermsVersion']) || array_key_exists('acceptedTermsVersion', $options))) {
126             Setup_Controller::getInstance()->saveAcceptedTerms($options['acceptedTermsVersion']);
127         }
128         
129         echo "Successfully installed " . count($applications) . " applications.\n";
130     }
131
132     /**
133      * prompt remaining options
134      * 
135      * @param array $_applications
136      * @param array $_options
137      * @return void
138      * 
139      * @todo add required version server side
140      */
141     protected function _promptRemainingOptions($_applications, &$_options) {
142         if (in_array('Tinebase', $_applications)) {
143             
144             if (! isset($_options['acceptedTermsVersion'])) {
145                 fwrite(STDOUT, PHP_EOL . file_get_contents(dirname(dirname(dirname(__FILE__))) . '/LICENSE' ));
146                 $licenseAnswer = Tinebase_Server_Cli::promptInput('I have read the license agreement and accept it (type "yes" to accept)');
147                 
148                 
149                 fwrite(STDOUT, PHP_EOL . file_get_contents(dirname(dirname(dirname(__FILE__))) . '/PRIVACY' ));
150                 $privacyAnswer = Tinebase_Server_Cli::promptInput('I have read the privacy agreement and accept it (type "yes" to accept)');
151             
152                 if (! (strtoupper($licenseAnswer) == 'YES' && strtoupper($privacyAnswer) == 'YES')) {
153                     echo "error: you need to accept the terms! exiting \n";
154                     exit (1);
155                 }
156                 
157                 $_options['acceptedTermsVersion'] = 1;
158             }
159             
160             
161             // initial username
162             if (! isset($_options['adminLoginName'])) {
163                 $_options['adminLoginName'] = Tinebase_Server_Cli::promptInput('Inital Admin Users Username');
164                 if (! $_options['adminLoginName']) {
165                     echo "error: username must be given! exiting \n";
166                     exit (1);
167                 }
168             }
169             
170             // initial password / can be empty => will trigger password change dialogue
171             if (! array_key_exists('adminPassword', $_options)) {
172                 $_options['adminPassword'] = $this->_promptPassword();
173             }
174         }
175     }
176     
177     /**
178      * prompt password
179      * 
180      * @return string
181      */
182     protected function _promptPassword()
183     {
184         $password1 = Tinebase_Server_Cli::promptInput('Admin user password', TRUE);
185         if (! $password1) {
186             echo "Error: Password must not be empty! Exiting ... \n";
187             exit (1);
188         }
189         $password2 = Tinebase_Server_Cli::promptInput('Confirm password', TRUE);
190         if ($password1 !== $password2) {
191             echo "Error: Passwords do not match! Exiting ... \n";
192             exit (1);
193         }
194         
195         return $password1;
196     }
197     
198     /**
199      * update existing applications
200      *
201      * @param Zend_Console_Getopt $_opts
202      * @return integer
203      */
204     protected function _update(Zend_Console_Getopt $_opts)
205     {
206         $maxLoops = 50;
207         do {
208             $result = $this->_updateApplications();
209             if ($_opts->v && ! empty($result['messages'])) {
210                 echo "Messages:\n";
211                 foreach ($result['messages'] as $message) {
212                     echo "  " . $message . "\n";
213                 }
214             }
215             $maxLoops--;
216         } while ($result['updated'] > 0 && $maxLoops > 0);
217         
218         return ($maxLoops > 0) ? 0 : 1;
219     }
220     
221     /**
222      * update all applications
223      * 
224      * @return array
225      */
226     protected function _updateApplications()
227     {
228         $controller = Setup_Controller::getInstance();
229         $applications = Tinebase_Application::getInstance()->getApplications(NULL, 'id');
230         
231         foreach ($applications as $key => &$application) {
232             try {
233                 if (! $controller->updateNeeded($application)) {
234                     unset($applications[$key]);
235                 }
236             } catch (Setup_Exception_NotFound $e) {
237                 Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ 
238                     . ' Failed to check if an application needs an update:' . $e->getMessage());
239                 unset($applications[$key]);
240             }
241         }
242
243         $result = array();
244         if (count($applications) > 0) {
245             $result = $controller->updateApplications($applications);
246             echo "Updated " . $result['updated'] . " application(s).\n";
247         } else {
248             $result['updated'] = 0;
249         }
250         
251         return $result;
252     }
253
254     /**
255      * uninstall applications
256      *
257      * @param Zend_Console_Getopt $_opts
258      */
259     protected function _uninstall(Zend_Console_Getopt $_opts)
260     {
261         $controller = Setup_Controller::getInstance();
262         
263         if($_opts->uninstall === true) {
264             $applications = Tinebase_Application::getInstance()->getApplications(NULL, 'id');
265         } else {
266             $applications = new Tinebase_Record_RecordSet('Tinebase_Model_Application');
267             $applicationNames = explode(',', $_opts->uninstall);
268             foreach($applicationNames as $applicationName) {
269                 $applicationName = ucfirst(trim($applicationName));
270                 try {
271                     $application = Tinebase_Application::getInstance()->getApplicationByName($applicationName);
272                     $applications->addRecord($application);
273                 } catch (Tinebase_Exception_NotFound $e) {
274                 }
275             }
276         }
277         
278         $controller->uninstallApplications($applications->name);
279         
280         echo "Successfully uninstalled " . count($applications) . " applications.\n";
281     }
282     
283     /**
284      * reinstall applications
285      * and reset Demodata
286      * php setup.php --reset_demodata USERNAME
287      * 
288      * @param Zend_Console_Getopt $_opts
289      */
290     protected function _resetDemodata(Zend_Console_Getopt $_opts)
291     {
292         $controller = Setup_Controller::getInstance();
293         $userController = Admin_Controller_User::getInstance();
294         $containerController = Tinebase_Container::getInstance();
295         $cli = new Tinebase_Frontend_Cli();
296         
297         //Don't reset this applications
298         $fixedApplications = array('Tinebase', 'Admin', 'Addressbook');
299         
300         //Log in
301         $opts = $_opts->getRemainingArgs();
302         $username = $opts[0];
303         if (empty($username)) {
304             echo "Username is missing!\n";
305             exit;
306         }
307         $user = Tinebase_User::getInstance()->getUserByLoginName($username);
308         Tinebase_Core::set(Tinebase_Core::USER, $user);
309         
310         //get all applications and remove some
311         $applications = Tinebase_Application::getInstance()->getApplications(NULL, 'id');
312         
313         foreach ($applications as $key => &$application) {
314             if (in_array($application, $fixedApplications)) {
315                 unset($applications[$key]);
316             }
317         }
318         
319         //get set rights
320         $users = Tinebase_Acl_Roles::getInstance()->getRoleByName('user role');
321         $rights = Tinebase_Acl_Roles::getInstance()->getRoleRights($users->getId());
322         
323         //Uninstall Applications
324         try {
325             $controller->uninstallApplications($applications->name);
326             echo "Successfully uninstalled " . count($applications) . " applications.\n";
327         } catch (Tinebase_Exception_NotFound $e) {
328         }
329         //Install Applications
330         try {
331             $controller->installApplications($applications->name);
332             echo "Successfully installed " . count($applications) . " applications.\n";
333         } catch (Tinebase_Exception_NotFound $e) {
334         }
335         
336         //set rights
337         foreach ($applications as $app) {
338             $newApplicationId = Tinebase_Application::getInstance()->getApplicationByName($app->name)->getId();
339             
340             foreach ($rights as &$right) {
341                 if ($right['application_id'] == $app->id) {
342                     $right['application_id'] = $newApplicationId;
343                 }
344             }
345         }
346         
347         Tinebase_Acl_Roles::getInstance()->setRoleRights($users->getId(), $rights);
348         echo "Successfully restored user rights.\n";
349         
350         //Clean up addressbooks
351         $internalContacts = $userController->getDefaultInternalAddressbook();
352         $containers = $containerController->getAll();
353         foreach ($containers as $key => &$container) {
354             if ($container->id == $internalContacts) {
355                 // Do nothing
356             } else {
357                 try {
358                     $containerController->deleteContainer($container, true);
359                 } catch (Exception $e) {
360                 }
361             }
362         }
363         unset($containers);
364         echo "Successfully cleand up containers.\n";
365         
366         //remove state
367         $db = Tinebase_Core::getDb();
368         $statement = "TRUNCATE TABLE " . $db->quoteIdentifier(SQL_TABLE_PREFIX . 'state');
369         $db->query($statement);
370         echo "Successfully truncated state table.\n";
371         
372         //Get Demodata
373         $cli->createAllDemoData();
374         
375         //clear Cache
376         Tinebase_Core::getCache()->clean(Zend_Cache::CLEANING_MODE_ALL);
377         echo "Successfully cleared Cache.\n";
378         
379         echo "Every thing done!\n";
380     }
381
382     /**
383      * Update Import Export Definitions for all applications
384      */
385     protected function _updateAllImportExportDefinitions(Zend_Console_Getopt $_opts){
386
387         $setupUser = Setup_Update_Abstract::getSetupFromConfigOrCreateOnTheFly();
388         if (! Tinebase_Core::getUser() instanceof Tinebase_Model_User) {
389             Tinebase_Core::set(Tinebase_Core::USER, $setupUser);
390         }
391
392         //get all applications
393         $applications = Tinebase_Application::getInstance()->getApplications(NULL, 'id');
394         foreach ($applications as $application) {
395             Setup_Controller::getInstance()->createImportExportDefinitions($application);
396             echo "Update definitions for " . $application->name . "...\n";
397         }
398     }
399     
400     /**
401      * list installed apps
402      */
403     protected function _listInstalled()
404     {
405         try {
406             $applications = Tinebase_Application::getInstance()->getApplications(NULL, 'id');
407         } catch (Zend_Db_Statement_Exception $e) {
408             echo "No applications installed\n";
409             return 1;
410         }
411         
412         echo "Currently installed applications:\n";
413         foreach($applications as $application) {
414             echo "* $application\n";
415         }
416         
417         return 0;
418     }
419     
420     /**
421      * import accounts from ldap
422      *
423      * @param Zend_Console_Getopt $_opts
424      */
425     protected function _importAccounts(Zend_Console_Getopt $_opts)
426     {
427         // disable timelimit during import of user accounts
428         Setup_Core::setExecutionLifeTime(0);
429         
430         // import groups
431         if (! $_opts->onlyusers) {
432             Tinebase_Group::syncGroups();
433         }
434         
435         // import users
436         $options = array('syncContactData' => TRUE);
437         if ($_opts->dbmailldap) {
438             $options['ldapplugins'] = array(
439                 new Tinebase_EmailUser_Imap_LdapDbmailSchema(),
440                 new Tinebase_EmailUser_Smtp_LdapDbmailSchema()
441             );
442         }
443
444         if ($_opts->syncdeletedusers) {
445             $options['deleteUsers'] = true;
446         }
447         if ($_opts->syncaccountstatus) {
448             $options['syncAccountStatus'] = true;
449         }
450         if ($_opts->syncontactphoto) {
451             $options['syncContactPhoto'] = true;
452         }
453
454         Tinebase_User::syncUsers($options);
455     }
456     
457     /**
458      * sync ldap passwords
459      * 
460      * @param Zend_Console_Getopt $_opts
461      */
462     protected function _syncPasswords(Zend_Console_Getopt $_opts)
463     {
464         Tinebase_User::syncLdapPasswords();
465     }
466     
467     /**
468      * import from egw14
469      * 
470      * @param Zend_Console_Getopt $_opts
471      */
472     protected function _egw14Import(Zend_Console_Getopt $_opts)
473     {
474         $args = $_opts->getRemainingArgs();
475         
476         if (count($args) < 1 || ! is_readable($args[0])) {
477             echo "can not open config file \n";
478             echo "see tine20.org/wiki/EGW_Migration_Howto for details \n\n";
479             echo "usage: ./setup.php --egw14import /path/to/config.ini (see Tinebase/Setup/Import/Egw14/config.ini)\n\n";
480             exit(1);
481         }
482         
483         try {
484             $config = new Zend_Config(array(), TRUE);
485             $config->merge(new Zend_Config_Ini($args[0]));
486             $config = $config->merge($config->all);
487         } catch (Zend_Config_Exception $e) {
488             fwrite(STDERR, "Error while parsing config file($args[0]) " .  $e->getMessage() . PHP_EOL);
489             exit(1);
490         }
491         
492         $writer = new Zend_Log_Writer_Stream('php://output');
493         $logger = new Zend_Log($writer);
494         
495         $filter = new Zend_Log_Filter_Priority((int) $config->loglevel);
496         $logger->addFilter($filter);
497         
498         $importer = new Tinebase_Setup_Import_Egw14($config, $logger);
499         $importer->import();
500     }
501     
502     /**
503      * do the environment check
504      *
505      * @return array
506      */
507     protected function _checkRequirements(Zend_Console_Getopt $_opts)
508     {
509         $results = Setup_Controller::getInstance()->checkRequirements();
510         if ($results['success']) {
511           echo "OK - All requirements are met\n";
512         } else {
513           echo "ERRORS - The following requirements are not met: \n";
514           foreach ($results['results'] as $result) {
515             if (!empty($result['message'])) {
516               echo "- " . strip_tags($result['message']) . "\n";
517             }
518           }
519         }
520     }
521     
522     /**
523      * set config
524      *
525      * @return array
526      */
527     protected function _setConfig(Zend_Console_Getopt $_opts)
528     {
529         $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
530         $errors = array();
531         if (empty($options['configkey'])) {
532             $errors[] = 'Missing argument: configkey';
533         }
534         if (! isset($options['configvalue'])) {
535             $errors[] = 'Missing argument: configvalue';
536         }
537         $configKey = (string)$options['configkey'];
538         $configValue = self::parseConfigValue($options['configvalue']);
539         $applicationName = (isset($options['app'])) ? $options['app'] : 'Tinebase';
540
541         if (! Tinebase_Application::getInstance()->isInstalled('Tinebase') || ! Tinebase_Application::getInstance()->isInstalled($applicationName)) {
542             $errors[] = $applicationName . ' is not installed';
543         }
544         
545         if (empty($errors)) {
546            Setup_Controller::getInstance()->setConfigOption($configKey, $configValue, $applicationName);
547            echo "OK - Updated configuration option $configKey for application $applicationName\n";
548         } else {
549             echo "ERRORS - The following errors occured: \n";
550             foreach ($errors as $error) {
551                 echo "- " . $error . "\n";
552             }
553         }
554     }
555     
556     /**
557      * get config
558      *
559      */
560     protected function _getConfig(Zend_Console_Getopt $_opts)
561     {
562         $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
563         $applicationName = (isset($options['app'])) ? $options['app'] : 'Tinebase';
564
565         $errors = array();
566         if (! Tinebase_Application::getInstance()->isInstalled('Tinebase') || ! Tinebase_Application::getInstance()->isInstalled($applicationName)) {
567             $errors[] = $applicationName . ' is not installed';
568             $config = null;
569         } else {
570             $config = Tinebase_Config_Abstract::factory($applicationName);
571         }
572
573         if (empty($options['configkey'])) {
574             $errors[] = 'Missing argument: configkey';
575             if ($config) {
576                 $errors[] = 'Available config settings:';
577                 $errors[] = print_r($config::getProperties(), true);
578             }
579         }
580         $configKey = (string)$options['configkey'];
581         
582         if (empty($errors)) {
583             $value = $config->get($configKey);
584             $value = is_string($value) ? $value : Zend_Json::encode($value);
585             echo $value . " \n";
586         } else {
587             echo "ERRORS - The following errors occured: \n";
588             foreach ($errors as $error) {
589                 echo "- " . $error . "\n";
590             }
591         }
592     }
593     
594     /**
595      * create admin user / activate existing user / allow to reset password
596      * 
597      * @param Zend_Console_Getopt $_opts
598      * 
599      * @todo check role by rights and not by name
600      * @todo replace echos with stdout logger
601      */
602     protected function _createAdminUser(Zend_Console_Getopt $_opts)
603     {
604         if (! Setup_Controller::getInstance()->isInstalled('Tinebase')) {
605             die('Install Tinebase first.');
606         }
607
608         $setupUser = Setup_Update_Abstract::getSetupFromConfigOrCreateOnTheFly();
609         if (! Tinebase_Core::getUser() instanceof Tinebase_Model_User) {
610             Tinebase_Core::set(Tinebase_Core::USER, $setupUser);
611         }
612
613         echo "Please enter a username. An existing user is reactivated and you can reset the password.\n";
614         $username = strtolower(Tinebase_Server_Cli::promptInput('Username'));
615         $tomorrow = Tinebase_DateTime::now()->addDay(1);
616         
617         try {
618             $user = Tinebase_User::getInstance()->getFullUserByLoginName($username);
619             echo "User $username already exists.\n";
620             Tinebase_User::getInstance()->setStatus($user->getId(), Tinebase_Model_User::ACCOUNT_STATUS_ENABLED);
621             echo "Activated admin user '$username'.\n";
622             
623             $expire = Tinebase_Server_Cli::promptInput('Should the admin user expire tomorrow (default: "no", "y" or "yes" for expiry)?');
624             if ($expire === 'y' or $expire === 'yes') {
625                 Tinebase_User::getInstance()->setExpiryDate($user->getId(), $tomorrow);
626                 echo "User expires tomorrow at $tomorrow.\n";
627             }
628             
629             $resetPw = Tinebase_Server_Cli::promptInput('Do you want to reset the password (default: "no", "y" or "yes" for reset)?');
630             if ($resetPw === 'y' or $resetPw === 'yes') {
631                 $password = $this->_promptPassword();
632                 Tinebase_User::getInstance()->setPassword($user, $password);
633                 echo "User password has been reset.\n";
634             }
635
636             try {
637                 Tinebase_User::getInstance()->assertAdminGroupMembership($user);
638                 echo "Added user to default admin group\n";
639             } catch (Exception $e) {
640                 Tinebase_Exception::log($e);
641                 echo "Could not add user to default admin group: " . $e->getMessage();
642             }
643
644             $this->_checkAdminRole($user);
645             
646         } catch (Tinebase_Exception_NotFound $tenf) {
647             // create new admin user that expires tomorrow
648             $password = $this->_promptPassword();
649             Tinebase_User::createInitialAccounts(array(
650                 'adminLoginName' => $username,
651                 'adminPassword'  => $password,
652                 'expires'        => $tomorrow,
653             ));
654             echo "Created new admin user '$username' that expires tomorrow.\n";
655         }
656     }
657
658
659     /**
660      * check admin role membership
661      * 
662      * @param Tinebase_Model_FullUser $user
663      */
664     protected function _checkAdminRole($user)
665     {
666         $roleMemberships = Tinebase_Acl_Roles::getInstance()->getRoleMemberships($user->getId());
667         $adminRoleFound = FALSE;
668         // TODO allow to configure this / pass it as param
669         $adminRoleName = 'admin role';
670
671         foreach ($roleMemberships as $roleId) {
672             $role = Tinebase_Acl_Roles::getInstance()->getRoleById($roleId);
673             if ($role->name === $adminRoleName) {
674                 $adminRoleFound = TRUE;
675                 break;
676             }
677         }
678
679         if (! $adminRoleFound || ! Tinebase_Acl_Roles::getInstance()->hasRight('Admin', $user->getId(), Tinebase_Acl_Rights::ADMIN)) {
680             echo "Admin role not found for user " . $user->accountLoginName . ".\n";
681
682             try {
683                 $adminRole = Tinebase_Acl_Roles::getInstance()->getRoleByName($adminRoleName);
684             } catch (Tinebase_Exception_NotFound $tenf) {
685                 $adminRole = $this->_createNewAdminRoleForAdmin($adminRoleName);
686             }
687
688             Tinebase_Acl_Roles::getInstance()->setRoleMembers($adminRole->getId(), array(
689                 array(
690                     'id'    => $user->getId(),
691                     'type'  => Tinebase_Acl_Rights::ACCOUNT_TYPE_USER, 
692                 )
693             ));
694             
695             echo "Added user " . $user->accountLoginName . " to role '$adminRoleName''.\n";
696             // @todo clear roles/groups cache
697         }
698     }
699
700     protected function _createNewAdminRoleForAdmin($adminRoleName)
701     {
702         $adminRole = new Tinebase_Model_Role(array(
703             'name'                  => $adminRoleName,
704             'description'           => 'admin role for tine. this role has all rights per default.',
705         ));
706
707         $adminRole = Tinebase_Acl_Roles::getInstance()->createRole($adminRole);
708         // add all rights for all apps
709         $enabledApps = Tinebase_Application::getInstance()->getApplicationsByState(Tinebase_Application::ENABLED);
710         $roleRights = array();
711         foreach ($enabledApps as $application) {
712             $allRights = Tinebase_Application::getInstance()->getAllRights($application->getId());
713             foreach ($allRights as $right) {
714                 $roleRights[] = array(
715                     'application_id' => $application->getId(),
716                     'right'          => $right,
717                 );
718             }
719         }
720         Tinebase_Acl_Roles::getInstance()->setRoleRights($adminRole->getId(), $roleRights);
721
722         return $adminRole;
723     }
724
725     /**
726      * @param Zend_Console_Getopt $_opts
727      * @throws Exception
728      */
729     protected function _backup(Zend_Console_Getopt $_opts)
730     {
731         $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
732         Setup_Controller::getInstance()->backup($options);
733     }
734
735     /**
736      * @param Zend_Console_Getopt $_opts
737      * @throws Exception
738      */
739     protected function _restore(Zend_Console_Getopt $_opts)
740     {
741         $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
742         Setup_Controller::getInstance()->restore($options);
743     }
744
745     /**
746      * @param Zend_Console_Getopt $_opts
747      * @throws Exception
748      */
749     protected function _installDump(Zend_Console_Getopt $_opts)
750     {
751         $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
752         Setup_Controller::getInstance()->installFromDump($options);
753     }
754
755     /**
756      * parse options
757      * 
758      * @param string $_value
759      * @return array|string
760      */
761     public static function parseConfigValue($_value)
762     {
763         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($_value, TRUE));
764         
765         // check value is json encoded
766         if (Tinebase_Helper::is_json($_value)) {
767             return Zend_Json::decode($_value); 
768         }
769         
770         $result = array(
771             'active' => 1
772         );
773
774         // keep spaces, \: and \,
775         $_value = preg_replace(array('/ /', '/\\\:/', '/\\\,/', '/\s*/'), array('§', '@', ';', ''), $_value);
776         
777         $parts = explode(',', $_value);
778         
779         foreach ($parts as $part) {
780             $part = str_replace(';', ',', $part);
781             $part = str_replace('§', ' ', $part);
782             $part = str_replace('@', ':', $part);
783             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $part);
784             if (strpos($part, '_') !== FALSE) {
785                 list($key, $sub) = preg_split('/_/', $part, 2);
786                 if (preg_match('/:/', $sub)) {
787                     list($subKey, $value) = explode(':', $sub);
788                     $result[$key][$subKey] = $value;
789                 } else {
790                     // might be a '_' in the value
791                     if (preg_match('/:/', $part)) {
792                         $exploded = explode(':', $part);
793                         $key = array_shift($exploded);
794                         $result[$key] = implode(':', $exploded);
795                     } else {
796                         throw new Timetracker_Exception_UnexpectedValue('You have an error in the config syntax (":" expected): ' . $part);
797                     }
798                 }
799             } else {
800                 if (strpos($part, ':') !== FALSE) {
801                     list($key, $value) = preg_split('/:/', $part, 2);
802                     $result[$key] = $value;
803                 } else {
804                     $result = $part;
805                 }
806             }
807         }
808
809         return $result;
810     }
811     
812     /**
813      * parse remaining args
814      * 
815      * @param string $_args
816      * @return array
817      */
818     protected function _parseRemainingArgs($_args)
819     {
820         $options = array();
821         foreach ($_args as $arg) {
822             if (strpos($arg, '=') !== FALSE) {
823                 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $arg);
824                 list($key, $value) = preg_split('/=/', $arg, 2);
825                 $options[$key] = $value;
826             }
827         }
828         
829         return $options;
830     }
831
832     protected function _compare(Zend_Console_Getopt $_opts)
833     {
834         $options = $this->_parseRemainingArgs($_opts->getRemainingArgs());
835         print_r(Setup_Controller::getInstance()->compareSchema($options));
836     }
837 }