silverstripe-framework/docs/en/02_Developer_Guides/11_Integration/How_Tos/custom_csvbulkloader.md
Aaron Carlino 6888901468
NEW: Update docs to be compliant with Gatsby site (#9314)
* First cut

* Temporarily disable composer.json for netlify build

* POC

* New recursive directory query, various refinements

* Fix flexbox

* new styled components plugin

* Apply frontmatter delimiters

* Mobile styles, animation

* Search

* Redesign, clean up

* Nuke the cache, try again

* fix file casing

* Remove production env file

* ID headers

* Move app to new repo

* Add frontmatter universally

* Hide children changelogs

* Add how to title

* New callout tags

* Revert inline code block change

* Replace note callouts

* Fix icons

* Repalce images

* Fix icon

* Fix image links

* Use proper SQL icon
2019-11-18 17:58:33 +13:00

120 lines
3.0 KiB
Markdown

---
title: A custom CSVBulkLoader instance
summary: Customise your data importing
icon: upload
---
# How to: A custom CSVBulkLoader instance
A an implementation of a custom `CSVBulkLoader` loader. In this example. we're provided with a unique CSV file
containing a list of football players and the team they play for. The file we have is in the format like below.
```
"SpielerNummer", "Name", "Geburtsdatum", "Gruppe"
11, "John Doe", 1982-05-12,"FC Bayern"
12, "Jane Johnson", 1982-05-12,"FC Bayern"
13, "Jimmy Dole",,"Schalke 04"
```
This data needs to be imported into our application. For this, we have two `DataObjects` setup. `Player` contains
information about the individual player and a relation set up for managing the `Team`.
**app/code/Player.php**.
```php
use SilverStripe\ORM\DataObject;
class Player extends DataObject
{
private static $db = [
'PlayerNumber' => 'Int',
'FirstName' => 'Text',
'LastName' => 'Text',
'Birthday' => 'Date'
];
private static $has_one = [
'Team' => 'FootballTeam'
];
}
```
**app/code/FootballTeam.php**
```php
use SilverStripe\ORM\DataObject;
class FootballTeam extends DataObject
{
private static $db = [
'Title' => 'Text'
];
private static $has_many = [
'Players' => 'Player'
];
}
```
Now going back to look at the CSV, we can see that what we're provided with does not match what our data model looks
like, so we have to create a sub class of `CsvBulkLoader` to handle the unique file. Things we need to consider with
the custom importer are:
* Convert property names (e.g Number to PlayerNumber) through providing a `$columnMap`.
* Split a combined "Name" field into `FirstName` and `LastName` by calling `importFirstAndLastName` on the `Name`
column
* Prevent duplicate imports by a custom `$duplicateChecks` definition.
* Create a `Team` automatically based on the `Gruppe` column and a entry for `$relationCallbacks`
Our final import looks like this.
**app/code/PlayerCsvBulkLoader.php**
```php
use SilverStripe\Dev\CsvBulkLoader;
class PlayerCsvBulkLoader extends CsvBulkLoader
{
public $columnMap = [
'Number' => 'PlayerNumber',
'Name' => '->importFirstAndLastName',
'Geburtsdatum' => 'Birthday',
'Gruppe' => 'Team.Title',
];
public $duplicateChecks = [
'SpielerNummer' => 'PlayerNumber'
];
public $relationCallbacks = [
'Team.Title' => [
'relationname' => 'Team',
'callback' => 'getTeamByTitle'
]
];
public static function importFirstAndLastName(&$obj, $val, $record)
{
$parts = explode(' ', $val);
if(count($parts) != 2) return false;
$obj->FirstName = $parts[0];
$obj->LastName = $parts[1];
}
public static function getTeamByTitle(&$obj, $val, $record)
{
return FootballTeam::get()->filter('Title', $val)->First();
}
}
```
## Related
* [CsvParser](api:SilverStripe\Dev\CsvParser)
* [ModelAdmin](api:SilverStripe\Admin\ModelAdmin)