Initialisation du package
This commit is contained in:
commit
f4a4a8b1e0
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"name": "sudalys/import-service",
|
||||||
|
"description": "Service Symfony pour l'importation et la validation de fichiers CSV et Excel (XLS/XLSX), avec transformation automatisée.",
|
||||||
|
"keywords": ["import","csv","excel","xls","xlsx","validation","sudalys"],
|
||||||
|
"type": "library",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Dorian Contal",
|
||||||
|
"email": "d.contal@sudalys.fr"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1",
|
||||||
|
"league/csv": "^9.11",
|
||||||
|
"phpoffice/phpspreadsheet": "^1.18",
|
||||||
|
"box/spout": "^3.3",
|
||||||
|
"psr/log": "^3.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\Service\\Import\\": "src/Service/Import/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"prefer-stable": true
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import;
|
||||||
|
use App\Service\Import\CsvValidator;
|
||||||
|
use App\Service\Import\Processor\BasicCsvFileProcessor;
|
||||||
|
use App\Service\Import\Processor\MainProcessor;
|
||||||
|
use App\Service\Import\ErrorHandler\LoggingErrorHandler;
|
||||||
|
use App\Service\Import\Specification\ExactHeaderSpecification;
|
||||||
|
use App\Service\Import\Specification\RegexColumnSpecification;
|
||||||
|
use App\Service\Import\Specification\NumericSpecification;
|
||||||
|
use App\Service\Import\Specification\RequiredColumnSpecification;
|
||||||
|
use App\Service\Import\Result\ImportResult;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
class CsvImportService
|
||||||
|
{
|
||||||
|
private CsvImporter $importer;
|
||||||
|
private array $header;
|
||||||
|
private array $regexListe;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{}
|
||||||
|
public function import(string $filePath, array $header, array $regexListe, array $requiredColumns, LoggerInterface $logger): array
|
||||||
|
{
|
||||||
|
$this->header = $header;
|
||||||
|
$this->regexListe = $regexListe;
|
||||||
|
|
||||||
|
$headerSpec = new ExactHeaderSpecification($this->header);
|
||||||
|
|
||||||
|
$columnSpecs = [];
|
||||||
|
|
||||||
|
foreach ($header as $col) {
|
||||||
|
// Si regex définie → priorité
|
||||||
|
if (isset($regexListe[$col])) {
|
||||||
|
$columnSpecs[$col] = new RegexColumnSpecification(
|
||||||
|
$regexListe[$col],
|
||||||
|
"Le format de la colonne '$col' est invalide."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elseif (in_array($col, $requiredColumns)) {
|
||||||
|
$columnSpecs[$col] = new RequiredColumnSpecification("La colonne '$col' est obligatoire.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$fileProcessor = new BasicCsvFileProcessor();
|
||||||
|
$validator = new CsvValidator($headerSpec, $columnSpecs);
|
||||||
|
$errorHandler = new LoggingErrorHandler($logger);
|
||||||
|
$mainProcessor = new MainProcessor();
|
||||||
|
|
||||||
|
$this->importer = new CsvImporter($fileProcessor, $validator,$errorHandler,
|
||||||
|
$mainProcessor,
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this->importer->import($filePath);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => $result->isSuccess(),
|
||||||
|
'errors' => $result->getErrors(),
|
||||||
|
'processedCount' => $result->getProcessedCount(),
|
||||||
|
'message' => $result->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Import;
|
||||||
|
|
||||||
|
use App\Service\Import\Interfaces\FileProcessorInterface;
|
||||||
|
use App\Service\Import\Interfaces\ValidatorInterface;
|
||||||
|
use App\Service\Import\Interfaces\ErrorHandlerInterface;
|
||||||
|
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||||
|
use App\Service\Import\Result\ImportResult;
|
||||||
|
|
||||||
|
use function Symfony\Component\DependencyInjection\Loader\Configurator\iterator;
|
||||||
|
|
||||||
|
class CsvImporter
|
||||||
|
{
|
||||||
|
private FileProcessorInterface $fileProcessor;
|
||||||
|
private ValidatorInterface $validator;
|
||||||
|
private ErrorHandlerInterface $errorHandler;
|
||||||
|
private DataProcessorInterface $dataProcessor;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
FileProcessorInterface $fileProcessor,
|
||||||
|
ValidatorInterface $validator,
|
||||||
|
ErrorHandlerInterface $errorHandler,
|
||||||
|
DataProcessorInterface $dataProcessor
|
||||||
|
) {
|
||||||
|
$this->fileProcessor = $fileProcessor;
|
||||||
|
$this->validator = $validator;
|
||||||
|
$this->errorHandler = $errorHandler;
|
||||||
|
$this->dataProcessor = $dataProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import(string $filePath): ImportResult
|
||||||
|
{
|
||||||
|
$rows = $this->fileProcessor->processfile($filePath);
|
||||||
|
$header = $this->fileProcessor->getHeader($filePath);
|
||||||
|
|
||||||
|
$validationResult = $this->validator->validate($header, $rows);
|
||||||
|
|
||||||
|
if ($validationResult->hasErrors()) {
|
||||||
|
$this->errorHandler->handle($validationResult->getErrors());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dataProcessor->process($rows);
|
||||||
|
|
||||||
|
|
||||||
|
return new ImportResult(
|
||||||
|
$validationResult->getErrors(),
|
||||||
|
!$validationResult->hasErrors(),
|
||||||
|
$validationResult->hasErrors() ? 'Import terminé avec erreurs.' : ' Import réussi.',
|
||||||
|
count($rows)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import;
|
||||||
|
|
||||||
|
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
||||||
|
use App\Service\Import\Result\ValidationResult;
|
||||||
|
use App\Service\Import\Interfaces\ValidatorInterface;
|
||||||
|
|
||||||
|
class CsvValidator implements ValidatorInterface
|
||||||
|
{
|
||||||
|
public function __construct(private HeaderSpecificationInterface $headerSpecification, private $columnSpecification){}
|
||||||
|
public function validate(array $header, iterable $records): ValidationResult
|
||||||
|
{
|
||||||
|
$errors = [];
|
||||||
|
$validData = [];
|
||||||
|
|
||||||
|
if (!$this->headerSpecification->isSatisfiedBy($header)) {
|
||||||
|
$errors[] = $this->headerSpecification->getErrorMessage();
|
||||||
|
$errors = array_merge($errors, $this->headerSpecification->getErrorsHeader($header));
|
||||||
|
}
|
||||||
|
$rowIndex = 2;
|
||||||
|
foreach ($records as $row){
|
||||||
|
$rowErrors = [];
|
||||||
|
foreach ($this->columnSpecification as $column => $specification) {
|
||||||
|
if (!isset($row[$column]) || !$specification->isSatisfiedBy($row[$column])) {
|
||||||
|
$rowErrors[] = "Ligne $rowIndex: " . $specification->getErrorMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($rowErrors)) {
|
||||||
|
$errors = array_merge($errors, $rowErrors);
|
||||||
|
} else {
|
||||||
|
$validData[] = $row;
|
||||||
|
}
|
||||||
|
$rowIndex++;
|
||||||
|
}
|
||||||
|
return new ValidationResult( $errors, $validData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\ErrorHandler;
|
||||||
|
use App\Service\Import\Interfaces\ErrorHandlerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
class LoggingErrorHandler implements ErrorHandlerInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
private LoggerInterface $logger;
|
||||||
|
|
||||||
|
public function __construct(LoggerInterface $logger)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function handle(array $errors): void
|
||||||
|
{
|
||||||
|
foreach ($errors as $error) {
|
||||||
|
$this->logger->error($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Import;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
|
||||||
|
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
|
||||||
|
|
||||||
|
|
||||||
|
class ExcelFileTransformer
|
||||||
|
{
|
||||||
|
public function transform(string $filePath, string $type = 'csv', int $headerPosition = 3): string
|
||||||
|
{
|
||||||
|
if (!file_exists($filePath)) {
|
||||||
|
throw new \RuntimeException("Le fichier n'existe pas.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
|
||||||
|
|
||||||
|
if ($extension === 'xls') {
|
||||||
|
$filePath = $this->convertXlsToXlsx($filePath);
|
||||||
|
} elseif ($extension === 'xlsx') {
|
||||||
|
$filePath = $this->purgeXlsx($filePath);
|
||||||
|
} else {
|
||||||
|
throw new \RuntimeException("Format non pris en charge : .$extension");
|
||||||
|
}
|
||||||
|
|
||||||
|
$reader = ReaderEntityFactory::createXLSXReader();
|
||||||
|
$reader->open($filePath);
|
||||||
|
|
||||||
|
$tmpCsvPath = tempnam(sys_get_temp_dir(), 'converted_') . '.' . $type;
|
||||||
|
$handle = fopen($tmpCsvPath, 'w');
|
||||||
|
|
||||||
|
$rowIndex = 1;
|
||||||
|
foreach ($reader->getSheetIterator() as $sheet) {
|
||||||
|
if ($sheet->getName() !== '__ACTIVE_SHEET__') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach ($sheet->getRowIterator() as $row) {
|
||||||
|
if ($rowIndex++ < $headerPosition) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cells = array_map(function($cell) {
|
||||||
|
$value = $cell->getValue();
|
||||||
|
if ($value instanceof \DateTime) {
|
||||||
|
return $value->format('Y-m-d H:i');
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}, $row->getCells());
|
||||||
|
|
||||||
|
fputcsv($handle, $cells);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$reader->close();
|
||||||
|
fclose($handle);
|
||||||
|
|
||||||
|
return $tmpCsvPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function convertXlsToXlsx(string $xlsFilePath): string
|
||||||
|
{
|
||||||
|
if (!file_exists($xlsFilePath)) {
|
||||||
|
throw new \RuntimeException("Le fichier XLS n'existe pas : $xlsFilePath");
|
||||||
|
}
|
||||||
|
$reader = IOFactory::createReader('Xls');
|
||||||
|
$reader->setReadDataOnly(false);
|
||||||
|
$spreadsheet = $reader->load($xlsFilePath);
|
||||||
|
$activeSheet = $spreadsheet->getSheet($spreadsheet->getActiveSheetIndex());
|
||||||
|
$originalTitle = $activeSheet->getTitle();
|
||||||
|
$activeSheet->setTitle('__ACTIVE_SHEET__');
|
||||||
|
$xlsxFilePath = tempnam(sys_get_temp_dir(), 'converted_') . '.xlsx';
|
||||||
|
$writer = new Xlsx($spreadsheet);
|
||||||
|
$writer->setPreCalculateFormulas(false);
|
||||||
|
$writer->save($xlsxFilePath);
|
||||||
|
$activeSheet->setTitle($originalTitle);
|
||||||
|
return $xlsxFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function purgeXlsx(string $filePath): string
|
||||||
|
{
|
||||||
|
$reader = IOFactory::createReader('Xlsx');
|
||||||
|
$reader->setReadDataOnly(false);
|
||||||
|
$spreadsheet = $reader->load($filePath);
|
||||||
|
|
||||||
|
$activeSheet = $spreadsheet->getSheet($spreadsheet->getActiveSheetIndex());
|
||||||
|
$originalTitle = $activeSheet->getTitle();
|
||||||
|
$activeSheet->setTitle('__ACTIVE_SHEET__');
|
||||||
|
|
||||||
|
$purgedPath = tempnam(sys_get_temp_dir(), 'purged_') . '.xlsx';
|
||||||
|
$writer = new Xlsx($spreadsheet);
|
||||||
|
$writer->setPreCalculateFormulas(false);
|
||||||
|
$writer->save($purgedPath);
|
||||||
|
|
||||||
|
// Optionally restore original title in memory
|
||||||
|
$activeSheet->setTitle($originalTitle);
|
||||||
|
|
||||||
|
return $purgedPath;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Interfaces;
|
||||||
|
interface ColumnSpecificationInterface
|
||||||
|
{
|
||||||
|
public function isSatisfiedBy(string $value): bool;
|
||||||
|
|
||||||
|
public function getErrorMessage(): string;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Interfaces;
|
||||||
|
interface DataProcessorInterface
|
||||||
|
|
||||||
|
{
|
||||||
|
public function process(array $validdata): void;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Interfaces;
|
||||||
|
interface ErrorHandlerInterface
|
||||||
|
{
|
||||||
|
public function handle(array $errors): void;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Interfaces;
|
||||||
|
interface FileProcessorInterface
|
||||||
|
{
|
||||||
|
public function processFile(string $Path): array;
|
||||||
|
public function getHeader(string $path): array;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Interfaces;
|
||||||
|
interface HeaderSpecificationInterface
|
||||||
|
{
|
||||||
|
public function isSatisfiedBy(array $header): bool;
|
||||||
|
public function getErrorMessage(): string;
|
||||||
|
public function getErrorsHeader(array $header): array;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Interfaces;
|
||||||
|
use App\Service\Import\Result\ValidationResult;
|
||||||
|
|
||||||
|
interface ValidatorInterface
|
||||||
|
{
|
||||||
|
public function validate(array $header, iterable $records ): ValidationResult;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Processor;
|
||||||
|
use App\Service\Import\Interfaces\FileProcessorInterface;
|
||||||
|
|
||||||
|
use League\Csv\Reader;
|
||||||
|
|
||||||
|
class BasicCsvFileProcessor implements FileProcessorInterface
|
||||||
|
{
|
||||||
|
public function processFile(string $path): array
|
||||||
|
{
|
||||||
|
$csv = Reader::createFromPath($path, 'r');
|
||||||
|
$csv->setHeaderOffset(0);
|
||||||
|
return iterator_to_array($csv->getRecords(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeader(string $path): array
|
||||||
|
{
|
||||||
|
$csv = Reader::createFromPath($path, 'r');
|
||||||
|
$csv->setHeaderOffset(0);
|
||||||
|
|
||||||
|
return $csv->getHeader();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Processor;
|
||||||
|
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||||
|
|
||||||
|
class DatabaseDataProcessor implements DataProcessorInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(array $validdata): void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Import\Processor;
|
||||||
|
|
||||||
|
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||||
|
//use App\Service\Import\Interfaces\AutreProcessorInterface; // Ajoute d'autres interfaces de traitement si nécessaire
|
||||||
|
|
||||||
|
class MainProcessor implements DataProcessorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DataProcessorInterface[]
|
||||||
|
*/
|
||||||
|
private array $processors = [];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// BasicCsvFileProcessor pas nécessaire ici car déjà géré dans le service d'importation en amont
|
||||||
|
$this->processors[] = new DatabaseDataProcessor();
|
||||||
|
// $this->processors[] = new AutreProcessor(); // Ajoute d'autres ici au besoin
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(array $row): void
|
||||||
|
{
|
||||||
|
foreach ($this->processors as $processor) {
|
||||||
|
$processor->process($row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Import\Result;
|
||||||
|
|
||||||
|
class ImportResult
|
||||||
|
{
|
||||||
|
private array $errors;
|
||||||
|
private bool $success;
|
||||||
|
private string $message;
|
||||||
|
private int $processedCount;
|
||||||
|
|
||||||
|
public function __construct(array $errors, bool $success, string $message, int $processedCount)
|
||||||
|
{
|
||||||
|
$this->errors = $errors;
|
||||||
|
$this->success = $success;
|
||||||
|
$this->message = $message;
|
||||||
|
$this->processedCount = $processedCount;
|
||||||
|
}
|
||||||
|
public function getErrors(): array
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
public function isSuccess(): bool
|
||||||
|
{
|
||||||
|
return $this->success;
|
||||||
|
}
|
||||||
|
public function getMessage(): string
|
||||||
|
{
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
public function getProcessedCount(): int
|
||||||
|
{
|
||||||
|
return $this->processedCount;
|
||||||
|
}
|
||||||
|
public function hasErrors(): bool
|
||||||
|
{
|
||||||
|
return !empty($this->errors);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Import\Result;
|
||||||
|
|
||||||
|
class ValidationResult
|
||||||
|
{
|
||||||
|
private array $errors;
|
||||||
|
private array $validData;
|
||||||
|
|
||||||
|
public function __construct(array $errors, array $validData)
|
||||||
|
{
|
||||||
|
$this->errors = $errors;
|
||||||
|
$this->validData = $validData;
|
||||||
|
}
|
||||||
|
public function getErrors(): array
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
public function getValidData(): array
|
||||||
|
{
|
||||||
|
return $this->validData;
|
||||||
|
}
|
||||||
|
public function hasErrors(): bool
|
||||||
|
{
|
||||||
|
return !empty($this->errors);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Import\Specification;
|
||||||
|
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
||||||
|
|
||||||
|
class ExactHeaderSpecification implements HeaderSpecificationInterface
|
||||||
|
{
|
||||||
|
private array $expectedHeader;
|
||||||
|
private string $errorMessage = 'L\'en-tête ne correspond pas';
|
||||||
|
|
||||||
|
public function __construct(array $expectedHeader)
|
||||||
|
{
|
||||||
|
$this->expectedHeader = $expectedHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSatisfiedBy(array $header): bool
|
||||||
|
{
|
||||||
|
return $header === $this->expectedHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrorMessage(): string
|
||||||
|
{
|
||||||
|
return $this->errorMessage;
|
||||||
|
}
|
||||||
|
public function getErrorsHeader(array $header): array
|
||||||
|
{
|
||||||
|
$errorsHeader = [];
|
||||||
|
foreach ($this->expectedHeader as $key => $value) {
|
||||||
|
if (!isset($header[$key]) || $header[$key] !== $value) {
|
||||||
|
$errorsHeader[] = "La colonne $value est manquante ou ne correspond pas à la valeur attendue [ $header[$key] ]";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $errorsHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Specification;
|
||||||
|
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
|
class NumericSpecification implements ColumnSpecificationInterface
|
||||||
|
{
|
||||||
|
private string $errorMessage ;
|
||||||
|
private string $pattern;
|
||||||
|
|
||||||
|
public function __construct(string $pattern, string $errorMessage)
|
||||||
|
{
|
||||||
|
$this->pattern = $pattern;
|
||||||
|
$this->errorMessage = $errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSatisfiedBy(string $value): bool
|
||||||
|
{
|
||||||
|
return preg_match($this->pattern, $value) === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrorMessage(): string
|
||||||
|
{
|
||||||
|
return $this->errorMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Service\Import\Specification;
|
||||||
|
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
|
class RegexColumnSpecification implements ColumnSpecificationInterface
|
||||||
|
{
|
||||||
|
private string $pattern;
|
||||||
|
private string $errorMessage;
|
||||||
|
|
||||||
|
public function __construct(string $pattern, string $errorMessage)
|
||||||
|
{
|
||||||
|
$this->pattern = $pattern;
|
||||||
|
$this->errorMessage = $errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSatisfiedBy(string $value): bool
|
||||||
|
{
|
||||||
|
return preg_match($this->pattern, $value) === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrorMessage(): string
|
||||||
|
{
|
||||||
|
return $this->errorMessage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Import\Specification;
|
||||||
|
|
||||||
|
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
|
class RequiredColumnSpecification implements ColumnSpecificationInterface
|
||||||
|
{
|
||||||
|
private string $errorMessage;
|
||||||
|
|
||||||
|
public function __construct(string $errorMessage = 'Ce champ est requis.')
|
||||||
|
{
|
||||||
|
$this->errorMessage = $errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSatisfiedBy(mixed $value): bool
|
||||||
|
{
|
||||||
|
return !empty($value) && trim($value) !== '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrorMessage(): string
|
||||||
|
{
|
||||||
|
return $this->errorMessage;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue