Compare commits
No commits in common. "main" and "1.0.0" have entirely different histories.
115
README.md
115
README.md
|
@ -1,115 +0,0 @@
|
||||||
# 📦 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": {
|
||||||
"Sudalys\\ImportService\\": "src/Service/Import/"
|
"App\\Service\\Import\\": "src/Service/Import/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService;
|
namespace App\Service\Import;
|
||||||
|
use App\Service\Import\CsvValidator;
|
||||||
use Sudalys\ImportService\CsvValidator;
|
use App\Service\Import\Processor\BasicCsvFileProcessor;
|
||||||
use Sudalys\ImportService\Processor\BasicCsvFileProcessor;
|
use App\Service\Import\Processor\MainProcessor;
|
||||||
use Sudalys\ImportService\Processor\MainProcessor;
|
use App\Service\Import\ErrorHandler\LoggingErrorHandler;
|
||||||
use Sudalys\ImportService\ErrorHandler\LoggingErrorHandler;
|
use App\Service\Import\Specification\ExactHeaderSpecification;
|
||||||
use Sudalys\ImportService\Specification\ExactHeaderSpecification;
|
use App\Service\Import\Specification\RegexColumnSpecification;
|
||||||
use Sudalys\ImportService\Specification\RegexColumnSpecification;
|
use App\Service\Import\Specification\NumericSpecification;
|
||||||
use Sudalys\ImportService\Specification\NumericSpecification;
|
use App\Service\Import\Specification\RequiredColumnSpecification;
|
||||||
use Sudalys\ImportService\Specification\RequiredColumnSpecification;
|
use App\Service\Import\Result\ImportResult;
|
||||||
use Sudalys\ImportService\Result\ImportResult;
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
class CsvImportService
|
class CsvImportService
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Sudalys\ImportService;
|
namespace App\Service\Import;
|
||||||
|
|
||||||
use Sudalys\ImportService\Interfaces\FileProcessorInterface;
|
use App\Service\Import\Interfaces\FileProcessorInterface;
|
||||||
use Sudalys\ImportService\Interfaces\ValidatorInterface;
|
use App\Service\Import\Interfaces\ValidatorInterface;
|
||||||
use Sudalys\ImportService\Interfaces\ErrorHandlerInterface;
|
use App\Service\Import\Interfaces\ErrorHandlerInterface;
|
||||||
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||||
use Sudalys\ImportService\Result\ImportResult;
|
use App\Service\Import\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 Sudalys\ImportService;
|
namespace App\Service\Import;
|
||||||
|
|
||||||
use Sudalys\ImportService\Interfaces\HeaderSpecificationInterface;
|
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
||||||
use Sudalys\ImportService\Result\ValidationResult;
|
use App\Service\Import\Result\ValidationResult;
|
||||||
use Sudalys\ImportService\Interfaces\ValidatorInterface;
|
use App\Service\Import\Interfaces\ValidatorInterface;
|
||||||
|
|
||||||
class CsvValidator implements ValidatorInterface
|
class CsvValidator implements ValidatorInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\ErrorHandler;
|
namespace App\Service\Import\ErrorHandler;
|
||||||
use Sudalys\ImportService\Interfaces\ErrorHandlerInterface;
|
use App\Service\Import\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 Sudalys\ImportService;
|
namespace App\Service\Import;
|
||||||
|
|
||||||
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 Sudalys\ImportService\Interfaces;
|
namespace App\Service\Import\Interfaces;
|
||||||
interface ColumnSpecificationInterface
|
interface ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
public function isSatisfiedBy(string $value): bool;
|
public function isSatisfiedBy(string $value): bool;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Interfaces;
|
namespace App\Service\Import\Interfaces;
|
||||||
interface DataProcessorInterface
|
interface DataProcessorInterface
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Interfaces;
|
namespace App\Service\Import\Interfaces;
|
||||||
interface ErrorHandlerInterface
|
interface ErrorHandlerInterface
|
||||||
{
|
{
|
||||||
public function handle(array $errors): void;
|
public function handle(array $errors): void;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Interfaces;
|
namespace App\Service\Import\Interfaces;
|
||||||
interface FileProcessorInterface
|
interface FileProcessorInterface
|
||||||
{
|
{
|
||||||
public function processFile(string $Path): array;
|
public function processFile(string $Path): array;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Interfaces;
|
namespace App\Service\Import\Interfaces;
|
||||||
interface HeaderSpecificationInterface
|
interface HeaderSpecificationInterface
|
||||||
{
|
{
|
||||||
public function isSatisfiedBy(array $header): bool;
|
public function isSatisfiedBy(array $header): bool;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Interfaces;
|
namespace App\Service\Import\Interfaces;
|
||||||
use Sudalys\ImportService\Result\ValidationResult;
|
use App\Service\Import\Result\ValidationResult;
|
||||||
|
|
||||||
interface ValidatorInterface
|
interface ValidatorInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Processor;
|
namespace App\Service\Import\Processor;
|
||||||
use Sudalys\ImportService\Interfaces\FileProcessorInterface;
|
use App\Service\Import\Interfaces\FileProcessorInterface;
|
||||||
|
|
||||||
use League\Csv\Reader;
|
use League\Csv\Reader;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Processor;
|
namespace App\Service\Import\Processor;
|
||||||
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||||
|
|
||||||
class DatabaseDataProcessor implements DataProcessorInterface
|
class DatabaseDataProcessor implements DataProcessorInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Sudalys\ImportService\Processor;
|
namespace App\Service\Import\Processor;
|
||||||
|
|
||||||
use Sudalys\ImportService\Interfaces\DataProcessorInterface;
|
use App\Service\Import\Interfaces\DataProcessorInterface;
|
||||||
//use Sudalys\ImportService\Interfaces\AutreProcessorInterface; // Ajoute d'autres interfaces de traitement si nécessaire
|
//use App\Service\Import\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 Sudalys\ImportService\Result;
|
namespace App\Service\Import\Result;
|
||||||
|
|
||||||
class ImportResult
|
class ImportResult
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Sudalys\ImportService\Result;
|
namespace App\Service\Import\Result;
|
||||||
|
|
||||||
class ValidationResult
|
class ValidationResult
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Sudalys\ImportService\Specification;
|
namespace App\Service\Import\Specification;
|
||||||
use Sudalys\ImportService\Interfaces\HeaderSpecificationInterface;
|
use App\Service\Import\Interfaces\HeaderSpecificationInterface;
|
||||||
|
|
||||||
class ExactHeaderSpecification implements HeaderSpecificationInterface
|
class ExactHeaderSpecification implements HeaderSpecificationInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Specification;
|
namespace App\Service\Import\Specification;
|
||||||
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
class NumericSpecification implements ColumnSpecificationInterface
|
class NumericSpecification implements ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Sudalys\ImportService\Specification;
|
namespace App\Service\Import\Specification;
|
||||||
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
class RegexColumnSpecification implements ColumnSpecificationInterface
|
class RegexColumnSpecification implements ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
|
@ -15,11 +15,7 @@ class RegexColumnSpecification implements ColumnSpecificationInterface
|
||||||
|
|
||||||
public function isSatisfiedBy(string $value): bool
|
public function isSatisfiedBy(string $value): bool
|
||||||
{
|
{
|
||||||
if(!empty($value) || !trim($value) === '') {
|
return preg_match($this->pattern, $value) === 1;
|
||||||
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 Sudalys\ImportService\Specification;
|
namespace App\Service\Import\Specification;
|
||||||
|
|
||||||
use Sudalys\ImportService\Interfaces\ColumnSpecificationInterface;
|
use App\Service\Import\Interfaces\ColumnSpecificationInterface;
|
||||||
|
|
||||||
class RequiredColumnSpecification implements ColumnSpecificationInterface
|
class RequiredColumnSpecification implements ColumnSpecificationInterface
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue