<?php
namespace App\Utils\CSV\Reader; class RowValidator { protected $expectedColumns = null; protected $expectedColumns_type = "strict"; protected $spreadsheet = null; protected $columnFormats = []; public function __construct(\App\Utils\CSV\Reader\AbstractReader $spreadsheet) { $this->spreadsheet = $spreadsheet; } public function __destruct() { $this->spreadsheet = null; } public function setExpectedColumns(array $expectedColumns, string $expectedColumns_type='strict') { $this->expectedColumns = $expectedColumns; $this->expectedColumns_type = $expectedColumns_type; } public function getExpectedColumns() { return $this->expectedColumns; } public function setColumnFormats($columnFormats) { $this->columnFormats = $columnFormats; return $this; } public function getColumnFormats() { return $this->columnFormats; } public function validate($value, string $rawValue, string $field, \App\Utils\CSV\Reader\Row $row) { $cfg = $this->columnFormats[$field]; switch ($cfg['type']) { case 'callback': if ($cfg['callback:validate']) { $cfg['callback:validate']($cfg, $value, $field, $row); } return; break; case 'S': break; case 'N': if (!is_numeric($rawValue)) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid format on line {$row->getLineIndex()}"); } break; case 'NI': case 'NI+': case 'NI-': if ($rawValue && !is_int($value)) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid format on line {$row->getLineIndex()}"); } if ($cfg['type']=='NI+') { if ($value<=0) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid value on line {$row->getLineIndex()}"); } } if ($cfg['type']=='NI-') { if ($value>+0) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid value on line {$row->getLineIndex()}"); } } break; case 'NF': case 'NF+': case 'NF-': if ($rawValue && !is_float($value)) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid format on line {$row->getLineIndex()}"); } if ($cfg['type']=='NF+') { if ($value<=0) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid value on line {$row->getLineIndex()}"); } } if ($cfg['type']=='NF-') { if ($value>+0) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid value on line {$row->getLineIndex()}"); } } break; case 'D': if ($rawValue && !$value) { throw new \Exception\Validator\InvalidValue("Field '{$field}', with value '{$value}' has an invalid format on line {$row->getLineIndex()}"); } break; } if ($cfg['req']==='M') { if (!$value) { throw new \Exception\Validator\EmptyValue("Field '{$field}', with value '{$value}' has an invalid value on line {$row->getLineIndex()}"); } } } public function validateRow(\App\Utils\CSV\Reader\Row $row) { if ($this->expectedColumns!==null) { $rowData = $row->getRawFields(); $totalExpectedColumns = count($this->expectedColumns); $matchedColumns = 0; foreach ($this->expectedColumns as $col) { if (isset($rowData[$col])) { $matchedColumns++; } } switch ($this->expectedColumns_type) { case 'strict': if ($matchedColumns!==$totalExpectedColumns) { throw new \Exception\Validator\MismatchedValue("It should have {$totalExpectedColumns} columns and i found {$matchedColumns} columns. Column names expected: ".implode(",", $this->expectedColumns)); } break; case 'allow-more': if ($matchedColumns<$totalExpectedColumns) { throw new \Exception\Validator\MismatchedValue("It should have more than {$totalExpectedColumns} columns and i found {$matchedColumns} columns"); } break; case 'allow-none': if ($matchedColumns!==$totalExpectedColumns && $matchedColumns!==0) { throw new \Exception\Validator\MismatchedValue("It should have either {$totalExpectedColumns} columns or 0 column. I found {$matchedColumns} columns"); } break; default: throw new \Exception("invalid expectedColumns_type specified ('{$this->expectedColumns_type}' found)"); break; } } } } 