Completed
Push — master ( dba968...9e87bf )
by Maxence
02:27
created

Live::displayResult()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 53

Duplication

Lines 53
Ratio 100 %

Importance

Changes 0
Metric Value
dl 53
loc 53
rs 9.0254
c 0
b 0
f 0
cc 4
nc 4
nop 1

How to fix   Long Method   

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
2
/**
3
 * FullTextSearch - Full text search framework for Nextcloud
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2018
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\FullTextSearch\Command;
28
29
use Exception;
30
use OCA\FullTextSearch\Exceptions\InterruptException;
31
use OCA\FullTextSearch\Exceptions\TickDoesNotExistException;
32
use OCA\FullTextSearch\Model\ExtendedBase;
33
use OCA\FullTextSearch\Model\Runner;
34
use OCA\FullTextSearch\Model\Index as ModelIndex;
35
use OCA\FullTextSearch\Service\CliService;
36
use OCA\FullTextSearch\Service\ConfigService;
37
use OCA\FullTextSearch\Service\IndexService;
38
use OCA\FullTextSearch\Service\MiscService;
39
use OCA\FullTextSearch\Service\PlatformService;
40
use OCA\FullTextSearch\Service\ProviderService;
41
use OCA\FullTextSearch\Service\RunningService;
42
use OCP\IUserManager;
43
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
44
use Symfony\Component\Console\Input\InputInterface;
45
use Symfony\Component\Console\Output\OutputInterface;
46
use Symfony\Component\Console\Terminal;
47
48
49
class Live extends ExtendedBase {
50
51
	const CYCLE_DELAY = 300000;
52
53
	const PANEL_RUN = 'run';
54
	const PANEL_RUN_LINE_MEMORY = 'Memory: %_memory%';
55
56
	const PANEL_INDEX = 'indexing';
57
	const PANEL_INDEX_LINE_HEADER = '┌─ Indexing %_paused% ────';
58
	const PANEL_INDEX_LINE_ACCOUNT = '│ Provider: <info>%providerName:-20s%</info> Account: <info>%userId%</info>';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 112 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
59
	const PANEL_INDEX_LINE_ACTION = '│ Action: <info>%action%</info>';
60
	const PANEL_INDEX_LINE_DOCUMENT = '│ Document: <info>%documentId%</info>';
61
	const PANEL_INDEX_LINE_INFO = '│ Info: <info>%info%</info>';
62
	const PANEL_INDEX_LINE_TITLE = '│ Title: <info>%title%</info>';
63
	const PANEL_INDEX_LINE_CONTENT = '│ Content size: <info>%content%</info>';
64
	const PANEL_INDEX_LINE_PROGRESS = '│ Progress: %documentCurrent:6s%/%documentTotal%';
65
	const PANEL_INDEX_LINE_FOOTER = '└──';
66
67
	const PANEL_RESULT = 'result';
68
	const PANEL_RESULT_LINE_HEADER = '┌─ Results ────';
69
	const PANEL_RESULT_LINE_RESULT = '│ Result: <info>%resultCurrent:6s%</info>/<info>%resultTotal%</info>';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 105 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
70
	const PANEL_RESULT_LINE_INDEX = '│ Index: <info>%resultIndex%</info>';
71
	const PANEL_RESULT_LINE_STATUS = '│ Status: %resultStatusColored%';
72
	const PANEL_RESULT_LINE_MESSAGE1 = '│ Message: <info>%resultMessageA%</info>';
73
	const PANEL_RESULT_LINE_MESSAGE2 = '│ <info>%resultMessageB%</info>';
74
	const PANEL_RESULT_LINE_MESSAGE3 = '│ <info>%resultMessageC%</info>';
75
	const PANEL_RESULT_LINE_FOOTER = '└──';
76
77
	const PANEL_ERRORS = 'errors';
78
	const PANEL_ERRORS_LINE_HEADER = '┌─ Errors ────';
79
	const PANEL_ERRORS_LINE_ERRORS = '│ Error: <comment>%errorCurrent:6s%</comment>/<comment>%errorTotal%</comment>';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 114 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
80
	const PANEL_ERRORS_LINE_ERROR_INDEX = '│ Index: <comment>%errorIndex%</comment>';
81
	const PANEL_ERRORS_LINE_ERROR_EXCEPTION = '│ Exception: <comment>%errorException%</comment>';
82
	const PANEL_ERRORS_LINE_ERROR_MESSAGE1 = '│ Message: <comment>%errorMessageA%</comment>';
83
	const PANEL_ERRORS_LINE_ERROR_MESSAGE2 = '│ <comment>%errorMessageB%</comment>';
84
	const PANEL_ERRORS_LINE_ERROR_MESSAGE3 = '│ <comment>%errorMessageC%</comment>';
85
	const PANEL_ERRORS_LINE_FOOTER = '└──';
86
87
	const PANEL_COMMANDS_ROOT = 'root';
88
	const PANEL_COMMANDS_ROOT_LINE = '## <char>q</char>:quit ## <char>p</char>:pause ';
89
	const PANEL_COMMANDS_PAUSED = 'paused';
90
	const PANEL_COMMANDS_PAUSED_LINE = '## <char>q</char>:quit ## <char>u</char>:unpause ## <char>n</char>:next step';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 115 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
91
	const PANEL_COMMANDS_DONE = 'done';
92
	const PANEL_COMMANDS_DONE_LINE = '## <char>q</char>:quit';
93
	const PANEL_COMMANDS_NAVIGATION = 'navigation';
94
	const PANEL_COMMANDS_ERRORS_LINE = '## <char>f</char>:first error ## <char>h</char>/<char>j</char>:prec/next error ## <char>d</char>:delete error ## <char>l</char>:last error';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 177 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
95
	const PANEL_COMMANDS_RESULTS_LINE = '## <char>x</char>:first result ## <char>c</char>/<char>v</char>:prec/next result ## <char>b</char>:last result';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 150 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
96
97
98
	/** @var IUserManager */
