Completed
Push — master ( 4a9cb8...f72f55 )
by Morris
12:46
created

Repair::getRepairSteps()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 21
nc 1
nop 0
dl 0
loc 26
rs 8.8571
c 0
b 0
f 0
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\App\AppStore\Bundles\BundleFetcher;
34
use OC\Repair\CleanTags;
35
use OC\Repair\Collation;
36
use OC\Repair\MoveUpdaterStepFile;
37
use OC\Repair\NC11\CleanPreviews;
38
use OC\Repair\NC11\FixMountStorages;
39
use OC\Repair\NC11\MoveAvatars;
40
use OC\Repair\NC12\InstallCoreBundle;
41
use OC\Repair\NC12\UpdateLanguageCodes;
42
use OC\Repair\OldGroupMembershipShares;
43
use OC\Repair\RemoveRootShares;
44
use OC\Repair\SqliteAutoincrement;
45
use OC\Repair\RepairMimeTypes;
46
use OC\Repair\RepairInvalidShares;
47
use OCP\AppFramework\QueryException;
48
use OCP\Migration\IOutput;
49
use OCP\Migration\IRepairStep;
50
use Symfony\Component\EventDispatcher\EventDispatcher;
51
use Symfony\Component\EventDispatcher\GenericEvent;
52
53
class Repair implements IOutput{
54
	/* @var IRepairStep[] */
55
	private $repairSteps;
56
	/** @var EventDispatcher */
57
	private $dispatcher;
58
	/** @var string */
59
	private $currentStep;
60
61
	/**
62
	 * Creates a new repair step runner
63
	 *
64
	 * @param IRepairStep[] $repairSteps array of RepairStep instances
65
	 * @param EventDispatcher $dispatcher
66
	 */
67
	public function __construct($repairSteps = [], EventDispatcher $dispatcher = null) {
68
		$this->repairSteps = $repairSteps;
69
		$this->dispatcher = $dispatcher;
70
	}
71
72
	/**
73
	 * Run a series of repair steps for common problems
74
	 */
75
	public function run() {
76
		if (count($this->repairSteps) === 0) {
77
			$this->emit('\OC\Repair', 'info', array('No repair steps available'));
78
			return;
79
		}
80
		// run each repair step
81
		foreach ($this->repairSteps as $step) {
82
			$this->currentStep = $step->getName();
83
			$this->emit('\OC\Repair', 'step', [$this->currentStep]);
84
			$step->run($this);
85
		}
86
	}
87
88
	/**
89
	 * Add repair step
90
	 *
91
	 * @param IRepairStep|string $repairStep repair step
92
	 * @throws \Exception
93
	 */
94
	public function addStep($repairStep) {
95
		if (is_string($repairStep)) {
96
			try {
97
				$s = \OC::$server->query($repairStep);
98
			} catch (QueryException $e) {
99
				if (class_exists($repairStep)) {
100
					$s = new $repairStep();
101
				} else {
102
					throw new \Exception("Repair step '$repairStep' is unknown");
103
				}
104
			}
105
106
			if ($s instanceof IRepairStep) {
107
				$this->repairSteps[] = $s;
108
			} else {
109
				throw new \Exception("Repair step '$repairStep' is not of type \\OCP\\Migration\\IRepairStep");
110
			}
111
		} else {
112
			$this->repairSteps[] = $repairStep;
113
		}
114
	}
115
116
	/**
117
	 * Returns the default repair steps to be run on the
118
	 * command line or after an upgrade.
119
	 *
120
	 * @return IRepairStep[]
121
	 */
122
	public static function getRepairSteps() {
123
		return [
124
			new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), \OC::$server->getDatabaseConnection(), false),
125
			new RepairMimeTypes(\OC::$server->getConfig()),
126
			new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()),
127
			new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
128
			new RemoveRootShares(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getLazyRootFolder()),
129
			new MoveUpdaterStepFile(\OC::$server->getConfig()),
130
			new MoveAvatars(
131
				\OC::$server->getJobList(),
132
				\OC::$server->getConfig()
133
			),
134
			new CleanPreviews(
135
				\OC::$server->getJobList(),
136
				\OC::$server->getUserManager(),
137
				\OC::$server->getConfig()
138
			),
139
			new FixMountStorages(\OC::$server->getDatabaseConnection()),
140
			new UpdateLanguageCodes(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig()),
141
			new InstallCoreBundle(
142
				\OC::$server->query(BundleFetcher::class),
143
				\OC::$server->getConfig(),
144
				\OC::$server->query(Installer::class)
145
			)
146
		];
147
	}
148
149
	/**
150
	 * Returns expensive repair steps to be run on the
151
	 * command line with a special option.
152
	 *
153
	 * @return IRepairStep[]
154
	 */
155
	public static function getExpensiveRepairSteps() {
156
		return [
157
			new OldGroupMembershipShares(\OC::$server->getDatabaseConnection(), \OC::$server->getGroupManager()),
158
		];
159
	}
160
161
	/**
162
	 * Returns the repair steps to be run before an
163
	 * upgrade.
164
	 *
165
	 * @return IRepairStep[]
166
	 */
167
	public static function getBeforeUpgradeRepairSteps() {
168
		$connection = \OC::$server->getDatabaseConnection();
169
		$steps = [
170
			new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), $connection, true),
171
			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...
172
		];
173
174
		return $steps;
175
	}
176
177
	/**
178
	 * @param string $scope
179
	 * @param string $method
180
	 * @param array $arguments
181
	 */
182
	public function emit($scope, $method, array $arguments = []) {
183
		if (!is_null($this->dispatcher)) {
184
			$this->dispatcher->dispatch("$scope::$method",
185
				new GenericEvent("$scope::$method", $arguments));
186
		}
187
	}
188
189
	public function info($string) {
190
		// for now just emit as we did in the past
191
		$this->emit('\OC\Repair', 'info', array($string));
192
	}
193
194
	/**
195
	 * @param string $message
196
	 */
197
	public function warning($message) {
198
		// for now just emit as we did in the past
199
		$this->emit('\OC\Repair', 'warning', [$message]);
200
	}
201
202
	/**
203
	 * @param int $max
204
	 */
205
	public function startProgress($max = 0) {
206
		// for now just emit as we did in the past
207
		$this->emit('\OC\Repair', 'startProgress', [$max, $this->currentStep]);
208
	}
209
210
	/**
211
	 * @param int $step
212
	 * @param string $description
213
	 */
214
	public function advance($step = 1, $description = '') {
215
		// for now just emit as we did in the past
216
		$this->emit('\OC\Repair', 'advance', [$step, $description]);
217
	}
218
219
	/**
220
	 * @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...
221
	 */
222
	public function finishProgress() {
223
		// for now just emit as we did in the past
224
		$this->emit('\OC\Repair', 'finishProgress', []);
225
	}
226
}
227