Skip to content

Commit 400a755

Browse files
committed
ENH GridFieldExportButton improvement
1 parent d871f40 commit 400a755

File tree

2 files changed

+168
-11
lines changed

2 files changed

+168
-11
lines changed

src/Forms/GridField/GridFieldExportButton.php

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
use LogicException;
77
use SilverStripe\Control\HTTPRequest;
88
use SilverStripe\Control\HTTPResponse;
9+
use SilverStripe\Core\ClassInfo;
910
use SilverStripe\Core\Config\Config;
10-
use SilverStripe\ORM\DataList;
11-
use SilverStripe\ORM\ArrayList;
1211
use SilverStripe\View\ViewableData;
1312

1413
/**
@@ -42,6 +41,16 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
4241
*/
4342
protected $targetFragment;
4443

44+
/**
45+
* Export file name
46+
*/
47+
protected $exportFileName = '[classname]-export-[timestamp].csv';
48+
49+
/**
50+
* Export file name timestamp format
51+
*/
52+
protected $timeStampFormat = 'Y-m-d-H-i-s';
53+
4554
/**
4655
* Set to true to disable XLS sanitisation
4756
* [SS-2017-007] Ensure all cells with leading [@=+] have a leading tab
@@ -54,11 +63,25 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
5463
/**
5564
* @param string $targetFragment The HTML fragment to write the button into
5665
* @param array $exportColumns The columns to include in the export
66+
* @param string $exportFileName Export file name
67+
* @param string $timeStampFormat Export file name timestamp format
5768
*/
58-
public function __construct($targetFragment = "after", $exportColumns = null)
59-
{
69+
public function __construct(
70+
$targetFragment = 'after',
71+
$exportColumns = null,
72+
$exportFileName = null,
73+
$timeStampFormat = null
74+
) {
6075
$this->targetFragment = $targetFragment;
6176
$this->exportColumns = $exportColumns;
77+
78+
if ($exportFileName) {
79+
$this->exportFileName = $exportFileName;
80+
}
81+
82+
if ($timeStampFormat) {
83+
$this->timeStampFormat = $timeStampFormat;
84+
}
6285
}
6386

6487
/**
@@ -128,8 +151,7 @@ public function getURLHandlers($gridField)
128151
*/
129152
public function handleExport($gridField, $request = null)
130153
{
131-
$now = date("d-m-Y-H-i");
132-
$fileName = "export-$now.csv";
154+
$fileName = $this->getExportFileName($gridField);
133155

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

tests/php/Forms/GridField/GridFieldExportButtonTest.php

Lines changed: 75 additions & 5 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();
@@ -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($this->gridField)
240+
);
241+
242+
$this->exportButton->setExportFileName('[classname]-export.csv');
243+
244+
$this->assertEquals(
245+
'team-export.csv',
246+
$this->exportButton->getExportFileName($this->gridField)
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-59.csv',
256+
$this->exportButton->getExportFileName($this->gridField)
257+
);
258+
259+
$this->exportButton->setExportFileName('[classname]-export-[timestamp].csv');
260+
261+
$this->assertEquals(
262+
'team-export-2024-12-31-22-10-59.csv',
263+
$this->exportButton->getExportFileName($this->gridField)
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-His');
275+
276+
$this->assertEquals(
277+
'export-20241231-221059.csv',
278+
$this->exportButton->getExportFileName($this->gridField)
279+
);
280+
281+
$this->exportButton->setTimeStampFormat('d-m-Y');
282+
283+
$this->assertEquals(
284+
'team-export-31-12-2024.csv',
285+
$this->exportButton->getExportFileName($this->gridField)
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)