Completed
Push — stable10 ( 65dd17...7321ba )
by Björn
10:16
created

Repair   C

Complexity

Total Complexity 21

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 25

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 182
rs 5
wmc 21
lcom 2
cbo 25

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A run() 0 12 3
B addStep() 0 21 5
B getRepairSteps() 0 24 1
A getExpensiveRepairSteps() 0 5 1
A getBeforeUpgradeRepairSteps() 0 19 3
A emit() 0 6 2
A info() 0 4 1
A warning() 0 4 1
A startProgress() 0 4 1
A advance() 0 4 1
A finishProgress() 0 4 1
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Georg Ehrke <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Lukas Reschke <[email protected]>
9
 * @author Morris Jobke <[email protected]>
10
 * @author Robin Appelman <[email protected]>
11
 * @author Roeland Jago Douma <[email protected]>
12
 * @author Thomas Müller <[email protected]>
13
 * @author Vincent Petry <[email protected]>
14
 *
15
 * @license AGPL-3.0
16
 *
17
 * This code is free software: you can redistribute it and/or modify
18
 * it under the terms of the GNU Affero General Public License, version 3,
19
 * as published by the Free Software Foundation.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License, version 3,
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
28
 *
29
 */
30
31
namespace OC;
32
33
use OC\Repair\AssetCache;
34
use OC\Repair\AvatarPermissions;
35
use OC\Repair\CleanTags;
36
use OC\Repair\Collation;
37
use OC\Repair\DropOldJobs;
38
use OC\Repair\OldGroupMembershipShares;
39
use OC\Repair\RemoveGetETagEntries;
40
use OC\Repair\RemoveOldShares;
41
use OC\Repair\RemoveRootShares;
42
use OC\Repair\SharePropagation;
43
use OC\Repair\SqliteAutoincrement;
44
use OC\Repair\DropOldTables;
45
use OC\Repair\FillETags;
46
use OC\Repair\InnoDB;
47
use OC\Repair\RepairLegacyStorages;
48
use OC\Repair\RepairMimeTypes;
49
use OC\Repair\SearchLuceneTables;
50
use OC\Repair\UpdateOutdatedOcsIds;
51
use OC\Repair\RepairInvalidShares;
52
use OC\Repair\RepairUnmergedShares;
53
use OCP\AppFramework\QueryException;
54
use OCP\Migration\IOutput;
55
use OCP\Migration\IRepairStep;
56
use Symfony\Component\EventDispatcher\EventDispatcher;
57
use Symfony\Component\EventDispatcher\GenericEvent;
58
59
class Repair implements IOutput{
60
	/* @var IRepairStep[] */
61
	private $repairSteps;
62
	/** @var EventDispatcher */
63
	private $dispatcher;
64
	/** @var string */
65
	private $currentStep;
66
67
	/**
68
	 * Creates a new repair step runner
69
	 *
70
	 * @param IRepairStep[] $repairSteps array of RepairStep instances
71
	 * @param EventDispatcher $dispatcher
72
	 */
73
	public function __construct($repairSteps = [], EventDispatcher $dispatcher = null) {
74
		$this->repairSteps = $repairSteps;
75
		$this->dispatcher = $dispatcher;
76
	}
77
78
	/**
79
	 * Run a series of repair steps for common problems
80
	 */
81
	public function run() {
82
		if (count($this->repairSteps) === 0) {
83
			$this->emit('\OC\Repair', 'info', array('No repair steps available'));
84
			return;
85
		}
86
		// run each repair step
87
		foreach ($this->repairSteps as $step) {
88
			$this->currentStep = $step->getName();
89
			$this->emit('\OC\Repair', 'step', [$this->currentStep]);
90
			$step->run($this);
91
		}
92
	}
93
94
	/**
95
	 * Add repair step
96
	 *
97
	 * @param IRepairStep|string $repairStep repair step
98
	 * @throws \Exception
99
	 */
100
	public function addStep($repairStep) {
101
		if (is_string($repairStep)) {
102
			try {
103
				$s = \OC::$server->query($repairStep);
104
			} catch (QueryException $e) {
105
				if (class_exists($repairStep)) {
106
					$s = new $repairStep();
107
				} else {
108
					throw new \Exception("Repair step '$repairStep' is unknown");
109
				}
110
			}
111
112
			if ($s instanceof IRepairStep) {
113
				$this->repairSteps[] = $s;
114
			} else {
115
				throw new \Exception("Repair step '$repairStep' is not of type \\OCP\\Migration\\IRepairStep");
116
			}
117
		} else {
118
			$this->repairSteps[] = $repairStep;
119
		}
120
	}
121
122
	/**
123
	 * Returns the default repair steps to be run on the
124
	 * command line or after an upgrade.
125
	 *
126
	 * @return IRepairStep[]
127
	 */
128
	public static function getRepairSteps() {
129
		return [
130
			new RepairMimeTypes(\OC::$server->getConfig()),
131
			new RepairLegacyStorages(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
132
			new AssetCache(),
133
			new FillETags(\OC::$server->getDatabaseConnection()),
134
			new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()),
135
			new DropOldTables(\OC::$server->getDatabaseConnection()),
136
			new DropOldJobs(\OC::$server->getJobList()),
137
			new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
138
			new UpdateOutdatedOcsIds(\OC::$server->getConfig()),
139
			new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
140
			new SharePropagation(\OC::$server->getConfig()),
141
			new RemoveOldShares(\OC::$server->getDatabaseConnection()),
142
			new AvatarPermissions(\OC::$server->getDatabaseConnection()),
143
			new RemoveRootShares(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getLazyRootFolder()),
144
			new RepairUnmergedShares(
145
				\OC::$server->getConfig(),
146
				\OC::$server->getDatabaseConnection(),
147
				\OC::$server->getUserManager(),
148
				\OC::$server->getGroupManager()
149
			),
150
		];
151
	}
152
153
	/**
154
	 * Returns expensive repair steps to be run on the
155
	 * command line with a special option.
156
	 *
157
	 * @return IRepairStep[]
158
	 */
159
	public static function getExpensiveRepairSteps() {
160
		return [
161
			new OldGroupMembershipShares(\OC::$server->getDatabaseConnection(), \OC::$server->getGroupManager()),
162
		];
163
	}
164
165
	/**
166
	 * Returns the repair steps to be run before an
167
	 * upgrade.
168
	 *
169
	 * @return IRepairStep[]
170
	 */
171
	public static function getBeforeUpgradeRepairSteps() {
172
		$connection = \OC::$server->getDatabaseConnection();
173
		$steps = [
174
			new InnoDB(),
175
			new Collation(\OC::$server->getConfig(), $connection),
0 ignored issues
show
Compatibility introduced by
$connection of type object<OCP\IDBConnection> is not a sub-type of object<OC\DB\Connection>. It seems like you assume a concrete implementation of the interface OCP\IDBConnection to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
176
			new SqliteAutoincrement($connection),
0 ignored issues
show
Compatibility introduced by
$connection of type object<OCP\IDBConnection> is not a sub-type of object<OC\DB\Connection>. It seems like you assume a concrete implementation of the interface OCP\IDBConnection to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
177
			new SearchLuceneTables(),
178
		];
179
180
		//There is no need to delete all previews on every single update
181
		//only 7.0.0 through 7.0.2 generated broken previews
182
		$currentVersion = \OC::$server->getConfig()->getSystemValue('version');
183
		if (version_compare($currentVersion, '7.0.0.0', '>=') &&
184
			version_compare($currentVersion, '7.0.3.4', '<=')) {
185
			$steps[] = new \OC\Repair\Preview();
186
		}
187
188
		return $steps;
189
	}
190
191
	/**
192
	 * @param string $scope
193
	 * @param string $method
194
	 * @param array $arguments
195
	 */
196
	public function emit($scope, $method, array $arguments = []) {
197
		if (!is_null($this->dispatcher)) {
198
			$this->dispatcher->dispatch("$scope::$method",
199
				new GenericEvent("$scope::$method", $arguments));
200
		}
201
	}
202
203
	public function info($string) {
204
		// for now just emit as we did in the past
205
		$this->emit('\OC\Repair', 'info', array($string));
206
	}
207
208
	/**
209
	 * @param string $message
210
	 */
211
	public function warning($message) {
212
		// for now just emit as we did in the past
213
		$this->emit('\OC\Repair', 'warning', [$message]);
214
	}
215
216
	/**
217
	 * @param int $max
218
	 */
219
	public function startProgress($max = 0) {
220
		// for now just emit as we did in the past
221
		$this->emit('\OC\Repair', 'startProgress', [$max, $this->currentStep]);
222
	}
223
224
	/**
225
	 * @param int $step
226
	 * @param string $description
227
	 */
228
	public function advance($step = 1, $description = '') {
229
		// for now just emit as we did in the past
230
		$this->emit('\OC\Repair', 'advance', [$step, $description]);
231
	}
232
233
	/**
234
	 * @param int $max
0 ignored issues
show
Bug introduced by
There is no parameter named $max. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
235
	 */
236
	public function finishProgress() {
237
		// for now just emit as we did in the past
238
		$this->emit('\OC\Repair', 'finishProgress', []);
239
	}
240
}
241