Skip to content

Commit 81cf409

Browse files
committed
FIX ModelAdmin::$model_importers alias support
Hasn't been considered when introducing aliases rather than class names in $managed_models. Fixed a regression from when we introduced $modelTab. This is backwards compatible since $modelTab falls back to $modelClass. Also improved $model_importers to fall back to the default per model, rather than requiring definition of *all* models on a non-null value.
1 parent bd8b138 commit 81cf409

File tree

4 files changed

+106
-40
lines changed

4 files changed

+106
-40
lines changed

code/ModelAdmin.php

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,34 @@
22

33
namespace SilverStripe\Admin;
44

5-
use SilverStripe\Control\Controller;
6-
use SilverStripe\Control\HTTPRequest;
7-
use SilverStripe\Control\HTTPResponse;
5+
use SilverStripe\Forms\Form;
86
use SilverStripe\Core\Convert;
7+
use SilverStripe\ORM\ArrayList;
98
use SilverStripe\Dev\BulkLoader;
9+
use SilverStripe\ORM\DataObject;
10+
use SilverStripe\View\ArrayData;
11+
use SilverStripe\Dev\CsvBulkLoader;
1012
use SilverStripe\Dev\Deprecation;
11-
use SilverStripe\Forms\CheckboxField;
1213
use SilverStripe\Forms\FieldList;
1314
use SilverStripe\Forms\FileField;
14-
use SilverStripe\Forms\Form;
1515
use SilverStripe\Forms\FormAction;
16+
use SilverStripe\Forms\HiddenField;
17+
use SilverStripe\Security\Security;
18+
use SilverStripe\Control\Controller;
19+
use SilverStripe\Forms\LiteralField;
20+
use SilverStripe\Control\HTTPRequest;
21+
use SilverStripe\Forms\CheckboxField;
22+
use SilverStripe\Control\HTTPResponse;
23+
use SilverStripe\ORM\ValidationResult;
1624
use SilverStripe\Forms\GridField\GridField;
1725
use SilverStripe\Forms\GridField\GridFieldConfig;
18-
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
26+
use SilverStripe\Forms\GridField\GridFieldPaginator;
1927
use SilverStripe\Forms\GridField\GridFieldDetailForm;
28+
use SilverStripe\Forms\GridField\GridFieldPrintButton;
2029
use SilverStripe\Forms\GridField\GridFieldExportButton;
2130
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
2231
use SilverStripe\Forms\GridField\GridFieldImportButton;
23-
use SilverStripe\Forms\GridField\GridFieldPaginator;
24-
use SilverStripe\Forms\GridField\GridFieldPrintButton;
25-
use SilverStripe\Forms\HiddenField;
26-
use SilverStripe\Forms\LiteralField;
27-
use SilverStripe\ORM\ArrayList;
28-
use SilverStripe\ORM\DataObject;
29-
use SilverStripe\ORM\ValidationResult;
30-
use SilverStripe\Security\Security;
31-
use SilverStripe\View\ArrayData;
32+
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
3233

3334
/**
3435
* Generates a three-pane UI for editing model classes, tabular results and edit forms.
@@ -103,14 +104,16 @@ abstract class ModelAdmin extends LeftAndMain
103104
/**
104105
* Change this variable if you don't want the Import from CSV form to appear.
105106
* This variable can be a boolean or an array.
106-
* If array, you can list className you want the form to appear on. i.e. array('myClassOne','myClassTwo')
107+
* If array, you can list {@link $managed_models} keys
108+
* you want the form to appear on. i.e. array('myClassOne','myClassTwo')
107109
*/
108110
public $showImportForm = true;
109111

110112
/**
111113
* Change this variable if you don't want the gridfield search to appear.
112114
* This variable can be a boolean or an array.
113-
* If array, you can list className you want the form to appear on. i.e. array('myClassOne','myClassTwo')
115+
* If array, you can list {@link $managed_models} keys
116+
* you want the form to appear on. i.e. array('myClassOne','myClassTwo')
114117
*/
115118
public $showSearchForm = true;
116119