99
	private $userManager;
100
101
	/** @var ConfigService */
102
	private $configService;
103
104
	/** @var CliService */
105
	private $cliService;
106
107
	/** @var RunningService */
108
	private $runningService;
109
110
	/** @var IndexService */
111
	private $indexService;
112
113
	/** @var PlatformService */
114
	private $platformService;
115
116
	/** @var ProviderService */
117
	private $providerService;
118
119
	/** @var MiscService */
120
	private $miscService;
121
122
123
	/** @var Runner */
124
	private $runner;
125
126
	/** @var Terminal */
127
	private $terminal;
128
129
	/** @var array */
130
	private $errors = [];
131
132
	/** @var bool */
133
	private $navigateLastError = true;
134
135
	/** @var array */
136
	private $results = [];
137
138
	/** @var bool */
139
	private $navigateLastResult = true;
140
141
	/**
142
	 * Live constructor.
143
	 *
144
	 * @param IUserManager $userManager
145
	 * @param RunningService $runningService
146
	 * @param ConfigService $configService
147
	 * @param CliService $cliService
148
	 * @param IndexService $indexService
149
	 * @param PlatformService $platformService
150
	 * @param ProviderService $providerService
151
	 * @param MiscService $miscService
152
	 */
153
	public function __construct(
154
		IUserManager $userManager, RunningService $runningService, ConfigService $configService,
155
		CliService $cliService, IndexService $indexService, PlatformService $platformService,
156
		ProviderService $providerService, MiscService $miscService
157
	) {
158
		parent::__construct();
159
		$this->userManager = $userManager;
160
161
		$this->runner = new Runner($runningService, 'commandLive');
162
		$this->configService = $configService;
163
		$this->cliService = $cliService;
164
		$this->runningService = $runningService;
165
		$this->indexService = $indexService;
166
		$this->platformService = $platformService;
167
		$this->providerService = $providerService;
168
		$this->miscService = $miscService;
169
	}
170
171
172
	/**
173
	 *
174
	 */
175
	protected function configure() {
176
		parent::configure();
177
		$this->setName('fulltextsearch:live')
178
			 ->setDescription('Index files');
179
	}
180
181
182
	/**
183
	 * @param InputInterface $input
184
	 * @param OutputInterface $output
185
	 *
186
	 * @return int|null|void
187
	 * @throws Exception
188
	 */
