getLogger(); $lineValidator = $this->getLineValidator(); $csvLineConverter = $this->getCsvLineConverter(); $currentLineNumber = 0; $lines = explode(PHP_EOL, $file->readPsrStream()->getContents()); $header = $this->convertCsvLineToArray($lines[0]); $header = $this->trimLine($header); try { $this->getHeaderValidator()->validate($header, $template); } catch (Throwable $exception) { $logger->warning( sprintf( 'Tabular import: Unexpected error on line %s: %s', 1, $exception->getMessage() ) ); return $results->addException(1, $exception); } array_shift($lines); foreach (array_filter($lines) as $lineNumber => $line) { $currentLineNumber = $lineNumber + 2; $aggregatedException = null; $parsedLine = $this->trimLine($this->convertCsvLineToArray($line)); $headedLine = array_combine($header, $parsedLine); try { $lineValidator->validate($headedLine, $template); } catch (AggregatedValidationException $aggregatedException) { $results->addException($currentLineNumber, $aggregatedException); if ($aggregatedException->hasErrors()) { continue; } } catch (Throwable $exception) { $results->addException($currentLineNumber, $exception); $logger->error( sprintf( 'Tabular import: Unexpected error on line %s: %s', $currentLineNumber, $exception->getMessage() ) ); } $item = $csvLineConverter->convert($headedLine, $template, $aggregatedException); if ($item->isNoneResponse()) { $results->addException( $currentLineNumber, new WarningValidationException( 'A value should be provided for at least one of the columns: %s', [ 'choice_[1-99]_score, correct_answer', ] ) ); } $results->addItem($currentLineNumber, $item); } $results->setTotalScannedItems(max($currentLineNumber - 1, 0)); return $results; } private function trimLine(array $line): array { $newLine = []; foreach ($line as $value) { $newLine[] = trim((string)$value); } return $newLine; } private function convertCsvLineToArray(string $line): array { return str_getcsv($this->removeBOM($line), $this->getCsvSeparator()); } private function removeBOM(string $line): string { return str_replace("\xEF\xBB\xBF", '', $line); } private function getHeaderValidator(): ValidatorInterface { return $this->getServiceLocator()->get(HeaderValidator::class); } private function getLineValidator(): ValidatorInterface { return $this->getServiceLocator()->get(LineValidator::class); } private function getCsvLineConverter(): CsvLineConverter { return $this->getServiceLocator()->get(CsvLineConverter::class); } }