Skip to content

Commit 60edbf3

Browse files
committed
allow custom handlers description and distinct sample files
1 parent da0adb8 commit 60edbf3

File tree

3 files changed

+90
-28
lines changed

3 files changed

+90
-28
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,27 @@ This require some custom code on your `ModelAdmin` class that could look like th
6464
The import handlers only need to implement a `load` method that needs to return a result string
6565
or a `BulkLoader_Result` object.
6666

67+
These custom handlers can have a custom description and a custom sample file:
68+
69+
```php
70+
public static function getImportDescription()
71+
{
72+
return "This is my custom description";
73+
}
74+
75+
public static function getSampleFileLink()
76+
{
77+
return ExcelImportExport::createDownloadSampleLink(__CLASS__);
78+
}
79+
80+
public static function getSampleFile()
81+
{
82+
$data = []; // TODO
83+
ExcelImportExport::createSampleFile($data, __CLASS__);
84+
}
85+
86+
```
87+
6788
## Compatibility
6889

6990
Tested with ^5 and up

src/ExcelImportExport.php

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,32 @@ public static function importFieldsForClass($class)
151151
return array_combine($importedFields, $importedFields);
152152
}
153153

154+
public static function createDownloadSampleLink($importer = '')
155+
{
156+
/** @var \SilverStripe\Admin\ModelAdmin $owner */
157+
$owner = Controller::curr();
158+
$class = $owner->getModelClass();
159+
$downloadSampleLink = $owner->Link(str_replace('\\', '-', $class) . '/downloadsample?importer=' . urlencode($importer));
160+
$downloadSample = '<a href="' . $downloadSampleLink . '" class="no-ajax" target="_blank">' . _t(
161+
'ExcelImportExport.DownloadSample',
162+
'Download sample file'
163+
) . '</a>';
164+
return $downloadSample;
165+
}
166+
167+
public static function createSampleFile($data, $fileName)
168+
{
169+
$ext = self::getDefaultExtension();
170+
$fileNameExtension = pathinfo($fileName, PATHINFO_EXTENSION);
171+
if (!$fileNameExtension) {
172+
$fileName .= ".$ext";
173+
}
174+
$options = new Options();
175+
$options->creator = ExcelImportExport::config()->default_creator;
176+
SpreadCompat::output($data, $fileName, $options);
177+
exit();
178+
}
179+
154180
/**
155181
* Output a sample file for a class
156182
*
@@ -190,10 +216,7 @@ public static function sampleFileForClass($class)
190216
throw new Exception("`sampleImportData` must return an iterable");
191217
}
192218

193-
$options = new Options();
194-
$options->creator = ExcelImportExport::config()->default_creator;
195-
SpreadCompat::output($data, $fileName, $options);
196-
exit();
219+
self::createSampleFile($data, $fileName);
197220
}
198221

199222
/**

src/extensions/ModelAdminExcelExtension.php

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@ public function downloadsample()
8080
{
8181
/** @var \SilverStripe\Admin\ModelAdmin $owner */
8282
$owner = $this->owner;
83-
ExcelImportExport::sampleFileForClass($owner->getModelClass());
83+
$importer = $owner->getRequest()->getVar('importer');
84+
if ($importer && class_exists($importer) && method_exists($importer, 'getSampleFile')) {
85+
$importer::getSampleFile();
86+
} else {
87+
ExcelImportExport::sampleFileForClass($owner->getModelClass());
88+
}
8489
}
8590

