Installation Add the package via Composer:
composer require bigfoot/import-bundle:dev-master
Register the bundle in app/AppKernel.php:
new BigFoot\ImportBundle\BigFootImportBundle(),
Generate Base Structure Run the update command to scaffold the bundle:
php app/console generate:update
Generate your entity from a CSV/XML file:
php app/console generate:doctrine:entity
Update the database schema:
php app/console doctrine:schema:update --force
First Use Case: CSV Import
Services directory in your bundle.AbstractSimpleDataMapper for your entity:
namespace AppBundle\Services;
use BigFoot\ImportBundle\Services\AbstractSimpleDataMapper;
class MyEntityDataMapper extends AbstractSimpleDataMapper
{
const FIELD_ID = 'id';
const FIELD_NAME = 'name';
const FIELD_DESCRIPTION = 'description';
protected function getEntityClass()
{
return 'AppBundle\Entity\MyEntity';
}
}
$mapper = new MyEntityDataMapper();
$mapper->import($filePath);
CSV Import Workflow
mapData() in AbstractSimpleDataMapper:
protected function mapData($data)
{
$entity = new $this->getEntityClass();
$entity->setId($data[self::FIELD_ID]);
$entity->setName($data[self::FIELD_NAME]);
return $entity;
}
postImport():
protected function postImport($entities)
{
$em = $this->getEntityManager();
foreach ($entities as $entity) {
$em->persist($entity);
}
$em->flush();
}
XML Import Workflow
XmlMapper (documented in ./Resources/doc/xmlmapper.md) for XML-specific logic.$xmlMapper = new \BigFoot\ImportBundle\Services\XmlMapper();
$xmlMapper->map($xmlFile, $entity);
Batch Processing
$mapper->setChunkSize(100); // Process 100 rows at a time
$mapper->import($filePath);
import.pre/import.post events for cross-cutting concerns (e.g., logging, notifications).services.yml for reusable imports:
services:
app.my_entity_mapper:
class: AppBundle\Services\MyEntityDataMapper
arguments: ['@doctrine.orm.entity_manager']
Deprecated Package
doctrine/orm, symfony/console) manually.CSV Parsing Quirks
strtolower() in constants if headers vary:
const FIELD_NAME = strtolower('Name'); // 'name' vs 'NAME'
,). Override getDelimiter() if using tabs (\t) or pipes (|).XML Namespace Issues
XmlMapper or pre-process XML:
$xml = simplexml_load_file($filePath);
$xml->registerXPathNamespace('ns', 'http://example.com/ns');
Entity Manager Injection
AbstractSimpleDataMapper expects an EntityManager via constructor. Inject it explicitly:
$mapper = new MyEntityDataMapper($em);
preImport() to log file paths/headers:
protected function preImport($filePath)
{
$this->logger->info('Importing: ' . $filePath);
$headers = $this->getCsvHeaders($filePath);
$this->logger->debug('Headers:', $headers);
}
var_dump() or dd() in mapData() to inspect raw input:
protected function mapData($data)
{
dd($data); // Debug raw CSV row
// ...
}
prePersist() to avoid conflicts:
protected function prePersist($entity)
{
if ($this->entityExists($entity)) {
throw new \RuntimeException('Duplicate entity detected');
}
}
Custom Mappers
AbstractSimpleDataMapper for complex logic (e.g., nested entities, multi-step imports).class OrderDataMapper extends AbstractSimpleDataMapper
{
protected function mapData($data)
{
$order = new Order();
$order->setCustomer($this->mapCustomer($data));
return $order;
}
private function mapCustomer($data)
{
$customer = new Customer();
$customer->setEmail($data[self::FIELD_CUSTOMER_EMAIL]);
return $customer;
}
}
File Format Support
$data = json_decode(file_get_contents($filePath), true);
$mapper->import($data); // Modify mapper to handle arrays
Configuration
# app/config/config.yml
bigfoot_import:
default_chunk_size: 500
default_delimiter: ';'
$chunkSize = $this->container->getParameter('bigfoot_import.default_chunk_size');
How can I help you explore Laravel packages today?