CSV import can be easily achieved through PHP's built-in `fgetcsv()` method,
but this method doesn't know anything about your datamodel. In SilverStripe,
this can be handled through the a specialized CSV importer class that can
be customized to fit your data.
## The CsvBulkLoader class
The [api:CsvBulkLoader] class facilitate complex CSV-imports by defining column-mappings and custom converters.
It uses PHP's built-in `fgetcsv()` function to process CSV input, and accepts a file handle as an input.
Feature overview:
* Custom column mapping
* Auto-detection of CSV-header rows
* Duplicate detection based on custom criteria
* Automatic generation of relations based on one or more columns in the CSV-Data
* Definition of custom import methods (e.g. for date conversion or combining multiple columns)
* Optional deletion of existing records if they're not present in the CSV-file
* Results grouped by "imported", "updated" and "deleted"
## Usage
You can use the CsvBulkLoader without subclassing or other customizations, if the column names
in your CSV file match `$db` properties in your dataobject. E.g. a simple import for the
`[api:Member]` class could have this data in a file:
FirstName,LastName,Email
Donald,Duck,donald@disney.com
Daisy,Duck,daisy@disney.com
The loader would be triggered through the `load()` method:
:::php
$loader = new CsvBulkLoader('Member');
$result = $loader->load('<my-file-path>');
By the way, you can import `[api:Member]` and `[api:Group]` data through `http://localhost/admin/security`
interface out of the box.
## Import through ModelAdmin
The simplest way to use [api:CsvBulkLoader] is through a [api:ModelAdmin] interface - you get an upload form out of the box.
:::php
<?php
class PlayerAdmin extends ModelAdmin {
static $managed_models = array(
'Player'
);
static $model_importers = array(
'Player' => 'PlayerCsvBulkLoader',
);
static $url_segment = 'players';
}
?>
The new admin interface will be available under `http://localhost/admin/players`, the import form is located
below the search form on the left.
## Import through a custom controller
You can have more customized logic and interface feedback through a custom controller. Let's create a simple upload form (which is used for `MyDataObject` instances). You can access it through `http://localhost/MyController/?flush=all`.