Home » Featured, Headline, Software Development

How to Import External Data into SilverStripe models

16 April 2013 No Comment

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();
   }

}

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.

*
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