Utility class to facilitate complex CSV-imports by defining column-mappings and custom converters. Uses the fgetcsv() function to process CSV input. Accepts a file-handler as input
Simple upload form (creates new MyDataObject instances). You can access it through
/MyController/?flush=all.
<?php class MyController extends Controller { protected $template = "BlankPage"; function Link($action = null) { return Controller::join_links('MyController', $action); } function Form() { $form = new Form( $this, 'Form', new FieldSet( new FileField('CsvFile', false) ), new FieldSet( new FormAction('doUpload', 'Upload') ), new RequiredFields() ); return $form; } function doUpload($data, $form) { $loader = new CsvBulkLoader('MyDataObject'); $results = $loader->load($_FILES['CsvFile']['tmp_name']); $messages = array(); if($results->CreatedCount()) $messages[] = sprintf('Imported %d items', $results->CreatedCount()); if($results->UpdatedCount()) $messages[] = sprintf('Updated %d items', $results->UpdatedCount()); if($results->DeletedCount()) $messages[] = sprintf('Deleted %d items', $results->DeletedCount()); if(!$messages) $messages[] = 'No changes'; $form->sessionMessage(implode(', ', $messages), 'good'); return $this->redirectBack(); } }
Sample CSV Content
"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"
Datamodel for TeamMember
<?php class Player extends DataObject { static $db = array( 'PlayerNumber' => 'Int', 'FirstName' => 'Text', 'LastName' => 'Text', 'Birthday' => 'Date', ); static $has_one = array( 'Team' => 'FootballTeam' ); } ?>
Datamodel for FootballTeam:
<?php class FootballTeam extends DataObject { static $db = array( 'Title' => 'Text', ); static $has_many = array( 'Players' => 'Player' ); } ?>
Sample implementation of a custom loader. Assumes a CSV-file in a certain format (see below).
FirstName and Lastname by a custom importer method$duplicateChecks definitionTeam relations automatically based on the Gruppe colum in the CSV data<?php class PlayerCsvBulkLoader extends CsvBulkLoader { public $columnMap = array( 'Number' => 'PlayerNumber', 'Name' => '->importFirstAndLastName', 'Geburtsdatum' => 'Birthday', 'Gruppe' => 'Team.Title', ); public $duplicateChecks = array( 'SpielerNummer' => 'PlayerNumber' ); public $relationCallbacks = array( 'Team.Title' => array( 'relationname' => 'Team', 'callback' => 'getTeamByTitle' ) ); static function importFirstAndLastName(&$obj, $val, $record) { $parts = explode(' ', $val); if(count($parts) != 2) return false; $obj->FirstName = $parts[0]; $obj->LastName = $parts[1]; } static function getTeamByTitle(&$obj, $val, $record) { $SQL_val = Convert::raw2sql($val); return DataObject::get_one( 'FootballTeam', "Title = '{$SQL_val}'" ); } } ?>
Integration into a new ModelAdmin instance to get an upload form out of the box (accessible through /admin/players):
<?php class PlayerAdmin extends ModelAdmin { static $managed_models = array( 'Player' ); static $model_importers = array( 'Player' => 'PlayerCsvBulkLoader', ); static $url_segment = 'players'; } ?>
Please use comments for notes, tips and corrections about the described
functionality.
Use the Silverstripe Forum to
ask questions.