Skip to content

Commit 3ab48a2

Browse files
committed
ENH GridFieldExportButton improvement
1 parent d871f40 commit 3ab48a2

File tree

2 files changed

+169
-10
lines changed

2 files changed

+169
-10
lines changed

src/Forms/GridField/GridFieldExportButton.php

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use LogicException;
77
use SilverStripe\Control\HTTPRequest;
88
use SilverStripe\Control\HTTPResponse;
9+
use SilverStripe\Core\ClassInfo;
910
use SilverStripe\Core\Config\Config;
1011
use SilverStripe\ORM\DataList;
1112
use SilverStripe\ORM\ArrayList;
@@ -42,6 +43,16 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
4243
*/
4344
protected $targetFragment;
4445

46+
/**
47+
* Export file name
48+
*/
49+
protected $exportFileName = '[classname]-export-[timestamp].csv';
50+
51+
/**
52+
* Export file name timestamp format
53+
*/
54+
protected $timeStampFormat = 'Y-m-d-H-i';
55+
4556
/**
4657
* Set to true to disable XLS sanitisation
4758
* [SS-2017-007] Ensure all cells with leading [@=+] have a leading tab
@@ -54,11 +65,25 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
5465
/**
5566
* @param string $targetFragment The HTML fragment to write the button into
5667
* @param array $exportColumns The columns to include in the export
68+
* @param string $exportFileName Export file name
69+
* @param string $timeStampFormat Export file name timestamp format
5770
*/
58-
public function __construct($targetFragment = "after", $exportColumns = null)
59-
{
71+
public function __construct(
72+
$targetFragment = 'after',
73+
$exportColumns = null,
74+
$exportFileName = null,
75+
$timeStampFormat = null
76+
) {
6077
$this->targetFragment = $targetFragment;
6178
$this->exportColumns = $exportColumns;
79+
80+
if ($exportFileName) {
81+
$this->exportFileName = $exportFileName;
82+
}
83+
84+
if ($timeStampFormat) {
85+
$this->timeStampFormat = $timeStampFormat;
86+
}
6287
}
6388

6489
/**
@@ -128,8 +153,7 @@ public function getURLHandlers($gridField)
128153
*/
129154
public function handleExport($gridField, $request = null)
130155
{
131-
$now = date("d-m-Y-H-i");
132-
$fileName = "export-$now.csv";
156+
$fileName = $this->getExportFileName($gridField);
133157

134158
if ($fileData = $this->generateExportFileData($gridField)) {
135159
return HTTPRequest::send_file($fileData, $fileName, 'text/csv');
@@ -351,4 +375,69 @@ public function setCsvHasHeader($bool)
351375
$this->csvHasHeader = $bool;
352376
return $this;
353377
}
378+
379+
/**
380+
* @param string $exportFileName
381+
*
382+
* @return $this
383+
*/
384+
public function setExportFileName($exportFileName): GridFieldExportButton
385+
{
386+
$this->exportFileName = $exportFileName;
387+
388+
return $this;
389+
}
390+
391+
/**
392+
* @param GridField $gridField
393+
*
394+
* @return string
395+
*/
396+
public function getExportFileName(GridField $gridField): string
397+
{
398+
$exportFileName = $this->exportFileName;
399+
400+
if (!$exportFileName) {
401+
return null;
402+
}
403+
404+
if (str_contains($exportFileName, '[classname]')) {
405+
$className = strtolower(
406+
preg_replace(
407+
'/(?<!^)[A-Z]/',
408+
'-$0',
409+
ClassInfo::shortName(
410+
$gridField->getModelClass()
411+
)
412+
)
413+
);
414+
$exportFileName = str_replace(
415+
'[classname]',
416+
$className,
417+
$exportFileName
418+
);
419+
}
420+
421+
if (str_contains($exportFileName, '[timestamp]')) {
422+
$exportFileName = str_replace(
423+
'[timestamp]',
424+
date($this->timeStampFormat),
425+
$exportFileName
426+
);
427+
}
428+
429+
return $exportFileName;
430+
}
431+
432+
/**
433+
* @param string $timeStampFormat
434+
*
435+
* @return $this
436+
*/
437+
public function setTimeStampFormat($timeStampFormat): GridFieldExportButton
438+
{
439+
$this->timeStampFormat = $timeStampFormat;
440+
441+
return $this;
442+
}
354443
}

tests/php/Forms/GridField/GridFieldExportButtonTest.php

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
use SilverStripe\Forms\Tests\GridField\GridFieldExportButtonTest\Team;
1010
use SilverStripe\ORM\DataList;
1111
use SilverStripe\ORM\ArrayList;
12-
use SilverStripe\ORM\DataObject;
1312
use SilverStripe\Dev\SapphireTest;
1413
use SilverStripe\Forms\GridField\GridFieldConfig;
1514
use SilverStripe\Forms\GridField\GridFieldExportButton;
1615
use SilverStripe\Forms\GridField\GridField;
1716
use SilverStripe\Forms\GridField\GridFieldDataColumns;
1817
use SilverStripe\Forms\GridField\GridFieldPaginator;
18+
use SilverStripe\ORM\FieldType\DBDatetime;
1919
use SilverStripe\ORM\FieldType\DBField;
2020
use SilverStripe\View\ArrayData;
2121

@@ -32,6 +32,16 @@ class GridFieldExportButtonTest extends SapphireTest
3232
*/
3333
protected $gridField;
3434

35+
/**
36+
* @var GridFieldConfig
37+
*/
38+
protected $gridFieldConfig;
39+
40+
/**
41+
* @var GridFieldExportButton
42+
*/
43+
protected $exportButton;
44+
3545
protected static $fixture_file = 'GridFieldExportButtonTest.yml';
3646

3747
protected static $extra_dataobjects = [
@@ -45,8 +55,10 @@ protected function setUp(): void
4555

4656
$this->list = new DataList(Team::class);
4757
$this->list = $this->list->sort('Name');
48-
$config = GridFieldConfig::create()->addComponent(new GridFieldExportButton());
49-
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
58+
$this->gridFieldConfig = GridFieldConfig::create()->addComponent(
59+
$this->exportButton = new GridFieldExportButton()
60+
);
61+
$this->gridField = new GridField('testfield', 'testfield', $this->list, $this->gridFieldConfig);
5062
}
5163

5264
public function testCanView()
@@ -161,8 +173,8 @@ public function testArrayListInput()
161173
$button = new GridFieldExportButton();
162174
$columns = new GridFieldDataColumns();
163175
$columns->setDisplayFields(['ID' => 'ID']);
164-
$this->gridField->getConfig()->addComponent($columns);
165-
$this->gridField->getConfig()->addComponent(new GridFieldPaginator());
176+
$this->gridFieldConfig->addComponent($columns);
177+
$this->gridFieldConfig->addComponent(new GridFieldPaginator());
166178

167179
//Create an ArrayList 1 greater the Paginator's default 15 rows
168180
$arrayList = new ArrayList();
@@ -203,7 +215,7 @@ public function testGetExportColumnsForGridFieldThrowsException()
203215
{
204216
$component = new GridFieldExportButton();
205217
$gridField = new GridField('dummy', 'dummy', new ArrayList());
206-
$gridField->getConfig()->removeComponentsByType(GridFieldDataColumns::class);
218+
$gridFieldConfig->removeComponentsByType(GridFieldDataColumns::class);
207219
$modelClass = ArrayData::class;
208220
$gridField->setModelClass($modelClass);
209221

@@ -218,6 +230,64 @@ public function testGetExportColumnsForGridFieldThrowsException()
218230
$reflectionMethod->invoke($component, $gridField);
219231
}
220232

233+
public function testSetExportFileName()
234+
{
235+
$this->exportButton->setExportFileName('export.csv');
236+
237+
$this->assertEquals(
238+
'export.csv',
239+
$this->exportButton->getExportFileName()
240+
);
241+
242+
$this->exportButton->setExportFileName('[classname]-export.csv');
243+
244+
$this->assertEquals(
245+
'team-export.csv',
246+
$this->exportButton->getExportFileName()
247+
);
248+
249+
$mockDate = '2024-12-31 22:10:59';
250+
DBDatetime::set_mock_now($mockDate);
251+
252+
$this->exportButton->setExportFileName('export-[timestamp].csv');
253+
254+
$this->assertEquals(
255+
'export-2024-12-31-22-10.csv',
256+
$this->exportButton->getExportFileName()
257+
);
258+
259+
$this->exportButton->setExportFileName('[classname]-export-[timestamp].csv');
260+
261+
$this->assertEquals(
262+
'team-export-2024-12-31-22-10.csv',
263+
$this->exportButton->getExportFileName()
264+
);
265+
266+
DBDatetime::clear_mock_now();
267+
}
268+
269+
public function testSetTimeStampFormat()
270+
{
271+
$mockDate = '2024-12-31 22:10:59';
272+
DBDatetime::set_mock_now($mockDate);
273+
274+
$this->exportButton->setTimeStampFormat('Ymd-Hi');
275+
276+
$this->assertEquals(
277+
'export-20241231-2210.csv',
278+
$this->exportButton->getExportFileName()
279+
);
280+
281+
$this->exportButton->setTimeStampFormat('d-m-Y');
282+
283+
$this->assertEquals(
284+
'team-export-31-12-2024.csv',
285+
$this->exportButton->getExportFileName()
286+
);
287+
288+
DBDatetime::clear_mock_now();
289+
}
290+
221291
protected function createReader($string)
222292
{
223293
$reader = Reader::createFromString($string);

0 commit comments

Comments
 (0)