189
	protected function execute(InputInterface $input, OutputInterface $output) {
190
191
		if ($this->configService->getCloudVersion() < 14) {
192
			throw new Exception('This feature is only available on Nextcloud 14 or newer');
193
		}
194
195
		/** do not get stuck while waiting interactive input */
196
		readline_callback_handler_install(
197
			'', function() {
198
		}
199
		);
200
		stream_set_blocking(STDIN, false);
201
202
		$this->terminal = new Terminal();
203
204
		$outputStyle = new OutputFormatterStyle('white', 'black', ['bold']);
205
		$output->getFormatter()
206
			   ->setStyle('char', $outputStyle);
207
208
		$this->runner = new Runner($this->runningService, 'commandIndex', ['nextStep' => 'n']);
209
		$this->runner->onKeyPress([$this, 'onKeyPressed']);
210
		$this->runner->onNewIndexError([$this, 'onNewIndexError']);
211
		$this->runner->onNewIndexResult([$this, 'onNewIndexResult']);
212
213
214
		$this->indexService->setRunner($this->runner);
215
		$this->cliService->setRunner($this->runner);
216
217
		$this->generatePanels();
218
219
220
		try {
221
			$this->runner->sourceIsCommandLine($this, $output);
222
			$this->runner->start();
223
224
			$this->cliService->runDisplay($output);
225
			$this->generateIndexErrors();
226
			$this->displayError();
227
			$this->displayResult();
228
229
			$this->liveCycle();
230
231
		} catch (Exception $e) {
232
			$this->runner->exception($e->getMessage(), true);
0 ignored issues
show
Deprecated Code introduced by
The method OCA\FullTextSearch\Model\Runner::exception() has been deprecated with message: - verifier l'interet !?

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
233
			throw $e;
234
		}
235
236
		$this->runner->stop();
237
	}
238
239
240
	/**
241
	 * @throws Exception
242
	 * @throws InterruptException
243
	 * @throws TickDoesNotExistException
244
	 */
245
	private function liveCycle() {
246
247
		$platform = $this->platformService->getPlatform();
248
		$platform->setRunner($this->runner);
249
250
		while (true) {
251
252
			$indexes = $this->indexService->getQueuedIndexes();
253
254 View Code Duplication
			foreach ($indexes as $index) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
255
				$this->runner->updateAction('indexing');
256
257
				try {
258
					$provider = $this->providerService->getProvider($index->getProviderId());
259
					$provider->setRunner($this->runner);
260
					$this->indexService->updateDocument($platform, $provider, $index);
261
				} catch (Exception $e) {
262
					$this->runner->exception($e->getMessage(), false);
0 ignored issues
show
Deprecated Code introduced by
The method OCA\FullTextSearch\Model\Runner::exception() has been deprecated with message: - verifier l'interet !?

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
263
					// TODO - upgrade error number - after too many errors, delete index
264
					// TODO - do not count error if elasticsearch is down.
265
				}
266
			}
267
268
			$this->runner->updateAction('waiting', true);
269
270
			usleep(self::CYCLE_DELAY);
271
		}
272
273
		$this->runner->stop();
274
275
	}
276
277
278
	/**
279
	 * @param $key
280
	 */
281 View Code Duplication
	public function onKeyPressed($key) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
282
		$key = strtolower($key);
283
		if ($key === 'q') {
284
			try {
285
				$this->runner->stop();
286
			} catch (TickDoesNotExistException $e) {
287
				/** we do nohtin' */
288
			}
289
			exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method onKeyPressed() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
290
		}
291
292
		$current = $this->cliService->currentPanel('commands');
293
		if ($current === self::PANEL_COMMANDS_ROOT && $key === 'p') {
294
			$this->cliService->switchPanel('commands', self::PANEL_COMMANDS_PAUSED);
295
			$this->runner->pause(true);
296
		}
297
		if ($current === self::PANEL_COMMANDS_PAUSED && $key === 'u') {
298
			$this->cliService->switchPanel('commands', self::PANEL_COMMANDS_ROOT);
299
			$this->runner->pause(false);
300
		}
301
302
		if ($key === 'x') {
303
			$this->displayResult(-99);
304
		}
305
		if ($key === 'c') {
306
			$this->displayResult(-1);
307
		}
308
		if ($key === 'v') {
309
			$this->displayResult(1);
310
		}
311
		if ($key === 'b') {
312
			$this->displayResult(99);
313
		}
314
315
		if ($key === 'f') {
316
			$this->displayError(-99);
317
		}
