Completed
Pull Request — master (#551)
by Maxence
02:15
created

CirclesCheck::execute()   C

Complexity

Conditions 11
Paths 37

Size

Total Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 69
rs 6.5296
c 0
b 0
f 0
cc 11
nc 37
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
4
/**
5
 * Circles - Bring cloud-users closer together.
6
 *
7
 * This file is licensed under the Affero General Public License version 3 or
8
 * later. See the COPYING file.
9
 *
10
 * @author Maxence Lange <[email protected]>
11
 * @copyright 2017
12
 * @license GNU AGPL version 3 or any later version
13
 *
14
 * This program is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License as
16
 * published by the Free Software Foundation, either version 3 of the
17
 * License, or (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26
 *
27
 */
28
29
30
namespace OCA\Circles\Command;
31
32
use daita\MySmallPhpTools\Exceptions\RequestNetworkException;
33
use daita\MySmallPhpTools\Model\Nextcloud\nc22\NC22Request;
34
use daita\MySmallPhpTools\Model\Request;
35
use daita\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Request;
36
use daita\MySmallPhpTools\Traits\TArrayTools;
37
use Exception;
38
use OC\Core\Command\Base;
39
use OCA\Circles\AppInfo\Application;
40
use OCA\Circles\AppInfo\Capabilities;
41
use OCA\Circles\Model\GlobalScale\GSEvent;
42
use OCA\Circles\Service\ConfigService;
43
use OCA\Circles\Service\GlobalScaleService;
44
use OCA\Circles\Service\GSUpstreamService;
45
use Symfony\Component\Console\Input\InputInterface;
46
use Symfony\Component\Console\Input\InputOption;
47
use Symfony\Component\Console\Output\OutputInterface;
48
use Symfony\Component\Console\Question\ConfirmationQuestion;
49
use Symfony\Component\Process\Process;
50
51
52
/**
53
 * Class CirclesCheck
54
 *
55
 * @package OCA\Circles\Command
56
 */
57
class CirclesCheck extends Base {
58
59
60
	use TArrayTools;
61
	use TNC22Request;
62
63
64
	/** @var Capabilities */
65
	private $capabilities;
66
67
	/** @var GlobalScaleService */
68
	private $globalScaleService;
69
70
	/** @var GSUpstreamService */
71
	private $gsUpstreamService;
72
73
	/** @var ConfigService */
74
	private $configService;
75
76
77
	/** @var int */
78
	private $delay = 5;
79
80
	/** @var array */
81
	private $sessions = [];
82
83
	/**
84
	 * CirclesCheck constructor.
85
	 *
86
	 * @param Capabilities $capabilities
87
	 * @param GlobalScaleService $globalScaleService
88
	 * @param GSUpstreamService $gsUpstreamService
89
	 * @param ConfigService $configService
90
	 */
91
	public function __construct(
92
		Capabilities $capabilities, GlobalScaleService $globalScaleService,
93
		GSUpstreamService $gsUpstreamService, ConfigService $configService
94
	) {
95
		parent::__construct();
96
97
		$this->capabilities = $capabilities;
98
		$this->gsUpstreamService = $gsUpstreamService;
99
		$this->globalScaleService = $globalScaleService;
100
		$this->configService = $configService;
101
	}
102
103
104
	protected function configure() {
105
		parent::configure();
106
		$this->setName('circles:check')
107
			 ->setDescription('Checking your configuration')
108
			 ->addOption('delay', 'd', InputOption::VALUE_REQUIRED, 'delay before checking result')
109
			 ->addOption('capabilities', '', InputOption::VALUE_NONE, 'listing app\'s capabilities')
110
			 ->addOption('url', '', InputOption::VALUE_REQUIRED, 'specify a source url', '');
111
	}
112
113
114
	/**
115
	 * @param InputInterface $input
116
	 * @param OutputInterface $output
117
	 *
118
	 * @return int
119
	 * @throws Exception
120
	 */
121
	protected function execute(InputInterface $input, OutputInterface $output): int {
122
		if ($input->getOption('capabilities')) {
123
			$capabilities = $this->getArray('circles', $this->capabilities->getCapabilities());
124
			$output->writeln(json_encode($capabilities, JSON_PRETTY_PRINT));
125
126
			return 0;
127
		}
128
129
		if ($input->getOption('delay')) {
130
			$this->delay = (int)$input->getOption('delay');
131
		}
132
133
		$this->configService->setAppValue(ConfigService::TEST_NC_BASE, '');
134
		$this->configService->setAppValue(ConfigService::TEST_NC_BASE, $input->getOption('url'));
135
136
		if (!$this->testRequest($output, 'GET', 'core.CSRFToken.index')) {
137
			$this->configService->setAppValue(ConfigService::TEST_NC_BASE, '');
138
139
			return 0;
140
		}
141
142
		if (!$this->testRequest(
143
			$output, 'POST', 'circles.EventWrapper.asyncBroadcast',
144
			['token' => 'test-dummy-token']
145
		)) {
146
			$this->configService->setAppValue(ConfigService::TEST_NC_BASE, '');
147
148
			return 0;
149
		}
150
151
		$test = new GSEvent(GSEvent::TEST, true, true);
152
		$test->setAsync(true);
153
		$token = $this->gsUpstreamService->newEvent($test);
154
155
		$output->writeln('- Async request is sent, now waiting ' . $this->delay . ' seconds');
156
		sleep($this->delay);
157
		$output->writeln('- Pause is over, checking results for ' . $token);
158
159
		$wrappers = $this->gsUpstreamService->getEventsByToken($token);
160
161
		$result = [];
162
		$instances = array_merge($this->globalScaleService->getInstances(true));
0 ignored issues
show
Bug introduced by
The method getInstances() does not seem to exist on object<OCA\Circles\Service\GlobalScaleService>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
163
		foreach ($wrappers as $wrapper) {
164
			$result[$wrapper->getInstance()] = $wrapper->getEvent();
165
		}
166
167
		$localLooksGood = false;
168
		foreach ($instances as $instance) {
169
			$output->write($instance . ' ');
170
			if (array_key_exists($instance, $result)
171
				&& $result[$instance]->getResult()
172
									 ->gInt('status') === 1) {
173
				$output->writeln('<info>ok</info>');
174
				if ($this->configService->isLocalInstance($instance)) {
175
					$localLooksGood = true;
176
				}
177
			} else {
178
				$output->writeln('<error>fail</error>');
179
			}
180
		}
181
182
		$this->configService->setAppValue(ConfigService::TEST_NC_BASE, '');
183
184
		if ($localLooksGood) {
185
			$this->saveUrl($input, $output, $input->getOption('url'));
186
		}
187
188
		return 0;
189
	}
190
191
192
	/**
193
	 * @param OutputInterface $o
194
	 * @param string $type
195
	 * @param string $route
196
	 * @param array $args
197
	 *
198
	 * @return bool
199
	 * @throws RequestNetworkException
200
	 */
201
	private function testRequest(OutputInterface $o, string $type, string $route, array $args = []): bool {
202
		$request = new NC22Request('', Request::type($type));
203
		$this->configService->configureRequest($request, $route, $args);
204
		$request->setFollowLocation(false);
205
206
		$o->write('- ' . $type . ' request on ' . $request->getCompleteUrl() . ': ');
207
		$this->doRequest($request);
208
209
		$color = 'error';
210
		$result = $request->getResult();
211
		if ($result->getStatusCode() === 200) {
212
			$color = 'info';
213
		}
214
215
		$o->writeln('<' . $color . '>' . $result->getStatusCode() . '</' . $color . '>');
216
217
		if ($result->getStatusCode() === 200) {
218
			return true;
219
		}
220
221
		return false;
222
	}
223
224
225
	/**
226
	 * @param InputInterface $input
227
	 * @param OutputInterface $output
228
	 * @param string $address
229
	 */
230
	private function saveUrl(InputInterface $input, OutputInterface $output, string $address): void {
231
		if ($address === '') {
232
			return;
233
		}
234
235
		$output->writeln('');
236
		$output->writeln(
237
			'The address <info>' . $address . '</info> seems to reach your local Nextcloud.'
238
		);
239
240
		$helper = $this->getHelper('question');
241
		$output->writeln('');
242
		$question = new ConfirmationQuestion(
243
			'<info>Do you want to store this address in database ?</info> (y/N) ', false, '/^(y|Y)/i'
244
		);
245
246
		if (!$helper->ask($input, $output, $question)) {
247
			$output->writeln('Configuration NOT saved');
248
249
			return;
250
		}
251
252
		$this->configService->setAppValue(ConfigService::FORCE_NC_BASE, $address);
253
		$output->writeln(
254
			'New configuration <info>' . Application::APP_ID . '.' . ConfigService::FORCE_NC_BASE . '=\''
255
			. $address . '\'</info> stored in database'
256
		);
257
	}
258
259
}
260
261