Completed
Push — master ( f0b8b1...988dc2 )
by Maxence
02:48 queued 57s
created

Index::execute()   B

Complexity

Conditions 5
Paths 32

Size

Total Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 74
rs 8.2561
c 0
b 0
f 0
cc 5
nc 32
nop 2

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\TickDoesNotExistException;
31
use OCA\FullTextSearch\IFullTextSearchProvider;
32
use OCA\FullTextSearch\Model\ExtendedBase;
33
use OCA\FullTextSearch\Model\IndexOptions;
34
use OCA\FullTextSearch\Model\Index as ModelIndex;
35
use OCA\FullTextSearch\Model\Runner;
36
use OCA\FullTextSearch\Service\CliService;
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\InputArgument;
45
use Symfony\Component\Console\Input\InputInterface;
46
use Symfony\Component\Console\Output\OutputInterface;
47
48
49
class Index extends ExtendedBase {
50
51
//			'%job:1s%%message:-40s%%current:6s%/%max:6s% [%bar%] %percent:3s%% \n %duration% %infos:-12s% %jvm:-30s%      '
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 116 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...
52
	const PANEL_RUN = 'run';
53
	const PANEL_RUN_LINE_OPTIONS = 'Options: %options%';
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_RESULT = '│ Result: %resultColored%';
65
	const PANEL_INDEX_LINE_FOOTER = '└──';
66
67
	const PANEL_STATUS = 'status';
68
	const PANEL_STATUS_LINE_HEADER = '┌─ Status ────';
69
	const PANEL_STATUS_LINE_DOCUMENTS = '│ Progress: %documentLeft:6s%/%documentTotal%   %progressStatus%';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 104 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_STATUS_LINE_DOCUMENTS_LEFT = '│ Document left:';
71
	const PANEL_STATUS_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...
72
	const PANEL_STATUS_LINE_ERROR_MESSAGE = '│ Message: <comment>%errorMessage%</comment>';
73
	const PANEL_STATUS_LINE_ERROR_EXCEPTION = '│ Exception: <comment>%errorException%</comment>';
74
	const PANEL_STATUS_LINE_ERROR_INDEX = '│ Index: <comment>%errorIndex%</comment>';
75
76
77
	const PANEL_STATUS_LINE_FOOTER = '└──';
78
79
	const PANEL_LINE_EMPTY = '│ ';
80
81
	const PANEL_COMMANDS_ROOT = 'root';
82
	const PANEL_COMMANDS_ROOT_LINE = '## <char>q</char>:quit ## <char>p</char>:pause ';
83
	const PANEL_COMMANDS_PAUSED = 'paused';
84
	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...
85
	const PANEL_COMMANDS_DONE = 'done';
86
	const PANEL_COMMANDS_DONE_LINE = '## <char>q</char>:quit';
87
	const PANEL_COMMANDS_ERRORS = 'errors';
88
	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...
89
90
	/** @var IUserManager */
91
	private $userManager;
92
93
	/** @var RunningService */
94
	private $runningService;
95
96
	/** @var CliService */
97
	private $cliService;
98
99
	/** @var IndexService */
100
	private $indexService;
101
102
	/** @var PlatformService */
103
	private $platformService;
104
105
	/** @var ProviderService */
106
	private $providerService;
107
108
	/** @var MiscService */
109
	private $miscService;
110
111
112
	/** @var Runner */
113
	private $runner;
114
115
	/** @var array */
116
	private $errors = [];
117
118
	/** @var bool */
119
	private $navigateLastError = true;
120
121
122
	/**
123
	 * Index constructor.
124
	 *
125
	 * @param IUserManager $userManager
126
	 * @param RunningService $runningService
127
	 * @param CliService $cliService
128
	 * @param IndexService $indexService
129
	 * @param PlatformService $platformService
130
	 * @param ProviderService $providerService
131
	 * @param MiscService $miscService
132
	 */
133 View Code Duplication
	public function __construct(
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...
134
		IUserManager $userManager, RunningService $runningService, CliService $cliService,
135
		IndexService $indexService, PlatformService $platformService,
136
		ProviderService $providerService, MiscService $miscService
137
	) {
138
		parent::__construct();
139
		$this->userManager = $userManager;
140
141
		$this->runningService = $runningService;
142
		$this->cliService = $cliService;
143
		$this->indexService = $indexService;
144
145
		$this->platformService = $platformService;
146
		$this->providerService = $providerService;
147
		$this->miscService = $miscService;
148
	}
149
150
151
	/**
152
	 *
153
	 */
154
	protected function configure() {
155
		parent::configure();
156
		$this->setName('fulltextsearch:index')
157
			 ->setDescription('Index files')
158
			 ->addArgument('options', InputArgument::OPTIONAL, 'options');
159
	}
160
161
162
	/**
163
	 * @throws Exception
164
	 */
165
	public function interrupted() {
166
		if ($this->hasBeenInterrupted()) {
167
			throw new \Exception('ctrl-c');
168
		}
169
	}
170
171
172
	/**
173
	 * @param InputInterface $input
174
	 * @param OutputInterface $output
175
	 *
176
	 * @return int|null|void
177
	 * @throws Exception
178
	 */
179
	protected function execute(InputInterface $input, OutputInterface $output) {
180
181
		/** do not get stuck while waiting interactive input */
182
		readline_callback_handler_install(
183
			'', function() {
184
		}
185
		);
186
		stream_set_blocking(STDIN, false);
187
188
		$outputStyle = new OutputFormatterStyle('white', 'black', ['bold']);
189
		$output->getFormatter()
190
			   ->setStyle('char', $outputStyle);
191
192
		$options = $this->generateIndexOptions($input);
193
194
		$this->runner = new Runner($this->runningService, 'commandIndex', ['nextStep' => 'n']);
195
		$this->runner->onKeyPress([$this, 'onKeyPressed']);
196
		$this->runner->onNewAction([$this, 'onNewAction']);
197
		$this->runner->onNewIndexError([$this, 'onNewIndexError']);
198
		$this->runner->pause($options->getOption('paused', false));
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
$options->getOption('paused', false) is of type array|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
199
200
		$this->indexService->setRunner($this->runner);
201
		$this->cliService->setRunner($this->runner);
202
203
		$this->generatePanels();
204
		$this->runner->setInfo('options', json_encode($options));
205
206
		try {
207
			$this->runner->sourceIsCommandLine($this, $output);
208
			$this->runner->start();
209
210
			if ($options->getOption('errors') === 'reset') {
211
				$this->indexService->resetErrorsAll();
212
			}
213
214
			$this->testPlatform();
215
			$this->cliService->runDisplay($output);
216
			$this->generateIndexErrors();
217
			$this->displayError();
218
219
			$providers = $this->providerService->getProviders();
220
			foreach ($providers as $provider) {
221
222
				if (!$this->isIncludedProvider($options, $provider->getId())) {
223
					continue;
224
				}
225
226
				$provider->setRunner($this->runner);
227
				$provider->setIndexOptions($options);
228
				$this->indexProvider($provider, $options);
229
			}
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->setInfo('progressStatus', 'done');
237
		$this->runner->stop();
238
239
//		while (true) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
240
//			$this->runner->updateAction('_indexOver', true);
241
//			$pressed = strtolower($this->updateAction(''));
242
//			if ($pressed === $this->keys['nextStep']) {
243
//				$this->pauseRunning(false);
244
//				break;
245
//			}
246
//			usleep(300000);
247
//		}
248
249
250
//		$output->writeLn('');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
251
252
	}
253
254
255
	/**
256
	 * @param $key
257
	 */
258 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...
259
		$key = strtolower($key);
260
		if ($key === 'q') {
261
			try {
262
				$this->runner->stop();
263
			} catch (TickDoesNotExistException $e) {
264
				/** we do nohtin' */
265
			}
266
			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...
267
		}
268
269
		$current = $this->cliService->currentPanel('commands');
270
		if ($current === self::PANEL_COMMANDS_ROOT && $key === 'p') {
271
			$this->cliService->switchPanel('commands', self::PANEL_COMMANDS_PAUSED);
272
			$this->runner->pause(true);
273
		}
274
		if ($current === self::PANEL_COMMANDS_PAUSED && $key === 'u') {
275
			$this->cliService->switchPanel('commands', self::PANEL_COMMANDS_ROOT);
276
			$this->runner->pause(false);
277
		}
278
279
		if ($key === 'f') {
280
			$this->displayError(-99);
281
		}
282
		if ($key === 'h') {
283
			$this->displayError(-1);
284
		}
285
		if ($key === 'j') {
286
			$this->displayError(1);
287
		}
288
		if ($key === 'l') {
289
			$this->displayError(99);
290
		}
291
		if ($key === 'd') {
292
			$this->deleteError();
293
		}
294
	}
295
296
	/**
297
	 * @param string $action
298
	 */
299
	public function onNewAction($action) {
300
301
		if ($action === 'indexChunk' || $action === 'indexChunkEnd') {
302
			$this->runner->setInfoArray(
303
				[
304
					'documentId' => '',
305
					'title'      => '',
306
					'content'    => ''
307
				]
308
			);
309
		}
310
	}
311
312
313
	/**
314
	 * @param array $error
315
	 */
316
	public function onNewIndexError($error) {
317
		$this->errors[] = $error;
318
		$this->displayError();
319
	}
320
321
322
	/**
323
	 * @throws Exception
324
	 */
325
	private function testPlatform() {
326
		$platform = $this->platformService->getPlatform();
327
		$platform->testPlatform();
328
	}
329
330
331
	/**
332
	 * @param IFullTextSearchProvider $provider
333
	 * @param IndexOptions $options
334
	 *
335
	 * @throws Exception
336
	 */
337
	private function indexProvider(IFullTextSearchProvider $provider, IndexOptions $options) {
338
		$platform = $this->platformService->getPlatform();
339
		$platform->initializeIndex();
340
		$provider->onInitializingIndex($platform);
341
342
		$platform->setRunner($this->runner);
343
344
		$users = $this->generateUserList($options);
345
		foreach ($users as $user) {
346
			if ($user === null) {
347
				continue;
348
			}
349
350
			$this->indexService->indexProviderContentFromUser(
351
				$platform, $provider, $user->getUID(), $options
352
			);
353
		}
354
355
		$this->providerService->setProviderAsIndexed($provider, true);
356
357
	}
358
359
360
	/**
361
	 * @param InputInterface $input
362
	 *
363
	 * @return IndexOptions
364
	 */
365
	private function generateIndexOptions(InputInterface $input) {
366
		$jsonOptions = $input->getArgument('options');
367
		$options = json_decode($jsonOptions, true);
368
369
		if (!is_array($options)) {
370
			$options = [];
371
		}
372
373
		return new IndexOptions($options);
374
	}
375
376
377
	/**
378
	 * @param IndexOptions $options
379
	 * @param string $providerId
380
	 *
381
	 * @return bool
382
	 */
383
	private function isIncludedProvider(IndexOptions $options, $providerId) {
384
		if ($options->getOption('provider', '') !== ''
385
			&& $options->getOption('provider') !== $providerId) {
386
			return false;
387
		}
388
389
		if ($options->getOption('providers', null) !== null
390
			&& is_array($options->getOption('providers'))) {
391
			return (in_array($providerId, $options->getOption('providers')));
392
		}
393
394
		return true;
395
	}
396
397
398
	/**
399
	 * @param IndexOptions $options
400
	 *
401
	 * @return array
402
	 */
403
	private function generateUserList(IndexOptions $options) {
404
		if ($options->getOption('user', '') !== '') {
405
			return [$this->userManager->get($options->getOption('user'))];
406
		}
407
408
		if ($options->getOption('users', null) !== null
409
			&& is_array($options->getOption('users'))) {
410
			return array_map([$this->userManager, 'get'], $options->getOption('users'));
411
		}
412
413
		return $this->userManager->search('');
414
	}
415
416
417
	/**
418
	 *
419
	 */
420 View Code Duplication
	private function generatePanels() {
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...
421
422
		$this->cliService->createPanel(
423
			self::PANEL_RUN,
424
			[
425
				self::PANEL_RUN_LINE_OPTIONS,
426
				self::PANEL_RUN_LINE_MEMORY
427
			]
428
		);
429
		$this->cliService->createPanel(
430
			self::PANEL_INDEX, [
431
								 self::PANEL_INDEX_LINE_HEADER,
432
								 self::PANEL_INDEX_LINE_ACCOUNT,
433
								 self::PANEL_INDEX_LINE_ACTION,
434
								 self::PANEL_INDEX_LINE_DOCUMENT,
435
								 self::PANEL_INDEX_LINE_INFO,
436
								 self::PANEL_INDEX_LINE_TITLE,
437
								 self::PANEL_INDEX_LINE_CONTENT,
438
								 self::PANEL_INDEX_LINE_RESULT,
439
								 self::PANEL_INDEX_LINE_FOOTER,
440
							 ]
441
		);
442
443
		$this->cliService->createPanel(
444
			self::PANEL_STATUS, [
445
								  self::PANEL_STATUS_LINE_HEADER,
446
								  self::PANEL_STATUS_LINE_DOCUMENTS,
447
								  self::PANEL_STATUS_LINE_ERRORS,
448
								  self::PANEL_STATUS_LINE_ERROR_MESSAGE,
449
								  self::PANEL_STATUS_LINE_ERROR_EXCEPTION,
450
								  self::PANEL_STATUS_LINE_ERROR_INDEX,
451
								  self::PANEL_STATUS_LINE_FOOTER,
452
							  ]
453
		);
454
455
		$this->cliService->createPanel(
456
			self::PANEL_COMMANDS_ROOT, [
457
										 self::PANEL_COMMANDS_ROOT_LINE
458
									 ]
459
		);
460
461
		$this->cliService->createPanel(
462
			self::PANEL_COMMANDS_PAUSED, [
463
										   self::PANEL_COMMANDS_PAUSED_LINE
464
									   ]
465
		);
466
467
		$this->cliService->createPanel(
468
			self::PANEL_COMMANDS_ERRORS, [
469
										   self::PANEL_COMMANDS_ERRORS_LINE
470
									   ]
471
		);
472
473
		$this->cliService->initDisplay();
474
		$this->cliService->displayPanel('run', self::PANEL_RUN);
475
		$this->cliService->displayPanel('topPanel', self::PANEL_INDEX);
476
		$this->cliService->displayPanel('bottomPanel', self::PANEL_STATUS);
477
478
		$this->cliService->displayPanel('errors', self::PANEL_COMMANDS_ERRORS);
479
480
		if ($this->runner->isPaused()) {
481
			$this->cliService->displayPanel('commands', self::PANEL_COMMANDS_PAUSED);
482
		} else {
483
			$this->cliService->displayPanel('commands', self::PANEL_COMMANDS_ROOT);
484
		}
485
486
		$this->runner->setInfoArray(
487
			[
488
				'userId'         => '',
489
				'providerName'   => '',
490
				'_memory'        => '',
491
				'documentId'     => '',
492
				'action'         => '',
493
				'info'           => '',
494
				'title'          => '',
495
				'_paused'        => '',
496
				'content'        => '',
497
				'resultColored'  => '',
498
				'documentLeft'   => '',
499
				'documentTotal'  => '',
500
				'progressStatus' => '',
501
				'errorCurrent'   => '0',
502
				'errorTotal'     => '0',
503
				'errorMessage'   => '',
504
				'errorException' => '',
505
				'errorIndex'     => ''
506
			]
507
		);
508
	}
509
510
511
	/**
512
	 * @param int $pos
513
	 */
514 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...
515
		$total = sizeof($this->errors);
516
517
		if ($total === 0) {
518
			$this->runner->setInfoArray(
519
				[
520
					'errorCurrent' => 0,
521
					'errorTotal'   => 0,
522
				]
523
			);
524
525
			return;
526
		}
527
528
		$current = key($this->errors) + 1;
529
		$error = $this->getNavigationError($pos, ($current === 1), ($current === $total));
530
		$current = key($this->errors) + 1;
531
532
		if ($error === false) {
533
			return;
534
		}
535
536
		/** @var ModelIndex $index */
537
		$index = $error['index'];
538
		$errorIndex = '';
539
		if ($index !== null) {
540
			$errorIndex = $index->getProviderId() . ':' . $index->getDocumentId();
541
		}
542
543
		$this->runner->setInfoArray(
544
			[
545
				'errorCurrent'   => $current,
546
				'errorTotal'     => $total,
547
				'errorMessage'   => MiscService::get('message', $error, ''),
548
				'errorException' => MiscService::get('exception', $error, ''),
549
				'errorIndex'     => $errorIndex
550
			]
551
		);
552
	}