318
		if ($key === 'h') {
319
			$this->displayError(-1);
320
		}
321
		if ($key === 'j') {
322
			$this->displayError(1);
323
		}
324
		if ($key === 'l') {
325
			$this->displayError(99);
326
		}
327
		if ($key === 'd') {
328
			$this->deleteError();
329
		}
330
	}
331
332
333
	/**
334
	 * @param array $error
335
	 */
336
	public function onNewIndexError($error) {
337
		$this->errors[] = $error;
338
		$this->displayError();
339
	}
340
341
	/**
342
	 * @param array $result
343
	 */
344
	public function onNewIndexResult($result) {
345
		$this->results[] = $result;
346
		$this->displayResult();
347
	}
348
349
350
	/**
351
	 *
352
	 */
353
	private function generatePanels() {
354
355
		$this->cliService->createPanel(
356
			self::PANEL_RUN,
357
			[
358
				self::PANEL_RUN_LINE_MEMORY
359
			]
360
		);
361
362
		$this->cliService->createPanel(
363
			self::PANEL_INDEX, [
364
								 self::PANEL_INDEX_LINE_HEADER,
365
								 self::PANEL_INDEX_LINE_ACTION,
366
								 self::PANEL_INDEX_LINE_ACCOUNT,
367
								 self::PANEL_INDEX_LINE_DOCUMENT,
368
								 self::PANEL_INDEX_LINE_INFO,
369
								 self::PANEL_INDEX_LINE_TITLE,
370
								 self::PANEL_INDEX_LINE_CONTENT,
371
								 self::PANEL_INDEX_LINE_PROGRESS,
372
								 self::PANEL_INDEX_LINE_FOOTER,
373
							 ]
374
		);
375
376
		$this->cliService->createPanel(
377
			self::PANEL_RESULT, [
378
								  self::PANEL_RESULT_LINE_HEADER,
379
								  self::PANEL_RESULT_LINE_RESULT,
380
								  self::PANEL_RESULT_LINE_INDEX,
381
								  self::PANEL_RESULT_LINE_STATUS,
382
								  self::PANEL_RESULT_LINE_MESSAGE1,
383
								  self::PANEL_RESULT_LINE_MESSAGE2,
384
								  self::PANEL_RESULT_LINE_MESSAGE3,
385
								  self::PANEL_RESULT_LINE_FOOTER,
386
							  ]
387
		);
388
389
		$this->cliService->createPanel(
390
			self::PANEL_ERRORS, [
391
								  self::PANEL_ERRORS_LINE_HEADER,
392
								  self::PANEL_ERRORS_LINE_ERRORS,
393
								  self::PANEL_ERRORS_LINE_ERROR_INDEX,
394
								  self::PANEL_ERRORS_LINE_ERROR_EXCEPTION,
395
								  self::PANEL_ERRORS_LINE_ERROR_MESSAGE1,
396
								  self::PANEL_ERRORS_LINE_ERROR_MESSAGE2,
397
								  self::PANEL_ERRORS_LINE_ERROR_MESSAGE3,
398
								  self::PANEL_ERRORS_LINE_FOOTER,
399
							  ]
400
		);
401
402
		$this->cliService->createPanel(
403
			self::PANEL_COMMANDS_ROOT, [
404
										 self::PANEL_COMMANDS_ROOT_LINE
405
									 ]
406
		);
407
408
		$this->cliService->createPanel(
409
			self::PANEL_COMMANDS_PAUSED, [
410
										   self::PANEL_COMMANDS_PAUSED_LINE
411
									   ]
412
		);
413
414
		$this->cliService->createPanel(
415
			self::PANEL_COMMANDS_NAVIGATION, [
416
											   self::PANEL_COMMANDS_RESULTS_LINE,
417
											   self::PANEL_COMMANDS_ERRORS_LINE
418
										   ]
419
		);
420
421
		$this->cliService->initDisplay();
422
		$this->cliService->displayPanel('run', self::PANEL_RUN);
423
		$this->cliService->displayPanel('indexPanel', self::PANEL_INDEX);
424
		$this->cliService->displayPanel('resultsPanel', self::PANEL_RESULT);
425
		$this->cliService->displayPanel('errorsPanel', self::PANEL_ERRORS);
426
		$this->cliService->displayPanel('navigation', self::PANEL_COMMANDS_NAVIGATION);
427
428
		if ($this->runner->isPaused()) {
429
			$this->cliService->displayPanel('commands', self::PANEL_COMMANDS_PAUSED);
430
		} else {
431
			$this->cliService->displayPanel('commands', self::PANEL_COMMANDS_ROOT);
432
		}
433
434
		$this->runner->setInfoArray(
435
			[
436
				'userId'              => '',
437
				'providerName'        => '',
438
				'_memory'             => '',
439
				'documentId'          => '',
440
				'action'              => '',
441
				'info'                => '',
442
				'title'               => '',
443
				'_paused'             => '',
444
				'resultIndex'         => '',
445
				'resultCurrent'       => '',
446
				'resultTotal'         => '',
447
				'resultMessageA'      => '',
448
				'resultMessageB'      => '',
449
				'resultMessageC'      => '',
450
				'resultStatus'        => '',
451
				'resultStatusColored' => '',
452
				'content'             => '',
453
				'statusColored'       => '',
454
				'progressStatus'      => '',
455
				'errorCurrent'        => '0',
456
				'errorTotal'          => '0',
457
				'errorMessageA'       => '',
458
				'errorMessageB'       => '',
459
				'errorMessageC'       => '',
460
				'errorException'      => '',
461
				'errorIndex'          => ''
462
			]
463
		);
464
	}
