How to Import External Data into SilverStripe models

I have been working on importing external data into SilverStripe(SS) models. This post is for advanced users of SilverStripe CMS.
Assume we have SS models, Food and FoodCategory to which we want to import data into.

Food.php

class Food extends DataObject {
   public static $db = array(
      'ImportID' => 'Int', //reference primary key from old table
      'Name' => 'Varchar',
      'Slug' => 'Varchar',
   );
 
   public static $has_one = array(
     'FoodCategory' => 'FoodCategory'
   );
 
   public static $summary_fields = array(
     'Name', 'Slug'
   );
}

FoodCategory.php

class FoodCategory extends DataObject {
   public static $db = array(
      'Type' => 'Varchar',
   );
   
   public static $has_one = array(
      'Food' => 'Food'
   );
	
   public static $summary_fields = array(
      'Type'
   );
}

I am importing the data via ModelAdmin and the below class FoodImporter.php is being used. It extends the CsvBulkLoader framework class.
food_id, fk_foodcategory, name and slug are table fields in old tbl_food table which are mapped to the corresponding new SilverStripe Food table.
The importer checks for unique food titles and id’s to avoid duplicates.

FoodImporter.php

class FoodImporter extends CsvBulkLoader {

    public $columnMap = array(
       'food_id' => 'ImportID',
       'fk_foodcategory' => 'FoodCategoryID',
       'name' => 'Name',
       'slug' => 'Slug',
    );
   
    public $duplicateChecks = array(
       'ID' => array(
       'callback' => 'findDuplicateByImportID'
        ),
       'Name' => array(
       'callback' => 'findDuplicateByFoodName'
       )
    );

    public function __construct($objectClass = 'Food') {
	parent::__construct($objectClass);
    }

   /**
   * Find an existing object based on unique id
   * columns specified via {@link self::$duplicateChecks}
   *
   * @param int $ImportId CSV id column
   * @param array $record CSV data column
   * @return first array record
   */
   protected function findDuplicateByImportID($ImportId, $record) {
       if(!$ImportId) return;
       if(!singleton('Food')->hasDatabaseField($this->columnMap['food_id'])) return;
      return Food::get()->filter($this->columnMap['food_id'], $ImportId)->First();
   }

   /**
   * Find existing objects based on food title/name
   * columns specified via {@link self::$duplicateChecks}
   *
   * @param string $name CSV food name column
   * @param array $record CSV data column
   * @return first array record
   */
   protected function findDuplicateByFoodName($name, $record) {
       if(!$name) return;
       if(!singleton('Food')->hasDatabaseField($this->columnMap['name'])) return;

      return Food::get()->filter($this->columnMap['name'], $name)->First();
   }

}

Add a Comment

Your email address will not be published. Required fields are marked *

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Anti-spam image