@@ -119,8 +122,9 @@ abstract class ModelAdmin extends LeftAndMain
119122
* a subclass of {@link BulkLoader} (mostly CSV data).
120123
* By default {@link CsvBulkLoader} is used, assuming a standard mapping
121124
* of column names to {@link DataObject} properties/relations.
125+
* Use {@link $managed_models} keys.
122126
*
123-
* e.g. "BlogEntry" => "BlogEntryCsvBulkLoader"
127+
* Example: "BlogEntry" => "BlogEntryCsvBulkLoader"
124128
*
125129
* @config
126130
* @var array
@@ -485,23 +489,25 @@ public function getManagedModels()
485489
* with a default {@link CsvBulkLoader} class. In this case the column names of the first row
486490
* in the CSV file are assumed to have direct mappings to properties on the object.
487491
*
488-
* @return array Map of model class names to importer instances
492+
* @return array Map of model keys to importer instances (same keys as $managed_models)
489493
*/
490494
public function getModelImporters()
491495
{
492-
$importerClasses = $this->config()->get('model_importers');
496+
$importers = [];
497+
$importerSpec = $this->config()->get('model_importers');
498+
$models = $this->getManagedModels();
493499

494-
// fallback to all defined models if not explicitly defined
495-
if (is_null($importerClasses)) {
496-
$models = $this->getManagedModels();
497-
foreach ($models as $modelName => $options) {
498-
$importerClasses[$modelName] = 'SilverStripe\\Dev\\CsvBulkLoader';
500+
foreach ($models as $modelName => $options) {
501+
$modelClass = $options['dataClass'];
502+
if (isset($importerSpec[$modelName])) {
503+
$importerClass = $importerSpec[$modelName];
504+
} elseif (isset($importerSpec[$modelClass])) {
505+
$importerClass = $importerSpec[$modelClass];
506+
} else {
507+
$importerClass = CsvBulkLoader::class;
499508
}
500-
}
501-
502-
$importers = array();
503-
foreach ($importerClasses as $modelClass => $importerClass) {
504-
$importers[$modelClass] = new $importerClass($modelClass);
509+
// Needs to be indexed by name to avoid collisions
510+
$importers[$modelName] = new $importerClass($modelClass);
505511
}
506512

507513
return $importers;
@@ -601,14 +607,14 @@ public function ImportForm()
601607
public function import($data, $form, $request)
602608
{
603609
if (!$this->showImportForm || (is_array($this->showImportForm)
604-
&& !in_array($this->modelClass, $this->showImportForm))
610+
&& !in_array($this->modelTab, $this->showImportForm))
605611
) {
606612
return false;
607613
}
608614

609615
$importers = $this->getModelImporters();
610616
/** @var BulkLoader $loader */
611-
$loader = $importers[$this->modelClass];
617+
$loader = $importers[$this->modelTab];
612618

613619
// File wasn't properly uploaded, show a reminder to the user
614620
if (empty($_FILES['_CsvFile']['tmp_name']) ||

tests/php/ModelAdminTest.php

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
namespace SilverStripe\Admin\Tests;
44

5-
use SilverStripe\Admin\Tests\ModelAdminTest\Contact;
6-
use SilverStripe\Admin\Tests\ModelAdminTest\Player;
7-
use SilverStripe\Control\HTTPRequest;
5+
use SilverStripe\View\ArrayData;
86
use SilverStripe\Control\Session;
7+
use SilverStripe\Dev\CsvBulkLoader;
8+
use SilverStripe\Dev\FunctionalTest;
9+
use SilverStripe\Control\HTTPRequest;
10+
use SilverStripe\Security\Permission;
911
use SilverStripe\Forms\GridField\GridField;
12+
use SilverStripe\Admin\Tests\ModelAdminTest\Player;
13+
use SilverStripe\Admin\Tests\ModelAdminTest\Contact;
14+
use SilverStripe\Forms\GridField\GridFieldPrintButton;
1015
use SilverStripe\Forms\GridField\GridFieldExportButton;
1116
use SilverStripe\Forms\GridField\GridFieldImportButton;
12-
use SilverStripe\Forms\GridField\GridFieldPrintButton;
13-
use SilverStripe\Security\Permission;
14-
use SilverStripe\Dev\FunctionalTest;
15-
use SilverStripe\View\ArrayData;
17+
use SilverStripe\Admin\Tests\ModelAdminTest\ModelAdminTestBulkLoader;
1618

1719
class ModelAdminTest extends FunctionalTest
1820
{
@@ -164,6 +166,46 @@ public function testGetManagedModels()
164166
);
165167
}
166168

169+
public function testModelImporters()
170+
{
171+
$admin = new ModelAdminTest\MultiModelAdmin();
172+
173+
$importers = $admin->getModelImporters();
174+
175+
$this->assertArrayHasKey(
176+
Contact::class,
177+
$importers,
178+
'Infers importer for non-listed models'
179+
);
180+
$this->assertInstanceOf(
181+
CsvBulkLoader::class,
182+
$importers[Contact::class],
183+
'Sets default importer for non-listed models'
184+
);
185+
186+
$this->assertArrayHasKey(
187+
Player::class,
188+
$importers,
189+
'Discovers models referenced by class'
190+
);
191+
$this->assertInstanceOf(
192+
ModelAdminTestBulkLoader::class,
193+
$importers[Player::class],
194+
'Sets explicitly defined importer for models referenced by class'
195+
);
196+
197+
$this->assertArrayHasKey(
198+
'Player',
199+
$importers,
200+
'Discovers models referenced by alias'
201+
);
202+
$this->assertInstanceOf(
203+
ModelAdminTestBulkLoader::class,
204+
$importers['Player'],
205+
'Sets explicitly defined importer for models referenced by alias'
206+
);
207+
}
208+
167209
public function testGetManagedModelTabs()
168210
{
169211
$mock = $this->getMockBuilder(ModelAdminTest\MultiModelAdmin::class)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace SilverStripe\Admin\Tests\ModelAdminTest;
4+
5+
use SilverStripe\Dev\CsvBulkLoader;
6+
7+
class ModelAdminTestBulkLoader extends CsvBulkLoader
8+
{
9+
10+
}

tests/php/ModelAdminTest/MultiModelAdmin.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
namespace SilverStripe\Admin\Tests\ModelAdminTest;
44

5+
use SilverStripe\Dev\TestOnly;
56
use SilverStripe\Admin\ModelAdmin;
67
use SilverStripe\Control\Controller;
7-
use SilverStripe\Dev\TestOnly;
8+
use SilverStripe\Admin\Tests\ModelAdminTest\ModelAdminTestBulkLoader;
89

910
class MultiModelAdmin extends ModelAdmin implements TestOnly
1011
{
@@ -21,6 +22,13 @@ class MultiModelAdmin extends ModelAdmin implements TestOnly
2122
]
2223
];
2324

25+
private static $model_importers = [
26+
// Infer Contact importer
27+
// Contact::class,
28+
'Player' => ModelAdminTestBulkLoader::class,
29+
Player::class => ModelAdminTestBulkLoader::class,
30+
];
31+
2432
public function Link($action = null)
2533
{
2634
if (!$action) {

0 commit comments

Comments
 (0)