465
466
467
	/**
468
	 *
469
	 */
470 View Code Duplication
	private function generateIndexErrors() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
471
		$indexes = $this->indexService->getErrorIndexes();
472
473
		foreach ($indexes as $index) {
474
			foreach ($index->getErrors() as $error) {
475
				$this->errors[] = [
476
					'index'     => $index,
477
					'message'   => $error['message'],
478
					'exception' => $error['exception'],
479
					'severity'  => $error['sev']
480
				];
481
			}
482
483
		}
484
485
	}
486
487
488
	/**
489
	 * @param int $pos
490
	 */
491 View Code Duplication
	private function displayResult($pos = 0) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
492
		$total = sizeof($this->results);
493
494
		if ($total === 0) {
495
			$this->runner->setInfoArray(
496
				[
497
					'resultCurrent' => 0,
498
					'resultTotal'   => 0,
499
				]
500
			);
501
502
			return;
503
		}
504
505
		$current = key($this->results) + 1;
506
		$result = $this->getNavigationResult($pos, ($current === 1), ($current === $total));
507
		$current = key($this->results) + 1;
508
509
		if ($result === false) {
510
			return;
511
		}
512
513
		/** @var ModelIndex $index */
514
		$index = $result['index'];
515
		$resultIndex = '';
516
		if ($index !== null) {
517
			$resultIndex = $index->getProviderId() . ':' . $index->getDocumentId();
518
		}
519
520
521
		$width = $this->terminal->getWidth() - 13;
522
		$message = MiscService::get('message', $result, '');
523
		$msg1 = substr($message, 0, $width);
524
		$msg2 = substr($message, $width, $width + 10);
525
		$msg3 = substr($message, $width + $width + 10, $width + 10);
526
527
528
		$status = MiscService::get('status', $result, '');
529
		$type = MiscService::get('type', $result, '');
530
531
		$this->runner->setInfoArray(
532
			[
533
				'resultCurrent'  => $current,
534
				'resultTotal'    => $total,
535
				'resultMessageA' => trim($msg1),
536
				'resultMessageB' => trim($msg2),
537
				'resultMessageC' => trim($msg3),
538
				'resultStatus'   => $status,
539
				'resultIndex'    => $resultIndex
540
			]
541
		);
542
		$this->runner->setInfoColored('resultStatus', $type);
543
	}
544
545
	/**
546
	 * @param int $pos
547
	 */
548 View Code Duplication
	private function displayError($pos = 0) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
549
		$total = sizeof($this->errors);
550
551
		if ($total === 0) {
552
			$this->runner->setInfoArray(
553
				[
554
					'errorCurrent' => 0,
555
					'errorTotal'   => 0,
556
				]
557
			);
558
559
			return;
560
		}
561
562
		$current = key($this->errors) + 1;
563
		$error = $this->getNavigationError($pos, ($current === 1), ($current === $total));
564
		$current = key($this->errors) + 1;
