Compare commits

..

7 Commits
1.0.0 ... main

Author SHA1 Message Date
Dorian Contal 5acb21d503 Changement nom README pour affichage dans packagist 2025-05-14 10:53:04 +02:00
Dorian 6853bf95ae Condition si var vide non obligatoire mais regex 2025-05-14 10:46:22 +02:00
Dorian Contal e67eb62e57 Modif readme inclusion yaml et exemple import 2025-04-23 11:52:47 +02:00
Dorian Contal 0d3686e34e externalisation des import et use du package 2025-04-23 11:31:50 +02:00
Dorian Contal 07fe6226b8 Modification namespace 2025-04-23 11:06:32 +02:00
Dorian db5b7b7575 Actualiser Readme.md 2025-04-23 09:12:37 +02:00
Dorian 2ea5ff9a9c Actualiser Readme.md 2025-04-23 09:10:33 +02:00
23 changed files with 169 additions and 49 deletions

115
README.md Normal file
View File

@ -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

View File

View File

@ -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",

View File

@ -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

View File

@ -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;

View File

@ -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
{ {

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace App\Service\Import\Interfaces; namespace Sudalys\ImportService\Interfaces;
interface DataProcessorInterface interface DataProcessorInterface
{ {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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
{ {

View File

@ -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;

View File

@ -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
{ {

View File

@ -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
{ {

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Service\Import\Result; namespace Sudalys\ImportService\Result;
class ImportResult class ImportResult
{ {

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Service\Import\Result; namespace Sudalys\ImportService\Result;
class ValidationResult class ValidationResult
{ {

View File

@ -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
{ {

View File

@ -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
{ {

View File

@ -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
{ {
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

View File

@ -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
{ {