Passed
Push — master ( 54e3be...fad8dd )
by Blizzz
11:55 queued 10s
created
lib/private/Updater.php 2 patches
Indentation   +524 added lines, -524 removed lines patch added patch discarded remove patch
@@ -56,528 +56,528 @@
 block discarded – undo
56 56
  */
57 57
 class Updater extends BasicEmitter {
58 58
 
59
-	/** @var ILogger $log */
60
-	private $log;
61
-
62
-	/** @var IConfig */
63
-	private $config;
64
-
65
-	/** @var Checker */
66
-	private $checker;
67
-
68
-	/** @var Installer */
69
-	private $installer;
70
-
71
-	private $logLevelNames = [
72
-		0 => 'Debug',
73
-		1 => 'Info',
74
-		2 => 'Warning',
75
-		3 => 'Error',
76
-		4 => 'Fatal',
77
-	];
78
-
79
-	/**
80
-	 * @param IConfig $config
81
-	 * @param Checker $checker
82
-	 * @param ILogger $log
83
-	 * @param Installer $installer
84
-	 */
85
-	public function __construct(IConfig $config,
86
-								Checker $checker,
87
-								ILogger $log = null,
88
-								Installer $installer) {
89
-		$this->log = $log;
90
-		$this->config = $config;
91
-		$this->checker = $checker;
92
-		$this->installer = $installer;
93
-	}
94
-
95
-	/**
96
-	 * runs the update actions in maintenance mode, does not upgrade the source files
97
-	 * except the main .htaccess file
98
-	 *
99
-	 * @return bool true if the operation succeeded, false otherwise
100
-	 */
101
-	public function upgrade() {
102
-		$this->emitRepairEvents();
103
-		$this->logAllEvents();
104
-
105
-		$logLevel = $this->config->getSystemValue('loglevel', ILogger::WARN);
106
-		$this->emit('\OC\Updater', 'setDebugLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
107
-		$this->config->setSystemValue('loglevel', ILogger::DEBUG);
108
-
109
-		$wasMaintenanceModeEnabled = $this->config->getSystemValueBool('maintenance');
110
-
111
-		if (!$wasMaintenanceModeEnabled) {
112
-			$this->config->setSystemValue('maintenance', true);
113
-			$this->emit('\OC\Updater', 'maintenanceEnabled');
114
-		}
115
-
116
-		// Clear CAN_INSTALL file if not on git
117
-		if (\OC_Util::getChannel() !== 'git' && is_file(\OC::$configDir.'/CAN_INSTALL')) {
118
-			if (!unlink(\OC::$configDir . '/CAN_INSTALL')) {
119
-				$this->log->error('Could not cleanup CAN_INSTALL from your config folder. Please remove this file manually.');
120
-			}
121
-		}
122
-
123
-		$installedVersion = $this->config->getSystemValue('version', '0.0.0');
124
-		$currentVersion = implode('.', \OCP\Util::getVersion());
125
-
126
-		$this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, ['app' => 'core']);
127
-
128
-		$success = true;
129
-		try {
130
-			$this->doUpgrade($currentVersion, $installedVersion);
131
-		} catch (HintException $exception) {
132
-			$this->log->logException($exception, ['app' => 'core']);
133
-			$this->emit('\OC\Updater', 'failure', [$exception->getMessage() . ': ' .$exception->getHint()]);
134
-			$success = false;
135
-		} catch (\Exception $exception) {
136
-			$this->log->logException($exception, ['app' => 'core']);
137
-			$this->emit('\OC\Updater', 'failure', [get_class($exception) . ': ' .$exception->getMessage()]);
138
-			$success = false;
139
-		}
140
-
141
-		$this->emit('\OC\Updater', 'updateEnd', [$success]);
142
-
143
-		if (!$wasMaintenanceModeEnabled && $success) {
144
-			$this->config->setSystemValue('maintenance', false);
145
-			$this->emit('\OC\Updater', 'maintenanceDisabled');
146
-		} else {
147
-			$this->emit('\OC\Updater', 'maintenanceActive');
148
-		}
149
-
150
-		$this->emit('\OC\Updater', 'resetLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
151
-		$this->config->setSystemValue('loglevel', $logLevel);
152
-		$this->config->setSystemValue('installed', true);
153
-
154
-		return $success;
155
-	}
156
-
157
-	/**
158
-	 * Return version from which this version is allowed to upgrade from
159
-	 *
160
-	 * @return array allowed previous versions per vendor
161
-	 */
162
-	private function getAllowedPreviousVersions() {
163
-		// this should really be a JSON file
164
-		require \OC::$SERVERROOT . '/version.php';
165
-		/** @var array $OC_VersionCanBeUpgradedFrom */
166
-		return $OC_VersionCanBeUpgradedFrom;
167
-	}
168
-
169
-	/**
170
-	 * Return vendor from which this version was published
171
-	 *
172
-	 * @return string Get the vendor
173
-	 */
174
-	private function getVendor() {
175
-		// this should really be a JSON file
176
-		require \OC::$SERVERROOT . '/version.php';
177
-		/** @var string $vendor */
178
-		return (string) $vendor;
179
-	}
180
-
181
-	/**
182
-	 * Whether an upgrade to a specified version is possible
183
-	 * @param string $oldVersion
184
-	 * @param string $newVersion
185
-	 * @param array $allowedPreviousVersions
186
-	 * @return bool
187
-	 */
188
-	public function isUpgradePossible($oldVersion, $newVersion, array $allowedPreviousVersions) {
189
-		$version = explode('.', $oldVersion);
190
-		$majorMinor = $version[0] . '.' . $version[1];
191
-
192
-		$currentVendor = $this->config->getAppValue('core', 'vendor', '');
193
-
194
-		// Vendor was not set correctly on install, so we have to white-list known versions
195
-		if ($currentVendor === '' && isset($allowedPreviousVersions['owncloud'][$oldVersion])) {
196
-			$currentVendor = 'owncloud';
197
-		}
198
-
199
-		if ($currentVendor === 'nextcloud') {
200
-			return isset($allowedPreviousVersions[$currentVendor][$majorMinor])
201
-				&& (version_compare($oldVersion, $newVersion, '<=') ||
202
-					$this->config->getSystemValue('debug', false));
203
-		}
204
-
205
-		// Check if the instance can be migrated
206
-		return isset($allowedPreviousVersions[$currentVendor][$majorMinor]) ||
207
-			isset($allowedPreviousVersions[$currentVendor][$oldVersion]);
208
-	}
209
-
210
-	/**
211
-	 * runs the update actions in maintenance mode, does not upgrade the source files
212
-	 * except the main .htaccess file
213
-	 *
214
-	 * @param string $currentVersion current version to upgrade to
215
-	 * @param string $installedVersion previous version from which to upgrade from
216
-	 *
217
-	 * @throws \Exception
218
-	 */
219
-	private function doUpgrade($currentVersion, $installedVersion) {
220
-		// Stop update if the update is over several major versions
221
-		$allowedPreviousVersions = $this->getAllowedPreviousVersions();
222
-		if (!$this->isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersions)) {
223
-			throw new \Exception('Updates between multiple major versions and downgrades are unsupported.');
224
-		}
225
-
226
-		// Update .htaccess files
227
-		try {
228
-			Setup::updateHtaccess();
229
-			Setup::protectDataDirectory();
230
-		} catch (\Exception $e) {
231
-			throw new \Exception($e->getMessage());
232
-		}
233
-
234
-		// create empty file in data dir, so we can later find
235
-		// out that this is indeed an ownCloud data directory
236
-		// (in case it didn't exist before)
237
-		file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
238
-
239
-		// pre-upgrade repairs
240
-		$repair = new Repair(Repair::getBeforeUpgradeRepairSteps(), \OC::$server->getEventDispatcher());
241
-		$repair->run();
242
-
243
-		$this->doCoreUpgrade();
244
-
245
-		try {
246
-			// TODO: replace with the new repair step mechanism https://github.com/owncloud/core/pull/24378
247
-			Setup::installBackgroundJobs();
248
-		} catch (\Exception $e) {
249
-			throw new \Exception($e->getMessage());
250
-		}
251
-
252
-		// update all shipped apps
253
-		$this->checkAppsRequirements();
254
-		$this->doAppUpgrade();
255
-
256
-		// Update the appfetchers version so it downloads the correct list from the appstore
257
-		\OC::$server->getAppFetcher()->setVersion($currentVersion);
258
-
259
-		// upgrade appstore apps
260
-		$this->upgradeAppStoreApps(\OC::$server->getAppManager()->getInstalledApps());
261
-		$autoDisabledApps = \OC::$server->getAppManager()->getAutoDisabledApps();
262
-		$this->upgradeAppStoreApps($autoDisabledApps, true);
263
-
264
-		// install new shipped apps on upgrade
265
-		OC_App::loadApps(['authentication']);
266
-		$errors = Installer::installShippedApps(true);
267
-		foreach ($errors as $appId => $exception) {
268
-			/** @var \Exception $exception */
269
-			$this->log->logException($exception, ['app' => $appId]);
270
-			$this->emit('\OC\Updater', 'failure', [$appId . ': ' . $exception->getMessage()]);
271
-		}
272
-
273
-		// post-upgrade repairs
274
-		$repair = new Repair(Repair::getRepairSteps(), \OC::$server->getEventDispatcher());
275
-		$repair->run();
276
-
277
-		//Invalidate update feed
278
-		$this->config->setAppValue('core', 'lastupdatedat', 0);
279
-
280
-		// Check for code integrity if not disabled
281
-		if (\OC::$server->getIntegrityCodeChecker()->isCodeCheckEnforced()) {
282
-			$this->emit('\OC\Updater', 'startCheckCodeIntegrity');
283
-			$this->checker->runInstanceVerification();
284
-			$this->emit('\OC\Updater', 'finishedCheckCodeIntegrity');
285
-		}
286
-
287
-		// only set the final version if everything went well
288
-		$this->config->setSystemValue('version', implode('.', Util::getVersion()));
289
-		$this->config->setAppValue('core', 'vendor', $this->getVendor());
290
-	}
291
-
292
-	protected function doCoreUpgrade() {
293
-		$this->emit('\OC\Updater', 'dbUpgradeBefore');
294
-
295
-		// execute core migrations
296
-		$ms = new MigrationService('core', \OC::$server->getDatabaseConnection());
297
-		$ms->migrate();
298
-
299
-		$this->emit('\OC\Updater', 'dbUpgrade');
300
-	}
301
-
302
-	/**
303
-	 * upgrades all apps within a major ownCloud upgrade. Also loads "priority"
304
-	 * (types authentication, filesystem, logging, in that order) afterwards.
305
-	 *
306
-	 * @throws NeedsUpdateException
307
-	 */
308
-	protected function doAppUpgrade() {
309
-		$apps = \OC_App::getEnabledApps();
310
-		$priorityTypes = ['authentication', 'filesystem', 'logging'];
311
-		$pseudoOtherType = 'other';
312
-		$stacks = [$pseudoOtherType => []];
313
-
314
-		foreach ($apps as $appId) {
315
-			$priorityType = false;
316
-			foreach ($priorityTypes as $type) {
317
-				if (!isset($stacks[$type])) {
318
-					$stacks[$type] = [];
319
-				}
320
-				if (\OC_App::isType($appId, [$type])) {
321
-					$stacks[$type][] = $appId;
322
-					$priorityType = true;
323
-					break;
324
-				}
325
-			}
326
-			if (!$priorityType) {
327
-				$stacks[$pseudoOtherType][] = $appId;
328
-			}
329
-		}
330
-		foreach ($stacks as $type => $stack) {
331
-			foreach ($stack as $appId) {
332
-				if (\OC_App::shouldUpgrade($appId)) {
333
-					$this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, \OC_App::getAppVersion($appId)]);
334
-					\OC_App::updateApp($appId);
335
-					$this->emit('\OC\Updater', 'appUpgrade', [$appId, \OC_App::getAppVersion($appId)]);
336
-				}
337
-				if ($type !== $pseudoOtherType) {
338
-					// load authentication, filesystem and logging apps after
339
-					// upgrading them. Other apps my need to rely on modifying
340
-					// user and/or filesystem aspects.
341
-					\OC_App::loadApp($appId);
342
-				}
343
-			}
344
-		}
345
-	}
346
-
347
-	/**
348
-	 * check if the current enabled apps are compatible with the current
349
-	 * ownCloud version. disable them if not.
350
-	 * This is important if you upgrade ownCloud and have non ported 3rd
351
-	 * party apps installed.
352
-	 *
353
-	 * @return array
354
-	 * @throws \Exception
355
-	 */
356
-	private function checkAppsRequirements() {
357
-		$isCoreUpgrade = $this->isCodeUpgrade();
358
-		$apps = OC_App::getEnabledApps();
359
-		$version = implode('.', Util::getVersion());
360
-		$disabledApps = [];
361
-		$appManager = \OC::$server->getAppManager();
362
-		foreach ($apps as $app) {
363
-			// check if the app is compatible with this version of ownCloud
364
-			$info = OC_App::getAppInfo($app);
365
-			if ($info === null || !OC_App::isAppCompatible($version, $info)) {
366
-				if ($appManager->isShipped($app)) {
367
-					throw new \UnexpectedValueException('The files of the app "' . $app . '" were not correctly replaced before running the update');
368
-				}
369
-				\OC::$server->getAppManager()->disableApp($app, true);
370
-				$this->emit('\OC\Updater', 'incompatibleAppDisabled', [$app]);
371
-			}
372
-			// no need to disable any app in case this is a non-core upgrade
373
-			if (!$isCoreUpgrade) {
374
-				continue;
375
-			}
376
-			// shipped apps will remain enabled
377
-			if ($appManager->isShipped($app)) {
378
-				continue;
379
-			}
380
-			// authentication and session apps will remain enabled as well
381
-			if (OC_App::isType($app, ['session', 'authentication'])) {
382
-				continue;
383
-			}
384
-		}
385
-		return $disabledApps;
386
-	}
387
-
388
-	/**
389
-	 * @return bool
390
-	 */
391
-	private function isCodeUpgrade() {
392
-		$installedVersion = $this->config->getSystemValue('version', '0.0.0');
393
-		$currentVersion = implode('.', Util::getVersion());
394
-		if (version_compare($currentVersion, $installedVersion, '>')) {
395
-			return true;
396
-		}
397
-		return false;
398
-	}
399
-
400
-	/**
401
-	 * @param array $disabledApps
402
-	 * @param bool $reenable
403
-	 * @throws \Exception
404
-	 */
405
-	private function upgradeAppStoreApps(array $disabledApps, $reenable = false) {
406
-		foreach ($disabledApps as $app) {
407
-			try {
408
-				$this->emit('\OC\Updater', 'checkAppStoreAppBefore', [$app]);
409
-				if ($this->installer->isUpdateAvailable($app)) {
410
-					$this->emit('\OC\Updater', 'upgradeAppStoreApp', [$app]);
411
-					$this->installer->updateAppstoreApp($app);
412
-				}
413
-				$this->emit('\OC\Updater', 'checkAppStoreApp', [$app]);
414
-
415
-				if ($reenable) {
416
-					$ocApp = new \OC_App();
417
-					$ocApp->enable($app);
418
-				}
419
-			} catch (\Exception $ex) {
420
-				$this->log->logException($ex, ['app' => 'core']);
421
-			}
422
-		}
423
-	}
424
-
425
-	/**
426
-	 * Forward messages emitted by the repair routine
427
-	 */
428
-	private function emitRepairEvents() {
429
-		$dispatcher = \OC::$server->getEventDispatcher();
430
-		$dispatcher->addListener('\OC\Repair::warning', function ($event) {
431
-			if ($event instanceof GenericEvent) {
432
-				$this->emit('\OC\Updater', 'repairWarning', $event->getArguments());
433
-			}
434
-		});
435
-		$dispatcher->addListener('\OC\Repair::error', function ($event) {
436
-			if ($event instanceof GenericEvent) {
437
-				$this->emit('\OC\Updater', 'repairError', $event->getArguments());
438
-			}
439
-		});
440
-		$dispatcher->addListener('\OC\Repair::info', function ($event) {
441
-			if ($event instanceof GenericEvent) {
442
-				$this->emit('\OC\Updater', 'repairInfo', $event->getArguments());
443
-			}
444
-		});
445
-		$dispatcher->addListener('\OC\Repair::step', function ($event) {
446
-			if ($event instanceof GenericEvent) {
447
-				$this->emit('\OC\Updater', 'repairStep', $event->getArguments());
448
-			}
449
-		});
450
-	}
451
-
452
-	private function logAllEvents() {
453
-		$log = $this->log;
454
-
455
-		$dispatcher = \OC::$server->getEventDispatcher();
456
-		$dispatcher->addListener('\OC\DB\Migrator::executeSql', function ($event) use ($log) {
457
-			if (!$event instanceof GenericEvent) {
458
-				return;
459
-			}
460
-			$log->info('\OC\DB\Migrator::executeSql: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
461
-		});
462
-		$dispatcher->addListener('\OC\DB\Migrator::checkTable', function ($event) use ($log) {
463
-			if (!$event instanceof GenericEvent) {
464
-				return;
465
-			}
466
-			$log->info('\OC\DB\Migrator::checkTable: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
467
-		});
468
-
469
-		$repairListener = function ($event) use ($log) {
470
-			if (!$event instanceof GenericEvent) {
471
-				return;
472
-			}
473
-			switch ($event->getSubject()) {
474
-				case '\OC\Repair::startProgress':
475
-					$log->info('\OC\Repair::startProgress: Starting ... ' . $event->getArgument(1) .  ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
476
-					break;
477
-				case '\OC\Repair::advance':
478
-					$desc = $event->getArgument(1);
479
-					if (empty($desc)) {
480
-						$desc = '';
481
-					}
482
-					$log->info('\OC\Repair::advance: ' . $desc . ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
483
-
484
-					break;
485
-				case '\OC\Repair::finishProgress':
486
-					$log->info('\OC\Repair::finishProgress', ['app' => 'updater']);
487
-					break;
488
-				case '\OC\Repair::step':
489
-					$log->info('\OC\Repair::step: Repair step: ' . $event->getArgument(0), ['app' => 'updater']);
490
-					break;
491
-				case '\OC\Repair::info':
492
-					$log->info('\OC\Repair::info: Repair info: ' . $event->getArgument(0), ['app' => 'updater']);
493
-					break;
494
-				case '\OC\Repair::warning':
495
-					$log->warning('\OC\Repair::warning: Repair warning: ' . $event->getArgument(0), ['app' => 'updater']);
496
-					break;
497
-				case '\OC\Repair::error':
498
-					$log->error('\OC\Repair::error: Repair error: ' . $event->getArgument(0), ['app' => 'updater']);
499
-					break;
500
-			}
501
-		};
502
-
503
-		$dispatcher->addListener('\OC\Repair::startProgress', $repairListener);
504
-		$dispatcher->addListener('\OC\Repair::advance', $repairListener);
505
-		$dispatcher->addListener('\OC\Repair::finishProgress', $repairListener);
506
-		$dispatcher->addListener('\OC\Repair::step', $repairListener);
507
-		$dispatcher->addListener('\OC\Repair::info', $repairListener);
508
-		$dispatcher->addListener('\OC\Repair::warning', $repairListener);
509
-		$dispatcher->addListener('\OC\Repair::error', $repairListener);
510
-
511
-
512
-		$this->listen('\OC\Updater', 'maintenanceEnabled', function () use ($log) {
513
-			$log->info('\OC\Updater::maintenanceEnabled: Turned on maintenance mode', ['app' => 'updater']);
514
-		});
515
-		$this->listen('\OC\Updater', 'maintenanceDisabled', function () use ($log) {
516
-			$log->info('\OC\Updater::maintenanceDisabled: Turned off maintenance mode', ['app' => 'updater']);
517
-		});
518
-		$this->listen('\OC\Updater', 'maintenanceActive', function () use ($log) {
519
-			$log->info('\OC\Updater::maintenanceActive: Maintenance mode is kept active', ['app' => 'updater']);
520
-		});
521
-		$this->listen('\OC\Updater', 'updateEnd', function ($success) use ($log) {
522
-			if ($success) {
523
-				$log->info('\OC\Updater::updateEnd: Update successful', ['app' => 'updater']);
524
-			} else {
525
-				$log->error('\OC\Updater::updateEnd: Update failed', ['app' => 'updater']);
526
-			}
527
-		});
528
-		$this->listen('\OC\Updater', 'dbUpgradeBefore', function () use ($log) {
529
-			$log->info('\OC\Updater::dbUpgradeBefore: Updating database schema', ['app' => 'updater']);
530
-		});
531
-		$this->listen('\OC\Updater', 'dbUpgrade', function () use ($log) {
532
-			$log->info('\OC\Updater::dbUpgrade: Updated database', ['app' => 'updater']);
533
-		});
534
-		$this->listen('\OC\Updater', 'dbSimulateUpgradeBefore', function () use ($log) {
535
-			$log->info('\OC\Updater::dbSimulateUpgradeBefore: Checking whether the database schema can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
536
-		});
537
-		$this->listen('\OC\Updater', 'dbSimulateUpgrade', function () use ($log) {
538
-			$log->info('\OC\Updater::dbSimulateUpgrade: Checked database schema update', ['app' => 'updater']);
539
-		});
540
-		$this->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use ($log) {
541
-			$log->info('\OC\Updater::incompatibleAppDisabled: Disabled incompatible app: ' . $app, ['app' => 'updater']);
542
-		});
543
-		$this->listen('\OC\Updater', 'checkAppStoreAppBefore', function ($app) use ($log) {
544
-			$log->info('\OC\Updater::checkAppStoreAppBefore: Checking for update of app "' . $app . '" in appstore', ['app' => 'updater']);
545
-		});
546
-		$this->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($log) {
547
-			$log->info('\OC\Updater::upgradeAppStoreApp: Update app "' . $app . '" from appstore', ['app' => 'updater']);
548
-		});
549
-		$this->listen('\OC\Updater', 'checkAppStoreApp', function ($app) use ($log) {
550
-			$log->info('\OC\Updater::checkAppStoreApp: Checked for update of app "' . $app . '" in appstore', ['app' => 'updater']);
551
-		});
552
-		$this->listen('\OC\Updater', 'appUpgradeCheckBefore', function () use ($log) {
553
-			$log->info('\OC\Updater::appUpgradeCheckBefore: Checking updates of apps', ['app' => 'updater']);
554
-		});
555
-		$this->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($log) {
556
-			$log->info('\OC\Updater::appSimulateUpdate: Checking whether the database schema for <' . $app . '> can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
557
-		});
558
-		$this->listen('\OC\Updater', 'appUpgradeCheck', function () use ($log) {
559
-			$log->info('\OC\Updater::appUpgradeCheck: Checked database schema update for apps', ['app' => 'updater']);
560
-		});
561
-		$this->listen('\OC\Updater', 'appUpgradeStarted', function ($app) use ($log) {
562
-			$log->info('\OC\Updater::appUpgradeStarted: Updating <' . $app . '> ...', ['app' => 'updater']);
563
-		});
564
-		$this->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($log) {
565
-			$log->info('\OC\Updater::appUpgrade: Updated <' . $app . '> to ' . $version, ['app' => 'updater']);
566
-		});
567
-		$this->listen('\OC\Updater', 'failure', function ($message) use ($log) {
568
-			$log->error('\OC\Updater::failure: ' . $message, ['app' => 'updater']);
569
-		});
570
-		$this->listen('\OC\Updater', 'setDebugLogLevel', function () use ($log) {
571
-			$log->info('\OC\Updater::setDebugLogLevel: Set log level to debug', ['app' => 'updater']);
572
-		});
573
-		$this->listen('\OC\Updater', 'resetLogLevel', function ($logLevel, $logLevelName) use ($log) {
574
-			$log->info('\OC\Updater::resetLogLevel: Reset log level to ' . $logLevelName . '(' . $logLevel . ')', ['app' => 'updater']);
575
-		});
576
-		$this->listen('\OC\Updater', 'startCheckCodeIntegrity', function () use ($log) {
577
-			$log->info('\OC\Updater::startCheckCodeIntegrity: Starting code integrity check...', ['app' => 'updater']);
578
-		});
579
-		$this->listen('\OC\Updater', 'finishedCheckCodeIntegrity', function () use ($log) {
580
-			$log->info('\OC\Updater::finishedCheckCodeIntegrity: Finished code integrity check', ['app' => 'updater']);
581
-		});
582
-	}
59
+    /** @var ILogger $log */
60
+    private $log;
61
+
62
+    /** @var IConfig */
63
+    private $config;
64
+
65
+    /** @var Checker */
66
+    private $checker;
67
+
68
+    /** @var Installer */
69
+    private $installer;
70
+
71
+    private $logLevelNames = [
72
+        0 => 'Debug',
73
+        1 => 'Info',
74
+        2 => 'Warning',
75
+        3 => 'Error',
76
+        4 => 'Fatal',
77
+    ];
78
+
79
+    /**
80
+     * @param IConfig $config
81
+     * @param Checker $checker
82
+     * @param ILogger $log
83
+     * @param Installer $installer
84
+     */
85
+    public function __construct(IConfig $config,
86
+                                Checker $checker,
87
+                                ILogger $log = null,
88
+                                Installer $installer) {
89
+        $this->log = $log;
90
+        $this->config = $config;
91
+        $this->checker = $checker;
92
+        $this->installer = $installer;
93
+    }
94
+
95
+    /**
96
+     * runs the update actions in maintenance mode, does not upgrade the source files
97
+     * except the main .htaccess file
98
+     *
99
+     * @return bool true if the operation succeeded, false otherwise
100
+     */
101
+    public function upgrade() {
102
+        $this->emitRepairEvents();
103
+        $this->logAllEvents();
104
+
105
+        $logLevel = $this->config->getSystemValue('loglevel', ILogger::WARN);
106
+        $this->emit('\OC\Updater', 'setDebugLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
107
+        $this->config->setSystemValue('loglevel', ILogger::DEBUG);
108
+
109
+        $wasMaintenanceModeEnabled = $this->config->getSystemValueBool('maintenance');
110
+
111
+        if (!$wasMaintenanceModeEnabled) {
112
+            $this->config->setSystemValue('maintenance', true);
113
+            $this->emit('\OC\Updater', 'maintenanceEnabled');
114
+        }
115
+
116
+        // Clear CAN_INSTALL file if not on git
117
+        if (\OC_Util::getChannel() !== 'git' && is_file(\OC::$configDir.'/CAN_INSTALL')) {
118
+            if (!unlink(\OC::$configDir . '/CAN_INSTALL')) {
119
+                $this->log->error('Could not cleanup CAN_INSTALL from your config folder. Please remove this file manually.');
120
+            }
121
+        }
122
+
123
+        $installedVersion = $this->config->getSystemValue('version', '0.0.0');
124
+        $currentVersion = implode('.', \OCP\Util::getVersion());
125
+
126
+        $this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, ['app' => 'core']);
127
+
128
+        $success = true;
129
+        try {
130
+            $this->doUpgrade($currentVersion, $installedVersion);
131
+        } catch (HintException $exception) {
132
+            $this->log->logException($exception, ['app' => 'core']);
133
+            $this->emit('\OC\Updater', 'failure', [$exception->getMessage() . ': ' .$exception->getHint()]);
134
+            $success = false;
135
+        } catch (\Exception $exception) {
136
+            $this->log->logException($exception, ['app' => 'core']);
137
+            $this->emit('\OC\Updater', 'failure', [get_class($exception) . ': ' .$exception->getMessage()]);
138
+            $success = false;
139
+        }
140
+
141
+        $this->emit('\OC\Updater', 'updateEnd', [$success]);
142
+
143
+        if (!$wasMaintenanceModeEnabled && $success) {
144
+            $this->config->setSystemValue('maintenance', false);
145
+            $this->emit('\OC\Updater', 'maintenanceDisabled');
146
+        } else {
147
+            $this->emit('\OC\Updater', 'maintenanceActive');
148
+        }
149
+
150
+        $this->emit('\OC\Updater', 'resetLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
151
+        $this->config->setSystemValue('loglevel', $logLevel);
152
+        $this->config->setSystemValue('installed', true);
153
+
154
+        return $success;
155
+    }
156
+
157
+    /**
158
+     * Return version from which this version is allowed to upgrade from
159
+     *
160
+     * @return array allowed previous versions per vendor
161
+     */
162
+    private function getAllowedPreviousVersions() {
163
+        // this should really be a JSON file
164
+        require \OC::$SERVERROOT . '/version.php';
165
+        /** @var array $OC_VersionCanBeUpgradedFrom */
166
+        return $OC_VersionCanBeUpgradedFrom;
167
+    }
168
+
169
+    /**
170
+     * Return vendor from which this version was published
171
+     *
172
+     * @return string Get the vendor
173
+     */
174
+    private function getVendor() {
175
+        // this should really be a JSON file
176
+        require \OC::$SERVERROOT . '/version.php';
177
+        /** @var string $vendor */
178
+        return (string) $vendor;
179
+    }
180
+
181
+    /**
182
+     * Whether an upgrade to a specified version is possible
183
+     * @param string $oldVersion
184
+     * @param string $newVersion
185
+     * @param array $allowedPreviousVersions
186
+     * @return bool
187
+     */
188
+    public function isUpgradePossible($oldVersion, $newVersion, array $allowedPreviousVersions) {
189
+        $version = explode('.', $oldVersion);
190
+        $majorMinor = $version[0] . '.' . $version[1];
191
+
192
+        $currentVendor = $this->config->getAppValue('core', 'vendor', '');
193
+
194
+        // Vendor was not set correctly on install, so we have to white-list known versions
195
+        if ($currentVendor === '' && isset($allowedPreviousVersions['owncloud'][$oldVersion])) {
196
+            $currentVendor = 'owncloud';
197
+        }
198
+
199
+        if ($currentVendor === 'nextcloud') {
200
+            return isset($allowedPreviousVersions[$currentVendor][$majorMinor])
201
+                && (version_compare($oldVersion, $newVersion, '<=') ||
202
+                    $this->config->getSystemValue('debug', false));
203
+        }
204
+
205
+        // Check if the instance can be migrated
206
+        return isset($allowedPreviousVersions[$currentVendor][$majorMinor]) ||
207
+            isset($allowedPreviousVersions[$currentVendor][$oldVersion]);
208
+    }
209
+
210
+    /**
211
+     * runs the update actions in maintenance mode, does not upgrade the source files
212
+     * except the main .htaccess file
213
+     *
214
+     * @param string $currentVersion current version to upgrade to
215
+     * @param string $installedVersion previous version from which to upgrade from
216
+     *
217
+     * @throws \Exception
218
+     */
219
+    private function doUpgrade($currentVersion, $installedVersion) {
220
+        // Stop update if the update is over several major versions
221
+        $allowedPreviousVersions = $this->getAllowedPreviousVersions();
222
+        if (!$this->isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersions)) {
223
+            throw new \Exception('Updates between multiple major versions and downgrades are unsupported.');
224
+        }
225
+
226
+        // Update .htaccess files
227
+        try {
228
+            Setup::updateHtaccess();
229
+            Setup::protectDataDirectory();
230
+        } catch (\Exception $e) {
231
+            throw new \Exception($e->getMessage());
232
+        }
233
+
234
+        // create empty file in data dir, so we can later find
235
+        // out that this is indeed an ownCloud data directory
236
+        // (in case it didn't exist before)
237
+        file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
238
+
239
+        // pre-upgrade repairs
240
+        $repair = new Repair(Repair::getBeforeUpgradeRepairSteps(), \OC::$server->getEventDispatcher());
241
+        $repair->run();
242
+
243
+        $this->doCoreUpgrade();
244
+
245
+        try {
246
+            // TODO: replace with the new repair step mechanism https://github.com/owncloud/core/pull/24378
247
+            Setup::installBackgroundJobs();
248
+        } catch (\Exception $e) {
249
+            throw new \Exception($e->getMessage());
250
+        }
251
+
252
+        // update all shipped apps
253
+        $this->checkAppsRequirements();
254
+        $this->doAppUpgrade();
255
+
256
+        // Update the appfetchers version so it downloads the correct list from the appstore
257
+        \OC::$server->getAppFetcher()->setVersion($currentVersion);
258
+
259
+        // upgrade appstore apps
260
+        $this->upgradeAppStoreApps(\OC::$server->getAppManager()->getInstalledApps());
261
+        $autoDisabledApps = \OC::$server->getAppManager()->getAutoDisabledApps();
262
+        $this->upgradeAppStoreApps($autoDisabledApps, true);
263
+
264
+        // install new shipped apps on upgrade
265
+        OC_App::loadApps(['authentication']);
266
+        $errors = Installer::installShippedApps(true);
267
+        foreach ($errors as $appId => $exception) {
268
+            /** @var \Exception $exception */
269
+            $this->log->logException($exception, ['app' => $appId]);
270
+            $this->emit('\OC\Updater', 'failure', [$appId . ': ' . $exception->getMessage()]);
271
+        }
272
+
273
+        // post-upgrade repairs
274
+        $repair = new Repair(Repair::getRepairSteps(), \OC::$server->getEventDispatcher());
275
+        $repair->run();
276
+
277
+        //Invalidate update feed
278
+        $this->config->setAppValue('core', 'lastupdatedat', 0);
279
+
280
+        // Check for code integrity if not disabled
281
+        if (\OC::$server->getIntegrityCodeChecker()->isCodeCheckEnforced()) {
282
+            $this->emit('\OC\Updater', 'startCheckCodeIntegrity');
283
+            $this->checker->runInstanceVerification();
284
+            $this->emit('\OC\Updater', 'finishedCheckCodeIntegrity');
285
+        }
286
+
287
+        // only set the final version if everything went well
288
+        $this->config->setSystemValue('version', implode('.', Util::getVersion()));
289
+        $this->config->setAppValue('core', 'vendor', $this->getVendor());
290
+    }
291
+
292
+    protected function doCoreUpgrade() {
293
+        $this->emit('\OC\Updater', 'dbUpgradeBefore');
294
+
295
+        // execute core migrations
296
+        $ms = new MigrationService('core', \OC::$server->getDatabaseConnection());
297
+        $ms->migrate();
298
+
299
+        $this->emit('\OC\Updater', 'dbUpgrade');
300
+    }
301
+
302
+    /**
303
+     * upgrades all apps within a major ownCloud upgrade. Also loads "priority"
304
+     * (types authentication, filesystem, logging, in that order) afterwards.
305
+     *
306
+     * @throws NeedsUpdateException
307
+     */
308
+    protected function doAppUpgrade() {
309
+        $apps = \OC_App::getEnabledApps();
310
+        $priorityTypes = ['authentication', 'filesystem', 'logging'];
311
+        $pseudoOtherType = 'other';
312
+        $stacks = [$pseudoOtherType => []];
313
+
314
+        foreach ($apps as $appId) {
315
+            $priorityType = false;
316
+            foreach ($priorityTypes as $type) {
317
+                if (!isset($stacks[$type])) {
318
+                    $stacks[$type] = [];
319
+                }
320
+                if (\OC_App::isType($appId, [$type])) {
321
+                    $stacks[$type][] = $appId;
322
+                    $priorityType = true;
323
+                    break;
324
+                }
325
+            }
326
+            if (!$priorityType) {
327
+                $stacks[$pseudoOtherType][] = $appId;
328
+            }
329
+        }
330
+        foreach ($stacks as $type => $stack) {
331
+            foreach ($stack as $appId) {
332
+                if (\OC_App::shouldUpgrade($appId)) {
333
+                    $this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, \OC_App::getAppVersion($appId)]);
334
+                    \OC_App::updateApp($appId);
335
+                    $this->emit('\OC\Updater', 'appUpgrade', [$appId, \OC_App::getAppVersion($appId)]);
336
+                }
337
+                if ($type !== $pseudoOtherType) {
338
+                    // load authentication, filesystem and logging apps after
339
+                    // upgrading them. Other apps my need to rely on modifying
340
+                    // user and/or filesystem aspects.
341
+                    \OC_App::loadApp($appId);
342
+                }
343
+            }
344
+        }
345
+    }
346
+
347
+    /**
348
+     * check if the current enabled apps are compatible with the current
349
+     * ownCloud version. disable them if not.
350
+     * This is important if you upgrade ownCloud and have non ported 3rd
351
+     * party apps installed.
352
+     *
353
+     * @return array
354
+     * @throws \Exception
355
+     */
356
+    private function checkAppsRequirements() {
357
+        $isCoreUpgrade = $this->isCodeUpgrade();
358
+        $apps = OC_App::getEnabledApps();
359
+        $version = implode('.', Util::getVersion());
360
+        $disabledApps = [];
361
+        $appManager = \OC::$server->getAppManager();
362
+        foreach ($apps as $app) {
363
+            // check if the app is compatible with this version of ownCloud
364
+            $info = OC_App::getAppInfo($app);
365
+            if ($info === null || !OC_App::isAppCompatible($version, $info)) {
366
+                if ($appManager->isShipped($app)) {
367
+                    throw new \UnexpectedValueException('The files of the app "' . $app . '" were not correctly replaced before running the update');
368
+                }
369
+                \OC::$server->getAppManager()->disableApp($app, true);
370
+                $this->emit('\OC\Updater', 'incompatibleAppDisabled', [$app]);
371
+            }
372
+            // no need to disable any app in case this is a non-core upgrade
373
+            if (!$isCoreUpgrade) {
374
+                continue;
375
+            }
376
+            // shipped apps will remain enabled
377
+            if ($appManager->isShipped($app)) {
378
+                continue;
379
+            }
380
+            // authentication and session apps will remain enabled as well
381
+            if (OC_App::isType($app, ['session', 'authentication'])) {
382
+                continue;
383
+            }
384
+        }
385
+        return $disabledApps;
386
+    }
387
+
388
+    /**
389
+     * @return bool
390
+     */
391
+    private function isCodeUpgrade() {
392
+        $installedVersion = $this->config->getSystemValue('version', '0.0.0');
393
+        $currentVersion = implode('.', Util::getVersion());
394
+        if (version_compare($currentVersion, $installedVersion, '>')) {
395
+            return true;
396
+        }
397
+        return false;
398
+    }
399
+
400
+    /**
401
+     * @param array $disabledApps
402
+     * @param bool $reenable
403
+     * @throws \Exception
404
+     */
405
+    private function upgradeAppStoreApps(array $disabledApps, $reenable = false) {
406
+        foreach ($disabledApps as $app) {
407
+            try {
408
+                $this->emit('\OC\Updater', 'checkAppStoreAppBefore', [$app]);
409
+                if ($this->installer->isUpdateAvailable($app)) {
410
+                    $this->emit('\OC\Updater', 'upgradeAppStoreApp', [$app]);
411
+                    $this->installer->updateAppstoreApp($app);
412
+                }
413
+                $this->emit('\OC\Updater', 'checkAppStoreApp', [$app]);
414
+
415
+                if ($reenable) {
416
+                    $ocApp = new \OC_App();
417
+                    $ocApp->enable($app);
418
+                }
419
+            } catch (\Exception $ex) {
420
+                $this->log->logException($ex, ['app' => 'core']);
421
+            }
422
+        }
423
+    }
424
+
425
+    /**
426
+     * Forward messages emitted by the repair routine
427
+     */
428
+    private function emitRepairEvents() {
429
+        $dispatcher = \OC::$server->getEventDispatcher();
430
+        $dispatcher->addListener('\OC\Repair::warning', function ($event) {
431
+            if ($event instanceof GenericEvent) {
432
+                $this->emit('\OC\Updater', 'repairWarning', $event->getArguments());
433
+            }
434
+        });
435
+        $dispatcher->addListener('\OC\Repair::error', function ($event) {
436
+            if ($event instanceof GenericEvent) {
437
+                $this->emit('\OC\Updater', 'repairError', $event->getArguments());
438
+            }
439
+        });
440
+        $dispatcher->addListener('\OC\Repair::info', function ($event) {
441
+            if ($event instanceof GenericEvent) {
442
+                $this->emit('\OC\Updater', 'repairInfo', $event->getArguments());
443
+            }
444
+        });
445
+        $dispatcher->addListener('\OC\Repair::step', function ($event) {
446
+            if ($event instanceof GenericEvent) {
447
+                $this->emit('\OC\Updater', 'repairStep', $event->getArguments());
448
+            }
449
+        });
450
+    }
451
+
452
+    private function logAllEvents() {
453
+        $log = $this->log;
454
+
455
+        $dispatcher = \OC::$server->getEventDispatcher();
456
+        $dispatcher->addListener('\OC\DB\Migrator::executeSql', function ($event) use ($log) {
457
+            if (!$event instanceof GenericEvent) {
458
+                return;
459
+            }
460
+            $log->info('\OC\DB\Migrator::executeSql: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
461
+        });
462
+        $dispatcher->addListener('\OC\DB\Migrator::checkTable', function ($event) use ($log) {
463
+            if (!$event instanceof GenericEvent) {
464
+                return;
465
+            }
466
+            $log->info('\OC\DB\Migrator::checkTable: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
467
+        });
468
+
469
+        $repairListener = function ($event) use ($log) {
470
+            if (!$event instanceof GenericEvent) {
471
+                return;
472
+            }
473
+            switch ($event->getSubject()) {
474
+                case '\OC\Repair::startProgress':
475
+                    $log->info('\OC\Repair::startProgress: Starting ... ' . $event->getArgument(1) .  ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
476
+                    break;
477
+                case '\OC\Repair::advance':
478
+                    $desc = $event->getArgument(1);
479
+                    if (empty($desc)) {
480
+                        $desc = '';
481
+                    }
482
+                    $log->info('\OC\Repair::advance: ' . $desc . ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
483
+
484
+                    break;
485
+                case '\OC\Repair::finishProgress':
486
+                    $log->info('\OC\Repair::finishProgress', ['app' => 'updater']);
487
+                    break;
488
+                case '\OC\Repair::step':
489
+                    $log->info('\OC\Repair::step: Repair step: ' . $event->getArgument(0), ['app' => 'updater']);
490
+                    break;
491
+                case '\OC\Repair::info':
492
+                    $log->info('\OC\Repair::info: Repair info: ' . $event->getArgument(0), ['app' => 'updater']);
493
+                    break;
494
+                case '\OC\Repair::warning':
495
+                    $log->warning('\OC\Repair::warning: Repair warning: ' . $event->getArgument(0), ['app' => 'updater']);
496
+                    break;
497
+                case '\OC\Repair::error':
498
+                    $log->error('\OC\Repair::error: Repair error: ' . $event->getArgument(0), ['app' => 'updater']);
499
+                    break;
500
+            }
501
+        };
502
+
503
+        $dispatcher->addListener('\OC\Repair::startProgress', $repairListener);
504
+        $dispatcher->addListener('\OC\Repair::advance', $repairListener);
505
+        $dispatcher->addListener('\OC\Repair::finishProgress', $repairListener);
506
+        $dispatcher->addListener('\OC\Repair::step', $repairListener);
507
+        $dispatcher->addListener('\OC\Repair::info', $repairListener);
508
+        $dispatcher->addListener('\OC\Repair::warning', $repairListener);
509
+        $dispatcher->addListener('\OC\Repair::error', $repairListener);
510
+
511
+
512
+        $this->listen('\OC\Updater', 'maintenanceEnabled', function () use ($log) {
513
+            $log->info('\OC\Updater::maintenanceEnabled: Turned on maintenance mode', ['app' => 'updater']);
514
+        });
515
+        $this->listen('\OC\Updater', 'maintenanceDisabled', function () use ($log) {
516
+            $log->info('\OC\Updater::maintenanceDisabled: Turned off maintenance mode', ['app' => 'updater']);
517
+        });
518
+        $this->listen('\OC\Updater', 'maintenanceActive', function () use ($log) {
519
+            $log->info('\OC\Updater::maintenanceActive: Maintenance mode is kept active', ['app' => 'updater']);
520
+        });
521
+        $this->listen('\OC\Updater', 'updateEnd', function ($success) use ($log) {
522
+            if ($success) {
523
+                $log->info('\OC\Updater::updateEnd: Update successful', ['app' => 'updater']);
524
+            } else {
525
+                $log->error('\OC\Updater::updateEnd: Update failed', ['app' => 'updater']);
526
+            }
527
+        });
528
+        $this->listen('\OC\Updater', 'dbUpgradeBefore', function () use ($log) {
529
+            $log->info('\OC\Updater::dbUpgradeBefore: Updating database schema', ['app' => 'updater']);
530
+        });
531
+        $this->listen('\OC\Updater', 'dbUpgrade', function () use ($log) {
532
+            $log->info('\OC\Updater::dbUpgrade: Updated database', ['app' => 'updater']);
533
+        });
534
+        $this->listen('\OC\Updater', 'dbSimulateUpgradeBefore', function () use ($log) {
535
+            $log->info('\OC\Updater::dbSimulateUpgradeBefore: Checking whether the database schema can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
536
+        });
537
+        $this->listen('\OC\Updater', 'dbSimulateUpgrade', function () use ($log) {
538
+            $log->info('\OC\Updater::dbSimulateUpgrade: Checked database schema update', ['app' => 'updater']);
539
+        });
540
+        $this->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use ($log) {
541
+            $log->info('\OC\Updater::incompatibleAppDisabled: Disabled incompatible app: ' . $app, ['app' => 'updater']);
542
+        });
543
+        $this->listen('\OC\Updater', 'checkAppStoreAppBefore', function ($app) use ($log) {
544
+            $log->info('\OC\Updater::checkAppStoreAppBefore: Checking for update of app "' . $app . '" in appstore', ['app' => 'updater']);
545
+        });
546
+        $this->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($log) {
547
+            $log->info('\OC\Updater::upgradeAppStoreApp: Update app "' . $app . '" from appstore', ['app' => 'updater']);
548
+        });
549
+        $this->listen('\OC\Updater', 'checkAppStoreApp', function ($app) use ($log) {
550
+            $log->info('\OC\Updater::checkAppStoreApp: Checked for update of app "' . $app . '" in appstore', ['app' => 'updater']);
551
+        });
552
+        $this->listen('\OC\Updater', 'appUpgradeCheckBefore', function () use ($log) {
553
+            $log->info('\OC\Updater::appUpgradeCheckBefore: Checking updates of apps', ['app' => 'updater']);
554
+        });
555
+        $this->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($log) {
556
+            $log->info('\OC\Updater::appSimulateUpdate: Checking whether the database schema for <' . $app . '> can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
557
+        });
558
+        $this->listen('\OC\Updater', 'appUpgradeCheck', function () use ($log) {
559
+            $log->info('\OC\Updater::appUpgradeCheck: Checked database schema update for apps', ['app' => 'updater']);
560
+        });
561
+        $this->listen('\OC\Updater', 'appUpgradeStarted', function ($app) use ($log) {
562
+            $log->info('\OC\Updater::appUpgradeStarted: Updating <' . $app . '> ...', ['app' => 'updater']);
563
+        });
564
+        $this->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($log) {
565
+            $log->info('\OC\Updater::appUpgrade: Updated <' . $app . '> to ' . $version, ['app' => 'updater']);
566
+        });
567
+        $this->listen('\OC\Updater', 'failure', function ($message) use ($log) {
568
+            $log->error('\OC\Updater::failure: ' . $message, ['app' => 'updater']);
569
+        });
570
+        $this->listen('\OC\Updater', 'setDebugLogLevel', function () use ($log) {
571
+            $log->info('\OC\Updater::setDebugLogLevel: Set log level to debug', ['app' => 'updater']);
572
+        });
573
+        $this->listen('\OC\Updater', 'resetLogLevel', function ($logLevel, $logLevelName) use ($log) {
574
+            $log->info('\OC\Updater::resetLogLevel: Reset log level to ' . $logLevelName . '(' . $logLevel . ')', ['app' => 'updater']);
575
+        });
576
+        $this->listen('\OC\Updater', 'startCheckCodeIntegrity', function () use ($log) {
577
+            $log->info('\OC\Updater::startCheckCodeIntegrity: Starting code integrity check...', ['app' => 'updater']);
578
+        });
579
+        $this->listen('\OC\Updater', 'finishedCheckCodeIntegrity', function () use ($log) {
580
+            $log->info('\OC\Updater::finishedCheckCodeIntegrity: Finished code integrity check', ['app' => 'updater']);
581
+        });
582
+    }
583 583
 }
Please login to merge, or discard this patch.
Spacing   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 		$this->logAllEvents();
104 104
 
105 105
 		$logLevel = $this->config->getSystemValue('loglevel', ILogger::WARN);
106
-		$this->emit('\OC\Updater', 'setDebugLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
106
+		$this->emit('\OC\Updater', 'setDebugLogLevel', [$logLevel, $this->logLevelNames[$logLevel]]);
107 107
 		$this->config->setSystemValue('loglevel', ILogger::DEBUG);
108 108
 
109 109
 		$wasMaintenanceModeEnabled = $this->config->getSystemValueBool('maintenance');
@@ -115,7 +115,7 @@  discard block
 block discarded – undo
115 115
 
116 116
 		// Clear CAN_INSTALL file if not on git
117 117
 		if (\OC_Util::getChannel() !== 'git' && is_file(\OC::$configDir.'/CAN_INSTALL')) {
118
-			if (!unlink(\OC::$configDir . '/CAN_INSTALL')) {
118
+			if (!unlink(\OC::$configDir.'/CAN_INSTALL')) {
119 119
 				$this->log->error('Could not cleanup CAN_INSTALL from your config folder. Please remove this file manually.');
120 120
 			}
121 121
 		}
@@ -123,18 +123,18 @@  discard block
 block discarded – undo
123 123
 		$installedVersion = $this->config->getSystemValue('version', '0.0.0');
124 124
 		$currentVersion = implode('.', \OCP\Util::getVersion());
125 125
 
126
-		$this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, ['app' => 'core']);
126
+		$this->log->debug('starting upgrade from '.$installedVersion.' to '.$currentVersion, ['app' => 'core']);
127 127
 
128 128
 		$success = true;
129 129
 		try {
130 130
 			$this->doUpgrade($currentVersion, $installedVersion);
131 131
 		} catch (HintException $exception) {
132 132
 			$this->log->logException($exception, ['app' => 'core']);
133
-			$this->emit('\OC\Updater', 'failure', [$exception->getMessage() . ': ' .$exception->getHint()]);
133
+			$this->emit('\OC\Updater', 'failure', [$exception->getMessage().': '.$exception->getHint()]);
134 134
 			$success = false;
135 135
 		} catch (\Exception $exception) {
136 136
 			$this->log->logException($exception, ['app' => 'core']);
137
-			$this->emit('\OC\Updater', 'failure', [get_class($exception) . ': ' .$exception->getMessage()]);
137
+			$this->emit('\OC\Updater', 'failure', [get_class($exception).': '.$exception->getMessage()]);
138 138
 			$success = false;
139 139
 		}
140 140
 
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
 			$this->emit('\OC\Updater', 'maintenanceActive');
148 148
 		}
149 149
 
150
-		$this->emit('\OC\Updater', 'resetLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
150
+		$this->emit('\OC\Updater', 'resetLogLevel', [$logLevel, $this->logLevelNames[$logLevel]]);
151 151
 		$this->config->setSystemValue('loglevel', $logLevel);
152 152
 		$this->config->setSystemValue('installed', true);
153 153
 
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
 	 */
162 162
 	private function getAllowedPreviousVersions() {
163 163
 		// this should really be a JSON file
164
-		require \OC::$SERVERROOT . '/version.php';
164
+		require \OC::$SERVERROOT.'/version.php';
165 165
 		/** @var array $OC_VersionCanBeUpgradedFrom */
166 166
 		return $OC_VersionCanBeUpgradedFrom;
167 167
 	}
@@ -173,7 +173,7 @@  discard block
 block discarded – undo
173 173
 	 */
174 174
 	private function getVendor() {
175 175
 		// this should really be a JSON file
176
-		require \OC::$SERVERROOT . '/version.php';
176
+		require \OC::$SERVERROOT.'/version.php';
177 177
 		/** @var string $vendor */
178 178
 		return (string) $vendor;
179 179
 	}
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
 	 */
188 188
 	public function isUpgradePossible($oldVersion, $newVersion, array $allowedPreviousVersions) {
189 189
 		$version = explode('.', $oldVersion);
190
-		$majorMinor = $version[0] . '.' . $version[1];
190
+		$majorMinor = $version[0].'.'.$version[1];
191 191
 
192 192
 		$currentVendor = $this->config->getAppValue('core', 'vendor', '');
193 193
 
@@ -234,7 +234,7 @@  discard block
 block discarded – undo
234 234
 		// create empty file in data dir, so we can later find
235 235
 		// out that this is indeed an ownCloud data directory
236 236
 		// (in case it didn't exist before)
237
-		file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
237
+		file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
238 238
 
239 239
 		// pre-upgrade repairs
240 240
 		$repair = new Repair(Repair::getBeforeUpgradeRepairSteps(), \OC::$server->getEventDispatcher());
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
 		foreach ($errors as $appId => $exception) {
268 268
 			/** @var \Exception $exception */
269 269
 			$this->log->logException($exception, ['app' => $appId]);
270
-			$this->emit('\OC\Updater', 'failure', [$appId . ': ' . $exception->getMessage()]);
270
+			$this->emit('\OC\Updater', 'failure', [$appId.': '.$exception->getMessage()]);
271 271
 		}
272 272
 
273 273
 		// post-upgrade repairs
@@ -364,7 +364,7 @@  discard block
 block discarded – undo
364 364
 			$info = OC_App::getAppInfo($app);
365 365
 			if ($info === null || !OC_App::isAppCompatible($version, $info)) {
366 366
 				if ($appManager->isShipped($app)) {
367
-					throw new \UnexpectedValueException('The files of the app "' . $app . '" were not correctly replaced before running the update');
367
+					throw new \UnexpectedValueException('The files of the app "'.$app.'" were not correctly replaced before running the update');
368 368
 				}
369 369
 				\OC::$server->getAppManager()->disableApp($app, true);
370 370
 				$this->emit('\OC\Updater', 'incompatibleAppDisabled', [$app]);
@@ -427,22 +427,22 @@  discard block
 block discarded – undo
427 427
 	 */
428 428
 	private function emitRepairEvents() {
429 429
 		$dispatcher = \OC::$server->getEventDispatcher();
430
-		$dispatcher->addListener('\OC\Repair::warning', function ($event) {
430
+		$dispatcher->addListener('\OC\Repair::warning', function($event) {
431 431
 			if ($event instanceof GenericEvent) {
432 432
 				$this->emit('\OC\Updater', 'repairWarning', $event->getArguments());
433 433
 			}
434 434
 		});
435
-		$dispatcher->addListener('\OC\Repair::error', function ($event) {
435
+		$dispatcher->addListener('\OC\Repair::error', function($event) {
436 436
 			if ($event instanceof GenericEvent) {
437 437
 				$this->emit('\OC\Updater', 'repairError', $event->getArguments());
438 438
 			}
439 439
 		});
440
-		$dispatcher->addListener('\OC\Repair::info', function ($event) {
440
+		$dispatcher->addListener('\OC\Repair::info', function($event) {
441 441
 			if ($event instanceof GenericEvent) {
442 442
 				$this->emit('\OC\Updater', 'repairInfo', $event->getArguments());
443 443
 			}
444 444
 		});
445
-		$dispatcher->addListener('\OC\Repair::step', function ($event) {
445
+		$dispatcher->addListener('\OC\Repair::step', function($event) {
446 446
 			if ($event instanceof GenericEvent) {
447 447
 				$this->emit('\OC\Updater', 'repairStep', $event->getArguments());
448 448
 			}
@@ -453,49 +453,49 @@  discard block
 block discarded – undo
453 453
 		$log = $this->log;
454 454
 
455 455
 		$dispatcher = \OC::$server->getEventDispatcher();
456
-		$dispatcher->addListener('\OC\DB\Migrator::executeSql', function ($event) use ($log) {
456
+		$dispatcher->addListener('\OC\DB\Migrator::executeSql', function($event) use ($log) {
457 457
 			if (!$event instanceof GenericEvent) {
458 458
 				return;
459 459
 			}
460
-			$log->info('\OC\DB\Migrator::executeSql: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
460
+			$log->info('\OC\DB\Migrator::executeSql: '.$event->getSubject().' ('.$event->getArgument(0).' of '.$event->getArgument(1).')', ['app' => 'updater']);
461 461
 		});
462
-		$dispatcher->addListener('\OC\DB\Migrator::checkTable', function ($event) use ($log) {
462
+		$dispatcher->addListener('\OC\DB\Migrator::checkTable', function($event) use ($log) {
463 463
 			if (!$event instanceof GenericEvent) {
464 464
 				return;
465 465
 			}
466
-			$log->info('\OC\DB\Migrator::checkTable: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
466
+			$log->info('\OC\DB\Migrator::checkTable: '.$event->getSubject().' ('.$event->getArgument(0).' of '.$event->getArgument(1).')', ['app' => 'updater']);
467 467
 		});
468 468
 
469
-		$repairListener = function ($event) use ($log) {
469
+		$repairListener = function($event) use ($log) {
470 470
 			if (!$event instanceof GenericEvent) {
471 471
 				return;
472 472
 			}
473 473
 			switch ($event->getSubject()) {
474 474
 				case '\OC\Repair::startProgress':
475
-					$log->info('\OC\Repair::startProgress: Starting ... ' . $event->getArgument(1) .  ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
475
+					$log->info('\OC\Repair::startProgress: Starting ... '.$event->getArgument(1).' ('.$event->getArgument(0).')', ['app' => 'updater']);
476 476
 					break;
477 477
 				case '\OC\Repair::advance':
478 478
 					$desc = $event->getArgument(1);
479 479
 					if (empty($desc)) {
480 480
 						$desc = '';
481 481
 					}
482
-					$log->info('\OC\Repair::advance: ' . $desc . ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
482
+					$log->info('\OC\Repair::advance: '.$desc.' ('.$event->getArgument(0).')', ['app' => 'updater']);
483 483
 
484 484
 					break;
485 485
 				case '\OC\Repair::finishProgress':
486 486
 					$log->info('\OC\Repair::finishProgress', ['app' => 'updater']);
487 487
 					break;
488 488
 				case '\OC\Repair::step':
489
-					$log->info('\OC\Repair::step: Repair step: ' . $event->getArgument(0), ['app' => 'updater']);
489
+					$log->info('\OC\Repair::step: Repair step: '.$event->getArgument(0), ['app' => 'updater']);
490 490
 					break;
491 491
 				case '\OC\Repair::info':
492
-					$log->info('\OC\Repair::info: Repair info: ' . $event->getArgument(0), ['app' => 'updater']);
492
+					$log->info('\OC\Repair::info: Repair info: '.$event->getArgument(0), ['app' => 'updater']);
493 493
 					break;
494 494
 				case '\OC\Repair::warning':
495
-					$log->warning('\OC\Repair::warning: Repair warning: ' . $event->getArgument(0), ['app' => 'updater']);
495
+					$log->warning('\OC\Repair::warning: Repair warning: '.$event->getArgument(0), ['app' => 'updater']);
496 496
 					break;
497 497
 				case '\OC\Repair::error':
498
-					$log->error('\OC\Repair::error: Repair error: ' . $event->getArgument(0), ['app' => 'updater']);
498
+					$log->error('\OC\Repair::error: Repair error: '.$event->getArgument(0), ['app' => 'updater']);
499 499
 					break;
500 500
 			}
501 501
 		};
@@ -509,74 +509,74 @@  discard block
 block discarded – undo
509 509
 		$dispatcher->addListener('\OC\Repair::error', $repairListener);
510 510
 
511 511
 
512
-		$this->listen('\OC\Updater', 'maintenanceEnabled', function () use ($log) {
512
+		$this->listen('\OC\Updater', 'maintenanceEnabled', function() use ($log) {
513 513
 			$log->info('\OC\Updater::maintenanceEnabled: Turned on maintenance mode', ['app' => 'updater']);
514 514
 		});
515
-		$this->listen('\OC\Updater', 'maintenanceDisabled', function () use ($log) {
515
+		$this->listen('\OC\Updater', 'maintenanceDisabled', function() use ($log) {
516 516
 			$log->info('\OC\Updater::maintenanceDisabled: Turned off maintenance mode', ['app' => 'updater']);
517 517
 		});
518
-		$this->listen('\OC\Updater', 'maintenanceActive', function () use ($log) {
518
+		$this->listen('\OC\Updater', 'maintenanceActive', function() use ($log) {
519 519
 			$log->info('\OC\Updater::maintenanceActive: Maintenance mode is kept active', ['app' => 'updater']);
520 520
 		});
521
-		$this->listen('\OC\Updater', 'updateEnd', function ($success) use ($log) {
521
+		$this->listen('\OC\Updater', 'updateEnd', function($success) use ($log) {
522 522
 			if ($success) {
523 523
 				$log->info('\OC\Updater::updateEnd: Update successful', ['app' => 'updater']);
524 524
 			} else {
525 525
 				$log->error('\OC\Updater::updateEnd: Update failed', ['app' => 'updater']);
526 526
 			}
527 527
 		});
528
-		$this->listen('\OC\Updater', 'dbUpgradeBefore', function () use ($log) {
528
+		$this->listen('\OC\Updater', 'dbUpgradeBefore', function() use ($log) {
529 529
 			$log->info('\OC\Updater::dbUpgradeBefore: Updating database schema', ['app' => 'updater']);
530 530
 		});
531
-		$this->listen('\OC\Updater', 'dbUpgrade', function () use ($log) {
531
+		$this->listen('\OC\Updater', 'dbUpgrade', function() use ($log) {
532 532
 			$log->info('\OC\Updater::dbUpgrade: Updated database', ['app' => 'updater']);
533 533
 		});
534
-		$this->listen('\OC\Updater', 'dbSimulateUpgradeBefore', function () use ($log) {
534
+		$this->listen('\OC\Updater', 'dbSimulateUpgradeBefore', function() use ($log) {
535 535
 			$log->info('\OC\Updater::dbSimulateUpgradeBefore: Checking whether the database schema can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
536 536
 		});
537
-		$this->listen('\OC\Updater', 'dbSimulateUpgrade', function () use ($log) {
537
+		$this->listen('\OC\Updater', 'dbSimulateUpgrade', function() use ($log) {
538 538
 			$log->info('\OC\Updater::dbSimulateUpgrade: Checked database schema update', ['app' => 'updater']);
539 539
 		});
540
-		$this->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use ($log) {
541
-			$log->info('\OC\Updater::incompatibleAppDisabled: Disabled incompatible app: ' . $app, ['app' => 'updater']);
540
+		$this->listen('\OC\Updater', 'incompatibleAppDisabled', function($app) use ($log) {
541
+			$log->info('\OC\Updater::incompatibleAppDisabled: Disabled incompatible app: '.$app, ['app' => 'updater']);
542 542
 		});
543
-		$this->listen('\OC\Updater', 'checkAppStoreAppBefore', function ($app) use ($log) {
544
-			$log->info('\OC\Updater::checkAppStoreAppBefore: Checking for update of app "' . $app . '" in appstore', ['app' => 'updater']);
543
+		$this->listen('\OC\Updater', 'checkAppStoreAppBefore', function($app) use ($log) {
544
+			$log->info('\OC\Updater::checkAppStoreAppBefore: Checking for update of app "'.$app.'" in appstore', ['app' => 'updater']);
545 545
 		});
546
-		$this->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($log) {
547
-			$log->info('\OC\Updater::upgradeAppStoreApp: Update app "' . $app . '" from appstore', ['app' => 'updater']);
546
+		$this->listen('\OC\Updater', 'upgradeAppStoreApp', function($app) use ($log) {
547
+			$log->info('\OC\Updater::upgradeAppStoreApp: Update app "'.$app.'" from appstore', ['app' => 'updater']);
548 548
 		});
549
-		$this->listen('\OC\Updater', 'checkAppStoreApp', function ($app) use ($log) {
550
-			$log->info('\OC\Updater::checkAppStoreApp: Checked for update of app "' . $app . '" in appstore', ['app' => 'updater']);
549
+		$this->listen('\OC\Updater', 'checkAppStoreApp', function($app) use ($log) {
550
+			$log->info('\OC\Updater::checkAppStoreApp: Checked for update of app "'.$app.'" in appstore', ['app' => 'updater']);
551 551
 		});
552
-		$this->listen('\OC\Updater', 'appUpgradeCheckBefore', function () use ($log) {
552
+		$this->listen('\OC\Updater', 'appUpgradeCheckBefore', function() use ($log) {
553 553
 			$log->info('\OC\Updater::appUpgradeCheckBefore: Checking updates of apps', ['app' => 'updater']);
554 554
 		});
555
-		$this->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($log) {
556
-			$log->info('\OC\Updater::appSimulateUpdate: Checking whether the database schema for <' . $app . '> can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
555
+		$this->listen('\OC\Updater', 'appSimulateUpdate', function($app) use ($log) {
556
+			$log->info('\OC\Updater::appSimulateUpdate: Checking whether the database schema for <'.$app.'> can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
557 557
 		});
558
-		$this->listen('\OC\Updater', 'appUpgradeCheck', function () use ($log) {
558
+		$this->listen('\OC\Updater', 'appUpgradeCheck', function() use ($log) {
559 559
 			$log->info('\OC\Updater::appUpgradeCheck: Checked database schema update for apps', ['app' => 'updater']);
560 560
 		});
561
-		$this->listen('\OC\Updater', 'appUpgradeStarted', function ($app) use ($log) {
562
-			$log->info('\OC\Updater::appUpgradeStarted: Updating <' . $app . '> ...', ['app' => 'updater']);
561
+		$this->listen('\OC\Updater', 'appUpgradeStarted', function($app) use ($log) {
562
+			$log->info('\OC\Updater::appUpgradeStarted: Updating <'.$app.'> ...', ['app' => 'updater']);
563 563
 		});
564
-		$this->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($log) {
565
-			$log->info('\OC\Updater::appUpgrade: Updated <' . $app . '> to ' . $version, ['app' => 'updater']);
564
+		$this->listen('\OC\Updater', 'appUpgrade', function($app, $version) use ($log) {
565
+			$log->info('\OC\Updater::appUpgrade: Updated <'.$app.'> to '.$version, ['app' => 'updater']);
566 566
 		});
567
-		$this->listen('\OC\Updater', 'failure', function ($message) use ($log) {
568
-			$log->error('\OC\Updater::failure: ' . $message, ['app' => 'updater']);
567
+		$this->listen('\OC\Updater', 'failure', function($message) use ($log) {
568
+			$log->error('\OC\Updater::failure: '.$message, ['app' => 'updater']);
569 569
 		});
570
-		$this->listen('\OC\Updater', 'setDebugLogLevel', function () use ($log) {
570
+		$this->listen('\OC\Updater', 'setDebugLogLevel', function() use ($log) {
571 571
 			$log->info('\OC\Updater::setDebugLogLevel: Set log level to debug', ['app' => 'updater']);
572 572
 		});
573
-		$this->listen('\OC\Updater', 'resetLogLevel', function ($logLevel, $logLevelName) use ($log) {
574
-			$log->info('\OC\Updater::resetLogLevel: Reset log level to ' . $logLevelName . '(' . $logLevel . ')', ['app' => 'updater']);
573
+		$this->listen('\OC\Updater', 'resetLogLevel', function($logLevel, $logLevelName) use ($log) {
574
+			$log->info('\OC\Updater::resetLogLevel: Reset log level to '.$logLevelName.'('.$logLevel.')', ['app' => 'updater']);
575 575
 		});
576
-		$this->listen('\OC\Updater', 'startCheckCodeIntegrity', function () use ($log) {
576
+		$this->listen('\OC\Updater', 'startCheckCodeIntegrity', function() use ($log) {
577 577
 			$log->info('\OC\Updater::startCheckCodeIntegrity: Starting code integrity check...', ['app' => 'updater']);
578 578
 		});
579
-		$this->listen('\OC\Updater', 'finishedCheckCodeIntegrity', function () use ($log) {
579
+		$this->listen('\OC\Updater', 'finishedCheckCodeIntegrity', function() use ($log) {
580 580
 			$log->info('\OC\Updater::finishedCheckCodeIntegrity: Finished code integrity check', ['app' => 'updater']);
581 581
 		});
582 582
 	}
Please login to merge, or discard this patch.