565
566
		if ($error === false) {
567
			return;
568
		}
569
570
		/** @var ModelIndex $index */
571
		$index = $error['index'];
572
		$errorIndex = '';
573
		if ($index !== null) {
574
			$errorIndex = $index->getProviderId() . ':' . $index->getDocumentId();
575
		}
576
577
		$width = $this->terminal->getWidth() - 13;
578
		$message = MiscService::get('message', $error, '');
579
		$err1 = substr($message, 0, $width);
580
		$err2 = substr($message, $width, $width + 10);
581
		$err3 = substr($message, $width + $width + 10, $width + 10);
582
583
		$this->runner->setInfoArray(
584
			[
585
				'errorCurrent'   => $current,
586
				'errorTotal'     => $total,
587
				'errorMessageA'  => trim($err1),
588
				'errorMessageB'  => trim($err2),
589
				'errorMessageC'  => trim($err3),
590
				'errorException' => MiscService::get('exception', $error, ''),
591
				'errorIndex'     => $errorIndex
592
			]
593
		);
594
	}
595
596
597
	/**
598
	 * @param int $pos
599
	 * @param bool $isFirst
600
	 * @param bool $isLast
601
	 *
602
	 * @return bool|array
603
	 */
604
	private function getNavigationResult($pos, $isFirst, $isLast) {
605
606 View Code Duplication
		if ($pos === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
607
			if ($this->navigateLastResult === true) {
608
				return end($this->results);
609
			} else {
610
				return current($this->results);
611
			}
612
		}
613
614
		$this->navigateLastResult = false;
615
		if ($pos === -99) {
616
			return reset($this->results);
617
		}
618
619
		if ($pos === -1 && !$isFirst) {
620
			return prev($this->results);
621
		}
622
623
		if ($pos === 1 && !$isLast) {
624
			return next($this->results);
625
		}
626
627
		if ($pos === 99) {
628
			$this->navigateLastResult = true;
629
630
			return end($this->results);
631
		}
632
633
		return false;
634
	}
635
636
637
	/**
638
	 * @param int $pos
639
	 * @param bool $isFirst
640
	 * @param bool $isLast
641
	 *
642
	 * @return bool|array
643
	 */
644 View Code Duplication
	private function getNavigationError($pos, $isFirst, $isLast) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
645
646
		if ($pos === 0) {
647
			if ($this->navigateLastError === true) {
648
				return end($this->errors);
649
			} else {
650
				return current($this->errors);
651
			}
652
		}
653
654
		$this->navigateLastError = false;
655
		if ($pos === -99) {
656
			return reset($this->errors);
657
		}
658
659
		if ($pos === -1 && !$isFirst) {
660
			return prev($this->errors);
661
		}
662
663
		if ($pos === 1 && !$isLast) {
664
			return next($this->errors);
665
		}
666
667
		if ($pos === 99) {
668
			$this->navigateLastError = true;
669
670
			return end($this->errors);
671
		}
672
673
		return false;
674
	}
675
676
677
	/**
678
	 *
679
	 */
680 View Code Duplication
	private function deleteError() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
681
		$current = current($this->errors);
682
		if ($current === false) {
683
			return;
684
		}
685
686
		$this->runner->setInfoArray(
687
			[
688
				'errorMessageA'  => '',
689
				'errorMessageB'  => '',
690
				'errorMessageC'  => '',
691
				'errorException' => '',
692
				'errorIndex'     => ''
693
			]
694
		);
695
696
		$pos = key($this->errors);
697
698
		/** @var ModelIndex $index */
699
		$index = $current['index'];
700
		$this->indexService->resetErrorFromIndex($index);
701
702
		$errors = [];
703
		foreach ($this->errors as $error) {
704
			/** @var ModelIndex $errorIndex */
705
			$errorIndex = $error['index'];
706
			if ($index->getProviderId() === $errorIndex->getProviderId()
707
				&& $index->getDocumentId() === $errorIndex->getDocumentId()) {
708
				continue;
709
			}
710
711
			$errors[] = $error;
712
		}
713
714
		$this->errors = $errors;
715
		while (key($this->errors) < $pos) {
716
			if (next($this->errors) === false) {
717
				end($this->errors);
718
				break;
719
			}
720
		}
721
722
		$this->displayError();
723
	}
724
}
725
726
727
728