Creating a Custom CSV Importer for SilverStripe

I am working on creating a custom import engine for the SilverStripe site because the CSV files to be used are unfortunately not CSV formatted and cannot be improved (we have to work with what we are given for the most part). The files contain data separated by semi-colors, and each line is one entry:

"[ID]";"[First Name]";"[Middle Initial]";"[Last Name]";"[Title]";"[University/College]";"[Specialty]";"[Graduation Date]"

      

Any of these values ​​can be empty (i.e., the record may not have an average starting value or may not have a specified specialty). These fields are then simply marked as one space in a pair of double quotes:

"[ID]";"[First Name]";" ";"[Last Name]";"[Title]";"[University/College]";" ";"[Graduation Date]"

      

It's also important to note that CSV files do not have headers, and it is unlikely that they will be able to. I read about the CSVBulkLoader class for SilverStripe but it seems difficult to use without headers. Also, there is a problem with empty fields as I mentioned.

Is it possible to customize a file that splits data in CSV files at semicolons? That way, I could get each value on one line, and I could map them to fields in the SilverStripe Admin Model.

Here is the admin model I'm currently working on:

<?php
class PhysicianEducationAdmin extends ModelAdmin {

    private static $managed_models = array('PhysicianEducation');
    private static $url_segment = 'physicianeducation';
    private static $menu_title = 'Physician Education Info';

}

<?php

class PhysicianEducation extends DataObject {

    private static $db = array(
        'ProviderID' => 'varchar',
        'FirstName' => 'varchar(250)',
        'MiddleName' => 'varchar(250)',
        'LastName' => 'varchar(250)',
        'Title' => 'varchar(10)',
        'Institution' => 'varchar(550)',
        'Education' => 'varchar(250)',
        'Specialty' => 'varchar(250)',
        'EndDate' => 'Date',
    );

    public static $summary_fields = array(
        'ProviderID' => 'Provider ID',
        'FirstName' => 'First Name',
        'MiddleName' => 'Middle Initial',
        'LastName' => 'Last Name',
        'Title' => 'Title',
        'Institution' => 'Institution',
        'Education' => 'Education',
        'Specialty' => 'Speciality',
        'EndDate' => 'End Date',
    );

}

      

+3


source to share


2 answers


You should be able to use the fgetcsv () function http://php.net/manual/en/function.fgetcsv.php .



It allows you to specify a delimiter (for you ";") and a body (for you ""), which is the default.

+2


source


Silverstripe includes a CSVParser class that you can use for this. You can pass the delimiter as the second parameter in the constructor. Since the file does not have a header line, you can provide it with a function provideHeaderRow

. CSVParser implements the Iterator interface, so you can iterate over the object inside the loop:

$physicians = CSVParser::create('myfile.csv', ';');
$physicians->provideHeaderRow(array(...));

foreach($physicians as $physician) {
  $pe = PhysicianEducation::create()->update($physician);
  $pe->write();
}

      



You will need to add some validation to your DataObject (maybe do some validation in onBeforeWrite, or subclass Validator) to prevent invalid entries (such as empty fields) from being created.

+1


source







All Articles