Hello,
I'm working on a little internal CMS project using Silverstripe and I'm hitting a small bug. Wondering if it's an issue or if it's something I've overlooked.
I have a StaticText model that manages an arbitrary number of bits of text (essays, description, copyright statements, etc) as a has_many on either a Publication or Format model. This is working just fine.
I am using ModelAdmin (https://docs.silverstripe.org/en/3.3/developer_guides/customising_the_admin_interface/modeladmin/) to manage the interface. I'm also using CsvBulkLoader to import existing data from CSV. This is where I run into some problems.
The CSV import is working, and even gets as far as setting the ID number of the right polymorphic association (ie, StaticTextOfID has the right ID for Format on Format-related StaticTexts, and has the right ID for Publication on Publication-related StaticTexts). However, all of the values for the polymorphic class name in the db are set to "File".
The Silverstripe ORM creates the polymorphic "…OfClass" field as an Enum and includes all classes it knows about. The first on the list is "File", and since the Enum type does not allow nil values, it seems like that "File" value is coming from a blank value defaulting to the first one on the list. SO the only missing bit here is getting the CSVBulkUploader to set the Class of the polymorphic relation.
Bonus question: The other thing I am not sure how to handle is how I can make a dropdown select in ModelAdmin of all possible has_manys in the polymorphic relationship, ie, if I create a new StaticText, see all Formats and Publications together in one dropdown? Might not be possible, but thought I'd ask.
code follows:
ModelAdmin setup:
class PPAdmin extends ModelAdmin {
private static $managed_models = array(
'Format',
'Publication',
'StaticText'
);
private static $model_importers = array(
'Format' => 'CsvBulkLoader',
'Publication' => 'PublicationCsvBulkLoader',
'StaticText' => 'StaticTextCsvBulkLoader',
);
private static $url_segment = 'pp';
private static $menu_title = 'PP Content';
}
Publication model:
class Publication extends DataObject {
private static $db = array(
'Title' => 'Varchar(255)',
'Code' => 'Varchar(255)',
'Region' => "Enum('National,Northland,Auckland,Waikato,Bay of Plenty,Gisborne,Taranaki,Manawatu,Hawke\'s Bay,Wellington,Nelson,Marlborough,West Coast,Canterbury,Otago,Samoa')",
'TitleAlternate' => 'Varchar(255)',
'Publish' => "Enum('classic,staging,beta,everywhere')"
);
private static $has_many = array(
'StaticTexts' => 'StaticText.StaticTextOf'
);
private static $has_one = array(
'Format' => 'Format'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$formatList = Format::get()->map()->toArray();
$formatSelect = DropdownField::create('FormatID', 'Format')->setSource($formatList);
$fields->replaceField('FormatID', $formatSelect);
return $fields;
}
private static $defaults = array(
"Region" => 'National',
"Publish" => 'everywhere',
);
private static $summary_fields = array(
'Title',
'Code',
'Region',
'Publish'
);
StaticText model:
class StaticText extends DataObject {
private static $db = array(
'Language' => "Enum('en,mi')",
'Code' => "Enum('Acknowledgement,Essay,Description,Copyright,Content-acknowledgement,ShortText,LongText')",
'Content' => 'Text',
'StartYear' => 'Int',
'EndYear' => 'Int',
'Append' => "Enum('Yes,No')",
'Status' => "Enum('Unconfirmed,Needs Translation,Confirmed,Needs Editing')",
'Publish' => "Enum('classic,staging,beta,everywhere')"
);
private static $has_one = array(
'StaticTextOf' => 'DataObject'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$item_field = DropdownField::create('StaticTextOf');
$fields->addFieldToTab('Root.Main', $item_field);
return $fields;
}
private static $defaults = array(
"Language" => 'en',
"Append" => 'No',
"Status" => 'Unconfirmed',
"Publish" => 'everywhere',
);
private static $summary_fields = array(
'Language',
'Code',
'Status',
'Publish'
);
STaticTextUploader:
class StaticTextCsvBulkLoader extends CsvBulkLoader {
public $relationCallbacks = array(
'StaticTextOf' => array(
'relationname' => 'StaticTextOf',
'callback' => 'getItemByTitle'
)
);
public static function getItemByTitle(&$obj, $val, $record) {
$parts = split('---', $val, 2);
if ($parts[0] == 'Format') {
$item = Format::get()->filter('Title', $parts[1])->First();
} else {
$item = Publication::get()->filter('Title', $parts[1])->First();
}
return $item;
}
}