553
554
555
	/**
556
	 * @param int $pos
557
	 * @param bool $isFirst
558
	 * @param bool $isLast
559
	 *
560
	 * @return bool|array
561
	 */
562 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...
563
564
		if ($pos === 0) {
565
			if ($this->navigateLastError === true) {
566
				return end($this->errors);
567
			} else {
568
				return current($this->errors);
569
			}
570
		}
571
572
		$this->navigateLastError = false;
573
		if ($pos === -99) {
574
			return reset($this->errors);
575
		}
576
577
		if ($pos === -1 && !$isFirst) {
578
			return prev($this->errors);
579
		}
580
581
		if ($pos === 1 && !$isLast) {
582
			return next($this->errors);
583
		}
584
585
		if ($pos === 99) {
586
			$this->navigateLastError = true;
587
588
			return end($this->errors);
589
		}
590
591
		return false;
592
	}
593
594
595
	/**
596
	 *
597
	 */
598 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...
599
		$indexes = $this->indexService->getErrorIndexes();
600
601
		foreach ($indexes as $index) {
602
			foreach ($index->getErrors() as $error) {
603
				$this->errors[] = [
604
					'index'     => $index,
605
					'message'   => $error['message'],
606
					'exception' => $error['exception'],
607
					'severity'  => $error['sev']
608
				];
609
			}
610
611
		}
612
613
614
	}
615
616
617
	/**
618
	 *
619
	 */
620 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...
621
		$current = current($this->errors);
622
		if ($current === false) {
623
			return;
624
		}
625
626
		$this->runner->setInfoArray(
627
			[
628
				'errorMessage'   => '',
629
				'errorException' => '',
630
				'errorIndex'     => ''
631
			]
632
		);
633
634
		$pos = key($this->errors);
635
636
		/** @var ModelIndex $index */
637
		$index = $current['index'];
638
		$this->indexService->resetErrorFromIndex($index);
639
640
		$errors = [];
641
		foreach ($this->errors as $error) {
642
			/** @var ModelIndex $errorIndex */
643
			$errorIndex = $error['index'];
644
			if ($index->getProviderId() === $errorIndex->getProviderId()
645
				&& $index->getDocumentId() === $errorIndex->getDocumentId()) {
646
				continue;
647
			}
648
649
			$errors[] = $error;
650
		}
651
652
		$this->errors = $errors;
653
		while (key($this->errors) < $pos) {
654
			if (next($this->errors) === false) {
655
				end($this->errors);
656
				break;
657
			}
658
		}
659
660
		$this->displayError();
661
	}
662
663
}
664
665
666
667