8691
/**
@@ -166,17 +171,41 @@ public function updateImportForm(Form $form)
166171

167172
$fields = $form->Fields();
168173

169-
$downloadSampleLink = $owner->Link(str_replace('\\', '-', $class) . '/downloadsample');
170-
$downloadSample = '<a href="' . $downloadSampleLink . '" class="no-ajax" target="_blank">' . _t(
171-
'ExcelImportExport.DownloadSample',
172-
'Download sample file'
173-
) . '</a>';
174+
// We can implement a custom handler
175+
$importHandlers = [];
176+
$htmlDesc = '';
177+
$useDefaultSample = true;
178+
if ($modelSNG->hasMethod('listImportHandlers')) {
179+
$importHandlers = array_merge([
180+
'default' => _t('ExcelImportExport.DefaultHandler', 'Default import handler'),
181+
], $modelSNG->listImportHandlers());
182+
183+
$supportOnlyUpdate = [];
184+
foreach ($importHandlers as $class => $label) {
185+
if (!class_exists($class)) {
186+
continue;
187+
}
188+
if (method_exists($class, 'setOnlyUpdate')) {
189+
$supportOnlyUpdate[] = $class;
190+
}
191+
if (method_exists($class, 'getImportDescription')) {
192+
$htmlDesc .= '<div class="js-import-desc" data-name="' . $class . '" hidden>' . $class::getImportDescription() . '</div>';
193+
}
194+
if (method_exists($class, 'getSampleFileLink')) {
195+
$useDefaultSample = false;
196+
$htmlDesc .= '<div class="js-import-desc" data-name="' . $class . '" hidden>' . $class::getSampleFileLink() . '</div>';
197+
}
198+
}
199+
}
174200

175201
/** @var \SilverStripe\Forms\FileField|null $file */
176202
$file = $fields->dataFieldByName('_CsvFile');
177203
if ($file) {
178204
$csvDescription = ExcelImportExport::getValidExtensionsText();
179-
$csvDescription .= '. ' . $downloadSample;
205+
if ($useDefaultSample) {
206+
$downloadSample = ExcelImportExport::createDownloadSampleLink();
207+
$csvDescription .= '. ' . $downloadSample;
208+
}
180209
$file->setDescription($csvDescription);
181210
$file->getValidator()->setAllowedExtensions(ExcelImportExport::getValidExtensions());
182211
}
@@ -194,30 +223,19 @@ public function updateImportForm(Form $form)
194223
// We moved the specs into a nice to use download sample button
195224
$fields->removeByName("SpecFor{$modelName}");
196225

197-
// We can implement a custom handler
198-
$importHandlers = [];
199-
if ($modelSNG->hasMethod('listImportHandlers')) {
200-
$importHandlers = array_merge([
201-
'default' => _t('ExcelImportExport.DefaultHandler', 'Default import handler'),
202-
], $modelSNG->listImportHandlers());
203-
204-
$supportOnlyUpdate = [];
205-
foreach ($importHandlers as $class => $label) {
206-
if (class_exists($class) && method_exists($class, 'setOnlyUpdate')) {
207-
$supportOnlyUpdate[] = $class;
208-
}
209-
}
210-
226+
if (!empty($importHandlers)) {
211227
$form->Fields()->push($OnlyUpdateRecords = new CheckboxField("OnlyUpdateRecords", _t('ExcelImportExport.OnlyUpdateRecords', "Only update records")));
212228
$OnlyUpdateRecords->setAttribute("data-handlers", implode(",", $supportOnlyUpdate));
213-
}
214-
if (!empty($importHandlers)) {
229+
215230
$form->Fields()->push($ImportHandler = new OptionsetField("ImportHandler", _t('ExcelImportExport.PleaseSelectImportHandler', "Please select the import handler"), $importHandlers));
216231
// Simply check of this is supported or not for the given handler (if not, disable it)
217232
$js = <<<JS
218-
var cb=document.querySelector('#OnlyUpdateRecords');var accepted=cb.dataset.handlers.split(',');var item=([...this.querySelectorAll('input')].filter((input) => input.checked)[0]); cb.disabled=(item && accepted.includes(item.value)) ? '': 'disabled';
233+
var desc=document.querySelectorAll('.js-import-desc');var cb=document.querySelector('#OnlyUpdateRecords');var accepted=cb.dataset.handlers.split(',');var item=([...this.querySelectorAll('input')].filter((input) => input.checked)[0]); cb.disabled=(item && accepted.includes(item.value)) ? '': 'disabled';desc.forEach((el)=>el.hidden=!item||el.dataset.name!=item.value);;
219234
JS;
220235
$ImportHandler->setAttribute("onclick", $js);
236+
if ($htmlDesc) {
237+
$ImportHandler->setDescription($htmlDesc); // Description is an HTMLFragment
238+
}
221239
}
222240

223241
$actions = $form->Actions();

0 commit comments

Comments
 (0)