Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
|
5acb21d503 | |
|
6853bf95ae | |
|
e67eb62e57 | |
|
0d3686e34e | |
|
07fe6226b8 | |
|
db5b7b7575 | |
|
2ea5ff9a9c |
|
@ -0,0 +1,115 @@
|
||||||
|
# 📦 Import CSV & Excel Service (Symfony)
|
||||||
|
|
||||||
|
Un service Symfony modulaire pour importer, valider et transformer automatiquement des fichiers **CSV** et **Excel** (XLS/XLSX). Idéal pour les pipelines d'importation robustes avec gestion des erreurs et validation dynamique.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Installation
|
||||||
|
|
||||||
|
Ajoutez ce package via Composer :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require sudalys/import-service
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📂 Fonctionnalités
|
||||||
|
|
||||||
|
- ✅ Import de fichiers `.csv`, `.xls`, `.xlsx`
|
||||||
|
- ⚖️ Validation dynamique des colonnes avec regex
|
||||||
|
- 📊 Log des erreurs via le logger Symfony (PSR-3)
|
||||||
|
- 📃 Colonne obligatoire supportée
|
||||||
|
- ⚙️ Architecture extensible via des `Processor`
|
||||||
|
- 🔄 Conversion automatique des `.xls` vers `.xlsx`
|
||||||
|
- ❌ Suppression des colonnes vides pour éviter les erreurs de duplicat
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Utilisation
|
||||||
|
|
||||||
|
Voici un exemple typique dans votre contrôleur ou service d'importation :
|
||||||
|
|
||||||
|
```php
|
||||||
|
if (strtolower(pathinfo($filePath, PATHINFO_EXTENSION)) === 'xlsx' || strtolower(pathinfo($filePath, PATHINFO_EXTENSION)) === 'xls') {
|
||||||
|
$filePath = $excelTransformer->transform($filePath, 'Csv', 3); // 3 correspond à la ligne d'entête
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $importService->import(
|
||||||
|
$filePath,
|
||||||
|
$this->HeaderGeneral,
|
||||||
|
$this->regexListe,
|
||||||
|
$this->ColonneObligatoire,
|
||||||
|
$logger
|
||||||
|
);
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧑💻 Exemple d'Importation dans le Contrôleur
|
||||||
|
|
||||||
|
Dans votre contrôleur ou service, n'oubliez pas d'importer les classes nécessaires pour utiliser le service d'importation :
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Sudalys\ImportService\CsvImportService;
|
||||||
|
use Sudalys\ImportService\ExcelFileTransformer;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Configuration attendue
|
||||||
|
|
||||||
|
- `$HeaderGeneral` : tableau des en-têtes attendues (ordre et contenu exact)
|
||||||
|
- `$regexListe` : tableau associatif `colonne => regex`
|
||||||
|
- `$ColonneObligatoire` : tableau contenant les noms de colonnes obligatoires
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚫 Gestion des erreurs
|
||||||
|
|
||||||
|
Les erreurs de validation sont automatiquement loggées via `LoggingErrorHandler` qui utilise le logger PSR-3 de Symfony.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 Transformations Excel
|
||||||
|
|
||||||
|
Géré via `ExcelFileTransformer` :
|
||||||
|
- Conversion `.xls` → `.xlsx`
|
||||||
|
- Extraction des données via `Box\Spout`
|
||||||
|
- Ignorer les lignes pré-étêtées via `$headerPosition`
|
||||||
|
- Formatage des dates
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ Configuration du Service dans `services.yaml`
|
||||||
|
|
||||||
|
Pour que le service fonctionne correctement dans Symfony, ajoutez la configuration suivante dans votre fichier `services.yaml` :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
Sudalys\ImportService\:
|
||||||
|
resource: '../vendor/sudalys/import-service/src/Service/Import/'
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
public: false
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎓 Exigences
|
||||||
|
|
||||||
|
- PHP >= 8.1
|
||||||
|
- Symfony >= 5.4
|
||||||
|
- Extensions PHP : `ext-fileinfo`, `ext-mbstring`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"App\\Service\\Import\\": "src/Service/Import/"
|
"Sudalys\\ImportService\\": "src/Service/Import/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import;
|
namespace Sudalys\ImportService;
|
||||||
use App\Service\Import\CsvValidator;
|
|
||||||
use App\Service\Import\Processor\BasicCsvFileProcessor;
|
use Sudalys\ImportService\CsvValidator;
|
||||||
use App\Service\Import\Processor\MainProcessor;
|
use Sudalys\ImportService\Processor\BasicCsvFileProcessor;
|
||||||
use App\Service\Import\ErrorHandler\LoggingErrorHandler;
|
use Sudalys\ImportService\Processor\MainProcessor;
|
||||||
use App\Service\Import\Specification\ExactHeaderSpecification;
|
use Sudalys\ImportService\ErrorHandler\LoggingErrorHandler;
|
||||||
use App\Service\Import\Specification\RegexColumnSpecification;
|
use Sudalys\ImportService\Specification\ExactHeaderSpecification;
|
||||||
use App\Service\Import\Specification\NumericSpecification;
|
use Sudalys\ImportService\Specification\RegexColumnSpecification;
|
||||||
use App\Service\Import\Specification\RequiredColumnSpecification;
|
use Sudalys\ImportService\Specification\NumericSpecification;
|
||||||
use App\Service\Import\Result\ImportResult;
|
use Sudalys\ImportService\Specification\RequiredColumnSpecification;
|
||||||
|
use Sudalys\ImportService\Result\ImportResult;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class CsvImportService
|
class CsvImportService
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Service\Import;
|
namespace Sudalys\ImportService;
|
||||||
|
|
||||||
use App\Service\Import\Interfaces\FileProcessorInterface;
|
use Sudalys\ImportService\Interfaces\FileProcessorInterface;
|
||||||
use App\Service\Import\Interfaces\ValidatorInterface;
|
use Sudalys\ImportService\Interfaces\ValidatorInterface;
|
||||||
use App\Service\Import\Interfaces\ErrorHandlerInterface;
|
use Sudalys\ImportService\Interfaces\ErrorHandlerInterface;
|
||||||
use App\Service\Import\Interfaces\DataProcessorInterface;
|
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
||||||
use App\Service\Import\Result\ImportResult;
|
use Sudalys\ImportService\Result\ImportResult;
|
||||||
|
|
||||||
use function Symfony\Component\DependencyInjection\Loader\Configurator\iterator;
|
use function Symfony\Component\DependencyInjection\Loader\Configurator\iterator;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import;
|
namespace Sudalys\ImportService;
|
||||||
|
|
||||||
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
use Sudalys\ImportService\Interfaces\HeaderSpecificationInterface;
|
||||||
use App\Service\Import\Result\ValidationResult;
|
use Sudalys\ImportService\Result\ValidationResult;
|
||||||
use App\Service\Import\Interfaces\ValidatorInterface;
|
use Sudalys\ImportService\Interfaces\ValidatorInterface;
|
||||||
|
|
||||||
class CsvValidator implements ValidatorInterface
|
class CsvValidator implements ValidatorInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\ErrorHandler;
|
namespace Sudalys\ImportService\ErrorHandler;
|
||||||
use App\Service\Import\Interfaces\ErrorHandlerInterface;
|
use Sudalys\ImportService\Interfaces\ErrorHandlerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class LoggingErrorHandler implements ErrorHandlerInterface
|
class LoggingErrorHandler implements ErrorHandlerInterface
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Service\Import;
|
namespace Sudalys\ImportService;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Interfaces;
|
namespace Sudalys\ImportService\Interfaces;
|
||||||
interface ColumnSpecificationInterface
|
interface ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
public function isSatisfiedBy(string $value): bool;
|
public function isSatisfiedBy(string $value): bool;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Interfaces;
|
namespace Sudalys\ImportService\Interfaces;
|
||||||
interface DataProcessorInterface
|
interface DataProcessorInterface
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Interfaces;
|
namespace Sudalys\ImportService\Interfaces;
|
||||||
interface ErrorHandlerInterface
|
interface ErrorHandlerInterface
|
||||||
{
|
{
|
||||||
public function handle(array $errors): void;
|
public function handle(array $errors): void;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Interfaces;
|
namespace Sudalys\ImportService\Interfaces;
|
||||||
interface FileProcessorInterface
|
interface FileProcessorInterface
|
||||||
{
|
{
|
||||||
public function processFile(string $Path): array;
|
public function processFile(string $Path): array;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Interfaces;
|
namespace Sudalys\ImportService\Interfaces;
|
||||||
interface HeaderSpecificationInterface
|
interface HeaderSpecificationInterface
|
||||||
{
|
{
|
||||||
public function isSatisfiedBy(array $header): bool;
|
public function isSatisfiedBy(array $header): bool;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Interfaces;
|
namespace Sudalys\ImportService\Interfaces;
|
||||||
use App\Service\Import\Result\ValidationResult;
|
use Sudalys\ImportService\Result\ValidationResult;
|
||||||
|
|
||||||
interface ValidatorInterface
|
interface ValidatorInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Processor;
|
namespace Sudalys\ImportService\Processor;
|
||||||
use App\Service\Import\Interfaces\FileProcessorInterface;
|
use Sudalys\ImportService\Interfaces\FileProcessorInterface;
|
||||||
|
|
||||||
use League\Csv\Reader;
|
use League\Csv\Reader;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Processor;
|
namespace Sudalys\ImportService\Processor;
|
||||||
use App\Service\Import\Interfaces\DataProcessorInterface;
|
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
||||||
|
|
||||||
class DatabaseDataProcessor implements DataProcessorInterface
|
class DatabaseDataProcessor implements DataProcessorInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Service\Import\Processor;
|
namespace Sudalys\ImportService\Processor;
|
||||||
|
|
||||||
use App\Service\Import\Interfaces\DataProcessorInterface;
|
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
||||||
//use App\Service\Import\Interfaces\AutreProcessorInterface; // Ajoute d'autres interfaces de traitement si nécessaire
|
//use Sudalys\ImportService\Interfaces\AutreProcessorInterface; // Ajoute d'autres interfaces de traitement si nécessaire
|
||||||
|
|
||||||
class MainProcessor implements DataProcessorInterface
|
class MainProcessor implements DataProcessorInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Service\Import\Result;
|
namespace Sudalys\ImportService\Result;
|
||||||
|
|
||||||
class ImportResult
|
class ImportResult
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Service\Import\Result;
|
namespace Sudalys\ImportService\Result;
|
||||||
|
|
||||||
class ValidationResult
|
class ValidationResult
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Service\Import\Specification;
|
namespace Sudalys\ImportService\Specification;
|
||||||
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
use Sudalys\ImportService\Interfaces\HeaderSpecificationInterface;
|
||||||
|
|
||||||
class ExactHeaderSpecification implements HeaderSpecificationInterface
|
class ExactHeaderSpecification implements HeaderSpecificationInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Specification;
|
namespace Sudalys\ImportService\Specification;
|
||||||
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
class NumericSpecification implements ColumnSpecificationInterface
|
class NumericSpecification implements ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace App\Service\Import\Specification;
|
namespace Sudalys\ImportService\Specification;
|
||||||
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
class RegexColumnSpecification implements ColumnSpecificationInterface
|
class RegexColumnSpecification implements ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,11 @@ class RegexColumnSpecification implements ColumnSpecificationInterface
|
||||||
|
|
||||||
public function isSatisfiedBy(string $value): bool
|
public function isSatisfiedBy(string $value): bool
|
||||||
{
|
{
|
||||||
return preg_match($this->pattern, $value) === 1;
|
if(!empty($value) || !trim($value) === '') {
|
||||||
|
return preg_match($this->pattern, $value) === 1;
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getErrorMessage(): string
|
public function getErrorMessage(): string
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Service\Import\Specification;
|
namespace Sudalys\ImportService\Specification;
|
||||||
|
|
||||||
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
class RequiredColumnSpecification implements ColumnSpecificationInterface
|
class RequiredColumnSpecification implements ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue