Completed
Pull Request — master (#5231)
by Joas
15:54
created
core/Command/Db/Migrations/MigrateCommand.php 1 patch
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -32,33 +32,33 @@
 block discarded – undo
32 32
 
33 33
 class MigrateCommand extends Command {
34 34
 
35
-	/** @var IDBConnection */
36
-	private $connection;
35
+    /** @var IDBConnection */
36
+    private $connection;
37 37
 
38
-	/**
39
-	 * @param IDBConnection $connection
40
-	 */
41
-	public function __construct(IDBConnection $connection) {
42
-		$this->connection = $connection;
43
-		parent::__construct();
44
-	}
38
+    /**
39
+     * @param IDBConnection $connection
40
+     */
41
+    public function __construct(IDBConnection $connection) {
42
+        $this->connection = $connection;
43
+        parent::__construct();
44
+    }
45 45
 
46
-	protected function configure() {
47
-		$this
48
-			->setName('migrations:migrate')
49
-			->setDescription('Execute a migration to a specified version or the latest available version.')
50
-			->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
51
-			->addArgument('version', InputArgument::OPTIONAL, 'The version number (YYYYMMDDHHMMSS) or alias (first, prev, next, latest) to migrate to.', 'latest');
46
+    protected function configure() {
47
+        $this
48
+            ->setName('migrations:migrate')
49
+            ->setDescription('Execute a migration to a specified version or the latest available version.')
50
+            ->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
51
+            ->addArgument('version', InputArgument::OPTIONAL, 'The version number (YYYYMMDDHHMMSS) or alias (first, prev, next, latest) to migrate to.', 'latest');
52 52
 
53
-		parent::configure();
54
-	}
53
+        parent::configure();
54
+    }
55 55
 
56
-	public function execute(InputInterface $input, OutputInterface $output) {
57
-		$appName = $input->getArgument('app');
58
-		$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
59
-		$version = $input->getArgument('version');
56
+    public function execute(InputInterface $input, OutputInterface $output) {
57
+        $appName = $input->getArgument('app');
58
+        $ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
59
+        $version = $input->getArgument('version');
60 60
 
61
-		$ms->migrate($version);
62
-	}
61
+        $ms->migrate($version);
62
+    }
63 63
 
64 64
 }
Please login to merge, or discard this patch.
core/Command/Db/Migrations/ExecuteCommand.php 2 patches
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -36,57 +36,57 @@
 block discarded – undo
36 36
 
37 37
 class ExecuteCommand extends Command {
38 38
 
39
-	/** @var IDBConnection */
40
-	private $connection;
41
-	/** @var IConfig */
42
-	private $config;
39
+    /** @var IDBConnection */
40
+    private $connection;
41
+    /** @var IConfig */
42
+    private $config;
43 43
 
44
-	/**
45
-	 * ExecuteCommand constructor.
46
-	 *
47
-	 * @param IDBConnection $connection
48
-	 * @param IConfig $config
49
-	 */
50
-	public function __construct(IDBConnection $connection, IConfig $config) {
51
-		$this->connection = $connection;
52
-		$this->config = $config;
44
+    /**
45
+     * ExecuteCommand constructor.
46
+     *
47
+     * @param IDBConnection $connection
48
+     * @param IConfig $config
49
+     */
50
+    public function __construct(IDBConnection $connection, IConfig $config) {
51
+        $this->connection = $connection;
52
+        $this->config = $config;
53 53
 
54
-		parent::__construct();
55
-	}
54
+        parent::__construct();
55
+    }
56 56
 
57
-	protected function configure() {
58
-		$this
59
-			->setName('migrations:execute')
60
-			->setDescription('Execute a single migration version manually.')
61
-			->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
62
-			->addArgument('version', InputArgument::REQUIRED, 'The version to execute.', null);
57
+    protected function configure() {
58
+        $this
59
+            ->setName('migrations:execute')
60
+            ->setDescription('Execute a single migration version manually.')
61
+            ->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on')
62
+            ->addArgument('version', InputArgument::REQUIRED, 'The version to execute.', null);
63 63
 
64
-		parent::configure();
65
-	}
64
+        parent::configure();
65
+    }
66 66
 
67
-	/**
68
-	 * @param InputInterface $input
69
-	 * @param OutputInterface $output
70
-	 * @return int
71
-	 */
72
-	public function execute(InputInterface $input, OutputInterface $output) {
73
-		$appName = $input->getArgument('app');
74
-		$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
75
-		$version = $input->getArgument('version');
67
+    /**
68
+     * @param InputInterface $input
69
+     * @param OutputInterface $output
70
+     * @return int
71
+     */
72
+    public function execute(InputInterface $input, OutputInterface $output) {
73
+        $appName = $input->getArgument('app');
74
+        $ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
75
+        $version = $input->getArgument('version');
76 76
 
77
-		if ($this->config->getSystemValue('debug', false) === false) {
78
-			$olderVersions = $ms->getMigratedVersions();
79
-			$olderVersions[] = '0';
80
-			$olderVersions[] = 'prev';
81
-			if (in_array($version,  $olderVersions, true)) {
82
-				$output->writeln('<error>Can not go back to previous migration without debug enabled</error>');
83
-				return 1;
84
-			}
85
-		}
77
+        if ($this->config->getSystemValue('debug', false) === false) {
78
+            $olderVersions = $ms->getMigratedVersions();
79
+            $olderVersions[] = '0';
80
+            $olderVersions[] = 'prev';
81
+            if (in_array($version,  $olderVersions, true)) {
82
+                $output->writeln('<error>Can not go back to previous migration without debug enabled</error>');
83
+                return 1;
84
+            }
85
+        }
86 86
 
87 87
 
88
-		$ms->executeStep($version);
89
-		return 0;
90
-	}
88
+        $ms->executeStep($version);
89
+        return 0;
90
+    }
91 91
 
92 92
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -78,7 +78,7 @@
 block discarded – undo
78 78
 			$olderVersions = $ms->getMigratedVersions();
79 79
 			$olderVersions[] = '0';
80 80
 			$olderVersions[] = 'prev';
81
-			if (in_array($version,  $olderVersions, true)) {
81
+			if (in_array($version, $olderVersions, true)) {
82 82
 				$output->writeln('<error>Can not go back to previous migration without debug enabled</error>');
83 83
 				return 1;
84 84
 			}
Please login to merge, or discard this patch.
core/Command/Db/Migrations/StatusCommand.php 2 patches
Indentation   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -31,85 +31,85 @@
 block discarded – undo
31 31
 
32 32
 class StatusCommand extends Command {
33 33
 
34
-	/** @var IDBConnection */
35
-	private $connection;
36
-
37
-	/**
38
-	 * @param IDBConnection $connection
39
-	 */
40
-	public function __construct(IDBConnection $connection) {
41
-		$this->connection = $connection;
42
-		parent::__construct();
43
-	}
44
-
45
-	protected function configure() {
46
-		$this
47
-			->setName('migrations:status')
48
-			->setDescription('View the status of a set of migrations.')
49
-			->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on');
50
-	}
51
-
52
-	public function execute(InputInterface $input, OutputInterface $output) {
53
-		$appName = $input->getArgument('app');
54
-		$ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
55
-
56
-		$infos = $this->getMigrationsInfos($ms);
57
-		foreach ($infos as $key => $value) {
58
-			$output->writeln("    <comment>>></comment> $key: " . str_repeat(' ', 50 - strlen($key)) . $value);
59
-		}
60
-	}
61
-
62
-	/**
63
-	 * @param MigrationService $ms
64
-	 * @return array associative array of human readable info name as key and the actual information as value
65
-	 */
66
-	public function getMigrationsInfos(MigrationService $ms) {
67
-
68
-		$executedMigrations = $ms->getMigratedVersions();
69
-		$availableMigrations = $ms->getAvailableVersions();
70
-		$executedUnavailableMigrations = array_diff($executedMigrations, array_keys($availableMigrations));
71
-
72
-		$numExecutedUnavailableMigrations = count($executedUnavailableMigrations);
73
-		$numNewMigrations = count(array_diff(array_keys($availableMigrations), $executedMigrations));
74
-
75
-		$infos = [
76
-			'App'								=> $ms->getApp(),
77
-			'Version Table Name'				=> $ms->getMigrationsTableName(),
78
-			'Migrations Namespace'				=> $ms->getMigrationsNamespace(),
79
-			'Migrations Directory'				=> $ms->getMigrationsDirectory(),
80
-			'Previous Version'					=> $this->getFormattedVersionAlias($ms, 'prev'),
81
-			'Current Version'					=> $this->getFormattedVersionAlias($ms, 'current'),
82
-			'Next Version'						=> $this->getFormattedVersionAlias($ms, 'next'),
83
-			'Latest Version'					=> $this->getFormattedVersionAlias($ms, 'latest'),
84
-			'Executed Migrations'				=> count($executedMigrations),
85
-			'Executed Unavailable Migrations'	=> $numExecutedUnavailableMigrations,
86
-			'Available Migrations'				=> count($availableMigrations),
87
-			'New Migrations'					=> $numNewMigrations,
88
-		];
89
-
90
-		return $infos;
91
-	}
92
-
93
-	/**
94
-	 * @param MigrationService $migrationService
95
-	 * @param string $alias
96
-	 * @return mixed|null|string
97
-	 */
98
-	private function getFormattedVersionAlias(MigrationService $migrationService, $alias) {
99
-		$migration = $migrationService->getMigration($alias);
100
-		//No version found
101
-		if ($migration === null) {
102
-			if ($alias === 'next') {
103
-				return 'Already at latest migration step';
104
-			}
105
-
106
-			if ($alias === 'prev') {
107
-				return 'Already at first migration step';
108
-			}
109
-		}
110
-
111
-		return $migration;
112
-	}
34
+    /** @var IDBConnection */
35
+    private $connection;
36
+
37
+    /**
38
+     * @param IDBConnection $connection
39
+     */
40
+    public function __construct(IDBConnection $connection) {
41
+        $this->connection = $connection;
42
+        parent::__construct();
43
+    }
44
+
45
+    protected function configure() {
46
+        $this
47
+            ->setName('migrations:status')
48
+            ->setDescription('View the status of a set of migrations.')
49
+            ->addArgument('app', InputArgument::REQUIRED, 'Name of the app this migration command shall work on');
50
+    }
51
+
52
+    public function execute(InputInterface $input, OutputInterface $output) {
53
+        $appName = $input->getArgument('app');
54
+        $ms = new MigrationService($appName, $this->connection, new ConsoleOutput($output));
55
+
56
+        $infos = $this->getMigrationsInfos($ms);
57
+        foreach ($infos as $key => $value) {
58
+            $output->writeln("    <comment>>></comment> $key: " . str_repeat(' ', 50 - strlen($key)) . $value);
59
+        }
60
+    }
61
+
62
+    /**
63
+     * @param MigrationService $ms
64
+     * @return array associative array of human readable info name as key and the actual information as value
65
+     */
66
+    public function getMigrationsInfos(MigrationService $ms) {
67
+
68
+        $executedMigrations = $ms->getMigratedVersions();
69
+        $availableMigrations = $ms->getAvailableVersions();
70
+        $executedUnavailableMigrations = array_diff($executedMigrations, array_keys($availableMigrations));
71
+
72
+        $numExecutedUnavailableMigrations = count($executedUnavailableMigrations);
73
+        $numNewMigrations = count(array_diff(array_keys($availableMigrations), $executedMigrations));
74
+
75
+        $infos = [
76
+            'App'								=> $ms->getApp(),
77
+            'Version Table Name'				=> $ms->getMigrationsTableName(),
78
+            'Migrations Namespace'				=> $ms->getMigrationsNamespace(),
79
+            'Migrations Directory'				=> $ms->getMigrationsDirectory(),
80
+            'Previous Version'					=> $this->getFormattedVersionAlias($ms, 'prev'),
81
+            'Current Version'					=> $this->getFormattedVersionAlias($ms, 'current'),
82
+            'Next Version'						=> $this->getFormattedVersionAlias($ms, 'next'),
83
+            'Latest Version'					=> $this->getFormattedVersionAlias($ms, 'latest'),
84
+            'Executed Migrations'				=> count($executedMigrations),
85
+            'Executed Unavailable Migrations'	=> $numExecutedUnavailableMigrations,
86
+            'Available Migrations'				=> count($availableMigrations),
87
+            'New Migrations'					=> $numNewMigrations,
88
+        ];
89
+
90
+        return $infos;
91
+    }
92
+
93
+    /**
94
+     * @param MigrationService $migrationService
95
+     * @param string $alias
96
+     * @return mixed|null|string
97
+     */
98
+    private function getFormattedVersionAlias(MigrationService $migrationService, $alias) {
99
+        $migration = $migrationService->getMigration($alias);
100
+        //No version found
101
+        if ($migration === null) {
102
+            if ($alias === 'next') {
103
+                return 'Already at latest migration step';
104
+            }
105
+
106
+            if ($alias === 'prev') {
107
+                return 'Already at first migration step';
108
+            }
109
+        }
110
+
111
+        return $migration;
112
+    }
113 113
 
114 114
 
115 115
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@
 block discarded – undo
55 55
 
56 56
 		$infos = $this->getMigrationsInfos($ms);
57 57
 		foreach ($infos as $key => $value) {
58
-			$output->writeln("    <comment>>></comment> $key: " . str_repeat(' ', 50 - strlen($key)) . $value);
58
+			$output->writeln("    <comment>>></comment> $key: ".str_repeat(' ', 50 - strlen($key)).$value);
59 59
 		}
60 60
 	}
61 61
 
Please login to merge, or discard this patch.
core/register_command.php 1 patch
Indentation   +92 added lines, -92 removed lines patch added patch discarded remove patch
@@ -40,119 +40,119 @@
 block discarded – undo
40 40
 $application->add(new OC\Core\Command\App\CheckCode($infoParser));
41 41
 $application->add(new OC\Core\Command\L10n\CreateJs());
42 42
 $application->add(new \OC\Core\Command\Integrity\SignApp(
43
-		\OC::$server->getIntegrityCodeChecker(),
44
-		new \OC\IntegrityCheck\Helpers\FileAccessHelper(),
45
-		\OC::$server->getURLGenerator()
43
+        \OC::$server->getIntegrityCodeChecker(),
44
+        new \OC\IntegrityCheck\Helpers\FileAccessHelper(),
45
+        \OC::$server->getURLGenerator()
46 46
 ));
47 47
 $application->add(new \OC\Core\Command\Integrity\SignCore(
48
-		\OC::$server->getIntegrityCodeChecker(),
49
-		new \OC\IntegrityCheck\Helpers\FileAccessHelper()
48
+        \OC::$server->getIntegrityCodeChecker(),
49
+        new \OC\IntegrityCheck\Helpers\FileAccessHelper()
50 50
 ));
51 51
 $application->add(new \OC\Core\Command\Integrity\CheckApp(
52
-		\OC::$server->getIntegrityCodeChecker()
52
+        \OC::$server->getIntegrityCodeChecker()
53 53
 ));
54 54
 $application->add(new \OC\Core\Command\Integrity\CheckCore(
55
-		\OC::$server->getIntegrityCodeChecker()
55
+        \OC::$server->getIntegrityCodeChecker()
56 56
 ));
57 57
 
58 58
 
59 59
 if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
60
-	$application->add(new OC\Core\Command\App\Disable(\OC::$server->getAppManager()));
61
-	$application->add(new OC\Core\Command\App\Enable(\OC::$server->getAppManager()));
62
-	$application->add(new OC\Core\Command\App\GetPath());
63
-	$application->add(new OC\Core\Command\App\ListApps(\OC::$server->getAppManager()));
60
+    $application->add(new OC\Core\Command\App\Disable(\OC::$server->getAppManager()));
61
+    $application->add(new OC\Core\Command\App\Enable(\OC::$server->getAppManager()));
62
+    $application->add(new OC\Core\Command\App\GetPath());
63
+    $application->add(new OC\Core\Command\App\ListApps(\OC::$server->getAppManager()));
64 64
 	
65
-	$application->add(new OC\Core\Command\TwoFactorAuth\Enable(
66
-		\OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
67
-	));
68
-	$application->add(new OC\Core\Command\TwoFactorAuth\Disable(
69
-		\OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
70
-	));
65
+    $application->add(new OC\Core\Command\TwoFactorAuth\Enable(
66
+        \OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
67
+    ));
68
+    $application->add(new OC\Core\Command\TwoFactorAuth\Disable(
69
+        \OC::$server->getTwoFactorAuthManager(), \OC::$server->getUserManager()
70
+    ));
71 71
 
72
-	$application->add(new OC\Core\Command\Background\Cron(\OC::$server->getConfig()));
73
-	$application->add(new OC\Core\Command\Background\WebCron(\OC::$server->getConfig()));
74
-	$application->add(new OC\Core\Command\Background\Ajax(\OC::$server->getConfig()));
72
+    $application->add(new OC\Core\Command\Background\Cron(\OC::$server->getConfig()));
73
+    $application->add(new OC\Core\Command\Background\WebCron(\OC::$server->getConfig()));
74
+    $application->add(new OC\Core\Command\Background\Ajax(\OC::$server->getConfig()));
75 75
 
76
-	$application->add(new OC\Core\Command\Config\App\DeleteConfig(\OC::$server->getConfig()));
77
-	$application->add(new OC\Core\Command\Config\App\GetConfig(\OC::$server->getConfig()));
78
-	$application->add(new OC\Core\Command\Config\App\SetConfig(\OC::$server->getConfig()));
79
-	$application->add(new OC\Core\Command\Config\Import(\OC::$server->getConfig()));
80
-	$application->add(new OC\Core\Command\Config\ListConfigs(\OC::$server->getSystemConfig(), \OC::$server->getAppConfig()));
81
-	$application->add(new OC\Core\Command\Config\System\DeleteConfig(\OC::$server->getSystemConfig()));
82
-	$application->add(new OC\Core\Command\Config\System\GetConfig(\OC::$server->getSystemConfig()));
83
-	$application->add(new OC\Core\Command\Config\System\SetConfig(\OC::$server->getSystemConfig()));
76
+    $application->add(new OC\Core\Command\Config\App\DeleteConfig(\OC::$server->getConfig()));
77
+    $application->add(new OC\Core\Command\Config\App\GetConfig(\OC::$server->getConfig()));
78
+    $application->add(new OC\Core\Command\Config\App\SetConfig(\OC::$server->getConfig()));
79
+    $application->add(new OC\Core\Command\Config\Import(\OC::$server->getConfig()));
80
+    $application->add(new OC\Core\Command\Config\ListConfigs(\OC::$server->getSystemConfig(), \OC::$server->getAppConfig()));
81
+    $application->add(new OC\Core\Command\Config\System\DeleteConfig(\OC::$server->getSystemConfig()));
82
+    $application->add(new OC\Core\Command\Config\System\GetConfig(\OC::$server->getSystemConfig()));
83
+    $application->add(new OC\Core\Command\Config\System\SetConfig(\OC::$server->getSystemConfig()));
84 84
 
85
-	$application->add(new OC\Core\Command\Db\GenerateChangeScript());
86
-	$application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory(\OC::$server->getSystemConfig())));
87
-	$application->add(new OC\Core\Command\Db\ConvertMysqlToMB4(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection(), \OC::$server->getURLGenerator(), \OC::$server->getLogger()));
88
-	$application->add(new OC\Core\Command\Db\Migrations\StatusCommand(\OC::$server->getDatabaseConnection()));
89
-	$application->add(new OC\Core\Command\Db\Migrations\MigrateCommand(\OC::$server->getDatabaseConnection()));
90
-	$application->add(new OC\Core\Command\Db\Migrations\GenerateCommand(\OC::$server->getDatabaseConnection()));
91
-	$application->add(new OC\Core\Command\Db\Migrations\ExecuteCommand(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()));
85
+    $application->add(new OC\Core\Command\Db\GenerateChangeScript());
86
+    $application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory(\OC::$server->getSystemConfig())));
87
+    $application->add(new OC\Core\Command\Db\ConvertMysqlToMB4(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection(), \OC::$server->getURLGenerator(), \OC::$server->getLogger()));
88
+    $application->add(new OC\Core\Command\Db\Migrations\StatusCommand(\OC::$server->getDatabaseConnection()));
89
+    $application->add(new OC\Core\Command\Db\Migrations\MigrateCommand(\OC::$server->getDatabaseConnection()));
90
+    $application->add(new OC\Core\Command\Db\Migrations\GenerateCommand(\OC::$server->getDatabaseConnection()));
91
+    $application->add(new OC\Core\Command\Db\Migrations\ExecuteCommand(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()));
92 92
 
93
-	$application->add(new OC\Core\Command\Encryption\Disable(\OC::$server->getConfig()));
94
-	$application->add(new OC\Core\Command\Encryption\Enable(\OC::$server->getConfig(), \OC::$server->getEncryptionManager()));
95
-	$application->add(new OC\Core\Command\Encryption\ListModules(\OC::$server->getEncryptionManager()));
96
-	$application->add(new OC\Core\Command\Encryption\SetDefaultModule(\OC::$server->getEncryptionManager()));
97
-	$application->add(new OC\Core\Command\Encryption\Status(\OC::$server->getEncryptionManager()));
98
-	$application->add(new OC\Core\Command\Encryption\EncryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getAppManager(), \OC::$server->getConfig(), new \Symfony\Component\Console\Helper\QuestionHelper()));
99
-	$application->add(new OC\Core\Command\Encryption\DecryptAll(
100
-		\OC::$server->getEncryptionManager(),
101
-		\OC::$server->getAppManager(),
102
-		\OC::$server->getConfig(),
103
-		new \OC\Encryption\DecryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getUserManager(), new \OC\Files\View()),
104
-		new \Symfony\Component\Console\Helper\QuestionHelper())
105
-	);
93
+    $application->add(new OC\Core\Command\Encryption\Disable(\OC::$server->getConfig()));
94
+    $application->add(new OC\Core\Command\Encryption\Enable(\OC::$server->getConfig(), \OC::$server->getEncryptionManager()));
95
+    $application->add(new OC\Core\Command\Encryption\ListModules(\OC::$server->getEncryptionManager()));
96
+    $application->add(new OC\Core\Command\Encryption\SetDefaultModule(\OC::$server->getEncryptionManager()));
97
+    $application->add(new OC\Core\Command\Encryption\Status(\OC::$server->getEncryptionManager()));
98
+    $application->add(new OC\Core\Command\Encryption\EncryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getAppManager(), \OC::$server->getConfig(), new \Symfony\Component\Console\Helper\QuestionHelper()));
99
+    $application->add(new OC\Core\Command\Encryption\DecryptAll(
100
+        \OC::$server->getEncryptionManager(),
101
+        \OC::$server->getAppManager(),
102
+        \OC::$server->getConfig(),
103
+        new \OC\Encryption\DecryptAll(\OC::$server->getEncryptionManager(), \OC::$server->getUserManager(), new \OC\Files\View()),
104
+        new \Symfony\Component\Console\Helper\QuestionHelper())
105
+    );
106 106
 
107
-	$application->add(new OC\Core\Command\Log\Manage(\OC::$server->getConfig()));
108
-	$application->add(new OC\Core\Command\Log\File(\OC::$server->getConfig()));
107
+    $application->add(new OC\Core\Command\Log\Manage(\OC::$server->getConfig()));
108
+    $application->add(new OC\Core\Command\Log\File(\OC::$server->getConfig()));
109 109
 
110
-	$view = new \OC\Files\View();
111
-	$util = new \OC\Encryption\Util(
112
-		$view,
113
-		\OC::$server->getUserManager(),
114
-		\OC::$server->getGroupManager(),
115
-		\OC::$server->getConfig()
116
-	);
117
-	$application->add(new OC\Core\Command\Encryption\ChangeKeyStorageRoot(
118
-			$view,
119
-			\OC::$server->getUserManager(),
120
-			\OC::$server->getConfig(),
121
-			$util,
122
-			new \Symfony\Component\Console\Helper\QuestionHelper()
123
-		)
124
-	);
125
-	$application->add(new OC\Core\Command\Encryption\ShowKeyStorageRoot($util));
110
+    $view = new \OC\Files\View();
111
+    $util = new \OC\Encryption\Util(
112
+        $view,
113
+        \OC::$server->getUserManager(),
114
+        \OC::$server->getGroupManager(),
115
+        \OC::$server->getConfig()
116
+    );
117
+    $application->add(new OC\Core\Command\Encryption\ChangeKeyStorageRoot(
118
+            $view,
119
+            \OC::$server->getUserManager(),
120
+            \OC::$server->getConfig(),
121
+            $util,
122
+            new \Symfony\Component\Console\Helper\QuestionHelper()
123
+        )
124
+    );
125
+    $application->add(new OC\Core\Command\Encryption\ShowKeyStorageRoot($util));
126 126
 
127
-	$application->add(new OC\Core\Command\Maintenance\DataFingerprint(\OC::$server->getConfig(), new \OC\AppFramework\Utility\TimeFactory()));
128
-	$application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateDB(\OC::$server->getMimeTypeDetector(), \OC::$server->getMimeTypeLoader()));
129
-	$application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateJS(\OC::$server->getMimeTypeDetector()));
130
-	$application->add(new OC\Core\Command\Maintenance\Mode(\OC::$server->getConfig()));
131
-	$application->add(new OC\Core\Command\Maintenance\UpdateHtaccess());
127
+    $application->add(new OC\Core\Command\Maintenance\DataFingerprint(\OC::$server->getConfig(), new \OC\AppFramework\Utility\TimeFactory()));
128
+    $application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateDB(\OC::$server->getMimeTypeDetector(), \OC::$server->getMimeTypeLoader()));
129
+    $application->add(new OC\Core\Command\Maintenance\Mimetype\UpdateJS(\OC::$server->getMimeTypeDetector()));
130
+    $application->add(new OC\Core\Command\Maintenance\Mode(\OC::$server->getConfig()));
131
+    $application->add(new OC\Core\Command\Maintenance\UpdateHtaccess());
132 132
 
133
-	$application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->getLogger()));
134
-	$application->add(new OC\Core\Command\Maintenance\Repair(
135
-		new \OC\Repair(\OC\Repair::getRepairSteps(), \OC::$server->getEventDispatcher()), \OC::$server->getConfig(),
136
-		\OC::$server->getEventDispatcher()));
133
+    $application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->getLogger()));
134
+    $application->add(new OC\Core\Command\Maintenance\Repair(
135
+        new \OC\Repair(\OC\Repair::getRepairSteps(), \OC::$server->getEventDispatcher()), \OC::$server->getConfig(),
136
+        \OC::$server->getEventDispatcher()));
137 137
 
138
-	$application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
139
-	$application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
140
-	$application->add(new OC\Core\Command\User\Disable(\OC::$server->getUserManager()));
141
-	$application->add(new OC\Core\Command\User\Enable(\OC::$server->getUserManager()));
142
-	$application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
143
-	$application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
144
-	$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
145
-	$application->add(new OC\Core\Command\User\Setting(\OC::$server->getUserManager(), \OC::$server->getConfig(), \OC::$server->getDatabaseConnection()));
146
-	$application->add(new OC\Core\Command\User\ListCommand(\OC::$server->getUserManager()));
147
-	$application->add(new OC\Core\Command\User\Info(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
138
+    $application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
139
+    $application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
140
+    $application->add(new OC\Core\Command\User\Disable(\OC::$server->getUserManager()));
141
+    $application->add(new OC\Core\Command\User\Enable(\OC::$server->getUserManager()));
142
+    $application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
143
+    $application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
144
+    $application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
145
+    $application->add(new OC\Core\Command\User\Setting(\OC::$server->getUserManager(), \OC::$server->getConfig(), \OC::$server->getDatabaseConnection()));
146
+    $application->add(new OC\Core\Command\User\ListCommand(\OC::$server->getUserManager()));
147
+    $application->add(new OC\Core\Command\User\Info(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
148 148
 
149
-	$application->add(new OC\Core\Command\Group\ListCommand(\OC::$server->getGroupManager()));
150
-	$application->add(new OC\Core\Command\Group\AddUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
151
-	$application->add(new OC\Core\Command\Group\RemoveUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
149
+    $application->add(new OC\Core\Command\Group\ListCommand(\OC::$server->getGroupManager()));
150
+    $application->add(new OC\Core\Command\Group\AddUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
151
+    $application->add(new OC\Core\Command\Group\RemoveUser(\OC::$server->getUserManager(), \OC::$server->getGroupManager()));
152 152
 
153
-	$application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
154
-	$application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
155
-	$application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
153
+    $application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
154
+    $application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
155
+    $application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
156 156
 } else {
157
-	$application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getSystemConfig()));
157
+    $application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getSystemConfig()));
158 158
 }
Please login to merge, or discard this patch.
lib/private/legacy/app.php 2 patches
Indentation   +1190 added lines, -1190 removed lines patch added patch discarded remove patch
@@ -61,1194 +61,1194 @@
 block discarded – undo
61 61
  * upgrading and removing apps.
62 62
  */
63 63
 class OC_App {
64
-	static private $appVersion = [];
65
-	static private $adminForms = array();
66
-	static private $personalForms = array();
67
-	static private $appInfo = array();
68
-	static private $appTypes = array();
69
-	static private $loadedApps = array();
70
-	static private $altLogin = array();
71
-	static private $alreadyRegistered = [];
72
-	const officialApp = 200;
73
-
74
-	/**
75
-	 * clean the appId
76
-	 *
77
-	 * @param string|boolean $app AppId that needs to be cleaned
78
-	 * @return string
79
-	 */
80
-	public static function cleanAppId($app) {
81
-		return str_replace(array('\0', '/', '\\', '..'), '', $app);
82
-	}
83
-
84
-	/**
85
-	 * Check if an app is loaded
86
-	 *
87
-	 * @param string $app
88
-	 * @return bool
89
-	 */
90
-	public static function isAppLoaded($app) {
91
-		return in_array($app, self::$loadedApps, true);
92
-	}
93
-
94
-	/**
95
-	 * loads all apps
96
-	 *
97
-	 * @param string[] | string | null $types
98
-	 * @return bool
99
-	 *
100
-	 * This function walks through the ownCloud directory and loads all apps
101
-	 * it can find. A directory contains an app if the file /appinfo/info.xml
102
-	 * exists.
103
-	 *
104
-	 * if $types is set, only apps of those types will be loaded
105
-	 */
106
-	public static function loadApps($types = null) {
107
-		if (\OC::$server->getSystemConfig()->getValue('maintenance', false)) {
108
-			return false;
109
-		}
110
-		// Load the enabled apps here
111
-		$apps = self::getEnabledApps();
112
-
113
-		// Add each apps' folder as allowed class path
114
-		foreach($apps as $app) {
115
-			$path = self::getAppPath($app);
116
-			if($path !== false) {
117
-				self::registerAutoloading($app, $path);
118
-			}
119
-		}
120
-
121
-		// prevent app.php from printing output
122
-		ob_start();
123
-		foreach ($apps as $app) {
124
-			if ((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) {
125
-				self::loadApp($app);
126
-			}
127
-		}
128
-		ob_end_clean();
129
-
130
-		return true;
131
-	}
132
-
133
-	/**
134
-	 * load a single app
135
-	 *
136
-	 * @param string $app
137
-	 */
138
-	public static function loadApp($app) {
139
-		self::$loadedApps[] = $app;
140
-		$appPath = self::getAppPath($app);
141
-		if($appPath === false) {
142
-			return;
143
-		}
144
-
145
-		// in case someone calls loadApp() directly
146
-		self::registerAutoloading($app, $appPath);
147
-
148
-		if (is_file($appPath . '/appinfo/app.php')) {
149
-			\OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
150
-			self::requireAppFile($app);
151
-			if (self::isType($app, array('authentication'))) {
152
-				// since authentication apps affect the "is app enabled for group" check,
153
-				// the enabled apps cache needs to be cleared to make sure that the
154
-				// next time getEnableApps() is called it will also include apps that were
155
-				// enabled for groups
156
-				self::$enabledAppsCache = array();
157
-			}
158
-			\OC::$server->getEventLogger()->end('load_app_' . $app);
159
-		}
160
-
161
-		$info = self::getAppInfo($app);
162
-		if (!empty($info['activity']['filters'])) {
163
-			foreach ($info['activity']['filters'] as $filter) {
164
-				\OC::$server->getActivityManager()->registerFilter($filter);
165
-			}
166
-		}
167
-		if (!empty($info['activity']['settings'])) {
168
-			foreach ($info['activity']['settings'] as $setting) {
169
-				\OC::$server->getActivityManager()->registerSetting($setting);
170
-			}
171
-		}
172
-		if (!empty($info['activity']['providers'])) {
173
-			foreach ($info['activity']['providers'] as $provider) {
174
-				\OC::$server->getActivityManager()->registerProvider($provider);
175
-			}
176
-		}
177
-	}
178
-
179
-	/**
180
-	 * @internal
181
-	 * @param string $app
182
-	 * @param string $path
183
-	 */
184
-	public static function registerAutoloading($app, $path) {
185
-		$key = $app . '-' . $path;
186
-		if(isset(self::$alreadyRegistered[$key])) {
187
-			return;
188
-		}
189
-		self::$alreadyRegistered[$key] = true;
190
-		// Register on PSR-4 composer autoloader
191
-		$appNamespace = \OC\AppFramework\App::buildAppNamespace($app);
192
-		\OC::$server->registerNamespace($app, $appNamespace);
193
-		\OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true);
194
-		if (defined('PHPUNIT_RUN') || defined('CLI_TEST_RUN')) {
195
-			\OC::$composerAutoloader->addPsr4($appNamespace . '\\Tests\\', $path . '/tests/', true);
196
-		}
197
-
198
-		// Register on legacy autoloader
199
-		\OC::$loader->addValidRoot($path);
200
-	}
201
-
202
-	/**
203
-	 * Load app.php from the given app
204
-	 *
205
-	 * @param string $app app name
206
-	 */
207
-	private static function requireAppFile($app) {
208
-		try {
209
-			// encapsulated here to avoid variable scope conflicts
210
-			require_once $app . '/appinfo/app.php';
211
-		} catch (Error $ex) {
212
-			\OC::$server->getLogger()->logException($ex);
213
-			$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
214
-			if (!in_array($app, $blacklist)) {
215
-				self::disable($app);
216
-			}
217
-		}
218
-	}
219
-
220
-	/**
221
-	 * check if an app is of a specific type
222
-	 *
223
-	 * @param string $app
224
-	 * @param string|array $types
225
-	 * @return bool
226
-	 */
227
-	public static function isType($app, $types) {
228
-		if (is_string($types)) {
229
-			$types = array($types);
230
-		}
231
-		$appTypes = self::getAppTypes($app);
232
-		foreach ($types as $type) {
233
-			if (array_search($type, $appTypes) !== false) {
234
-				return true;
235
-			}
236
-		}
237
-		return false;
238
-	}
239
-
240
-	/**
241
-	 * get the types of an app
242
-	 *
243
-	 * @param string $app
244
-	 * @return array
245
-	 */
246
-	private static function getAppTypes($app) {
247
-		//load the cache
248
-		if (count(self::$appTypes) == 0) {
249
-			self::$appTypes = \OC::$server->getAppConfig()->getValues(false, 'types');
250
-		}
251
-
252
-		if (isset(self::$appTypes[$app])) {
253
-			return explode(',', self::$appTypes[$app]);
254
-		} else {
255
-			return array();
256
-		}
257
-	}
258
-
259
-	/**
260
-	 * read app types from info.xml and cache them in the database
261
-	 */
262
-	public static function setAppTypes($app) {
263
-		$appData = self::getAppInfo($app);
264
-		if(!is_array($appData)) {
265
-			return;
266
-		}
267
-
268
-		if (isset($appData['types'])) {
269
-			$appTypes = implode(',', $appData['types']);
270
-		} else {
271
-			$appTypes = '';
272
-			$appData['types'] = [];
273
-		}
274
-
275
-		\OC::$server->getAppConfig()->setValue($app, 'types', $appTypes);
276
-
277
-		if (\OC::$server->getAppManager()->hasProtectedAppType($appData['types'])) {
278
-			$enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'yes');
279
-			if ($enabled !== 'yes' && $enabled !== 'no') {
280
-				\OC::$server->getAppConfig()->setValue($app, 'enabled', 'yes');
281
-			}
282
-		}
283
-	}
284
-
285
-	/**
286
-	 * check if app is shipped
287
-	 *
288
-	 * @param string $appId the id of the app to check
289
-	 * @return bool
290
-	 *
291
-	 * Check if an app that is installed is a shipped app or installed from the appstore.
292
-	 */
293
-	public static function isShipped($appId) {
294
-		return \OC::$server->getAppManager()->isShipped($appId);
295
-	}
296
-
297
-	/**
298
-	 * get all enabled apps
299
-	 */
300
-	protected static $enabledAppsCache = array();
301
-
302
-	/**
303
-	 * Returns apps enabled for the current user.
304
-	 *
305
-	 * @param bool $forceRefresh whether to refresh the cache
306
-	 * @param bool $all whether to return apps for all users, not only the
307
-	 * currently logged in one
308
-	 * @return string[]
309
-	 */
310
-	public static function getEnabledApps($forceRefresh = false, $all = false) {
311
-		if (!\OC::$server->getSystemConfig()->getValue('installed', false)) {
312
-			return array();
313
-		}
314
-		// in incognito mode or when logged out, $user will be false,
315
-		// which is also the case during an upgrade
316
-		$appManager = \OC::$server->getAppManager();
317
-		if ($all) {
318
-			$user = null;
319
-		} else {
320
-			$user = \OC::$server->getUserSession()->getUser();
321
-		}
322
-
323
-		if (is_null($user)) {
324
-			$apps = $appManager->getInstalledApps();
325
-		} else {
326
-			$apps = $appManager->getEnabledAppsForUser($user);
327
-		}
328
-		$apps = array_filter($apps, function ($app) {
329
-			return $app !== 'files';//we add this manually
330
-		});
331
-		sort($apps);
332
-		array_unshift($apps, 'files');
333
-		return $apps;
334
-	}
335
-
336
-	/**
337
-	 * checks whether or not an app is enabled
338
-	 *
339
-	 * @param string $app app
340
-	 * @return bool
341
-	 *
342
-	 * This function checks whether or not an app is enabled.
343
-	 */
344
-	public static function isEnabled($app) {
345
-		return \OC::$server->getAppManager()->isEnabledForUser($app);
346
-	}
347
-
348
-	/**
349
-	 * enables an app
350
-	 *
351
-	 * @param string $appId
352
-	 * @param array $groups (optional) when set, only these groups will have access to the app
353
-	 * @throws \Exception
354
-	 * @return void
355
-	 *
356
-	 * This function set an app as enabled in appconfig.
357
-	 */
358
-	public function enable($appId,
359
-						   $groups = null) {
360
-		self::$enabledAppsCache = []; // flush
361
-
362
-		// Check if app is already downloaded
363
-		$installer = new Installer(
364
-			\OC::$server->getAppFetcher(),
365
-			\OC::$server->getHTTPClientService(),
366
-			\OC::$server->getTempManager(),
367
-			\OC::$server->getLogger(),
368
-			\OC::$server->getConfig()
369
-		);
370
-		$isDownloaded = $installer->isDownloaded($appId);
371
-
372
-		if(!$isDownloaded) {
373
-			$installer->downloadApp($appId);
374
-		}
375
-
376
-		$installer->installApp($appId);
377
-
378
-		$appManager = \OC::$server->getAppManager();
379
-		if (!is_null($groups)) {
380
-			$groupManager = \OC::$server->getGroupManager();
381
-			$groupsList = [];
382
-			foreach ($groups as $group) {
383
-				$groupItem = $groupManager->get($group);
384
-				if ($groupItem instanceof \OCP\IGroup) {
385
-					$groupsList[] = $groupManager->get($group);
386
-				}
387
-			}
388
-			$appManager->enableAppForGroups($appId, $groupsList);
389
-		} else {
390
-			$appManager->enableApp($appId);
391
-		}
392
-	}
393
-
394
-	/**
395
-	 * @param string $app
396
-	 * @return bool
397
-	 */
398
-	public static function removeApp($app) {
399
-		if (self::isShipped($app)) {
400
-			return false;
401
-		}
402
-
403
-		$installer = new Installer(
404
-			\OC::$server->getAppFetcher(),
405
-			\OC::$server->getHTTPClientService(),
406
-			\OC::$server->getTempManager(),
407
-			\OC::$server->getLogger(),
408
-			\OC::$server->getConfig()
409
-		);
410
-		return $installer->removeApp($app);
411
-	}
412
-
413
-	/**
414
-	 * This function set an app as disabled in appconfig.
415
-	 *
416
-	 * @param string $app app
417
-	 * @throws Exception
418
-	 */
419
-	public static function disable($app) {
420
-		// flush
421
-		self::$enabledAppsCache = array();
422
-
423
-		// run uninstall steps
424
-		$appData = OC_App::getAppInfo($app);
425
-		if (!is_null($appData)) {
426
-			OC_App::executeRepairSteps($app, $appData['repair-steps']['uninstall']);
427
-		}
428
-
429
-		// emit disable hook - needed anymore ?
430
-		\OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app));
431
-
432
-		// finally disable it
433
-		$appManager = \OC::$server->getAppManager();
434
-		$appManager->disableApp($app);
435
-	}
436
-
437
-	// This is private as well. It simply works, so don't ask for more details
438
-	private static function proceedNavigation($list) {
439
-		usort($list, function($a, $b) {
440
-			if (isset($a['order']) && isset($b['order'])) {
441
-				return ($a['order'] < $b['order']) ? -1 : 1;
442
-			} else if (isset($a['order']) || isset($b['order'])) {
443
-				return isset($a['order']) ? -1 : 1;
444
-			} else {
445
-				return ($a['name'] < $b['name']) ? -1 : 1;
446
-			}
447
-		});
448
-
449
-		$activeApp = OC::$server->getNavigationManager()->getActiveEntry();
450
-		foreach ($list as $index => &$navEntry) {
451
-			if ($navEntry['id'] == $activeApp) {
452
-				$navEntry['active'] = true;
453
-			} else {
454
-				$navEntry['active'] = false;
455
-			}
456
-		}
457
-		unset($navEntry);
458
-
459
-		return $list;
460
-	}
461
-
462
-	/**
463
-	 * Get the path where to install apps
464
-	 *
465
-	 * @return string|false
466
-	 */
467
-	public static function getInstallPath() {
468
-		if (\OC::$server->getSystemConfig()->getValue('appstoreenabled', true) == false) {
469
-			return false;
470
-		}
471
-
472
-		foreach (OC::$APPSROOTS as $dir) {
473
-			if (isset($dir['writable']) && $dir['writable'] === true) {
474
-				return $dir['path'];
475
-			}
476
-		}
477
-
478
-		\OCP\Util::writeLog('core', 'No application directories are marked as writable.', \OCP\Util::ERROR);
479
-		return null;
480
-	}
481
-
482
-
483
-	/**
484
-	 * search for an app in all app-directories
485
-	 *
486
-	 * @param string $appId
487
-	 * @return false|string
488
-	 */
489
-	public static function findAppInDirectories($appId) {
490
-		$sanitizedAppId = self::cleanAppId($appId);
491
-		if($sanitizedAppId !== $appId) {
492
-			return false;
493
-		}
494
-		static $app_dir = array();
495
-
496
-		if (isset($app_dir[$appId])) {
497
-			return $app_dir[$appId];
498
-		}
499
-
500
-		$possibleApps = array();
501
-		foreach (OC::$APPSROOTS as $dir) {
502
-			if (file_exists($dir['path'] . '/' . $appId)) {
503
-				$possibleApps[] = $dir;
504
-			}
505
-		}
506
-
507
-		if (empty($possibleApps)) {
508
-			return false;
509
-		} elseif (count($possibleApps) === 1) {
510
-			$dir = array_shift($possibleApps);
511
-			$app_dir[$appId] = $dir;
512
-			return $dir;
513
-		} else {
514
-			$versionToLoad = array();
515
-			foreach ($possibleApps as $possibleApp) {
516
-				$version = self::getAppVersionByPath($possibleApp['path']);
517
-				if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
518
-					$versionToLoad = array(
519
-						'dir' => $possibleApp,
520
-						'version' => $version,
521
-					);
522
-				}
523
-			}
524
-			$app_dir[$appId] = $versionToLoad['dir'];
525
-			return $versionToLoad['dir'];
526
-			//TODO - write test
527
-		}
528
-	}
529
-
530
-	/**
531
-	 * Get the directory for the given app.
532
-	 * If the app is defined in multiple directories, the first one is taken. (false if not found)
533
-	 *
534
-	 * @param string $appId
535
-	 * @return string|false
536
-	 */
537
-	public static function getAppPath($appId) {
538
-		if ($appId === null || trim($appId) === '') {
539
-			return false;
540
-		}
541
-
542
-		if (($dir = self::findAppInDirectories($appId)) != false) {
543
-			return $dir['path'] . '/' . $appId;
544
-		}
545
-		return false;
546
-	}
547
-
548
-	/**
549
-	 * Get the path for the given app on the access
550
-	 * If the app is defined in multiple directories, the first one is taken. (false if not found)
551
-	 *
552
-	 * @param string $appId
553
-	 * @return string|false
554
-	 */
555
-	public static function getAppWebPath($appId) {
556
-		if (($dir = self::findAppInDirectories($appId)) != false) {
557
-			return OC::$WEBROOT . $dir['url'] . '/' . $appId;
558
-		}
559
-		return false;
560
-	}
561
-
562
-	/**
563
-	 * get the last version of the app from appinfo/info.xml
564
-	 *
565
-	 * @param string $appId
566
-	 * @param bool $useCache
567
-	 * @return string
568
-	 */
569
-	public static function getAppVersion($appId, $useCache = true) {
570
-		if($useCache && isset(self::$appVersion[$appId])) {
571
-			return self::$appVersion[$appId];
572
-		}
573
-
574
-		$file = self::getAppPath($appId);
575
-		self::$appVersion[$appId] = ($file !== false) ? self::getAppVersionByPath($file) : '0';
576
-		return self::$appVersion[$appId];
577
-	}
578
-
579
-	/**
580
-	 * get app's version based on it's path
581
-	 *
582
-	 * @param string $path
583
-	 * @return string
584
-	 */
585
-	public static function getAppVersionByPath($path) {
586
-		$infoFile = $path . '/appinfo/info.xml';
587
-		$appData = self::getAppInfo($infoFile, true);
588
-		return isset($appData['version']) ? $appData['version'] : '';
589
-	}
590
-
591
-
592
-	/**
593
-	 * Read all app metadata from the info.xml file
594
-	 *
595
-	 * @param string $appId id of the app or the path of the info.xml file
596
-	 * @param bool $path
597
-	 * @param string $lang
598
-	 * @return array|null
599
-	 * @note all data is read from info.xml, not just pre-defined fields
600
-	 */
601
-	public static function getAppInfo($appId, $path = false, $lang = null) {
602
-		if ($path) {
603
-			$file = $appId;
604
-		} else {
605
-			if ($lang === null && isset(self::$appInfo[$appId])) {
606
-				return self::$appInfo[$appId];
607
-			}
608
-			$appPath = self::getAppPath($appId);
609
-			if($appPath === false) {
610
-				return null;
611
-			}
612
-			$file = $appPath . '/appinfo/info.xml';
613
-		}
614
-
615
-		$parser = new InfoParser(\OC::$server->getMemCacheFactory()->create('core.appinfo'));
616
-		$data = $parser->parse($file);
617
-
618
-		if (is_array($data)) {
619
-			$data = OC_App::parseAppInfo($data, $lang);
620
-		}
621
-		if(isset($data['ocsid'])) {
622
-			$storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
623
-			if($storedId !== '' && $storedId !== $data['ocsid']) {
624
-				$data['ocsid'] = $storedId;
625
-			}
626
-		}
627
-
628
-		if ($lang === null) {
629
-			self::$appInfo[$appId] = $data;
630
-		}
631
-
632
-		return $data;
633
-	}
634
-
635
-	/**
636
-	 * Returns the navigation
637
-	 *
638
-	 * @return array
639
-	 *
640
-	 * This function returns an array containing all entries added. The
641
-	 * entries are sorted by the key 'order' ascending. Additional to the keys
642
-	 * given for each app the following keys exist:
643
-	 *   - active: boolean, signals if the user is on this navigation entry
644
-	 */
645
-	public static function getNavigation() {
646
-		$entries = OC::$server->getNavigationManager()->getAll();
647
-		return self::proceedNavigation($entries);
648
-	}
649
-
650
-	/**
651
-	 * Returns the Settings Navigation
652
-	 *
653
-	 * @return string[]
654
-	 *
655
-	 * This function returns an array containing all settings pages added. The
656
-	 * entries are sorted by the key 'order' ascending.
657
-	 */
658
-	public static function getSettingsNavigation() {
659
-		$entries = OC::$server->getNavigationManager()->getAll('settings');
660
-		return self::proceedNavigation($entries);
661
-	}
662
-
663
-	/**
664
-	 * get the id of loaded app
665
-	 *
666
-	 * @return string
667
-	 */
668
-	public static function getCurrentApp() {
669
-		$request = \OC::$server->getRequest();
670
-		$script = substr($request->getScriptName(), strlen(OC::$WEBROOT) + 1);
671
-		$topFolder = substr($script, 0, strpos($script, '/'));
672
-		if (empty($topFolder)) {
673
-			$path_info = $request->getPathInfo();
674
-			if ($path_info) {
675
-				$topFolder = substr($path_info, 1, strpos($path_info, '/', 1) - 1);
676
-			}
677
-		}
678
-		if ($topFolder == 'apps') {
679
-			$length = strlen($topFolder);
680
-			return substr($script, $length + 1, strpos($script, '/', $length + 1) - $length - 1);
681
-		} else {
682
-			return $topFolder;
683
-		}
684
-	}
685
-
686
-	/**
687
-	 * @param string $type
688
-	 * @return array
689
-	 */
690
-	public static function getForms($type) {
691
-		$forms = array();
692
-		switch ($type) {
693
-			case 'admin':
694
-				$source = self::$adminForms;
695
-				break;
696
-			case 'personal':
697
-				$source = self::$personalForms;
698
-				break;
699
-			default:
700
-				return array();
701
-		}
702
-		foreach ($source as $form) {
703
-			$forms[] = include $form;
704
-		}
705
-		return $forms;
706
-	}
707
-
708
-	/**
709
-	 * register an admin form to be shown
710
-	 *
711
-	 * @param string $app
712
-	 * @param string $page
713
-	 */
714
-	public static function registerAdmin($app, $page) {
715
-		self::$adminForms[] = $app . '/' . $page . '.php';
716
-	}
717
-
718
-	/**
719
-	 * register a personal form to be shown
720
-	 * @param string $app
721
-	 * @param string $page
722
-	 */
723
-	public static function registerPersonal($app, $page) {
724
-		self::$personalForms[] = $app . '/' . $page . '.php';
725
-	}
726
-
727
-	/**
728
-	 * @param array $entry
729
-	 */
730
-	public static function registerLogIn(array $entry) {
731
-		self::$altLogin[] = $entry;
732
-	}
733
-
734
-	/**
735
-	 * @return array
736
-	 */
737
-	public static function getAlternativeLogIns() {
738
-		return self::$altLogin;
739
-	}
740
-
741
-	/**
742
-	 * get a list of all apps in the apps folder
743
-	 *
744
-	 * @return array an array of app names (string IDs)
745
-	 * @todo: change the name of this method to getInstalledApps, which is more accurate
746
-	 */
747
-	public static function getAllApps() {
748
-
749
-		$apps = array();
750
-
751
-		foreach (OC::$APPSROOTS as $apps_dir) {
752
-			if (!is_readable($apps_dir['path'])) {
753
-				\OCP\Util::writeLog('core', 'unable to read app folder : ' . $apps_dir['path'], \OCP\Util::WARN);
754
-				continue;
755
-			}
756
-			$dh = opendir($apps_dir['path']);
757
-
758
-			if (is_resource($dh)) {
759
-				while (($file = readdir($dh)) !== false) {
760
-
761
-					if ($file[0] != '.' and is_dir($apps_dir['path'] . '/' . $file) and is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')) {
762
-
763
-						$apps[] = $file;
764
-					}
765
-				}
766
-			}
767
-		}
768
-
769
-		return $apps;
770
-	}
771
-
772
-	/**
773
-	 * List all apps, this is used in apps.php
774
-	 *
775
-	 * @return array
776
-	 */
777
-	public function listAllApps() {
778
-		$installedApps = OC_App::getAllApps();
779
-
780
-		//we don't want to show configuration for these
781
-		$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
782
-		$appList = array();
783
-		$langCode = \OC::$server->getL10N('core')->getLanguageCode();
784
-		$urlGenerator = \OC::$server->getURLGenerator();
785
-
786
-		foreach ($installedApps as $app) {
787
-			if (array_search($app, $blacklist) === false) {
788
-
789
-				$info = OC_App::getAppInfo($app, false, $langCode);
790
-				if (!is_array($info)) {
791
-					\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
792
-					continue;
793
-				}
794
-
795
-				if (!isset($info['name'])) {
796
-					\OCP\Util::writeLog('core', 'App id "' . $app . '" has no name in appinfo', \OCP\Util::ERROR);
797
-					continue;
798
-				}
799
-
800
-				$enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'no');
801
-				$info['groups'] = null;
802
-				if ($enabled === 'yes') {
803
-					$active = true;
804
-				} else if ($enabled === 'no') {
805
-					$active = false;
806
-				} else {
807
-					$active = true;
808
-					$info['groups'] = $enabled;
809
-				}
810
-
811
-				$info['active'] = $active;
812
-
813
-				if (self::isShipped($app)) {
814
-					$info['internal'] = true;
815
-					$info['level'] = self::officialApp;
816
-					$info['removable'] = false;
817
-				} else {
818
-					$info['internal'] = false;
819
-					$info['removable'] = true;
820
-				}
821
-
822
-				$appPath = self::getAppPath($app);
823
-				if($appPath !== false) {
824
-					$appIcon = $appPath . '/img/' . $app . '.svg';
825
-					if (file_exists($appIcon)) {
826
-						$info['preview'] = \OC::$server->getURLGenerator()->imagePath($app, $app . '.svg');
827
-						$info['previewAsIcon'] = true;
828
-					} else {
829
-						$appIcon = $appPath . '/img/app.svg';
830
-						if (file_exists($appIcon)) {
831
-							$info['preview'] = \OC::$server->getURLGenerator()->imagePath($app, 'app.svg');
832
-							$info['previewAsIcon'] = true;
833
-						}
834
-					}
835
-				}
836
-				// fix documentation
837
-				if (isset($info['documentation']) && is_array($info['documentation'])) {
838
-					foreach ($info['documentation'] as $key => $url) {
839
-						// If it is not an absolute URL we assume it is a key
840
-						// i.e. admin-ldap will get converted to go.php?to=admin-ldap
841
-						if (stripos($url, 'https://') !== 0 && stripos($url, 'http://') !== 0) {
842
-							$url = $urlGenerator->linkToDocs($url);
843
-						}
844
-
845
-						$info['documentation'][$key] = $url;
846
-					}
847
-				}
848
-
849
-				$info['version'] = OC_App::getAppVersion($app);
850
-				$appList[] = $info;
851
-			}
852
-		}
853
-
854
-		return $appList;
855
-	}
856
-
857
-	/**
858
-	 * Returns the internal app ID or false
859
-	 * @param string $ocsID
860
-	 * @return string|false
861
-	 */
862
-	public static function getInternalAppIdByOcs($ocsID) {
863
-		if(is_numeric($ocsID)) {
864
-			$idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid');
865
-			if(array_search($ocsID, $idArray)) {
866
-				return array_search($ocsID, $idArray);
867
-			}
868
-		}
869
-		return false;
870
-	}
871
-
872
-	public static function shouldUpgrade($app) {
873
-		$versions = self::getAppVersions();
874
-		$currentVersion = OC_App::getAppVersion($app);
875
-		if ($currentVersion && isset($versions[$app])) {
876
-			$installedVersion = $versions[$app];
877
-			if (!version_compare($currentVersion, $installedVersion, '=')) {
878
-				return true;
879
-			}
880
-		}
881
-		return false;
882
-	}
883
-
884
-	/**
885
-	 * Adjust the number of version parts of $version1 to match
886
-	 * the number of version parts of $version2.
887
-	 *
888
-	 * @param string $version1 version to adjust
889
-	 * @param string $version2 version to take the number of parts from
890
-	 * @return string shortened $version1
891
-	 */
892
-	private static function adjustVersionParts($version1, $version2) {
893
-		$version1 = explode('.', $version1);
894
-		$version2 = explode('.', $version2);
895
-		// reduce $version1 to match the number of parts in $version2
896
-		while (count($version1) > count($version2)) {
897
-			array_pop($version1);
898
-		}
899
-		// if $version1 does not have enough parts, add some
900
-		while (count($version1) < count($version2)) {
901
-			$version1[] = '0';
902
-		}
903
-		return implode('.', $version1);
904
-	}
905
-
906
-	/**
907
-	 * Check whether the current ownCloud version matches the given
908
-	 * application's version requirements.
909
-	 *
910
-	 * The comparison is made based on the number of parts that the
911
-	 * app info version has. For example for ownCloud 6.0.3 if the
912
-	 * app info version is expecting version 6.0, the comparison is
913
-	 * made on the first two parts of the ownCloud version.
914
-	 * This means that it's possible to specify "requiremin" => 6
915
-	 * and "requiremax" => 6 and it will still match ownCloud 6.0.3.
916
-	 *
917
-	 * @param string $ocVersion ownCloud version to check against
918
-	 * @param array $appInfo app info (from xml)
919
-	 *
920
-	 * @return boolean true if compatible, otherwise false
921
-	 */
922
-	public static function isAppCompatible($ocVersion, $appInfo) {
923
-		$requireMin = '';
924
-		$requireMax = '';
925
-		if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) {
926
-			$requireMin = $appInfo['dependencies']['nextcloud']['@attributes']['min-version'];
927
-		} elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['min-version'])) {
928
-			$requireMin = $appInfo['dependencies']['owncloud']['@attributes']['min-version'];
929
-		} else if (isset($appInfo['requiremin'])) {
930
-			$requireMin = $appInfo['requiremin'];
931
-		} else if (isset($appInfo['require'])) {
932
-			$requireMin = $appInfo['require'];
933
-		}
934
-
935
-		if (isset($appInfo['dependencies']['nextcloud']['@attributes']['max-version'])) {
936
-			$requireMax = $appInfo['dependencies']['nextcloud']['@attributes']['max-version'];
937
-		} elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['max-version'])) {
938
-			$requireMax = $appInfo['dependencies']['owncloud']['@attributes']['max-version'];
939
-		} else if (isset($appInfo['requiremax'])) {
940
-			$requireMax = $appInfo['requiremax'];
941
-		}
942
-
943
-		if (is_array($ocVersion)) {
944
-			$ocVersion = implode('.', $ocVersion);
945
-		}
946
-
947
-		if (!empty($requireMin)
948
-			&& version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<')
949
-		) {
950
-
951
-			return false;
952
-		}
953
-
954
-		if (!empty($requireMax)
955
-			&& version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>')
956
-		) {
957
-			return false;
958
-		}
959
-
960
-		return true;
961
-	}
962
-
963
-	/**
964
-	 * get the installed version of all apps
965
-	 */
966
-	public static function getAppVersions() {
967
-		static $versions;
968
-
969
-		if(!$versions) {
970
-			$appConfig = \OC::$server->getAppConfig();
971
-			$versions = $appConfig->getValues(false, 'installed_version');
972
-		}
973
-		return $versions;
974
-	}
975
-
976
-	/**
977
-	 * @param string $app
978
-	 * @param \OCP\IConfig $config
979
-	 * @param \OCP\IL10N $l
980
-	 * @return bool
981
-	 *
982
-	 * @throws Exception if app is not compatible with this version of ownCloud
983
-	 * @throws Exception if no app-name was specified
984
-	 */
985
-	public function installApp($app,
986
-							   \OCP\IConfig $config,
987
-							   \OCP\IL10N $l) {
988
-		if ($app !== false) {
989
-			// check if the app is compatible with this version of ownCloud
990
-			$info = self::getAppInfo($app);
991
-			if(!is_array($info)) {
992
-				throw new \Exception(
993
-					$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
994
-						[$info['name']]
995
-					)
996
-				);
997
-			}
998
-
999
-			$version = \OCP\Util::getVersion();
1000
-			if (!self::isAppCompatible($version, $info)) {
1001
-				throw new \Exception(
1002
-					$l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
1003
-						array($info['name'])
1004
-					)
1005
-				);
1006
-			}
1007
-
1008
-			// check for required dependencies
1009
-			self::checkAppDependencies($config, $l, $info);
1010
-
1011
-			$config->setAppValue($app, 'enabled', 'yes');
1012
-			if (isset($appData['id'])) {
1013
-				$config->setAppValue($app, 'ocsid', $appData['id']);
1014
-			}
1015
-
1016
-			if(isset($info['settings']) && is_array($info['settings'])) {
1017
-				$appPath = self::getAppPath($app);
1018
-				self::registerAutoloading($app, $appPath);
1019
-				\OC::$server->getSettingsManager()->setupSettings($info['settings']);
1020
-			}
1021
-
1022
-			\OC_Hook::emit('OC_App', 'post_enable', array('app' => $app));
1023
-		} else {
1024
-			if(empty($appName) ) {
1025
-				throw new \Exception($l->t("No app name specified"));
1026
-			} else {
1027
-				throw new \Exception($l->t("App '%s' could not be installed!", $appName));
1028
-			}
1029
-		}
1030
-
1031
-		return $app;
1032
-	}
1033
-
1034
-	/**
1035
-	 * update the database for the app and call the update script
1036
-	 *
1037
-	 * @param string $appId
1038
-	 * @return bool
1039
-	 */
1040
-	public static function updateApp($appId) {
1041
-		$appPath = self::getAppPath($appId);
1042
-		if($appPath === false) {
1043
-			return false;
1044
-		}
1045
-		$appData = self::getAppInfo($appId);
1046
-		self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
1047
-
1048
-		if (file_exists($appPath . '/appinfo/database.xml')) {
1049
-			OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml');
1050
-		} else {
1051
-			$ms = new MigrationService($appId, \OC::$server->getDatabaseConnection());
1052
-			$ms->migrate();
1053
-		}
1054
-
1055
-		self::executeRepairSteps($appId, $appData['repair-steps']['post-migration']);
1056
-		self::setupLiveMigrations($appId, $appData['repair-steps']['live-migration']);
1057
-		unset(self::$appVersion[$appId]);
1058
-
1059
-		// run upgrade code
1060
-		if (file_exists($appPath . '/appinfo/update.php')) {
1061
-			self::loadApp($appId);
1062
-			include $appPath . '/appinfo/update.php';
1063
-		}
1064
-		self::registerAutoloading($appId, $appPath);
1065
-		self::setupBackgroundJobs($appData['background-jobs']);
1066
-		if(isset($appData['settings']) && is_array($appData['settings'])) {
1067
-			\OC::$server->getSettingsManager()->setupSettings($appData['settings']);
1068
-		}
1069
-
1070
-		//set remote/public handlers
1071
-		if (array_key_exists('ocsid', $appData)) {
1072
-			\OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']);
1073
-		} elseif(\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1074
-			\OC::$server->getConfig()->deleteAppValue($appId, 'ocsid');
1075
-		}
1076
-		foreach ($appData['remote'] as $name => $path) {
1077
-			\OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
1078
-		}
1079
-		foreach ($appData['public'] as $name => $path) {
1080
-			\OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
1081
-		}
1082
-
1083
-		self::setAppTypes($appId);
1084
-
1085
-		$version = \OC_App::getAppVersion($appId);
1086
-		\OC::$server->getAppConfig()->setValue($appId, 'installed_version', $version);
1087
-
1088
-		\OC::$server->getEventDispatcher()->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent(
1089
-			ManagerEvent::EVENT_APP_UPDATE, $appId
1090
-		));
1091
-
1092
-		return true;
1093
-	}
1094
-
1095
-	/**
1096
-	 * @param string $appId
1097
-	 * @param string[] $steps
1098
-	 * @throws \OC\NeedsUpdateException
1099
-	 */
1100
-	public static function executeRepairSteps($appId, array $steps) {
1101
-		if (empty($steps)) {
1102
-			return;
1103
-		}
1104
-		// load the app
1105
-		self::loadApp($appId);
1106
-
1107
-		$dispatcher = OC::$server->getEventDispatcher();
1108
-
1109
-		// load the steps
1110
-		$r = new Repair([], $dispatcher);
1111
-		foreach ($steps as $step) {
1112
-			try {
1113
-				$r->addStep($step);
1114
-			} catch (Exception $ex) {
1115
-				$r->emit('\OC\Repair', 'error', [$ex->getMessage()]);
1116
-				\OC::$server->getLogger()->logException($ex);
1117
-			}
1118
-		}
1119
-		// run the steps
1120
-		$r->run();
1121
-	}
1122
-
1123
-	public static function setupBackgroundJobs(array $jobs) {
1124
-		$queue = \OC::$server->getJobList();
1125
-		foreach ($jobs as $job) {
1126
-			$queue->add($job);
1127
-		}
1128
-	}
1129
-
1130
-	/**
1131
-	 * @param string $appId
1132
-	 * @param string[] $steps
1133
-	 */
1134
-	private static function setupLiveMigrations($appId, array $steps) {
1135
-		$queue = \OC::$server->getJobList();
1136
-		foreach ($steps as $step) {
1137
-			$queue->add('OC\Migration\BackgroundRepair', [
1138
-				'app' => $appId,
1139
-				'step' => $step]);
1140
-		}
1141
-	}
1142
-
1143
-	/**
1144
-	 * @param string $appId
1145
-	 * @return \OC\Files\View|false
1146
-	 */
1147
-	public static function getStorage($appId) {
1148
-		if (OC_App::isEnabled($appId)) { //sanity check
1149
-			if (\OC::$server->getUserSession()->isLoggedIn()) {
1150
-				$view = new \OC\Files\View('/' . OC_User::getUser());
1151
-				if (!$view->file_exists($appId)) {
1152
-					$view->mkdir($appId);
1153
-				}
1154
-				return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
1155
-			} else {
1156
-				\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR);
1157
-				return false;
1158
-			}
1159
-		} else {
1160
-			\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', \OCP\Util::ERROR);
1161
-			return false;
1162
-		}
1163
-	}
1164
-
1165
-	protected static function findBestL10NOption($options, $lang) {
1166
-		$fallback = $similarLangFallback = $englishFallback = false;
1167
-
1168
-		$lang = strtolower($lang);
1169
-		$similarLang = $lang;
1170
-		if (strpos($similarLang, '_')) {
1171
-			// For "de_DE" we want to find "de" and the other way around
1172
-			$similarLang = substr($lang, 0, strpos($lang, '_'));
1173
-		}
1174
-
1175
-		foreach ($options as $option) {
1176
-			if (is_array($option)) {
1177
-				if ($fallback === false) {
1178
-					$fallback = $option['@value'];
1179
-				}
1180
-
1181
-				if (!isset($option['@attributes']['lang'])) {
1182
-					continue;
1183
-				}
1184
-
1185
-				$attributeLang = strtolower($option['@attributes']['lang']);
1186
-				if ($attributeLang === $lang) {
1187
-					return $option['@value'];
1188
-				}
1189
-
1190
-				if ($attributeLang === $similarLang) {
1191
-					$similarLangFallback = $option['@value'];
1192
-				} else if (strpos($attributeLang, $similarLang . '_') === 0) {
1193
-					if ($similarLangFallback === false) {
1194
-						$similarLangFallback =  $option['@value'];
1195
-					}
1196
-				}
1197
-			} else {
1198
-				$englishFallback = $option;
1199
-			}
1200
-		}
1201
-
1202
-		if ($similarLangFallback !== false) {
1203
-			return $similarLangFallback;
1204
-		} else if ($englishFallback !== false) {
1205
-			return $englishFallback;
1206
-		}
1207
-		return (string) $fallback;
1208
-	}
1209
-
1210
-	/**
1211
-	 * parses the app data array and enhanced the 'description' value
1212
-	 *
1213
-	 * @param array $data the app data
1214
-	 * @param string $lang
1215
-	 * @return array improved app data
1216
-	 */
1217
-	public static function parseAppInfo(array $data, $lang = null) {
1218
-
1219
-		if ($lang && isset($data['name']) && is_array($data['name'])) {
1220
-			$data['name'] = self::findBestL10NOption($data['name'], $lang);
1221
-		}
1222
-		if ($lang && isset($data['summary']) && is_array($data['summary'])) {
1223
-			$data['summary'] = self::findBestL10NOption($data['summary'], $lang);
1224
-		}
1225
-		if ($lang && isset($data['description']) && is_array($data['description'])) {
1226
-			$data['description'] = trim(self::findBestL10NOption($data['description'], $lang));
1227
-		} else if (isset($data['description']) && is_string($data['description'])) {
1228
-			$data['description'] = trim($data['description']);
1229
-		} else  {
1230
-			$data['description'] = '';
1231
-		}
1232
-
1233
-		return $data;
1234
-	}
1235
-
1236
-	/**
1237
-	 * @param \OCP\IConfig $config
1238
-	 * @param \OCP\IL10N $l
1239
-	 * @param array $info
1240
-	 * @throws \Exception
1241
-	 */
1242
-	public static function checkAppDependencies($config, $l, $info) {
1243
-		$dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l);
1244
-		$missing = $dependencyAnalyzer->analyze($info);
1245
-		if (!empty($missing)) {
1246
-			$missingMsg = join(PHP_EOL, $missing);
1247
-			throw new \Exception(
1248
-				$l->t('App "%s" cannot be installed because the following dependencies are not fulfilled: %s',
1249
-					[$info['name'], $missingMsg]
1250
-				)
1251
-			);
1252
-		}
1253
-	}
64
+    static private $appVersion = [];
65
+    static private $adminForms = array();
66
+    static private $personalForms = array();
67
+    static private $appInfo = array();
68
+    static private $appTypes = array();
69
+    static private $loadedApps = array();
70
+    static private $altLogin = array();
71
+    static private $alreadyRegistered = [];
72
+    const officialApp = 200;
73
+
74
+    /**
75
+     * clean the appId
76
+     *
77
+     * @param string|boolean $app AppId that needs to be cleaned
78
+     * @return string
79
+     */
80
+    public static function cleanAppId($app) {
81
+        return str_replace(array('\0', '/', '\\', '..'), '', $app);
82
+    }
83
+
84
+    /**
85
+     * Check if an app is loaded
86
+     *
87
+     * @param string $app
88
+     * @return bool
89
+     */
90
+    public static function isAppLoaded($app) {
91
+        return in_array($app, self::$loadedApps, true);
92
+    }
93
+
94
+    /**
95
+     * loads all apps
96
+     *
97
+     * @param string[] | string | null $types
98
+     * @return bool
99
+     *
100
+     * This function walks through the ownCloud directory and loads all apps
101
+     * it can find. A directory contains an app if the file /appinfo/info.xml
102
+     * exists.
103
+     *
104
+     * if $types is set, only apps of those types will be loaded
105
+     */
106
+    public static function loadApps($types = null) {
107
+        if (\OC::$server->getSystemConfig()->getValue('maintenance', false)) {
108
+            return false;
109
+        }
110
+        // Load the enabled apps here
111
+        $apps = self::getEnabledApps();
112
+
113
+        // Add each apps' folder as allowed class path
114
+        foreach($apps as $app) {
115
+            $path = self::getAppPath($app);
116
+            if($path !== false) {
117
+                self::registerAutoloading($app, $path);
118
+            }
119
+        }
120
+
121
+        // prevent app.php from printing output
122
+        ob_start();
123
+        foreach ($apps as $app) {
124
+            if ((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) {
125
+                self::loadApp($app);
126
+            }
127
+        }
128
+        ob_end_clean();
129
+
130
+        return true;
131
+    }
132
+
133
+    /**
134
+     * load a single app
135
+     *
136
+     * @param string $app
137
+     */
138
+    public static function loadApp($app) {
139
+        self::$loadedApps[] = $app;
140
+        $appPath = self::getAppPath($app);
141
+        if($appPath === false) {
142
+            return;
143
+        }
144
+
145
+        // in case someone calls loadApp() directly
146
+        self::registerAutoloading($app, $appPath);
147
+
148
+        if (is_file($appPath . '/appinfo/app.php')) {
149
+            \OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
150
+            self::requireAppFile($app);
151
+            if (self::isType($app, array('authentication'))) {
152
+                // since authentication apps affect the "is app enabled for group" check,
153
+                // the enabled apps cache needs to be cleared to make sure that the
154
+                // next time getEnableApps() is called it will also include apps that were
155
+                // enabled for groups
156
+                self::$enabledAppsCache = array();
157
+            }
158
+            \OC::$server->getEventLogger()->end('load_app_' . $app);
159
+        }
160
+
161
+        $info = self::getAppInfo($app);
162
+        if (!empty($info['activity']['filters'])) {
163
+            foreach ($info['activity']['filters'] as $filter) {
164
+                \OC::$server->getActivityManager()->registerFilter($filter);
165
+            }
166
+        }
167
+        if (!empty($info['activity']['settings'])) {
168
+            foreach ($info['activity']['settings'] as $setting) {
169
+                \OC::$server->getActivityManager()->registerSetting($setting);
170
+            }
171
+        }
172
+        if (!empty($info['activity']['providers'])) {
173
+            foreach ($info['activity']['providers'] as $provider) {
174
+                \OC::$server->getActivityManager()->registerProvider($provider);
175
+            }
176
+        }
177
+    }
178
+
179
+    /**
180
+     * @internal
181
+     * @param string $app
182
+     * @param string $path
183
+     */
184
+    public static function registerAutoloading($app, $path) {
185
+        $key = $app . '-' . $path;
186
+        if(isset(self::$alreadyRegistered[$key])) {
187
+            return;
188
+        }
189
+        self::$alreadyRegistered[$key] = true;
190
+        // Register on PSR-4 composer autoloader
191
+        $appNamespace = \OC\AppFramework\App::buildAppNamespace($app);
192
+        \OC::$server->registerNamespace($app, $appNamespace);
193
+        \OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true);
194
+        if (defined('PHPUNIT_RUN') || defined('CLI_TEST_RUN')) {
195
+            \OC::$composerAutoloader->addPsr4($appNamespace . '\\Tests\\', $path . '/tests/', true);
196
+        }
197
+
198
+        // Register on legacy autoloader
199
+        \OC::$loader->addValidRoot($path);
200
+    }
201
+
202
+    /**
203
+     * Load app.php from the given app
204
+     *
205
+     * @param string $app app name
206
+     */
207
+    private static function requireAppFile($app) {
208
+        try {
209
+            // encapsulated here to avoid variable scope conflicts
210
+            require_once $app . '/appinfo/app.php';
211
+        } catch (Error $ex) {
212
+            \OC::$server->getLogger()->logException($ex);
213
+            $blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
214
+            if (!in_array($app, $blacklist)) {
215
+                self::disable($app);
216
+            }
217
+        }
218
+    }
219
+
220
+    /**
221
+     * check if an app is of a specific type
222
+     *
223
+     * @param string $app
224
+     * @param string|array $types
225
+     * @return bool
226
+     */
227
+    public static function isType($app, $types) {
228
+        if (is_string($types)) {
229
+            $types = array($types);
230
+        }
231
+        $appTypes = self::getAppTypes($app);
232
+        foreach ($types as $type) {
233
+            if (array_search($type, $appTypes) !== false) {
234
+                return true;
235
+            }
236
+        }
237
+        return false;
238
+    }
239
+
240
+    /**
241
+     * get the types of an app
242
+     *
243
+     * @param string $app
244
+     * @return array
245
+     */
246
+    private static function getAppTypes($app) {
247
+        //load the cache
248
+        if (count(self::$appTypes) == 0) {
249
+            self::$appTypes = \OC::$server->getAppConfig()->getValues(false, 'types');
250
+        }
251
+
252
+        if (isset(self::$appTypes[$app])) {
253
+            return explode(',', self::$appTypes[$app]);
254
+        } else {
255
+            return array();
256
+        }
257
+    }
258
+
259
+    /**
260
+     * read app types from info.xml and cache them in the database
261
+     */
262
+    public static function setAppTypes($app) {
263
+        $appData = self::getAppInfo($app);
264
+        if(!is_array($appData)) {
265
+            return;
266
+        }
267
+
268
+        if (isset($appData['types'])) {
269
+            $appTypes = implode(',', $appData['types']);
270
+        } else {
271
+            $appTypes = '';
272
+            $appData['types'] = [];
273
+        }
274
+
275
+        \OC::$server->getAppConfig()->setValue($app, 'types', $appTypes);
276
+
277
+        if (\OC::$server->getAppManager()->hasProtectedAppType($appData['types'])) {
278
+            $enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'yes');
279
+            if ($enabled !== 'yes' && $enabled !== 'no') {
280
+                \OC::$server->getAppConfig()->setValue($app, 'enabled', 'yes');
281
+            }
282
+        }
283
+    }
284
+
285
+    /**
286
+     * check if app is shipped
287
+     *
288
+     * @param string $appId the id of the app to check
289
+     * @return bool
290
+     *
291
+     * Check if an app that is installed is a shipped app or installed from the appstore.
292
+     */
293
+    public static function isShipped($appId) {
294
+        return \OC::$server->getAppManager()->isShipped($appId);
295
+    }
296
+
297
+    /**
298
+     * get all enabled apps
299
+     */
300
+    protected static $enabledAppsCache = array();
301
+
302
+    /**
303
+     * Returns apps enabled for the current user.
304
+     *
305
+     * @param bool $forceRefresh whether to refresh the cache
306
+     * @param bool $all whether to return apps for all users, not only the
307
+     * currently logged in one
308
+     * @return string[]
309
+     */
310
+    public static function getEnabledApps($forceRefresh = false, $all = false) {
311
+        if (!\OC::$server->getSystemConfig()->getValue('installed', false)) {
312
+            return array();
313
+        }
314
+        // in incognito mode or when logged out, $user will be false,
315
+        // which is also the case during an upgrade
316
+        $appManager = \OC::$server->getAppManager();
317
+        if ($all) {
318
+            $user = null;
319
+        } else {
320
+            $user = \OC::$server->getUserSession()->getUser();
321
+        }
322
+
323
+        if (is_null($user)) {
324
+            $apps = $appManager->getInstalledApps();
325
+        } else {
326
+            $apps = $appManager->getEnabledAppsForUser($user);
327
+        }
328
+        $apps = array_filter($apps, function ($app) {
329
+            return $app !== 'files';//we add this manually
330
+        });
331
+        sort($apps);
332
+        array_unshift($apps, 'files');
333
+        return $apps;
334
+    }
335
+
336
+    /**
337
+     * checks whether or not an app is enabled
338
+     *
339
+     * @param string $app app
340
+     * @return bool
341
+     *
342
+     * This function checks whether or not an app is enabled.
343
+     */
344
+    public static function isEnabled($app) {
345
+        return \OC::$server->getAppManager()->isEnabledForUser($app);
346
+    }
347
+
348
+    /**
349
+     * enables an app
350
+     *
351
+     * @param string $appId
352
+     * @param array $groups (optional) when set, only these groups will have access to the app
353
+     * @throws \Exception
354
+     * @return void
355
+     *
356
+     * This function set an app as enabled in appconfig.
357
+     */
358
+    public function enable($appId,
359
+                            $groups = null) {
360
+        self::$enabledAppsCache = []; // flush
361
+
362
+        // Check if app is already downloaded
363
+        $installer = new Installer(
364
+            \OC::$server->getAppFetcher(),
365
+            \OC::$server->getHTTPClientService(),
366
+            \OC::$server->getTempManager(),
367
+            \OC::$server->getLogger(),
368
+            \OC::$server->getConfig()
369
+        );
370
+        $isDownloaded = $installer->isDownloaded($appId);
371
+
372
+        if(!$isDownloaded) {
373
+            $installer->downloadApp($appId);
374
+        }
375
+
376
+        $installer->installApp($appId);
377
+
378
+        $appManager = \OC::$server->getAppManager();
379
+        if (!is_null($groups)) {
380
+            $groupManager = \OC::$server->getGroupManager();
381
+            $groupsList = [];
382
+            foreach ($groups as $group) {
383
+                $groupItem = $groupManager->get($group);
384
+                if ($groupItem instanceof \OCP\IGroup) {
385
+                    $groupsList[] = $groupManager->get($group);
386
+                }
387
+            }
388
+            $appManager->enableAppForGroups($appId, $groupsList);
389
+        } else {
390
+            $appManager->enableApp($appId);
391
+        }
392
+    }
393
+
394
+    /**
395
+     * @param string $app
396
+     * @return bool
397
+     */
398
+    public static function removeApp($app) {
399
+        if (self::isShipped($app)) {
400
+            return false;
401
+        }
402
+
403
+        $installer = new Installer(
404
+            \OC::$server->getAppFetcher(),
405
+            \OC::$server->getHTTPClientService(),
406
+            \OC::$server->getTempManager(),
407
+            \OC::$server->getLogger(),
408
+            \OC::$server->getConfig()
409
+        );
410
+        return $installer->removeApp($app);
411
+    }
412
+
413
+    /**
414
+     * This function set an app as disabled in appconfig.
415
+     *
416
+     * @param string $app app
417
+     * @throws Exception
418
+     */
419
+    public static function disable($app) {
420
+        // flush
421
+        self::$enabledAppsCache = array();
422
+
423
+        // run uninstall steps
424
+        $appData = OC_App::getAppInfo($app);
425
+        if (!is_null($appData)) {
426
+            OC_App::executeRepairSteps($app, $appData['repair-steps']['uninstall']);
427
+        }
428
+
429
+        // emit disable hook - needed anymore ?
430
+        \OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app));
431
+
432
+        // finally disable it
433
+        $appManager = \OC::$server->getAppManager();
434
+        $appManager->disableApp($app);
435
+    }
436
+
437
+    // This is private as well. It simply works, so don't ask for more details
438
+    private static function proceedNavigation($list) {
439
+        usort($list, function($a, $b) {
440
+            if (isset($a['order']) && isset($b['order'])) {
441
+                return ($a['order'] < $b['order']) ? -1 : 1;
442
+            } else if (isset($a['order']) || isset($b['order'])) {
443
+                return isset($a['order']) ? -1 : 1;
444
+            } else {
445
+                return ($a['name'] < $b['name']) ? -1 : 1;
446
+            }
447
+        });
448
+
449
+        $activeApp = OC::$server->getNavigationManager()->getActiveEntry();
450
+        foreach ($list as $index => &$navEntry) {
451
+            if ($navEntry['id'] == $activeApp) {
452
+                $navEntry['active'] = true;
453
+            } else {
454
+                $navEntry['active'] = false;
455
+            }
456
+        }
457
+        unset($navEntry);
458
+
459
+        return $list;
460
+    }
461
+
462
+    /**
463
+     * Get the path where to install apps
464
+     *
465
+     * @return string|false
466
+     */
467
+    public static function getInstallPath() {
468
+        if (\OC::$server->getSystemConfig()->getValue('appstoreenabled', true) == false) {
469
+            return false;
470
+        }
471
+
472
+        foreach (OC::$APPSROOTS as $dir) {
473
+            if (isset($dir['writable']) && $dir['writable'] === true) {
474
+                return $dir['path'];
475
+            }
476
+        }
477
+
478
+        \OCP\Util::writeLog('core', 'No application directories are marked as writable.', \OCP\Util::ERROR);
479
+        return null;
480
+    }
481
+
482
+
483
+    /**
484
+     * search for an app in all app-directories
485
+     *
486
+     * @param string $appId
487
+     * @return false|string
488
+     */
489
+    public static function findAppInDirectories($appId) {
490
+        $sanitizedAppId = self::cleanAppId($appId);
491
+        if($sanitizedAppId !== $appId) {
492
+            return false;
493
+        }
494
+        static $app_dir = array();
495
+
496
+        if (isset($app_dir[$appId])) {
497
+            return $app_dir[$appId];
498
+        }
499
+
500
+        $possibleApps = array();
501
+        foreach (OC::$APPSROOTS as $dir) {
502
+            if (file_exists($dir['path'] . '/' . $appId)) {
503
+                $possibleApps[] = $dir;
504
+            }
505
+        }
506
+
507
+        if (empty($possibleApps)) {
508
+            return false;
509
+        } elseif (count($possibleApps) === 1) {
510
+            $dir = array_shift($possibleApps);
511
+            $app_dir[$appId] = $dir;
512
+            return $dir;
513
+        } else {
514
+            $versionToLoad = array();
515
+            foreach ($possibleApps as $possibleApp) {
516
+                $version = self::getAppVersionByPath($possibleApp['path']);
517
+                if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
518
+                    $versionToLoad = array(
519
+                        'dir' => $possibleApp,
520
+                        'version' => $version,
521
+                    );
522
+                }
523
+            }
524
+            $app_dir[$appId] = $versionToLoad['dir'];
525
+            return $versionToLoad['dir'];
526
+            //TODO - write test
527
+        }
528
+    }
529
+
530
+    /**
531
+     * Get the directory for the given app.
532
+     * If the app is defined in multiple directories, the first one is taken. (false if not found)
533
+     *
534
+     * @param string $appId
535
+     * @return string|false
536
+     */
537
+    public static function getAppPath($appId) {
538
+        if ($appId === null || trim($appId) === '') {
539
+            return false;
540
+        }
541
+
542
+        if (($dir = self::findAppInDirectories($appId)) != false) {
543
+            return $dir['path'] . '/' . $appId;
544
+        }
545
+        return false;
546
+    }
547
+
548
+    /**
549
+     * Get the path for the given app on the access
550
+     * If the app is defined in multiple directories, the first one is taken. (false if not found)
551
+     *
552
+     * @param string $appId
553
+     * @return string|false
554
+     */
555
+    public static function getAppWebPath($appId) {
556
+        if (($dir = self::findAppInDirectories($appId)) != false) {
557
+            return OC::$WEBROOT . $dir['url'] . '/' . $appId;
558
+        }
559
+        return false;
560
+    }
561
+
562
+    /**
563
+     * get the last version of the app from appinfo/info.xml
564
+     *
565
+     * @param string $appId
566
+     * @param bool $useCache
567
+     * @return string
568
+     */
569
+    public static function getAppVersion($appId, $useCache = true) {
570
+        if($useCache && isset(self::$appVersion[$appId])) {
571
+            return self::$appVersion[$appId];
572
+        }
573
+
574
+        $file = self::getAppPath($appId);
575
+        self::$appVersion[$appId] = ($file !== false) ? self::getAppVersionByPath($file) : '0';
576
+        return self::$appVersion[$appId];
577
+    }
578
+
579
+    /**
580
+     * get app's version based on it's path
581
+     *
582
+     * @param string $path
583
+     * @return string
584
+     */
585
+    public static function getAppVersionByPath($path) {
586
+        $infoFile = $path . '/appinfo/info.xml';
587
+        $appData = self::getAppInfo($infoFile, true);
588
+        return isset($appData['version']) ? $appData['version'] : '';
589
+    }
590
+
591
+
592
+    /**
593
+     * Read all app metadata from the info.xml file
594
+     *
595
+     * @param string $appId id of the app or the path of the info.xml file
596
+     * @param bool $path
597
+     * @param string $lang
598
+     * @return array|null
599
+     * @note all data is read from info.xml, not just pre-defined fields
600
+     */
601
+    public static function getAppInfo($appId, $path = false, $lang = null) {
602
+        if ($path) {
603
+            $file = $appId;
604
+        } else {
605
+            if ($lang === null && isset(self::$appInfo[$appId])) {
606
+                return self::$appInfo[$appId];
607
+            }
608
+            $appPath = self::getAppPath($appId);
609
+            if($appPath === false) {
610
+                return null;
611
+            }
612
+            $file = $appPath . '/appinfo/info.xml';
613
+        }
614
+
615
+        $parser = new InfoParser(\OC::$server->getMemCacheFactory()->create('core.appinfo'));
616
+        $data = $parser->parse($file);
617
+
618
+        if (is_array($data)) {
619
+            $data = OC_App::parseAppInfo($data, $lang);
620
+        }
621
+        if(isset($data['ocsid'])) {
622
+            $storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
623
+            if($storedId !== '' && $storedId !== $data['ocsid']) {
624
+                $data['ocsid'] = $storedId;
625
+            }
626
+        }
627
+
628
+        if ($lang === null) {
629
+            self::$appInfo[$appId] = $data;
630
+        }
631
+
632
+        return $data;
633
+    }
634
+
635
+    /**
636
+     * Returns the navigation
637
+     *
638
+     * @return array
639
+     *
640
+     * This function returns an array containing all entries added. The
641
+     * entries are sorted by the key 'order' ascending. Additional to the keys
642
+     * given for each app the following keys exist:
643
+     *   - active: boolean, signals if the user is on this navigation entry
644
+     */
645
+    public static function getNavigation() {
646
+        $entries = OC::$server->getNavigationManager()->getAll();
647
+        return self::proceedNavigation($entries);
648
+    }
649
+
650
+    /**
651
+     * Returns the Settings Navigation
652
+     *
653
+     * @return string[]
654
+     *
655
+     * This function returns an array containing all settings pages added. The
656
+     * entries are sorted by the key 'order' ascending.
657
+     */
658
+    public static function getSettingsNavigation() {
659
+        $entries = OC::$server->getNavigationManager()->getAll('settings');
660
+        return self::proceedNavigation($entries);
661
+    }
662
+
663
+    /**
664
+     * get the id of loaded app
665
+     *
666
+     * @return string
667
+     */
668
+    public static function getCurrentApp() {
669
+        $request = \OC::$server->getRequest();
670
+        $script = substr($request->getScriptName(), strlen(OC::$WEBROOT) + 1);
671
+        $topFolder = substr($script, 0, strpos($script, '/'));
672
+        if (empty($topFolder)) {
673
+            $path_info = $request->getPathInfo();
674
+            if ($path_info) {
675
+                $topFolder = substr($path_info, 1, strpos($path_info, '/', 1) - 1);
676
+            }
677
+        }
678
+        if ($topFolder == 'apps') {
679
+            $length = strlen($topFolder);
680
+            return substr($script, $length + 1, strpos($script, '/', $length + 1) - $length - 1);
681
+        } else {
682
+            return $topFolder;
683
+        }
684
+    }
685
+
686
+    /**
687
+     * @param string $type
688
+     * @return array
689
+     */
690
+    public static function getForms($type) {
691
+        $forms = array();
692
+        switch ($type) {
693
+            case 'admin':
694
+                $source = self::$adminForms;
695
+                break;
696
+            case 'personal':
697
+                $source = self::$personalForms;
698
+                break;
699
+            default:
700
+                return array();
701
+        }
702
+        foreach ($source as $form) {
703
+            $forms[] = include $form;
704
+        }
705
+        return $forms;
706
+    }
707
+
708
+    /**
709
+     * register an admin form to be shown
710
+     *
711
+     * @param string $app
712
+     * @param string $page
713
+     */
714
+    public static function registerAdmin($app, $page) {
715
+        self::$adminForms[] = $app . '/' . $page . '.php';
716
+    }
717
+
718
+    /**
719
+     * register a personal form to be shown
720
+     * @param string $app
721
+     * @param string $page
722
+     */
723
+    public static function registerPersonal($app, $page) {
724
+        self::$personalForms[] = $app . '/' . $page . '.php';
725
+    }
726
+
727
+    /**
728
+     * @param array $entry
729
+     */
730
+    public static function registerLogIn(array $entry) {
731
+        self::$altLogin[] = $entry;
732
+    }
733
+
734
+    /**
735
+     * @return array
736
+     */
737
+    public static function getAlternativeLogIns() {
738
+        return self::$altLogin;
739
+    }
740
+
741
+    /**
742
+     * get a list of all apps in the apps folder
743
+     *
744
+     * @return array an array of app names (string IDs)
745
+     * @todo: change the name of this method to getInstalledApps, which is more accurate
746
+     */
747
+    public static function getAllApps() {
748
+
749
+        $apps = array();
750
+
751
+        foreach (OC::$APPSROOTS as $apps_dir) {
752
+            if (!is_readable($apps_dir['path'])) {
753
+                \OCP\Util::writeLog('core', 'unable to read app folder : ' . $apps_dir['path'], \OCP\Util::WARN);
754
+                continue;
755
+            }
756
+            $dh = opendir($apps_dir['path']);
757
+
758
+            if (is_resource($dh)) {
759
+                while (($file = readdir($dh)) !== false) {
760
+
761
+                    if ($file[0] != '.' and is_dir($apps_dir['path'] . '/' . $file) and is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')) {
762
+
763
+                        $apps[] = $file;
764
+                    }
765
+                }
766
+            }
767
+        }
768
+
769
+        return $apps;
770
+    }
771
+
772
+    /**
773
+     * List all apps, this is used in apps.php
774
+     *
775
+     * @return array
776
+     */
777
+    public function listAllApps() {
778
+        $installedApps = OC_App::getAllApps();
779
+
780
+        //we don't want to show configuration for these
781
+        $blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
782
+        $appList = array();
783
+        $langCode = \OC::$server->getL10N('core')->getLanguageCode();
784
+        $urlGenerator = \OC::$server->getURLGenerator();
785
+
786
+        foreach ($installedApps as $app) {
787
+            if (array_search($app, $blacklist) === false) {
788
+
789
+                $info = OC_App::getAppInfo($app, false, $langCode);
790
+                if (!is_array($info)) {
791
+                    \OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
792
+                    continue;
793
+                }
794
+
795
+                if (!isset($info['name'])) {
796
+                    \OCP\Util::writeLog('core', 'App id "' . $app . '" has no name in appinfo', \OCP\Util::ERROR);
797
+                    continue;
798
+                }
799
+
800
+                $enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'no');
801
+                $info['groups'] = null;
802
+                if ($enabled === 'yes') {
803
+                    $active = true;
804
+                } else if ($enabled === 'no') {
805
+                    $active = false;
806
+                } else {
807
+                    $active = true;
808
+                    $info['groups'] = $enabled;
809
+                }
810
+
811
+                $info['active'] = $active;
812
+
813
+                if (self::isShipped($app)) {
814
+                    $info['internal'] = true;
815
+                    $info['level'] = self::officialApp;
816
+                    $info['removable'] = false;
817
+                } else {
818
+                    $info['internal'] = false;
819
+                    $info['removable'] = true;
820
+                }
821
+
822
+                $appPath = self::getAppPath($app);
823
+                if($appPath !== false) {
824
+                    $appIcon = $appPath . '/img/' . $app . '.svg';
825
+                    if (file_exists($appIcon)) {
826
+                        $info['preview'] = \OC::$server->getURLGenerator()->imagePath($app, $app . '.svg');
827
+                        $info['previewAsIcon'] = true;
828
+                    } else {
829
+                        $appIcon = $appPath . '/img/app.svg';
830
+                        if (file_exists($appIcon)) {
831
+                            $info['preview'] = \OC::$server->getURLGenerator()->imagePath($app, 'app.svg');
832
+                            $info['previewAsIcon'] = true;
833
+                        }
834
+                    }
835
+                }
836
+                // fix documentation
837
+                if (isset($info['documentation']) && is_array($info['documentation'])) {
838
+                    foreach ($info['documentation'] as $key => $url) {
839
+                        // If it is not an absolute URL we assume it is a key
840
+                        // i.e. admin-ldap will get converted to go.php?to=admin-ldap
841
+                        if (stripos($url, 'https://') !== 0 && stripos($url, 'http://') !== 0) {
842
+                            $url = $urlGenerator->linkToDocs($url);
843
+                        }
844
+
845
+                        $info['documentation'][$key] = $url;
846
+                    }
847
+                }
848
+
849
+                $info['version'] = OC_App::getAppVersion($app);
850
+                $appList[] = $info;
851
+            }
852
+        }
853
+
854
+        return $appList;
855
+    }
856
+
857
+    /**
858
+     * Returns the internal app ID or false
859
+     * @param string $ocsID
860
+     * @return string|false
861
+     */
862
+    public static function getInternalAppIdByOcs($ocsID) {
863
+        if(is_numeric($ocsID)) {
864
+            $idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid');
865
+            if(array_search($ocsID, $idArray)) {
866
+                return array_search($ocsID, $idArray);
867
+            }
868
+        }
869
+        return false;
870
+    }
871
+
872
+    public static function shouldUpgrade($app) {
873
+        $versions = self::getAppVersions();
874
+        $currentVersion = OC_App::getAppVersion($app);
875
+        if ($currentVersion && isset($versions[$app])) {
876
+            $installedVersion = $versions[$app];
877
+            if (!version_compare($currentVersion, $installedVersion, '=')) {
878
+                return true;
879
+            }
880
+        }
881
+        return false;
882
+    }
883
+
884
+    /**
885
+     * Adjust the number of version parts of $version1 to match
886
+     * the number of version parts of $version2.
887
+     *
888
+     * @param string $version1 version to adjust
889
+     * @param string $version2 version to take the number of parts from
890
+     * @return string shortened $version1
891
+     */
892
+    private static function adjustVersionParts($version1, $version2) {
893
+        $version1 = explode('.', $version1);
894
+        $version2 = explode('.', $version2);
895
+        // reduce $version1 to match the number of parts in $version2
896
+        while (count($version1) > count($version2)) {
897
+            array_pop($version1);
898
+        }
899
+        // if $version1 does not have enough parts, add some
900
+        while (count($version1) < count($version2)) {
901
+            $version1[] = '0';
902
+        }
903
+        return implode('.', $version1);
904
+    }
905
+
906
+    /**
907
+     * Check whether the current ownCloud version matches the given
908
+     * application's version requirements.
909
+     *
910
+     * The comparison is made based on the number of parts that the
911
+     * app info version has. For example for ownCloud 6.0.3 if the
912
+     * app info version is expecting version 6.0, the comparison is
913
+     * made on the first two parts of the ownCloud version.
914
+     * This means that it's possible to specify "requiremin" => 6
915
+     * and "requiremax" => 6 and it will still match ownCloud 6.0.3.
916
+     *
917
+     * @param string $ocVersion ownCloud version to check against
918
+     * @param array $appInfo app info (from xml)
919
+     *
920
+     * @return boolean true if compatible, otherwise false
921
+     */
922
+    public static function isAppCompatible($ocVersion, $appInfo) {
923
+        $requireMin = '';
924
+        $requireMax = '';
925
+        if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) {
926
+            $requireMin = $appInfo['dependencies']['nextcloud']['@attributes']['min-version'];
927
+        } elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['min-version'])) {
928
+            $requireMin = $appInfo['dependencies']['owncloud']['@attributes']['min-version'];
929
+        } else if (isset($appInfo['requiremin'])) {
930
+            $requireMin = $appInfo['requiremin'];
931
+        } else if (isset($appInfo['require'])) {
932
+            $requireMin = $appInfo['require'];
933
+        }
934
+
935
+        if (isset($appInfo['dependencies']['nextcloud']['@attributes']['max-version'])) {
936
+            $requireMax = $appInfo['dependencies']['nextcloud']['@attributes']['max-version'];
937
+        } elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['max-version'])) {
938
+            $requireMax = $appInfo['dependencies']['owncloud']['@attributes']['max-version'];
939
+        } else if (isset($appInfo['requiremax'])) {
940
+            $requireMax = $appInfo['requiremax'];
941
+        }
942
+
943
+        if (is_array($ocVersion)) {
944
+            $ocVersion = implode('.', $ocVersion);
945
+        }
946
+
947
+        if (!empty($requireMin)
948
+            && version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<')
949
+        ) {
950
+
951
+            return false;
952
+        }
953
+
954
+        if (!empty($requireMax)
955
+            && version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>')
956
+        ) {
957
+            return false;
958
+        }
959
+
960
+        return true;
961
+    }
962
+
963
+    /**
964
+     * get the installed version of all apps
965
+     */
966
+    public static function getAppVersions() {
967
+        static $versions;
968
+
969
+        if(!$versions) {
970
+            $appConfig = \OC::$server->getAppConfig();
971
+            $versions = $appConfig->getValues(false, 'installed_version');
972
+        }
973
+        return $versions;
974
+    }
975
+
976
+    /**
977
+     * @param string $app
978
+     * @param \OCP\IConfig $config
979
+     * @param \OCP\IL10N $l
980
+     * @return bool
981
+     *
982
+     * @throws Exception if app is not compatible with this version of ownCloud
983
+     * @throws Exception if no app-name was specified
984
+     */
985
+    public function installApp($app,
986
+                                \OCP\IConfig $config,
987
+                                \OCP\IL10N $l) {
988
+        if ($app !== false) {
989
+            // check if the app is compatible with this version of ownCloud
990
+            $info = self::getAppInfo($app);
991
+            if(!is_array($info)) {
992
+                throw new \Exception(
993
+                    $l->t('App "%s" cannot be installed because appinfo file cannot be read.',
994
+                        [$info['name']]
995
+                    )
996
+                );
997
+            }
998
+
999
+            $version = \OCP\Util::getVersion();
1000
+            if (!self::isAppCompatible($version, $info)) {
1001
+                throw new \Exception(
1002
+                    $l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
1003
+                        array($info['name'])
1004
+                    )
1005
+                );
1006
+            }
1007
+
1008
+            // check for required dependencies
1009
+            self::checkAppDependencies($config, $l, $info);
1010
+
1011
+            $config->setAppValue($app, 'enabled', 'yes');
1012
+            if (isset($appData['id'])) {
1013
+                $config->setAppValue($app, 'ocsid', $appData['id']);
1014
+            }
1015
+
1016
+            if(isset($info['settings']) && is_array($info['settings'])) {
1017
+                $appPath = self::getAppPath($app);
1018
+                self::registerAutoloading($app, $appPath);
1019
+                \OC::$server->getSettingsManager()->setupSettings($info['settings']);
1020
+            }
1021
+
1022
+            \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app));
1023
+        } else {
1024
+            if(empty($appName) ) {
1025
+                throw new \Exception($l->t("No app name specified"));
1026
+            } else {
1027
+                throw new \Exception($l->t("App '%s' could not be installed!", $appName));
1028
+            }
1029
+        }
1030
+
1031
+        return $app;
1032
+    }
1033
+
1034
+    /**
1035
+     * update the database for the app and call the update script
1036
+     *
1037
+     * @param string $appId
1038
+     * @return bool
1039
+     */
1040
+    public static function updateApp($appId) {
1041
+        $appPath = self::getAppPath($appId);
1042
+        if($appPath === false) {
1043
+            return false;
1044
+        }
1045
+        $appData = self::getAppInfo($appId);
1046
+        self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
1047
+
1048
+        if (file_exists($appPath . '/appinfo/database.xml')) {
1049
+            OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml');
1050
+        } else {
1051
+            $ms = new MigrationService($appId, \OC::$server->getDatabaseConnection());
1052
+            $ms->migrate();
1053
+        }
1054
+
1055
+        self::executeRepairSteps($appId, $appData['repair-steps']['post-migration']);
1056
+        self::setupLiveMigrations($appId, $appData['repair-steps']['live-migration']);
1057
+        unset(self::$appVersion[$appId]);
1058
+
1059
+        // run upgrade code
1060
+        if (file_exists($appPath . '/appinfo/update.php')) {
1061
+            self::loadApp($appId);
1062
+            include $appPath . '/appinfo/update.php';
1063
+        }
1064
+        self::registerAutoloading($appId, $appPath);
1065
+        self::setupBackgroundJobs($appData['background-jobs']);
1066
+        if(isset($appData['settings']) && is_array($appData['settings'])) {
1067
+            \OC::$server->getSettingsManager()->setupSettings($appData['settings']);
1068
+        }
1069
+
1070
+        //set remote/public handlers
1071
+        if (array_key_exists('ocsid', $appData)) {
1072
+            \OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']);
1073
+        } elseif(\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1074
+            \OC::$server->getConfig()->deleteAppValue($appId, 'ocsid');
1075
+        }
1076
+        foreach ($appData['remote'] as $name => $path) {
1077
+            \OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
1078
+        }
1079
+        foreach ($appData['public'] as $name => $path) {
1080
+            \OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
1081
+        }
1082
+
1083
+        self::setAppTypes($appId);
1084
+
1085
+        $version = \OC_App::getAppVersion($appId);
1086
+        \OC::$server->getAppConfig()->setValue($appId, 'installed_version', $version);
1087
+
1088
+        \OC::$server->getEventDispatcher()->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent(
1089
+            ManagerEvent::EVENT_APP_UPDATE, $appId
1090
+        ));
1091
+
1092
+        return true;
1093
+    }
1094
+
1095
+    /**
1096
+     * @param string $appId
1097
+     * @param string[] $steps
1098
+     * @throws \OC\NeedsUpdateException
1099
+     */
1100
+    public static function executeRepairSteps($appId, array $steps) {
1101
+        if (empty($steps)) {
1102
+            return;
1103
+        }
1104
+        // load the app
1105
+        self::loadApp($appId);
1106
+
1107
+        $dispatcher = OC::$server->getEventDispatcher();
1108
+
1109
+        // load the steps
1110
+        $r = new Repair([], $dispatcher);
1111
+        foreach ($steps as $step) {
1112
+            try {
1113
+                $r->addStep($step);
1114
+            } catch (Exception $ex) {
1115
+                $r->emit('\OC\Repair', 'error', [$ex->getMessage()]);
1116
+                \OC::$server->getLogger()->logException($ex);
1117
+            }
1118
+        }
1119
+        // run the steps
1120
+        $r->run();
1121
+    }
1122
+
1123
+    public static function setupBackgroundJobs(array $jobs) {
1124
+        $queue = \OC::$server->getJobList();
1125
+        foreach ($jobs as $job) {
1126
+            $queue->add($job);
1127
+        }
1128
+    }
1129
+
1130
+    /**
1131
+     * @param string $appId
1132
+     * @param string[] $steps
1133
+     */
1134
+    private static function setupLiveMigrations($appId, array $steps) {
1135
+        $queue = \OC::$server->getJobList();
1136
+        foreach ($steps as $step) {
1137
+            $queue->add('OC\Migration\BackgroundRepair', [
1138
+                'app' => $appId,
1139
+                'step' => $step]);
1140
+        }
1141
+    }
1142
+
1143
+    /**
1144
+     * @param string $appId
1145
+     * @return \OC\Files\View|false
1146
+     */
1147
+    public static function getStorage($appId) {
1148
+        if (OC_App::isEnabled($appId)) { //sanity check
1149
+            if (\OC::$server->getUserSession()->isLoggedIn()) {
1150
+                $view = new \OC\Files\View('/' . OC_User::getUser());
1151
+                if (!$view->file_exists($appId)) {
1152
+                    $view->mkdir($appId);
1153
+                }
1154
+                return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
1155
+            } else {
1156
+                \OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR);
1157
+                return false;
1158
+            }
1159
+        } else {
1160
+            \OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', \OCP\Util::ERROR);
1161
+            return false;
1162
+        }
1163
+    }
1164
+
1165
+    protected static function findBestL10NOption($options, $lang) {
1166
+        $fallback = $similarLangFallback = $englishFallback = false;
1167
+
1168
+        $lang = strtolower($lang);
1169
+        $similarLang = $lang;
1170
+        if (strpos($similarLang, '_')) {
1171
+            // For "de_DE" we want to find "de" and the other way around
1172
+            $similarLang = substr($lang, 0, strpos($lang, '_'));
1173
+        }
1174
+
1175
+        foreach ($options as $option) {
1176
+            if (is_array($option)) {
1177
+                if ($fallback === false) {
1178
+                    $fallback = $option['@value'];
1179
+                }
1180
+
1181
+                if (!isset($option['@attributes']['lang'])) {
1182
+                    continue;
1183
+                }
1184
+
1185
+                $attributeLang = strtolower($option['@attributes']['lang']);
1186
+                if ($attributeLang === $lang) {
1187
+                    return $option['@value'];
1188
+                }
1189
+
1190
+                if ($attributeLang === $similarLang) {
1191
+                    $similarLangFallback = $option['@value'];
1192
+                } else if (strpos($attributeLang, $similarLang . '_') === 0) {
1193
+                    if ($similarLangFallback === false) {
1194
+                        $similarLangFallback =  $option['@value'];
1195
+                    }
1196
+                }
1197
+            } else {
1198
+                $englishFallback = $option;
1199
+            }
1200
+        }
1201
+
1202
+        if ($similarLangFallback !== false) {
1203
+            return $similarLangFallback;
1204
+        } else if ($englishFallback !== false) {
1205
+            return $englishFallback;
1206
+        }
1207
+        return (string) $fallback;
1208
+    }
1209
+
1210
+    /**
1211
+     * parses the app data array and enhanced the 'description' value
1212
+     *
1213
+     * @param array $data the app data
1214
+     * @param string $lang
1215
+     * @return array improved app data
1216
+     */
1217
+    public static function parseAppInfo(array $data, $lang = null) {
1218
+
1219
+        if ($lang && isset($data['name']) && is_array($data['name'])) {
1220
+            $data['name'] = self::findBestL10NOption($data['name'], $lang);
1221
+        }
1222
+        if ($lang && isset($data['summary']) && is_array($data['summary'])) {
1223
+            $data['summary'] = self::findBestL10NOption($data['summary'], $lang);
1224
+        }
1225
+        if ($lang && isset($data['description']) && is_array($data['description'])) {
1226
+            $data['description'] = trim(self::findBestL10NOption($data['description'], $lang));
1227
+        } else if (isset($data['description']) && is_string($data['description'])) {
1228
+            $data['description'] = trim($data['description']);
1229
+        } else  {
1230
+            $data['description'] = '';
1231
+        }
1232
+
1233
+        return $data;
1234
+    }
1235
+
1236
+    /**
1237
+     * @param \OCP\IConfig $config
1238
+     * @param \OCP\IL10N $l
1239
+     * @param array $info
1240
+     * @throws \Exception
1241
+     */
1242
+    public static function checkAppDependencies($config, $l, $info) {
1243
+        $dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l);
1244
+        $missing = $dependencyAnalyzer->analyze($info);
1245
+        if (!empty($missing)) {
1246
+            $missingMsg = join(PHP_EOL, $missing);
1247
+            throw new \Exception(
1248
+                $l->t('App "%s" cannot be installed because the following dependencies are not fulfilled: %s',
1249
+                    [$info['name'], $missingMsg]
1250
+                )
1251
+            );
1252
+        }
1253
+    }
1254 1254
 }
Please login to merge, or discard this patch.
Spacing   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -111,9 +111,9 @@  discard block
 block discarded – undo
111 111
 		$apps = self::getEnabledApps();
112 112
 
113 113
 		// Add each apps' folder as allowed class path
114
-		foreach($apps as $app) {
114
+		foreach ($apps as $app) {
115 115
 			$path = self::getAppPath($app);
116
-			if($path !== false) {
116
+			if ($path !== false) {
117 117
 				self::registerAutoloading($app, $path);
118 118
 			}
119 119
 		}
@@ -138,15 +138,15 @@  discard block
 block discarded – undo
138 138
 	public static function loadApp($app) {
139 139
 		self::$loadedApps[] = $app;
140 140
 		$appPath = self::getAppPath($app);
141
-		if($appPath === false) {
141
+		if ($appPath === false) {
142 142
 			return;
143 143
 		}
144 144
 
145 145
 		// in case someone calls loadApp() directly
146 146
 		self::registerAutoloading($app, $appPath);
147 147
 
148
-		if (is_file($appPath . '/appinfo/app.php')) {
149
-			\OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
148
+		if (is_file($appPath.'/appinfo/app.php')) {
149
+			\OC::$server->getEventLogger()->start('load_app_'.$app, 'Load app: '.$app);
150 150
 			self::requireAppFile($app);
151 151
 			if (self::isType($app, array('authentication'))) {
152 152
 				// since authentication apps affect the "is app enabled for group" check,
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
 				// enabled for groups
156 156
 				self::$enabledAppsCache = array();
157 157
 			}
158
-			\OC::$server->getEventLogger()->end('load_app_' . $app);
158
+			\OC::$server->getEventLogger()->end('load_app_'.$app);
159 159
 		}
160 160
 
161 161
 		$info = self::getAppInfo($app);
@@ -182,17 +182,17 @@  discard block
 block discarded – undo
182 182
 	 * @param string $path
183 183
 	 */
184 184
 	public static function registerAutoloading($app, $path) {
185
-		$key = $app . '-' . $path;
186
-		if(isset(self::$alreadyRegistered[$key])) {
185
+		$key = $app.'-'.$path;
186
+		if (isset(self::$alreadyRegistered[$key])) {
187 187
 			return;
188 188
 		}
189 189
 		self::$alreadyRegistered[$key] = true;
190 190
 		// Register on PSR-4 composer autoloader
191 191
 		$appNamespace = \OC\AppFramework\App::buildAppNamespace($app);
192 192
 		\OC::$server->registerNamespace($app, $appNamespace);
193
-		\OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true);
193
+		\OC::$composerAutoloader->addPsr4($appNamespace.'\\', $path.'/lib/', true);
194 194
 		if (defined('PHPUNIT_RUN') || defined('CLI_TEST_RUN')) {
195
-			\OC::$composerAutoloader->addPsr4($appNamespace . '\\Tests\\', $path . '/tests/', true);
195
+			\OC::$composerAutoloader->addPsr4($appNamespace.'\\Tests\\', $path.'/tests/', true);
196 196
 		}
197 197
 
198 198
 		// Register on legacy autoloader
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
 	private static function requireAppFile($app) {
208 208
 		try {
209 209
 			// encapsulated here to avoid variable scope conflicts
210
-			require_once $app . '/appinfo/app.php';
210
+			require_once $app.'/appinfo/app.php';
211 211
 		} catch (Error $ex) {
212 212
 			\OC::$server->getLogger()->logException($ex);
213 213
 			$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
 	 */
262 262
 	public static function setAppTypes($app) {
263 263
 		$appData = self::getAppInfo($app);
264
-		if(!is_array($appData)) {
264
+		if (!is_array($appData)) {
265 265
 			return;
266 266
 		}
267 267
 
@@ -325,8 +325,8 @@  discard block
 block discarded – undo
325 325
 		} else {
326 326
 			$apps = $appManager->getEnabledAppsForUser($user);
327 327
 		}
328
-		$apps = array_filter($apps, function ($app) {
329
-			return $app !== 'files';//we add this manually
328
+		$apps = array_filter($apps, function($app) {
329
+			return $app !== 'files'; //we add this manually
330 330
 		});
331 331
 		sort($apps);
332 332
 		array_unshift($apps, 'files');
@@ -369,7 +369,7 @@  discard block
 block discarded – undo
369 369
 		);
370 370
 		$isDownloaded = $installer->isDownloaded($appId);
371 371
 
372
-		if(!$isDownloaded) {
372
+		if (!$isDownloaded) {
373 373
 			$installer->downloadApp($appId);
374 374
 		}
375 375
 
@@ -488,7 +488,7 @@  discard block
 block discarded – undo
488 488
 	 */
489 489
 	public static function findAppInDirectories($appId) {
490 490
 		$sanitizedAppId = self::cleanAppId($appId);
491
-		if($sanitizedAppId !== $appId) {
491
+		if ($sanitizedAppId !== $appId) {
492 492
 			return false;
493 493
 		}
494 494
 		static $app_dir = array();
@@ -499,7 +499,7 @@  discard block
 block discarded – undo
499 499
 
500 500
 		$possibleApps = array();
501 501
 		foreach (OC::$APPSROOTS as $dir) {
502
-			if (file_exists($dir['path'] . '/' . $appId)) {
502
+			if (file_exists($dir['path'].'/'.$appId)) {
503 503
 				$possibleApps[] = $dir;
504 504
 			}
505 505
 		}
@@ -540,7 +540,7 @@  discard block
 block discarded – undo
540 540
 		}
541 541
 
542 542
 		if (($dir = self::findAppInDirectories($appId)) != false) {
543
-			return $dir['path'] . '/' . $appId;
543
+			return $dir['path'].'/'.$appId;
544 544
 		}
545 545
 		return false;
546 546
 	}
@@ -554,7 +554,7 @@  discard block
 block discarded – undo
554 554
 	 */
555 555
 	public static function getAppWebPath($appId) {
556 556
 		if (($dir = self::findAppInDirectories($appId)) != false) {
557
-			return OC::$WEBROOT . $dir['url'] . '/' . $appId;
557
+			return OC::$WEBROOT.$dir['url'].'/'.$appId;
558 558
 		}
559 559
 		return false;
560 560
 	}
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
 	 * @return string
568 568
 	 */
569 569
 	public static function getAppVersion($appId, $useCache = true) {
570
-		if($useCache && isset(self::$appVersion[$appId])) {
570
+		if ($useCache && isset(self::$appVersion[$appId])) {
571 571
 			return self::$appVersion[$appId];
572 572
 		}
573 573
 
@@ -583,7 +583,7 @@  discard block
 block discarded – undo
583 583
 	 * @return string
584 584
 	 */
585 585
 	public static function getAppVersionByPath($path) {
586
-		$infoFile = $path . '/appinfo/info.xml';
586
+		$infoFile = $path.'/appinfo/info.xml';
587 587
 		$appData = self::getAppInfo($infoFile, true);
588 588
 		return isset($appData['version']) ? $appData['version'] : '';
589 589
 	}
@@ -606,10 +606,10 @@  discard block
 block discarded – undo
606 606
 				return self::$appInfo[$appId];
607 607
 			}
608 608
 			$appPath = self::getAppPath($appId);
609
-			if($appPath === false) {
609
+			if ($appPath === false) {
610 610
 				return null;
611 611
 			}
612
-			$file = $appPath . '/appinfo/info.xml';
612
+			$file = $appPath.'/appinfo/info.xml';
613 613
 		}
614 614
 
615 615
 		$parser = new InfoParser(\OC::$server->getMemCacheFactory()->create('core.appinfo'));
@@ -618,9 +618,9 @@  discard block
 block discarded – undo
618 618
 		if (is_array($data)) {
619 619
 			$data = OC_App::parseAppInfo($data, $lang);
620 620
 		}
621
-		if(isset($data['ocsid'])) {
621
+		if (isset($data['ocsid'])) {
622 622
 			$storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
623
-			if($storedId !== '' && $storedId !== $data['ocsid']) {
623
+			if ($storedId !== '' && $storedId !== $data['ocsid']) {
624 624
 				$data['ocsid'] = $storedId;
625 625
 			}
626 626
 		}
@@ -712,7 +712,7 @@  discard block
 block discarded – undo
712 712
 	 * @param string $page
713 713
 	 */
714 714
 	public static function registerAdmin($app, $page) {
715
-		self::$adminForms[] = $app . '/' . $page . '.php';
715
+		self::$adminForms[] = $app.'/'.$page.'.php';
716 716
 	}
717 717
 
718 718
 	/**
@@ -721,7 +721,7 @@  discard block
 block discarded – undo
721 721
 	 * @param string $page
722 722
 	 */
723 723
 	public static function registerPersonal($app, $page) {
724
-		self::$personalForms[] = $app . '/' . $page . '.php';
724
+		self::$personalForms[] = $app.'/'.$page.'.php';
725 725
 	}
726 726
 
727 727
 	/**
@@ -750,7 +750,7 @@  discard block
 block discarded – undo
750 750
 
751 751
 		foreach (OC::$APPSROOTS as $apps_dir) {
752 752
 			if (!is_readable($apps_dir['path'])) {
753
-				\OCP\Util::writeLog('core', 'unable to read app folder : ' . $apps_dir['path'], \OCP\Util::WARN);
753
+				\OCP\Util::writeLog('core', 'unable to read app folder : '.$apps_dir['path'], \OCP\Util::WARN);
754 754
 				continue;
755 755
 			}
756 756
 			$dh = opendir($apps_dir['path']);
@@ -758,7 +758,7 @@  discard block
 block discarded – undo
758 758
 			if (is_resource($dh)) {
759 759
 				while (($file = readdir($dh)) !== false) {
760 760
 
761
-					if ($file[0] != '.' and is_dir($apps_dir['path'] . '/' . $file) and is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')) {
761
+					if ($file[0] != '.' and is_dir($apps_dir['path'].'/'.$file) and is_file($apps_dir['path'].'/'.$file.'/appinfo/info.xml')) {
762 762
 
763 763
 						$apps[] = $file;
764 764
 					}
@@ -788,12 +788,12 @@  discard block
 block discarded – undo
788 788
 
789 789
 				$info = OC_App::getAppInfo($app, false, $langCode);
790 790
 				if (!is_array($info)) {
791
-					\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
791
+					\OCP\Util::writeLog('core', 'Could not read app info file for app "'.$app.'"', \OCP\Util::ERROR);
792 792
 					continue;
793 793
 				}
794 794
 
795 795
 				if (!isset($info['name'])) {
796
-					\OCP\Util::writeLog('core', 'App id "' . $app . '" has no name in appinfo', \OCP\Util::ERROR);
796
+					\OCP\Util::writeLog('core', 'App id "'.$app.'" has no name in appinfo', \OCP\Util::ERROR);
797 797
 					continue;
798 798
 				}
799 799
 
@@ -820,13 +820,13 @@  discard block
 block discarded – undo
820 820
 				}
821 821
 
822 822
 				$appPath = self::getAppPath($app);
823
-				if($appPath !== false) {
824
-					$appIcon = $appPath . '/img/' . $app . '.svg';
823
+				if ($appPath !== false) {
824
+					$appIcon = $appPath.'/img/'.$app.'.svg';
825 825
 					if (file_exists($appIcon)) {
826
-						$info['preview'] = \OC::$server->getURLGenerator()->imagePath($app, $app . '.svg');
826
+						$info['preview'] = \OC::$server->getURLGenerator()->imagePath($app, $app.'.svg');
827 827
 						$info['previewAsIcon'] = true;
828 828
 					} else {
829
-						$appIcon = $appPath . '/img/app.svg';
829
+						$appIcon = $appPath.'/img/app.svg';
830 830
 						if (file_exists($appIcon)) {
831 831
 							$info['preview'] = \OC::$server->getURLGenerator()->imagePath($app, 'app.svg');
832 832
 							$info['previewAsIcon'] = true;
@@ -860,9 +860,9 @@  discard block
 block discarded – undo
860 860
 	 * @return string|false
861 861
 	 */
862 862
 	public static function getInternalAppIdByOcs($ocsID) {
863
-		if(is_numeric($ocsID)) {
863
+		if (is_numeric($ocsID)) {
864 864
 			$idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid');
865
-			if(array_search($ocsID, $idArray)) {
865
+			if (array_search($ocsID, $idArray)) {
866 866
 				return array_search($ocsID, $idArray);
867 867
 			}
868 868
 		}
@@ -966,7 +966,7 @@  discard block
 block discarded – undo
966 966
 	public static function getAppVersions() {
967 967
 		static $versions;
968 968
 
969
-		if(!$versions) {
969
+		if (!$versions) {
970 970
 			$appConfig = \OC::$server->getAppConfig();
971 971
 			$versions = $appConfig->getValues(false, 'installed_version');
972 972
 		}
@@ -988,7 +988,7 @@  discard block
 block discarded – undo
988 988
 		if ($app !== false) {
989 989
 			// check if the app is compatible with this version of ownCloud
990 990
 			$info = self::getAppInfo($app);
991
-			if(!is_array($info)) {
991
+			if (!is_array($info)) {
992 992
 				throw new \Exception(
993 993
 					$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
994 994
 						[$info['name']]
@@ -1013,7 +1013,7 @@  discard block
 block discarded – undo
1013 1013
 				$config->setAppValue($app, 'ocsid', $appData['id']);
1014 1014
 			}
1015 1015
 
1016
-			if(isset($info['settings']) && is_array($info['settings'])) {
1016
+			if (isset($info['settings']) && is_array($info['settings'])) {
1017 1017
 				$appPath = self::getAppPath($app);
1018 1018
 				self::registerAutoloading($app, $appPath);
1019 1019
 				\OC::$server->getSettingsManager()->setupSettings($info['settings']);
@@ -1021,7 +1021,7 @@  discard block
 block discarded – undo
1021 1021
 
1022 1022
 			\OC_Hook::emit('OC_App', 'post_enable', array('app' => $app));
1023 1023
 		} else {
1024
-			if(empty($appName) ) {
1024
+			if (empty($appName)) {
1025 1025
 				throw new \Exception($l->t("No app name specified"));
1026 1026
 			} else {
1027 1027
 				throw new \Exception($l->t("App '%s' could not be installed!", $appName));
@@ -1039,14 +1039,14 @@  discard block
 block discarded – undo
1039 1039
 	 */
1040 1040
 	public static function updateApp($appId) {
1041 1041
 		$appPath = self::getAppPath($appId);
1042
-		if($appPath === false) {
1042
+		if ($appPath === false) {
1043 1043
 			return false;
1044 1044
 		}
1045 1045
 		$appData = self::getAppInfo($appId);
1046 1046
 		self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
1047 1047
 
1048
-		if (file_exists($appPath . '/appinfo/database.xml')) {
1049
-			OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml');
1048
+		if (file_exists($appPath.'/appinfo/database.xml')) {
1049
+			OC_DB::updateDbFromStructure($appPath.'/appinfo/database.xml');
1050 1050
 		} else {
1051 1051
 			$ms = new MigrationService($appId, \OC::$server->getDatabaseConnection());
1052 1052
 			$ms->migrate();
@@ -1057,27 +1057,27 @@  discard block
 block discarded – undo
1057 1057
 		unset(self::$appVersion[$appId]);
1058 1058
 
1059 1059
 		// run upgrade code
1060
-		if (file_exists($appPath . '/appinfo/update.php')) {
1060
+		if (file_exists($appPath.'/appinfo/update.php')) {
1061 1061
 			self::loadApp($appId);
1062
-			include $appPath . '/appinfo/update.php';
1062
+			include $appPath.'/appinfo/update.php';
1063 1063
 		}
1064 1064
 		self::registerAutoloading($appId, $appPath);
1065 1065
 		self::setupBackgroundJobs($appData['background-jobs']);
1066
-		if(isset($appData['settings']) && is_array($appData['settings'])) {
1066
+		if (isset($appData['settings']) && is_array($appData['settings'])) {
1067 1067
 			\OC::$server->getSettingsManager()->setupSettings($appData['settings']);
1068 1068
 		}
1069 1069
 
1070 1070
 		//set remote/public handlers
1071 1071
 		if (array_key_exists('ocsid', $appData)) {
1072 1072
 			\OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']);
1073
-		} elseif(\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1073
+		} elseif (\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1074 1074
 			\OC::$server->getConfig()->deleteAppValue($appId, 'ocsid');
1075 1075
 		}
1076 1076
 		foreach ($appData['remote'] as $name => $path) {
1077
-			\OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
1077
+			\OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $appId.'/'.$path);
1078 1078
 		}
1079 1079
 		foreach ($appData['public'] as $name => $path) {
1080
-			\OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
1080
+			\OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $appId.'/'.$path);
1081 1081
 		}
1082 1082
 
1083 1083
 		self::setAppTypes($appId);
@@ -1147,17 +1147,17 @@  discard block
 block discarded – undo
1147 1147
 	public static function getStorage($appId) {
1148 1148
 		if (OC_App::isEnabled($appId)) { //sanity check
1149 1149
 			if (\OC::$server->getUserSession()->isLoggedIn()) {
1150
-				$view = new \OC\Files\View('/' . OC_User::getUser());
1150
+				$view = new \OC\Files\View('/'.OC_User::getUser());
1151 1151
 				if (!$view->file_exists($appId)) {
1152 1152
 					$view->mkdir($appId);
1153 1153
 				}
1154
-				return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
1154
+				return new \OC\Files\View('/'.OC_User::getUser().'/'.$appId);
1155 1155
 			} else {
1156
-				\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR);
1156
+				\OCP\Util::writeLog('core', 'Can\'t get app storage, app '.$appId.', user not logged in', \OCP\Util::ERROR);
1157 1157
 				return false;
1158 1158
 			}
1159 1159
 		} else {
1160
-			\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', \OCP\Util::ERROR);
1160
+			\OCP\Util::writeLog('core', 'Can\'t get app storage, app '.$appId.' not enabled', \OCP\Util::ERROR);
1161 1161
 			return false;
1162 1162
 		}
1163 1163
 	}
@@ -1189,9 +1189,9 @@  discard block
 block discarded – undo
1189 1189
 
1190 1190
 				if ($attributeLang === $similarLang) {
1191 1191
 					$similarLangFallback = $option['@value'];
1192
-				} else if (strpos($attributeLang, $similarLang . '_') === 0) {
1192
+				} else if (strpos($attributeLang, $similarLang.'_') === 0) {
1193 1193
 					if ($similarLangFallback === false) {
1194
-						$similarLangFallback =  $option['@value'];
1194
+						$similarLangFallback = $option['@value'];
1195 1195
 					}
1196 1196
 				}
1197 1197
 			} else {
@@ -1226,7 +1226,7 @@  discard block
 block discarded – undo
1226 1226
 			$data['description'] = trim(self::findBestL10NOption($data['description'], $lang));
1227 1227
 		} else if (isset($data['description']) && is_string($data['description'])) {
1228 1228
 			$data['description'] = trim($data['description']);
1229
-		} else  {
1229
+		} else {
1230 1230
 			$data['description'] = '';
1231 1231
 		}
1232 1232
 
Please login to merge, or discard this patch.
lib/private/Setup.php 1 patch
Indentation   +483 added lines, -483 removed lines patch added patch discarded remove patch
@@ -48,487 +48,487 @@
 block discarded – undo
48 48
 use OCP\Security\ISecureRandom;
49 49
 
50 50
 class Setup {
51
-	/** @var SystemConfig */
52
-	protected $config;
53
-	/** @var IniGetWrapper */
54
-	protected $iniWrapper;
55
-	/** @var IL10N */
56
-	protected $l10n;
57
-	/** @var Defaults */
58
-	protected $defaults;
59
-	/** @var ILogger */
60
-	protected $logger;
61
-	/** @var ISecureRandom */
62
-	protected $random;
63
-
64
-	/**
65
-	 * @param SystemConfig $config
66
-	 * @param IniGetWrapper $iniWrapper
67
-	 * @param IL10N $l10n
68
-	 * @param Defaults $defaults
69
-	 * @param ILogger $logger
70
-	 * @param ISecureRandom $random
71
-	 */
72
-	public function __construct(SystemConfig $config,
73
-						 IniGetWrapper $iniWrapper,
74
-						 IL10N $l10n,
75
-						 Defaults $defaults,
76
-						 ILogger $logger,
77
-						 ISecureRandom $random
78
-		) {
79
-		$this->config = $config;
80
-		$this->iniWrapper = $iniWrapper;
81
-		$this->l10n = $l10n;
82
-		$this->defaults = $defaults;
83
-		$this->logger = $logger;
84
-		$this->random = $random;
85
-	}
86
-
87
-	static $dbSetupClasses = [
88
-		'mysql' => \OC\Setup\MySQL::class,
89
-		'pgsql' => \OC\Setup\PostgreSQL::class,
90
-		'oci'   => \OC\Setup\OCI::class,
91
-		'sqlite' => \OC\Setup\Sqlite::class,
92
-		'sqlite3' => \OC\Setup\Sqlite::class,
93
-	];
94
-
95
-	/**
96
-	 * Wrapper around the "class_exists" PHP function to be able to mock it
97
-	 * @param string $name
98
-	 * @return bool
99
-	 */
100
-	protected function class_exists($name) {
101
-		return class_exists($name);
102
-	}
103
-
104
-	/**
105
-	 * Wrapper around the "is_callable" PHP function to be able to mock it
106
-	 * @param string $name
107
-	 * @return bool
108
-	 */
109
-	protected function is_callable($name) {
110
-		return is_callable($name);
111
-	}
112
-
113
-	/**
114
-	 * Wrapper around \PDO::getAvailableDrivers
115
-	 *
116
-	 * @return array
117
-	 */
118
-	protected function getAvailableDbDriversForPdo() {
119
-		return \PDO::getAvailableDrivers();
120
-	}
121
-
122
-	/**
123
-	 * Get the available and supported databases of this instance
124
-	 *
125
-	 * @param bool $allowAllDatabases
126
-	 * @return array
127
-	 * @throws Exception
128
-	 */
129
-	public function getSupportedDatabases($allowAllDatabases = false) {
130
-		$availableDatabases = array(
131
-			'sqlite' =>  array(
132
-				'type' => 'pdo',
133
-				'call' => 'sqlite',
134
-				'name' => 'SQLite'
135
-			),
136
-			'mysql' => array(
137
-				'type' => 'pdo',
138
-				'call' => 'mysql',
139
-				'name' => 'MySQL/MariaDB'
140
-			),
141
-			'pgsql' => array(
142
-				'type' => 'pdo',
143
-				'call' => 'pgsql',
144
-				'name' => 'PostgreSQL'
145
-			),
146
-			'oci' => array(
147
-				'type' => 'function',
148
-				'call' => 'oci_connect',
149
-				'name' => 'Oracle'
150
-			)
151
-		);
152
-		if ($allowAllDatabases) {
153
-			$configuredDatabases = array_keys($availableDatabases);
154
-		} else {
155
-			$configuredDatabases = $this->config->getValue('supportedDatabases',
156
-				array('sqlite', 'mysql', 'pgsql'));
157
-		}
158
-		if(!is_array($configuredDatabases)) {
159
-			throw new Exception('Supported databases are not properly configured.');
160
-		}
161
-
162
-		$supportedDatabases = array();
163
-
164
-		foreach($configuredDatabases as $database) {
165
-			if(array_key_exists($database, $availableDatabases)) {
166
-				$working = false;
167
-				$type = $availableDatabases[$database]['type'];
168
-				$call = $availableDatabases[$database]['call'];
169
-
170
-				if ($type === 'function') {
171
-					$working = $this->is_callable($call);
172
-				} elseif($type === 'pdo') {
173
-					$working = in_array($call, $this->getAvailableDbDriversForPdo(), TRUE);
174
-				}
175
-				if($working) {
176
-					$supportedDatabases[$database] = $availableDatabases[$database]['name'];
177
-				}
178
-			}
179
-		}
180
-
181
-		return $supportedDatabases;
182
-	}
183
-
184
-	/**
185
-	 * Gathers system information like database type and does
186
-	 * a few system checks.
187
-	 *
188
-	 * @return array of system info, including an "errors" value
189
-	 * in case of errors/warnings
190
-	 */
191
-	public function getSystemInfo($allowAllDatabases = false) {
192
-		$databases = $this->getSupportedDatabases($allowAllDatabases);
193
-
194
-		$dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
195
-
196
-		$errors = array();
197
-
198
-		// Create data directory to test whether the .htaccess works
199
-		// Notice that this is not necessarily the same data directory as the one
200
-		// that will effectively be used.
201
-		if(!file_exists($dataDir)) {
202
-			@mkdir($dataDir);
203
-		}
204
-		$htAccessWorking = true;
205
-		if (is_dir($dataDir) && is_writable($dataDir)) {
206
-			// Protect data directory here, so we can test if the protection is working
207
-			\OC\Setup::protectDataDirectory();
208
-
209
-			try {
210
-				$util = new \OC_Util();
211
-				$htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
212
-			} catch (\OC\HintException $e) {
213
-				$errors[] = array(
214
-					'error' => $e->getMessage(),
215
-					'hint' => $e->getHint()
216
-				);
217
-				$htAccessWorking = false;
218
-			}
219
-		}
220
-
221
-		if (\OC_Util::runningOnMac()) {
222
-			$errors[] = array(
223
-				'error' => $this->l10n->t(
224
-					'Mac OS X is not supported and %s will not work properly on this platform. ' .
225
-					'Use it at your own risk! ',
226
-					$this->defaults->getName()
227
-				),
228
-				'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.')
229
-			);
230
-		}
231
-
232
-		if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
233
-			$errors[] = array(
234
-				'error' => $this->l10n->t(
235
-					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
236
-					'This will lead to problems with files over 4 GB and is highly discouraged.',
237
-					$this->defaults->getName()
238
-				),
239
-				'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.')
240
-			);
241
-		}
242
-
243
-		return array(
244
-			'hasSQLite' => isset($databases['sqlite']),
245
-			'hasMySQL' => isset($databases['mysql']),
246
-			'hasPostgreSQL' => isset($databases['pgsql']),
247
-			'hasOracle' => isset($databases['oci']),
248
-			'databases' => $databases,
249
-			'directory' => $dataDir,
250
-			'htaccessWorking' => $htAccessWorking,
251
-			'errors' => $errors,
252
-		);
253
-	}
254
-
255
-	/**
256
-	 * @param $options
257
-	 * @return array
258
-	 */
259
-	public function install($options) {
260
-		$l = $this->l10n;
261
-
262
-		$error = array();
263
-		$dbType = $options['dbtype'];
264
-
265
-		if(empty($options['adminlogin'])) {
266
-			$error[] = $l->t('Set an admin username.');
267
-		}
268
-		if(empty($options['adminpass'])) {
269
-			$error[] = $l->t('Set an admin password.');
270
-		}
271
-		if(empty($options['directory'])) {
272
-			$options['directory'] = \OC::$SERVERROOT."/data";
273
-		}
274
-
275
-		if (!isset(self::$dbSetupClasses[$dbType])) {
276
-			$dbType = 'sqlite';
277
-		}
278
-
279
-		$username = htmlspecialchars_decode($options['adminlogin']);
280
-		$password = htmlspecialchars_decode($options['adminpass']);
281
-		$dataDir = htmlspecialchars_decode($options['directory']);
282
-
283
-		$class = self::$dbSetupClasses[$dbType];
284
-		/** @var \OC\Setup\AbstractDatabase $dbSetup */
285
-		$dbSetup = new $class($l, 'db_structure.xml', $this->config,
286
-			$this->logger, $this->random);
287
-		$error = array_merge($error, $dbSetup->validate($options));
288
-
289
-		// validate the data directory
290
-		if (
291
-			(!is_dir($dataDir) and !mkdir($dataDir)) or
292
-			!is_writable($dataDir)
293
-		) {
294
-			$error[] = $l->t("Can't create or write into the data directory %s", array($dataDir));
295
-		}
296
-
297
-		if(count($error) != 0) {
298
-			return $error;
299
-		}
300
-
301
-		$request = \OC::$server->getRequest();
302
-
303
-		//no errors, good
304
-		if(isset($options['trusted_domains'])
305
-		    && is_array($options['trusted_domains'])) {
306
-			$trustedDomains = $options['trusted_domains'];
307
-		} else {
308
-			$trustedDomains = [$request->getInsecureServerHost()];
309
-		}
310
-
311
-		//use sqlite3 when available, otherwise sqlite2 will be used.
312
-		if($dbType=='sqlite' and class_exists('SQLite3')) {
313
-			$dbType='sqlite3';
314
-		}
315
-
316
-		//generate a random salt that is used to salt the local user passwords
317
-		$salt = $this->random->generate(30);
318
-		// generate a secret
319
-		$secret = $this->random->generate(48);
320
-
321
-		//write the config file
322
-		$this->config->setValues([
323
-			'passwordsalt'		=> $salt,
324
-			'secret'			=> $secret,
325
-			'trusted_domains'	=> $trustedDomains,
326
-			'datadirectory'		=> $dataDir,
327
-			'overwrite.cli.url'	=> $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT,
328
-			'dbtype'			=> $dbType,
329
-			'version'			=> implode('.', \OCP\Util::getVersion()),
330
-		]);
331
-
332
-		try {
333
-			$dbSetup->initialize($options);
334
-			$dbSetup->setupDatabase($username);
335
-			// apply necessary migrations
336
-			$dbSetup->runMigrations();
337
-		} catch (\OC\DatabaseSetupException $e) {
338
-			$error[] = array(
339
-				'error' => $e->getMessage(),
340
-				'hint' => $e->getHint()
341
-			);
342
-			return($error);
343
-		} catch (Exception $e) {
344
-			$error[] = array(
345
-				'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
346
-				'hint' => ''
347
-			);
348
-			return($error);
349
-		}
350
-
351
-		//create the user and group
352
-		$user =  null;
353
-		try {
354
-			$user = \OC::$server->getUserManager()->createUser($username, $password);
355
-			if (!$user) {
356
-				$error[] = "User <$username> could not be created.";
357
-			}
358
-		} catch(Exception $exception) {
359
-			$error[] = $exception->getMessage();
360
-		}
361
-
362
-		if(count($error) == 0) {
363
-			$config = \OC::$server->getConfig();
364
-			$config->setAppValue('core', 'installedat', microtime(true));
365
-			$config->setAppValue('core', 'lastupdatedat', microtime(true));
366
-			$config->setAppValue('core', 'vendor', $this->getVendor());
367
-
368
-			$group =\OC::$server->getGroupManager()->createGroup('admin');
369
-			$group->addUser($user);
370
-
371
-			// Install shipped apps and specified app bundles
372
-			Installer::installShippedApps();
373
-			$installer = new Installer(
374
-				\OC::$server->getAppFetcher(),
375
-				\OC::$server->getHTTPClientService(),
376
-				\OC::$server->getTempManager(),
377
-				\OC::$server->getLogger(),
378
-				\OC::$server->getConfig()
379
-			);
380
-			$bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
381
-			$defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
382
-			foreach($defaultInstallationBundles as $bundle) {
383
-				try {
384
-					$installer->installAppBundle($bundle);
385
-				} catch (Exception $e) {}
386
-			}
387
-
388
-			// create empty file in data dir, so we can later find
389
-			// out that this is indeed an ownCloud data directory
390
-			file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
391
-
392
-			// Update .htaccess files
393
-			Setup::updateHtaccess();
394
-			Setup::protectDataDirectory();
395
-
396
-			self::installBackgroundJobs();
397
-
398
-			//and we are done
399
-			$config->setSystemValue('installed', true);
400
-
401
-			// Create a session token for the newly created user
402
-			// The token provider requires a working db, so it's not injected on setup
403
-			/* @var $userSession User\Session */
404
-			$userSession = \OC::$server->getUserSession();
405
-			$defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
406
-			$userSession->setTokenProvider($defaultTokenProvider);
407
-			$userSession->login($username, $password);
408
-			$userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
409
-		}
410
-
411
-		return $error;
412
-	}
413
-
414
-	public static function installBackgroundJobs() {
415
-		\OC::$server->getJobList()->add('\OC\Authentication\Token\DefaultTokenCleanupJob');
416
-	}
417
-
418
-	/**
419
-	 * @return string Absolute path to htaccess
420
-	 */
421
-	private function pathToHtaccess() {
422
-		return \OC::$SERVERROOT.'/.htaccess';
423
-	}
424
-
425
-	/**
426
-	 * Append the correct ErrorDocument path for Apache hosts
427
-	 * @return bool True when success, False otherwise
428
-	 */
429
-	public static function updateHtaccess() {
430
-		$config = \OC::$server->getSystemConfig();
431
-
432
-		// For CLI read the value from overwrite.cli.url
433
-		if(\OC::$CLI) {
434
-			$webRoot = $config->getValue('overwrite.cli.url', '');
435
-			if($webRoot === '') {
436
-				return false;
437
-			}
438
-			$webRoot = parse_url($webRoot, PHP_URL_PATH);
439
-			$webRoot = rtrim($webRoot, '/');
440
-		} else {
441
-			$webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
442
-		}
443
-
444
-		$setupHelper = new \OC\Setup($config, \OC::$server->getIniWrapper(),
445
-			\OC::$server->getL10N('lib'), \OC::$server->query(Defaults::class), \OC::$server->getLogger(),
446
-			\OC::$server->getSecureRandom());
447
-
448
-		$htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
449
-		$content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
450
-		$htaccessContent = explode($content, $htaccessContent, 2)[0];
451
-
452
-		//custom 403 error page
453
-		$content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php";
454
-
455
-		//custom 404 error page
456
-		$content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php";
457
-
458
-		// Add rewrite rules if the RewriteBase is configured
459
-		$rewriteBase = $config->getValue('htaccess.RewriteBase', '');
460
-		if($rewriteBase !== '') {
461
-			$content .= "\n<IfModule mod_rewrite.c>";
462
-			$content .= "\n  Options -MultiViews";
463
-			$content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
464
-			$content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
465
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$";
466
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
467
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
468
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
469
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
470
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
471
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
472
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
473
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
474
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
475
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
476
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
477
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
478
-			$content .= "\n  RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*";
479
-			$content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
480
-			$content .= "\n  RewriteBase " . $rewriteBase;
481
-			$content .= "\n  <IfModule mod_env.c>";
482
-			$content .= "\n    SetEnv front_controller_active true";
483
-			$content .= "\n    <IfModule mod_dir.c>";
484
-			$content .= "\n      DirectorySlash off";
485
-			$content .= "\n    </IfModule>";
486
-			$content .= "\n  </IfModule>";
487
-			$content .= "\n</IfModule>";
488
-		}
489
-
490
-		if ($content !== '') {
491
-			//suppress errors in case we don't have permissions for it
492
-			return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
493
-		}
494
-
495
-		return false;
496
-	}
497
-
498
-	public static function protectDataDirectory() {
499
-		//Require all denied
500
-		$now =  date('Y-m-d H:i:s');
501
-		$content = "# Generated by Nextcloud on $now\n";
502
-		$content.= "# line below if for Apache 2.4\n";
503
-		$content.= "<ifModule mod_authz_core.c>\n";
504
-		$content.= "Require all denied\n";
505
-		$content.= "</ifModule>\n\n";
506
-		$content.= "# line below if for Apache 2.2\n";
507
-		$content.= "<ifModule !mod_authz_core.c>\n";
508
-		$content.= "deny from all\n";
509
-		$content.= "Satisfy All\n";
510
-		$content.= "</ifModule>\n\n";
511
-		$content.= "# section for Apache 2.2 and 2.4\n";
512
-		$content.= "<ifModule mod_autoindex.c>\n";
513
-		$content.= "IndexIgnore *\n";
514
-		$content.= "</ifModule>\n";
515
-
516
-		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
517
-		file_put_contents($baseDir . '/.htaccess', $content);
518
-		file_put_contents($baseDir . '/index.html', '');
519
-	}
520
-
521
-	/**
522
-	 * Return vendor from which this version was published
523
-	 *
524
-	 * @return string Get the vendor
525
-	 *
526
-	 * Copy of \OC\Updater::getVendor()
527
-	 */
528
-	private function getVendor() {
529
-		// this should really be a JSON file
530
-		require \OC::$SERVERROOT . '/version.php';
531
-		/** @var string $vendor */
532
-		return (string) $vendor;
533
-	}
51
+    /** @var SystemConfig */
52
+    protected $config;
53
+    /** @var IniGetWrapper */
54
+    protected $iniWrapper;
55
+    /** @var IL10N */
56
+    protected $l10n;
57
+    /** @var Defaults */
58
+    protected $defaults;
59
+    /** @var ILogger */
60
+    protected $logger;
61
+    /** @var ISecureRandom */
62
+    protected $random;
63
+
64
+    /**
65
+     * @param SystemConfig $config
66
+     * @param IniGetWrapper $iniWrapper
67
+     * @param IL10N $l10n
68
+     * @param Defaults $defaults
69
+     * @param ILogger $logger
70
+     * @param ISecureRandom $random
71
+     */
72
+    public function __construct(SystemConfig $config,
73
+                            IniGetWrapper $iniWrapper,
74
+                            IL10N $l10n,
75
+                            Defaults $defaults,
76
+                            ILogger $logger,
77
+                            ISecureRandom $random
78
+        ) {
79
+        $this->config = $config;
80
+        $this->iniWrapper = $iniWrapper;
81
+        $this->l10n = $l10n;
82
+        $this->defaults = $defaults;
83
+        $this->logger = $logger;
84
+        $this->random = $random;
85
+    }
86
+
87
+    static $dbSetupClasses = [
88
+        'mysql' => \OC\Setup\MySQL::class,
89
+        'pgsql' => \OC\Setup\PostgreSQL::class,
90
+        'oci'   => \OC\Setup\OCI::class,
91
+        'sqlite' => \OC\Setup\Sqlite::class,
92
+        'sqlite3' => \OC\Setup\Sqlite::class,
93
+    ];
94
+
95
+    /**
96
+     * Wrapper around the "class_exists" PHP function to be able to mock it
97
+     * @param string $name
98
+     * @return bool
99
+     */
100
+    protected function class_exists($name) {
101
+        return class_exists($name);
102
+    }
103
+
104
+    /**
105
+     * Wrapper around the "is_callable" PHP function to be able to mock it
106
+     * @param string $name
107
+     * @return bool
108
+     */
109
+    protected function is_callable($name) {
110
+        return is_callable($name);
111
+    }
112
+
113
+    /**
114
+     * Wrapper around \PDO::getAvailableDrivers
115
+     *
116
+     * @return array
117
+     */
118
+    protected function getAvailableDbDriversForPdo() {
119
+        return \PDO::getAvailableDrivers();
120
+    }
121
+
122
+    /**
123
+     * Get the available and supported databases of this instance
124
+     *
125
+     * @param bool $allowAllDatabases
126
+     * @return array
127
+     * @throws Exception
128
+     */
129
+    public function getSupportedDatabases($allowAllDatabases = false) {
130
+        $availableDatabases = array(
131
+            'sqlite' =>  array(
132
+                'type' => 'pdo',
133
+                'call' => 'sqlite',
134
+                'name' => 'SQLite'
135
+            ),
136
+            'mysql' => array(
137
+                'type' => 'pdo',
138
+                'call' => 'mysql',
139
+                'name' => 'MySQL/MariaDB'
140
+            ),
141
+            'pgsql' => array(
142
+                'type' => 'pdo',
143
+                'call' => 'pgsql',
144
+                'name' => 'PostgreSQL'
145
+            ),
146
+            'oci' => array(
147
+                'type' => 'function',
148
+                'call' => 'oci_connect',
149
+                'name' => 'Oracle'
150
+            )
151
+        );
152
+        if ($allowAllDatabases) {
153
+            $configuredDatabases = array_keys($availableDatabases);
154
+        } else {
155
+            $configuredDatabases = $this->config->getValue('supportedDatabases',
156
+                array('sqlite', 'mysql', 'pgsql'));
157
+        }
158
+        if(!is_array($configuredDatabases)) {
159
+            throw new Exception('Supported databases are not properly configured.');
160
+        }
161
+
162
+        $supportedDatabases = array();
163
+
164
+        foreach($configuredDatabases as $database) {
165
+            if(array_key_exists($database, $availableDatabases)) {
166
+                $working = false;
167
+                $type = $availableDatabases[$database]['type'];
168
+                $call = $availableDatabases[$database]['call'];
169
+
170
+                if ($type === 'function') {
171
+                    $working = $this->is_callable($call);
172
+                } elseif($type === 'pdo') {
173
+                    $working = in_array($call, $this->getAvailableDbDriversForPdo(), TRUE);
174
+                }
175
+                if($working) {
176
+                    $supportedDatabases[$database] = $availableDatabases[$database]['name'];
177
+                }
178
+            }
179
+        }
180
+
181
+        return $supportedDatabases;
182
+    }
183
+
184
+    /**
185
+     * Gathers system information like database type and does
186
+     * a few system checks.
187
+     *
188
+     * @return array of system info, including an "errors" value
189
+     * in case of errors/warnings
190
+     */
191
+    public function getSystemInfo($allowAllDatabases = false) {
192
+        $databases = $this->getSupportedDatabases($allowAllDatabases);
193
+
194
+        $dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
195
+
196
+        $errors = array();
197
+
198
+        // Create data directory to test whether the .htaccess works
199
+        // Notice that this is not necessarily the same data directory as the one
200
+        // that will effectively be used.
201
+        if(!file_exists($dataDir)) {
202
+            @mkdir($dataDir);
203
+        }
204
+        $htAccessWorking = true;
205
+        if (is_dir($dataDir) && is_writable($dataDir)) {
206
+            // Protect data directory here, so we can test if the protection is working
207
+            \OC\Setup::protectDataDirectory();
208
+
209
+            try {
210
+                $util = new \OC_Util();
211
+                $htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
212
+            } catch (\OC\HintException $e) {
213
+                $errors[] = array(
214
+                    'error' => $e->getMessage(),
215
+                    'hint' => $e->getHint()
216
+                );
217
+                $htAccessWorking = false;
218
+            }
219
+        }
220
+
221
+        if (\OC_Util::runningOnMac()) {
222
+            $errors[] = array(
223
+                'error' => $this->l10n->t(
224
+                    'Mac OS X is not supported and %s will not work properly on this platform. ' .
225
+                    'Use it at your own risk! ',
226
+                    $this->defaults->getName()
227
+                ),
228
+                'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.')
229
+            );
230
+        }
231
+
232
+        if($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
233
+            $errors[] = array(
234
+                'error' => $this->l10n->t(
235
+                    'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
236
+                    'This will lead to problems with files over 4 GB and is highly discouraged.',
237
+                    $this->defaults->getName()
238
+                ),
239
+                'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.')
240
+            );
241
+        }
242
+
243
+        return array(
244
+            'hasSQLite' => isset($databases['sqlite']),
245
+            'hasMySQL' => isset($databases['mysql']),
246
+            'hasPostgreSQL' => isset($databases['pgsql']),
247
+            'hasOracle' => isset($databases['oci']),
248
+            'databases' => $databases,
249
+            'directory' => $dataDir,
250
+            'htaccessWorking' => $htAccessWorking,
251
+            'errors' => $errors,
252
+        );
253
+    }
254
+
255
+    /**
256
+     * @param $options
257
+     * @return array
258
+     */
259
+    public function install($options) {
260
+        $l = $this->l10n;
261
+
262
+        $error = array();
263
+        $dbType = $options['dbtype'];
264
+
265
+        if(empty($options['adminlogin'])) {
266
+            $error[] = $l->t('Set an admin username.');
267
+        }
268
+        if(empty($options['adminpass'])) {
269
+            $error[] = $l->t('Set an admin password.');
270
+        }
271
+        if(empty($options['directory'])) {
272
+            $options['directory'] = \OC::$SERVERROOT."/data";
273
+        }
274
+
275
+        if (!isset(self::$dbSetupClasses[$dbType])) {
276
+            $dbType = 'sqlite';
277
+        }
278
+
279
+        $username = htmlspecialchars_decode($options['adminlogin']);
280
+        $password = htmlspecialchars_decode($options['adminpass']);
281
+        $dataDir = htmlspecialchars_decode($options['directory']);
282
+
283
+        $class = self::$dbSetupClasses[$dbType];
284
+        /** @var \OC\Setup\AbstractDatabase $dbSetup */
285
+        $dbSetup = new $class($l, 'db_structure.xml', $this->config,
286
+            $this->logger, $this->random);
287
+        $error = array_merge($error, $dbSetup->validate($options));
288
+
289
+        // validate the data directory
290
+        if (
291
+            (!is_dir($dataDir) and !mkdir($dataDir)) or
292
+            !is_writable($dataDir)
293
+        ) {
294
+            $error[] = $l->t("Can't create or write into the data directory %s", array($dataDir));
295
+        }
296
+
297
+        if(count($error) != 0) {
298
+            return $error;
299
+        }
300
+
301
+        $request = \OC::$server->getRequest();
302
+
303
+        //no errors, good
304
+        if(isset($options['trusted_domains'])
305
+            && is_array($options['trusted_domains'])) {
306
+            $trustedDomains = $options['trusted_domains'];
307
+        } else {
308
+            $trustedDomains = [$request->getInsecureServerHost()];
309
+        }
310
+
311
+        //use sqlite3 when available, otherwise sqlite2 will be used.
312
+        if($dbType=='sqlite' and class_exists('SQLite3')) {
313
+            $dbType='sqlite3';
314
+        }
315
+
316
+        //generate a random salt that is used to salt the local user passwords
317
+        $salt = $this->random->generate(30);
318
+        // generate a secret
319
+        $secret = $this->random->generate(48);
320
+
321
+        //write the config file
322
+        $this->config->setValues([
323
+            'passwordsalt'		=> $salt,
324
+            'secret'			=> $secret,
325
+            'trusted_domains'	=> $trustedDomains,
326
+            'datadirectory'		=> $dataDir,
327
+            'overwrite.cli.url'	=> $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT,
328
+            'dbtype'			=> $dbType,
329
+            'version'			=> implode('.', \OCP\Util::getVersion()),
330
+        ]);
331
+
332
+        try {
333
+            $dbSetup->initialize($options);
334
+            $dbSetup->setupDatabase($username);
335
+            // apply necessary migrations
336
+            $dbSetup->runMigrations();
337
+        } catch (\OC\DatabaseSetupException $e) {
338
+            $error[] = array(
339
+                'error' => $e->getMessage(),
340
+                'hint' => $e->getHint()
341
+            );
342
+            return($error);
343
+        } catch (Exception $e) {
344
+            $error[] = array(
345
+                'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
346
+                'hint' => ''
347
+            );
348
+            return($error);
349
+        }
350
+
351
+        //create the user and group
352
+        $user =  null;
353
+        try {
354
+            $user = \OC::$server->getUserManager()->createUser($username, $password);
355
+            if (!$user) {
356
+                $error[] = "User <$username> could not be created.";
357
+            }
358
+        } catch(Exception $exception) {
359
+            $error[] = $exception->getMessage();
360
+        }
361
+
362
+        if(count($error) == 0) {
363
+            $config = \OC::$server->getConfig();
364
+            $config->setAppValue('core', 'installedat', microtime(true));
365
+            $config->setAppValue('core', 'lastupdatedat', microtime(true));
366
+            $config->setAppValue('core', 'vendor', $this->getVendor());
367
+
368
+            $group =\OC::$server->getGroupManager()->createGroup('admin');
369
+            $group->addUser($user);
370
+
371
+            // Install shipped apps and specified app bundles
372
+            Installer::installShippedApps();
373
+            $installer = new Installer(
374
+                \OC::$server->getAppFetcher(),
375
+                \OC::$server->getHTTPClientService(),
376
+                \OC::$server->getTempManager(),
377
+                \OC::$server->getLogger(),
378
+                \OC::$server->getConfig()
379
+            );
380
+            $bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
381
+            $defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
382
+            foreach($defaultInstallationBundles as $bundle) {
383
+                try {
384
+                    $installer->installAppBundle($bundle);
385
+                } catch (Exception $e) {}
386
+            }
387
+
388
+            // create empty file in data dir, so we can later find
389
+            // out that this is indeed an ownCloud data directory
390
+            file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
391
+
392
+            // Update .htaccess files
393
+            Setup::updateHtaccess();
394
+            Setup::protectDataDirectory();
395
+
396
+            self::installBackgroundJobs();
397
+
398
+            //and we are done
399
+            $config->setSystemValue('installed', true);
400
+
401
+            // Create a session token for the newly created user
402
+            // The token provider requires a working db, so it's not injected on setup
403
+            /* @var $userSession User\Session */
404
+            $userSession = \OC::$server->getUserSession();
405
+            $defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
406
+            $userSession->setTokenProvider($defaultTokenProvider);
407
+            $userSession->login($username, $password);
408
+            $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
409
+        }
410
+
411
+        return $error;
412
+    }
413
+
414
+    public static function installBackgroundJobs() {
415
+        \OC::$server->getJobList()->add('\OC\Authentication\Token\DefaultTokenCleanupJob');
416
+    }
417
+
418
+    /**
419
+     * @return string Absolute path to htaccess
420
+     */
421
+    private function pathToHtaccess() {
422
+        return \OC::$SERVERROOT.'/.htaccess';
423
+    }
424
+
425
+    /**
426
+     * Append the correct ErrorDocument path for Apache hosts
427
+     * @return bool True when success, False otherwise
428
+     */
429
+    public static function updateHtaccess() {
430
+        $config = \OC::$server->getSystemConfig();
431
+
432
+        // For CLI read the value from overwrite.cli.url
433
+        if(\OC::$CLI) {
434
+            $webRoot = $config->getValue('overwrite.cli.url', '');
435
+            if($webRoot === '') {
436
+                return false;
437
+            }
438
+            $webRoot = parse_url($webRoot, PHP_URL_PATH);
439
+            $webRoot = rtrim($webRoot, '/');
440
+        } else {
441
+            $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
442
+        }
443
+
444
+        $setupHelper = new \OC\Setup($config, \OC::$server->getIniWrapper(),
445
+            \OC::$server->getL10N('lib'), \OC::$server->query(Defaults::class), \OC::$server->getLogger(),
446
+            \OC::$server->getSecureRandom());
447
+
448
+        $htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
449
+        $content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
450
+        $htaccessContent = explode($content, $htaccessContent, 2)[0];
451
+
452
+        //custom 403 error page
453
+        $content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php";
454
+
455
+        //custom 404 error page
456
+        $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php";
457
+
458
+        // Add rewrite rules if the RewriteBase is configured
459
+        $rewriteBase = $config->getValue('htaccess.RewriteBase', '');
460
+        if($rewriteBase !== '') {
461
+            $content .= "\n<IfModule mod_rewrite.c>";
462
+            $content .= "\n  Options -MultiViews";
463
+            $content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
464
+            $content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
465
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$";
466
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
467
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
468
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
469
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
470
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
471
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
472
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
473
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
474
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
475
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
476
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
477
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
478
+            $content .= "\n  RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*";
479
+            $content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
480
+            $content .= "\n  RewriteBase " . $rewriteBase;
481
+            $content .= "\n  <IfModule mod_env.c>";
482
+            $content .= "\n    SetEnv front_controller_active true";
483
+            $content .= "\n    <IfModule mod_dir.c>";
484
+            $content .= "\n      DirectorySlash off";
485
+            $content .= "\n    </IfModule>";
486
+            $content .= "\n  </IfModule>";
487
+            $content .= "\n</IfModule>";
488
+        }
489
+
490
+        if ($content !== '') {
491
+            //suppress errors in case we don't have permissions for it
492
+            return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n");
493
+        }
494
+
495
+        return false;
496
+    }
497
+
498
+    public static function protectDataDirectory() {
499
+        //Require all denied
500
+        $now =  date('Y-m-d H:i:s');
501
+        $content = "# Generated by Nextcloud on $now\n";
502
+        $content.= "# line below if for Apache 2.4\n";
503
+        $content.= "<ifModule mod_authz_core.c>\n";
504
+        $content.= "Require all denied\n";
505
+        $content.= "</ifModule>\n\n";
506
+        $content.= "# line below if for Apache 2.2\n";
507
+        $content.= "<ifModule !mod_authz_core.c>\n";
508
+        $content.= "deny from all\n";
509
+        $content.= "Satisfy All\n";
510
+        $content.= "</ifModule>\n\n";
511
+        $content.= "# section for Apache 2.2 and 2.4\n";
512
+        $content.= "<ifModule mod_autoindex.c>\n";
513
+        $content.= "IndexIgnore *\n";
514
+        $content.= "</ifModule>\n";
515
+
516
+        $baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
517
+        file_put_contents($baseDir . '/.htaccess', $content);
518
+        file_put_contents($baseDir . '/index.html', '');
519
+    }
520
+
521
+    /**
522
+     * Return vendor from which this version was published
523
+     *
524
+     * @return string Get the vendor
525
+     *
526
+     * Copy of \OC\Updater::getVendor()
527
+     */
528
+    private function getVendor() {
529
+        // this should really be a JSON file
530
+        require \OC::$SERVERROOT . '/version.php';
531
+        /** @var string $vendor */
532
+        return (string) $vendor;
533
+    }
534 534
 }
Please login to merge, or discard this patch.
lib/private/DB/OracleMigrator.php 1 patch
Indentation   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -32,106 +32,106 @@
 block discarded – undo
32 32
 use Doctrine\DBAL\Schema\Table;
33 33
 
34 34
 class OracleMigrator extends NoCheckMigrator {
35
-	/**
36
-	 * @param Schema $targetSchema
37
-	 * @param \Doctrine\DBAL\Connection $connection
38
-	 * @return \Doctrine\DBAL\Schema\SchemaDiff
39
-	 * @throws DBALException
40
-	 */
41
-	protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
42
-		$schemaDiff = parent::getDiff($targetSchema, $connection);
35
+    /**
36
+     * @param Schema $targetSchema
37
+     * @param \Doctrine\DBAL\Connection $connection
38
+     * @return \Doctrine\DBAL\Schema\SchemaDiff
39
+     * @throws DBALException
40
+     */
41
+    protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
42
+        $schemaDiff = parent::getDiff($targetSchema, $connection);
43 43
 
44
-		// oracle forces us to quote the identifiers
45
-		$schemaDiff->newTables = array_map(function(Table $table) {
46
-			return new Table(
47
-				$this->connection->quoteIdentifier($table->getName()),
48
-				array_map(function(Column $column) {
49
-					$newColumn = new Column(
50
-						$this->connection->quoteIdentifier($column->getName()),
51
-						$column->getType()
52
-					);
53
-					$newColumn->setAutoincrement($column->getAutoincrement());
54
-					$newColumn->setColumnDefinition($column->getColumnDefinition());
55
-					$newColumn->setComment($column->getComment());
56
-					$newColumn->setDefault($column->getDefault());
57
-					$newColumn->setFixed($column->getFixed());
58
-					$newColumn->setLength($column->getLength());
59
-					$newColumn->setNotnull($column->getNotnull());
60
-					$newColumn->setPrecision($column->getPrecision());
61
-					$newColumn->setScale($column->getScale());
62
-					$newColumn->setUnsigned($column->getUnsigned());
63
-					$newColumn->setPlatformOptions($column->getPlatformOptions());
64
-					$newColumn->setCustomSchemaOptions($column->getPlatformOptions());
65
-					return $newColumn;
66
-				}, $table->getColumns()),
67
-				array_map(function(Index $index) {
68
-					return new Index(
69
-						$this->connection->quoteIdentifier($index->getName()),
70
-						array_map(function($columnName) {
71
-							return $this->connection->quoteIdentifier($columnName);
72
-						}, $index->getColumns()),
73
-						$index->isUnique(),
74
-						$index->isPrimary(),
75
-						$index->getFlags(),
76
-						$index->getOptions()
77
-					);
78
-				}, $table->getIndexes()),
79
-				$table->getForeignKeys(),
80
-				0,
81
-				$table->getOptions()
82
-			);
83
-		}, $schemaDiff->newTables);
44
+        // oracle forces us to quote the identifiers
45
+        $schemaDiff->newTables = array_map(function(Table $table) {
46
+            return new Table(
47
+                $this->connection->quoteIdentifier($table->getName()),
48
+                array_map(function(Column $column) {
49
+                    $newColumn = new Column(
50
+                        $this->connection->quoteIdentifier($column->getName()),
51
+                        $column->getType()
52
+                    );
53
+                    $newColumn->setAutoincrement($column->getAutoincrement());
54
+                    $newColumn->setColumnDefinition($column->getColumnDefinition());
55
+                    $newColumn->setComment($column->getComment());
56
+                    $newColumn->setDefault($column->getDefault());
57
+                    $newColumn->setFixed($column->getFixed());
58
+                    $newColumn->setLength($column->getLength());
59
+                    $newColumn->setNotnull($column->getNotnull());
60
+                    $newColumn->setPrecision($column->getPrecision());
61
+                    $newColumn->setScale($column->getScale());
62
+                    $newColumn->setUnsigned($column->getUnsigned());
63
+                    $newColumn->setPlatformOptions($column->getPlatformOptions());
64
+                    $newColumn->setCustomSchemaOptions($column->getPlatformOptions());
65
+                    return $newColumn;
66
+                }, $table->getColumns()),
67
+                array_map(function(Index $index) {
68
+                    return new Index(
69
+                        $this->connection->quoteIdentifier($index->getName()),
70
+                        array_map(function($columnName) {
71
+                            return $this->connection->quoteIdentifier($columnName);
72
+                        }, $index->getColumns()),
73
+                        $index->isUnique(),
74
+                        $index->isPrimary(),
75
+                        $index->getFlags(),
76
+                        $index->getOptions()
77
+                    );
78
+                }, $table->getIndexes()),
79
+                $table->getForeignKeys(),
80
+                0,
81
+                $table->getOptions()
82
+            );
83
+        }, $schemaDiff->newTables);
84 84
 
85
-		$schemaDiff->removedTables = array_map(function(Table $table) {
86
-			return new Table(
87
-				$this->connection->quoteIdentifier($table->getName()),
88
-				$table->getColumns(),
89
-				$table->getIndexes(),
90
-				$table->getForeignKeys(),
91
-				0,
92
-				$table->getOptions()
93
-			);
94
-		}, $schemaDiff->removedTables);
85
+        $schemaDiff->removedTables = array_map(function(Table $table) {
86
+            return new Table(
87
+                $this->connection->quoteIdentifier($table->getName()),
88
+                $table->getColumns(),
89
+                $table->getIndexes(),
90
+                $table->getForeignKeys(),
91
+                0,
92
+                $table->getOptions()
93
+            );
94
+        }, $schemaDiff->removedTables);
95 95
 
96
-		foreach ($schemaDiff->changedTables as $tableDiff) {
97
-			$tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name);
98
-			foreach ($tableDiff->changedColumns as $column) {
99
-				$column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName);
100
-				// auto increment is not relevant for oracle and can anyhow not be applied on change
101
-				$column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']);
102
-			}
103
-			$tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) {
104
-				return count($column->changedProperties) > 0;
105
-			});
106
-		}
96
+        foreach ($schemaDiff->changedTables as $tableDiff) {
97
+            $tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name);
98
+            foreach ($tableDiff->changedColumns as $column) {
99
+                $column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName);
100
+                // auto increment is not relevant for oracle and can anyhow not be applied on change
101
+                $column->changedProperties = array_diff($column->changedProperties, ['autoincrement', 'unsigned']);
102
+            }
103
+            $tableDiff->changedColumns = array_filter($tableDiff->changedColumns, function (ColumnDiff $column) {
104
+                return count($column->changedProperties) > 0;
105
+            });
106
+        }
107 107
 
108
-		return $schemaDiff;
109
-	}
108
+        return $schemaDiff;
109
+    }
110 110
 
111
-	/**
112
-	 * @param string $name
113
-	 * @return string
114
-	 */
115
-	protected function generateTemporaryTableName($name) {
116
-		return 'oc_' . uniqid();
117
-	}
111
+    /**
112
+     * @param string $name
113
+     * @return string
114
+     */
115
+    protected function generateTemporaryTableName($name) {
116
+        return 'oc_' . uniqid();
117
+    }
118 118
 
119
-	/**
120
-	 * @param $statement
121
-	 * @return string
122
-	 */
123
-	protected function convertStatementToScript($statement) {
124
-		if (substr($statement, -1) === ';') {
125
-			return $statement . PHP_EOL . '/' . PHP_EOL;
126
-		}
127
-		$script = $statement . ';';
128
-		$script .= PHP_EOL;
129
-		$script .= PHP_EOL;
130
-		return $script;
131
-	}
119
+    /**
120
+     * @param $statement
121
+     * @return string
122
+     */
123
+    protected function convertStatementToScript($statement) {
124
+        if (substr($statement, -1) === ';') {
125
+            return $statement . PHP_EOL . '/' . PHP_EOL;
126
+        }
127
+        $script = $statement . ';';
128
+        $script .= PHP_EOL;
129
+        $script .= PHP_EOL;
130
+        return $script;
131
+    }
132 132
 
133
-	protected function getFilterExpression() {
134
-		return '/^"' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
135
-	}
133
+    protected function getFilterExpression() {
134
+        return '/^"' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
135
+    }
136 136
 
137 137
 }
Please login to merge, or discard this patch.
lib/private/DB/OracleConnection.php 2 patches
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -26,80 +26,80 @@
 block discarded – undo
26 26
 namespace OC\DB;
27 27
 
28 28
 class OracleConnection extends Connection {
29
-	/**
30
-	 * Quote the keys of the array
31
-	 */
32
-	private function quoteKeys(array $data) {
33
-		$return = [];
34
-		$c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
35
-		foreach($data as $key => $value) {
36
-			if ($key[0] !== $c) {
37
-				$return[$this->quoteIdentifier($key)] = $value;
38
-			} else {
39
-				$return[$key] = $value;
40
-			}
41
-		}
42
-		return $return;
43
-	}
29
+    /**
30
+     * Quote the keys of the array
31
+     */
32
+    private function quoteKeys(array $data) {
33
+        $return = [];
34
+        $c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
35
+        foreach($data as $key => $value) {
36
+            if ($key[0] !== $c) {
37
+                $return[$this->quoteIdentifier($key)] = $value;
38
+            } else {
39
+                $return[$key] = $value;
40
+            }
41
+        }
42
+        return $return;
43
+    }
44 44
 
45
-	/**
46
-	 * {@inheritDoc}
47
-	 */
48
-	public function insert($tableName, array $data, array $types = array()) {
49
-		if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
50
-			$tableName = $this->quoteIdentifier($tableName);
51
-		}
52
-		$data = $this->quoteKeys($data);
53
-		return parent::insert($tableName, $data, $types);
54
-	}
45
+    /**
46
+     * {@inheritDoc}
47
+     */
48
+    public function insert($tableName, array $data, array $types = array()) {
49
+        if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
50
+            $tableName = $this->quoteIdentifier($tableName);
51
+        }
52
+        $data = $this->quoteKeys($data);
53
+        return parent::insert($tableName, $data, $types);
54
+    }
55 55
 
56
-	/**
57
-	 * {@inheritDoc}
58
-	 */
59
-	public function update($tableName, array $data, array $identifier, array $types = array()) {
60
-		if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
61
-			$tableName = $this->quoteIdentifier($tableName);
62
-		}
63
-		$data = $this->quoteKeys($data);
64
-		$identifier = $this->quoteKeys($identifier);
65
-		return parent::update($tableName, $data, $identifier, $types);
66
-	}
56
+    /**
57
+     * {@inheritDoc}
58
+     */
59
+    public function update($tableName, array $data, array $identifier, array $types = array()) {
60
+        if ($tableName[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
61
+            $tableName = $this->quoteIdentifier($tableName);
62
+        }
63
+        $data = $this->quoteKeys($data);
64
+        $identifier = $this->quoteKeys($identifier);
65
+        return parent::update($tableName, $data, $identifier, $types);
66
+    }
67 67
 
68
-	/**
69
-	 * {@inheritDoc}
70
-	 */
71
-	public function delete($tableExpression, array $identifier, array $types = array()) {
72
-		if ($tableExpression[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
73
-			$tableExpression = $this->quoteIdentifier($tableExpression);
74
-		}
75
-		$identifier = $this->quoteKeys($identifier);
76
-		return parent::delete($tableExpression, $identifier);
77
-	}
68
+    /**
69
+     * {@inheritDoc}
70
+     */
71
+    public function delete($tableExpression, array $identifier, array $types = array()) {
72
+        if ($tableExpression[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
73
+            $tableExpression = $this->quoteIdentifier($tableExpression);
74
+        }
75
+        $identifier = $this->quoteKeys($identifier);
76
+        return parent::delete($tableExpression, $identifier);
77
+    }
78 78
 
79
-	/**
80
-	 * Drop a table from the database if it exists
81
-	 *
82
-	 * @param string $table table name without the prefix
83
-	 */
84
-	public function dropTable($table) {
85
-		$table = $this->tablePrefix . trim($table);
86
-		$table = $this->quoteIdentifier($table);
87
-		$schema = $this->getSchemaManager();
88
-		if($schema->tablesExist(array($table))) {
89
-			$schema->dropTable($table);
90
-		}
91
-	}
79
+    /**
80
+     * Drop a table from the database if it exists
81
+     *
82
+     * @param string $table table name without the prefix
83
+     */
84
+    public function dropTable($table) {
85
+        $table = $this->tablePrefix . trim($table);
86
+        $table = $this->quoteIdentifier($table);
87
+        $schema = $this->getSchemaManager();
88
+        if($schema->tablesExist(array($table))) {
89
+            $schema->dropTable($table);
90
+        }
91
+    }
92 92
 
93
-	/**
94
-	 * Check if a table exists
95
-	 *
96
-	 * @param string $table table name without the prefix
97
-	 * @return bool
98
-	 */
99
-	public function tableExists($table){
100
-		$table = $this->tablePrefix . trim($table);
101
-		$table = $this->quoteIdentifier($table);
102
-		$schema = $this->getSchemaManager();
103
-		return $schema->tablesExist(array($table));
104
-	}
93
+    /**
94
+     * Check if a table exists
95
+     *
96
+     * @param string $table table name without the prefix
97
+     * @return bool
98
+     */
99
+    public function tableExists($table){
100
+        $table = $this->tablePrefix . trim($table);
101
+        $table = $this->quoteIdentifier($table);
102
+        $schema = $this->getSchemaManager();
103
+        return $schema->tablesExist(array($table));
104
+    }
105 105
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
 	private function quoteKeys(array $data) {
33 33
 		$return = [];
34 34
 		$c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
35
-		foreach($data as $key => $value) {
35
+		foreach ($data as $key => $value) {
36 36
 			if ($key[0] !== $c) {
37 37
 				$return[$this->quoteIdentifier($key)] = $value;
38 38
 			} else {
@@ -82,10 +82,10 @@  discard block
 block discarded – undo
82 82
 	 * @param string $table table name without the prefix
83 83
 	 */
84 84
 	public function dropTable($table) {
85
-		$table = $this->tablePrefix . trim($table);
85
+		$table = $this->tablePrefix.trim($table);
86 86
 		$table = $this->quoteIdentifier($table);
87 87
 		$schema = $this->getSchemaManager();
88
-		if($schema->tablesExist(array($table))) {
88
+		if ($schema->tablesExist(array($table))) {
89 89
 			$schema->dropTable($table);
90 90
 		}
91 91
 	}
@@ -96,8 +96,8 @@  discard block
 block discarded – undo
96 96
 	 * @param string $table table name without the prefix
97 97
 	 * @return bool
98 98
 	 */
99
-	public function tableExists($table){
100
-		$table = $this->tablePrefix . trim($table);
99
+	public function tableExists($table) {
100
+		$table = $this->tablePrefix.trim($table);
101 101
 		$table = $this->quoteIdentifier($table);
102 102
 		$schema = $this->getSchemaManager();
103 103
 		return $schema->tablesExist(array($table));
Please login to merge, or discard this patch.
lib/private/DB/Migrator.php 1 patch
Indentation   +268 added lines, -268 removed lines patch added patch discarded remove patch
@@ -43,272 +43,272 @@
 block discarded – undo
43 43
 
44 44
 class Migrator {
45 45
 
46
-	/** @var \Doctrine\DBAL\Connection */
47
-	protected $connection;
48
-
49
-	/** @var ISecureRandom */
50
-	private $random;
51
-
52
-	/** @var IConfig */
53
-	protected $config;
54
-
55
-	/** @var EventDispatcher  */
56
-	private $dispatcher;
57
-
58
-	/** @var bool */
59
-	private $noEmit = false;
60
-
61
-	/**
62
-	 * @param \Doctrine\DBAL\Connection|Connection $connection
63
-	 * @param ISecureRandom $random
64
-	 * @param IConfig $config
65
-	 * @param EventDispatcher $dispatcher
66
-	 */
67
-	public function __construct(\Doctrine\DBAL\Connection $connection,
68
-								ISecureRandom $random,
69
-								IConfig $config,
70
-								EventDispatcher $dispatcher = null) {
71
-		$this->connection = $connection;
72
-		$this->random = $random;
73
-		$this->config = $config;
74
-		$this->dispatcher = $dispatcher;
75
-	}
76
-
77
-	/**
78
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
79
-	 */
80
-	public function migrate(Schema $targetSchema) {
81
-		$this->noEmit = true;
82
-		$this->applySchema($targetSchema);
83
-	}
84
-
85
-	/**
86
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
87
-	 * @return string
88
-	 */
89
-	public function generateChangeScript(Schema $targetSchema) {
90
-		$schemaDiff = $this->getDiff($targetSchema, $this->connection);
91
-
92
-		$script = '';
93
-		$sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform());
94
-		foreach ($sqls as $sql) {
95
-			$script .= $this->convertStatementToScript($sql);
96
-		}
97
-
98
-		return $script;
99
-	}
100
-
101
-	/**
102
-	 * @param Schema $targetSchema
103
-	 * @throws \OC\DB\MigrationException
104
-	 */
105
-	public function checkMigrate(Schema $targetSchema) {
106
-		$this->noEmit = true;
107
-		/**@var \Doctrine\DBAL\Schema\Table[] $tables */
108
-		$tables = $targetSchema->getTables();
109
-		$filterExpression = $this->getFilterExpression();
110
-		$this->connection->getConfiguration()->
111
-			setFilterSchemaAssetsExpression($filterExpression);
112
-		$existingTables = $this->connection->getSchemaManager()->listTableNames();
113
-
114
-		$step = 0;
115
-		foreach ($tables as $table) {
116
-			if (strpos($table->getName(), '.')) {
117
-				list(, $tableName) = explode('.', $table->getName());
118
-			} else {
119
-				$tableName = $table->getName();
120
-			}
121
-			$this->emitCheckStep($tableName, $step++, count($tables));
122
-			// don't need to check for new tables
123
-			if (array_search($tableName, $existingTables) !== false) {
124
-				$this->checkTableMigrate($table);
125
-			}
126
-		}
127
-	}
128
-
129
-	/**
130
-	 * Create a unique name for the temporary table
131
-	 *
132
-	 * @param string $name
133
-	 * @return string
134
-	 */
135
-	protected function generateTemporaryTableName($name) {
136
-		return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
137
-	}
138
-
139
-	/**
140
-	 * Check the migration of a table on a copy so we can detect errors before messing with the real table
141
-	 *
142
-	 * @param \Doctrine\DBAL\Schema\Table $table
143
-	 * @throws \OC\DB\MigrationException
144
-	 */
145
-	protected function checkTableMigrate(Table $table) {
146
-		$name = $table->getName();
147
-		$tmpName = $this->generateTemporaryTableName($name);
148
-
149
-		$this->copyTable($name, $tmpName);
150
-
151
-		//create the migration schema for the temporary table
152
-		$tmpTable = $this->renameTableSchema($table, $tmpName);
153
-		$schemaConfig = new SchemaConfig();
154
-		$schemaConfig->setName($this->connection->getDatabase());
155
-		$schema = new Schema(array($tmpTable), array(), $schemaConfig);
156
-
157
-		try {
158
-			$this->applySchema($schema);
159
-			$this->dropTable($tmpName);
160
-		} catch (DBALException $e) {
161
-			// pgsql needs to commit it's failed transaction before doing anything else
162
-			if ($this->connection->isTransactionActive()) {
163
-				$this->connection->commit();
164
-			}
165
-			$this->dropTable($tmpName);
166
-			throw new MigrationException($table->getName(), $e->getMessage());
167
-		}
168
-	}
169
-
170
-	/**
171
-	 * @param \Doctrine\DBAL\Schema\Table $table
172
-	 * @param string $newName
173
-	 * @return \Doctrine\DBAL\Schema\Table
174
-	 */
175
-	protected function renameTableSchema(Table $table, $newName) {
176
-		/**
177
-		 * @var \Doctrine\DBAL\Schema\Index[] $indexes
178
-		 */
179
-		$indexes = $table->getIndexes();
180
-		$newIndexes = array();
181
-		foreach ($indexes as $index) {
182
-			if ($index->isPrimary()) {
183
-				// do not rename primary key
184
-				$indexName = $index->getName();
185
-			} else {
186
-				// avoid conflicts in index names
187
-				$indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER);
188
-			}
189
-			$newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary());
190
-		}
191
-
192
-		// foreign keys are not supported so we just set it to an empty array
193
-		return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions());
194
-	}
195
-
196
-	public function createSchema() {
197
-		$filterExpression = $this->getFilterExpression();
198
-		$this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
199
-		return $this->connection->getSchemaManager()->createSchema();
200
-	}
201
-
202
-	/**
203
-	 * @param Schema $targetSchema
204
-	 * @param \Doctrine\DBAL\Connection $connection
205
-	 * @return \Doctrine\DBAL\Schema\SchemaDiff
206
-	 * @throws DBALException
207
-	 */
208
-	protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
209
-		// adjust varchar columns with a length higher then getVarcharMaxLength to clob
210
-		foreach ($targetSchema->getTables() as $table) {
211
-			foreach ($table->getColumns() as $column) {
212
-				if ($column->getType() instanceof StringType) {
213
-					if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) {
214
-						$column->setType(Type::getType('text'));
215
-						$column->setLength(null);
216
-					}
217
-				}
218
-			}
219
-		}
220
-
221
-		$filterExpression = $this->getFilterExpression();
222
-		$this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
223
-		$sourceSchema = $connection->getSchemaManager()->createSchema();
224
-
225
-		// remove tables we don't know about
226
-		/** @var $table \Doctrine\DBAL\Schema\Table */
227
-		foreach ($sourceSchema->getTables() as $table) {
228
-			if (!$targetSchema->hasTable($table->getName())) {
229
-				$sourceSchema->dropTable($table->getName());
230
-			}
231
-		}
232
-		// remove sequences we don't know about
233
-		foreach ($sourceSchema->getSequences() as $table) {
234
-			if (!$targetSchema->hasSequence($table->getName())) {
235
-				$sourceSchema->dropSequence($table->getName());
236
-			}
237
-		}
238
-
239
-		$comparator = new Comparator();
240
-		return $comparator->compare($sourceSchema, $targetSchema);
241
-	}
242
-
243
-	/**
244
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
245
-	 * @param \Doctrine\DBAL\Connection $connection
246
-	 */
247
-	protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) {
248
-		if (is_null($connection)) {
249
-			$connection = $this->connection;
250
-		}
251
-
252
-		$schemaDiff = $this->getDiff($targetSchema, $connection);
253
-
254
-		$connection->beginTransaction();
255
-		$sqls = $schemaDiff->toSql($connection->getDatabasePlatform());
256
-		$step = 0;
257
-		foreach ($sqls as $sql) {
258
-			$this->emit($sql, $step++, count($sqls));
259
-			$connection->query($sql);
260
-		}
261
-		$connection->commit();
262
-	}
263
-
264
-	/**
265
-	 * @param string $sourceName
266
-	 * @param string $targetName
267
-	 */
268
-	protected function copyTable($sourceName, $targetName) {
269
-		$quotedSource = $this->connection->quoteIdentifier($sourceName);
270
-		$quotedTarget = $this->connection->quoteIdentifier($targetName);
271
-
272
-		$this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')');
273
-		$this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource);
274
-	}
275
-
276
-	/**
277
-	 * @param string $name
278
-	 */
279
-	protected function dropTable($name) {
280
-		$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name));
281
-	}
282
-
283
-	/**
284
-	 * @param $statement
285
-	 * @return string
286
-	 */
287
-	protected function convertStatementToScript($statement) {
288
-		$script = $statement . ';';
289
-		$script .= PHP_EOL;
290
-		$script .= PHP_EOL;
291
-		return $script;
292
-	}
293
-
294
-	protected function getFilterExpression() {
295
-		return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
296
-	}
297
-
298
-	protected function emit($sql, $step, $max) {
299
-		if ($this->noEmit) {
300
-			return;
301
-		}
302
-		if(is_null($this->dispatcher)) {
303
-			return;
304
-		}
305
-		$this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max]));
306
-	}
307
-
308
-	private function emitCheckStep($tableName, $step, $max) {
309
-		if(is_null($this->dispatcher)) {
310
-			return;
311
-		}
312
-		$this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max]));
313
-	}
46
+    /** @var \Doctrine\DBAL\Connection */
47
+    protected $connection;
48
+
49
+    /** @var ISecureRandom */
50
+    private $random;
51
+
52
+    /** @var IConfig */
53
+    protected $config;
54
+
55
+    /** @var EventDispatcher  */
56
+    private $dispatcher;
57
+
58
+    /** @var bool */
59
+    private $noEmit = false;
60
+
61
+    /**
62
+     * @param \Doctrine\DBAL\Connection|Connection $connection
63
+     * @param ISecureRandom $random
64
+     * @param IConfig $config
65
+     * @param EventDispatcher $dispatcher
66
+     */
67
+    public function __construct(\Doctrine\DBAL\Connection $connection,
68
+                                ISecureRandom $random,
69
+                                IConfig $config,
70
+                                EventDispatcher $dispatcher = null) {
71
+        $this->connection = $connection;
72
+        $this->random = $random;
73
+        $this->config = $config;
74
+        $this->dispatcher = $dispatcher;
75
+    }
76
+
77
+    /**
78
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
79
+     */
80
+    public function migrate(Schema $targetSchema) {
81
+        $this->noEmit = true;
82
+        $this->applySchema($targetSchema);
83
+    }
84
+
85
+    /**
86
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
87
+     * @return string
88
+     */
89
+    public function generateChangeScript(Schema $targetSchema) {
90
+        $schemaDiff = $this->getDiff($targetSchema, $this->connection);
91
+
92
+        $script = '';
93
+        $sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform());
94
+        foreach ($sqls as $sql) {
95
+            $script .= $this->convertStatementToScript($sql);
96
+        }
97
+
98
+        return $script;
99
+    }
100
+
101
+    /**
102
+     * @param Schema $targetSchema
103
+     * @throws \OC\DB\MigrationException
104
+     */
105
+    public function checkMigrate(Schema $targetSchema) {
106
+        $this->noEmit = true;
107
+        /**@var \Doctrine\DBAL\Schema\Table[] $tables */
108
+        $tables = $targetSchema->getTables();
109
+        $filterExpression = $this->getFilterExpression();
110
+        $this->connection->getConfiguration()->
111
+            setFilterSchemaAssetsExpression($filterExpression);
112
+        $existingTables = $this->connection->getSchemaManager()->listTableNames();
113
+
114
+        $step = 0;
115
+        foreach ($tables as $table) {
116
+            if (strpos($table->getName(), '.')) {
117
+                list(, $tableName) = explode('.', $table->getName());
118
+            } else {
119
+                $tableName = $table->getName();
120
+            }
121
+            $this->emitCheckStep($tableName, $step++, count($tables));
122
+            // don't need to check for new tables
123
+            if (array_search($tableName, $existingTables) !== false) {
124
+                $this->checkTableMigrate($table);
125
+            }
126
+        }
127
+    }
128
+
129
+    /**
130
+     * Create a unique name for the temporary table
131
+     *
132
+     * @param string $name
133
+     * @return string
134
+     */
135
+    protected function generateTemporaryTableName($name) {
136
+        return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
137
+    }
138
+
139
+    /**
140
+     * Check the migration of a table on a copy so we can detect errors before messing with the real table
141
+     *
142
+     * @param \Doctrine\DBAL\Schema\Table $table
143
+     * @throws \OC\DB\MigrationException
144
+     */
145
+    protected function checkTableMigrate(Table $table) {
146
+        $name = $table->getName();
147
+        $tmpName = $this->generateTemporaryTableName($name);
148
+
149
+        $this->copyTable($name, $tmpName);
150
+
151
+        //create the migration schema for the temporary table
152
+        $tmpTable = $this->renameTableSchema($table, $tmpName);
153
+        $schemaConfig = new SchemaConfig();
154
+        $schemaConfig->setName($this->connection->getDatabase());
155
+        $schema = new Schema(array($tmpTable), array(), $schemaConfig);
156
+
157
+        try {
158
+            $this->applySchema($schema);
159
+            $this->dropTable($tmpName);
160
+        } catch (DBALException $e) {
161
+            // pgsql needs to commit it's failed transaction before doing anything else
162
+            if ($this->connection->isTransactionActive()) {
163
+                $this->connection->commit();
164
+            }
165
+            $this->dropTable($tmpName);
166
+            throw new MigrationException($table->getName(), $e->getMessage());
167
+        }
168
+    }
169
+
170
+    /**
171
+     * @param \Doctrine\DBAL\Schema\Table $table
172
+     * @param string $newName
173
+     * @return \Doctrine\DBAL\Schema\Table
174
+     */
175
+    protected function renameTableSchema(Table $table, $newName) {
176
+        /**
177
+         * @var \Doctrine\DBAL\Schema\Index[] $indexes
178
+         */
179
+        $indexes = $table->getIndexes();
180
+        $newIndexes = array();
181
+        foreach ($indexes as $index) {
182
+            if ($index->isPrimary()) {
183
+                // do not rename primary key
184
+                $indexName = $index->getName();
185
+            } else {
186
+                // avoid conflicts in index names
187
+                $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER);
188
+            }
189
+            $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary());
190
+        }
191
+
192
+        // foreign keys are not supported so we just set it to an empty array
193
+        return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions());
194
+    }
195
+
196
+    public function createSchema() {
197
+        $filterExpression = $this->getFilterExpression();
198
+        $this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
199
+        return $this->connection->getSchemaManager()->createSchema();
200
+    }
201
+
202
+    /**
203
+     * @param Schema $targetSchema
204
+     * @param \Doctrine\DBAL\Connection $connection
205
+     * @return \Doctrine\DBAL\Schema\SchemaDiff
206
+     * @throws DBALException
207
+     */
208
+    protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
209
+        // adjust varchar columns with a length higher then getVarcharMaxLength to clob
210
+        foreach ($targetSchema->getTables() as $table) {
211
+            foreach ($table->getColumns() as $column) {
212
+                if ($column->getType() instanceof StringType) {
213
+                    if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) {
214
+                        $column->setType(Type::getType('text'));
215
+                        $column->setLength(null);
216
+                    }
217
+                }
218
+            }
219
+        }
220
+
221
+        $filterExpression = $this->getFilterExpression();
222
+        $this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
223
+        $sourceSchema = $connection->getSchemaManager()->createSchema();
224
+
225
+        // remove tables we don't know about
226
+        /** @var $table \Doctrine\DBAL\Schema\Table */
227
+        foreach ($sourceSchema->getTables() as $table) {
228
+            if (!$targetSchema->hasTable($table->getName())) {
229
+                $sourceSchema->dropTable($table->getName());
230
+            }
231
+        }
232
+        // remove sequences we don't know about
233
+        foreach ($sourceSchema->getSequences() as $table) {
234
+            if (!$targetSchema->hasSequence($table->getName())) {
235
+                $sourceSchema->dropSequence($table->getName());
236
+            }
237
+        }
238
+
239
+        $comparator = new Comparator();
240
+        return $comparator->compare($sourceSchema, $targetSchema);
241
+    }
242
+
243
+    /**
244
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
245
+     * @param \Doctrine\DBAL\Connection $connection
246
+     */
247
+    protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) {
248
+        if (is_null($connection)) {
249
+            $connection = $this->connection;
250
+        }
251
+
252
+        $schemaDiff = $this->getDiff($targetSchema, $connection);
253
+
254
+        $connection->beginTransaction();
255
+        $sqls = $schemaDiff->toSql($connection->getDatabasePlatform());
256
+        $step = 0;
257
+        foreach ($sqls as $sql) {
258
+            $this->emit($sql, $step++, count($sqls));
259
+            $connection->query($sql);
260
+        }
261
+        $connection->commit();
262
+    }
263
+
264
+    /**
265
+     * @param string $sourceName
266
+     * @param string $targetName
267
+     */
268
+    protected function copyTable($sourceName, $targetName) {
269
+        $quotedSource = $this->connection->quoteIdentifier($sourceName);
270
+        $quotedTarget = $this->connection->quoteIdentifier($targetName);
271
+
272
+        $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')');
273
+        $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource);
274
+    }
275
+
276
+    /**
277
+     * @param string $name
278
+     */
279
+    protected function dropTable($name) {
280
+        $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name));
281
+    }
282
+
283
+    /**
284
+     * @param $statement
285
+     * @return string
286
+     */
287
+    protected function convertStatementToScript($statement) {
288
+        $script = $statement . ';';
289
+        $script .= PHP_EOL;
290
+        $script .= PHP_EOL;
291
+        return $script;
292
+    }
293
+
294
+    protected function getFilterExpression() {
295
+        return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
296
+    }
297
+
298
+    protected function emit($sql, $step, $max) {
299
+        if ($this->noEmit) {
300
+            return;
301
+        }
302
+        if(is_null($this->dispatcher)) {
303
+            return;
304
+        }
305
+        $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step+1, $max]));
306
+    }
307
+
308
+    private function emitCheckStep($tableName, $step, $max) {
309
+        if(is_null($this->dispatcher)) {
310
+            return;
311
+        }
312
+        $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step+1, $max]));
313
+    }
314 314
 }
Please login to merge, or discard this patch.