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": {
|
||||
"psr-4": {
|
||||
"App\\Service\\Import\\": "src/Service/Import/"
|
||||
"Sudalys\\ImportService\\": "src/Service/Import/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
<?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;
|
||||
namespace Sudalys\ImportService;
|
||||
|
||||
use Sudalys\ImportService\CsvValidator;
|
||||
use Sudalys\ImportService\Processor\BasicCsvFileProcessor;
|
||||
use Sudalys\ImportService\Processor\MainProcessor;
|
||||
use Sudalys\ImportService\ErrorHandler\LoggingErrorHandler;
|
||||
use Sudalys\ImportService\Specification\ExactHeaderSpecification;
|
||||
use Sudalys\ImportService\Specification\RegexColumnSpecification;
|
||||
use Sudalys\ImportService\Specification\NumericSpecification;
|
||||
use Sudalys\ImportService\Specification\RequiredColumnSpecification;
|
||||
use Sudalys\ImportService\Result\ImportResult;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class CsvImportService
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Import;
|
||||
namespace Sudalys\ImportService;
|
||||
|
||||
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 Sudalys\ImportService\Interfaces\FileProcessorInterface;
|
||||
use Sudalys\ImportService\Interfaces\ValidatorInterface;
|
||||
use Sudalys\ImportService\Interfaces\ErrorHandlerInterface;
|
||||
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
||||
use Sudalys\ImportService\Result\ImportResult;
|
||||
|
||||
use function Symfony\Component\DependencyInjection\Loader\Configurator\iterator;
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
namespace App\Service\Import;
|
||||
namespace Sudalys\ImportService;
|
||||
|
||||
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
||||
use App\Service\Import\Result\ValidationResult;
|
||||
use App\Service\Import\Interfaces\ValidatorInterface;
|
||||
use Sudalys\ImportService\Interfaces\HeaderSpecificationInterface;
|
||||
use Sudalys\ImportService\Result\ValidationResult;
|
||||
use Sudalys\ImportService\Interfaces\ValidatorInterface;
|
||||
|
||||
class CsvValidator implements ValidatorInterface
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
namespace App\Service\Import\ErrorHandler;
|
||||
use App\Service\Import\Interfaces\ErrorHandlerInterface;
|
||||
namespace Sudalys\ImportService\ErrorHandler;
|
||||
use Sudalys\ImportService\Interfaces\ErrorHandlerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class LoggingErrorHandler implements ErrorHandlerInterface
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Import;
|
||||
namespace Sudalys\ImportService;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Interfaces;
|
||||
namespace Sudalys\ImportService\Interfaces;
|
||||
interface ColumnSpecificationInterface
|
||||
{
|
||||
public function isSatisfiedBy(string $value): bool;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Interfaces;
|
||||
namespace Sudalys\ImportService\Interfaces;
|
||||
interface DataProcessorInterface
|
||||
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Interfaces;
|
||||
namespace Sudalys\ImportService\Interfaces;
|
||||
interface ErrorHandlerInterface
|
||||
{
|
||||
public function handle(array $errors): void;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Interfaces;
|
||||
namespace Sudalys\ImportService\Interfaces;
|
||||
interface FileProcessorInterface
|
||||
{
|
||||
public function processFile(string $Path): array;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Interfaces;
|
||||
namespace Sudalys\ImportService\Interfaces;
|
||||
interface HeaderSpecificationInterface
|
||||
{
|
||||
public function isSatisfiedBy(array $header): bool;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Interfaces;
|
||||
use App\Service\Import\Result\ValidationResult;
|
||||
namespace Sudalys\ImportService\Interfaces;
|
||||
use Sudalys\ImportService\Result\ValidationResult;
|
||||
|
||||
interface ValidatorInterface
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Processor;
|
||||
use App\Service\Import\Interfaces\FileProcessorInterface;
|
||||
namespace Sudalys\ImportService\Processor;
|
||||
use Sudalys\ImportService\Interfaces\FileProcessorInterface;
|
||||
|
||||
use League\Csv\Reader;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Processor;
|
||||
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||
namespace Sudalys\ImportService\Processor;
|
||||
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
||||
|
||||
class DatabaseDataProcessor implements DataProcessorInterface
|
||||
{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Import\Processor;
|
||||
namespace Sudalys\ImportService\Processor;
|
||||
|
||||
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||
//use App\Service\Import\Interfaces\AutreProcessorInterface; // Ajoute d'autres interfaces de traitement si nécessaire
|
||||
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
||||
//use Sudalys\ImportService\Interfaces\AutreProcessorInterface; // Ajoute d'autres interfaces de traitement si nécessaire
|
||||
|
||||
class MainProcessor implements DataProcessorInterface
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Import\Result;
|
||||
namespace Sudalys\ImportService\Result;
|
||||
|
||||
class ImportResult
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Import\Result;
|
||||
namespace Sudalys\ImportService\Result;
|
||||
|
||||
class ValidationResult
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service\Import\Specification;
|
||||
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
||||
namespace Sudalys\ImportService\Specification;
|
||||
use Sudalys\ImportService\Interfaces\HeaderSpecificationInterface;
|
||||
|
||||
class ExactHeaderSpecification implements HeaderSpecificationInterface
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Specification;
|
||||
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||
namespace Sudalys\ImportService\Specification;
|
||||
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
||||
|
||||
class NumericSpecification implements ColumnSpecificationInterface
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
namespace App\Service\Import\Specification;
|
||||
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||
namespace Sudalys\ImportService\Specification;
|
||||
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
||||
|
||||
class RegexColumnSpecification implements ColumnSpecificationInterface
|
||||
{
|
||||
|
@ -15,7 +15,11 @@ class RegexColumnSpecification implements ColumnSpecificationInterface
|
|||
|
||||
public function isSatisfiedBy(string $value): bool
|
||||
{
|
||||
if(!empty($value) || !trim($value) === '') {
|
||||
return preg_match($this->pattern, $value) === 1;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function getErrorMessage(): string
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue