Skip to content

Commit 6cc9719

Browse files
committed
ENH GridFieldExportButton improvement
1 parent d871f40 commit 6cc9719

File tree

2 files changed

+169
-11
lines changed

2 files changed

+169
-11
lines changed

src/Forms/GridField/GridFieldExportButton.php

+94-6
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
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;
11+
use SilverStripe\ORM\FieldType\DBDatetime;
1212
use SilverStripe\View\ViewableData;
1313

1414
/**
@@ -42,6 +42,16 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
4242
*/
4343
protected $targetFragment;
4444

45+
/**
46+
* Export file name
47+
*/
48+
protected $exportFileName = '[classname]-export-[timestamp].csv';
49+
50+
/**
51+
* Export file name timestamp format
52+
*/
53+
protected $timeStampFormat = 'yyyy-MM-dd-HH-mm-ss';
54+
4555
/**
4656
* Set to true to disable XLS sanitisation
4757
* [SS-2017-007] Ensure all cells with leading [@=+] have a leading tab
@@ -54,11 +64,25 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
5464
/**
5565
* @param string $targetFragment The HTML fragment to write the button into
5666
* @param array $exportColumns The columns to include in the export
67+
* @param string $exportFileName Export file name
68+
* @param string $timeStampFormat Export file name timestamp format
5769
*/
58-
public function __construct($targetFragment = "after", $exportColumns = null)
59-
{
70+
public function __construct(
71+
$targetFragment = 'after',
72+
$exportColumns = null,
73+
$exportFileName = null,
74+
$timeStampFormat = null
75+
) {
6076
$this->targetFragment = $targetFragment;
6177
$this->exportColumns = $exportColumns;
78+
79+
if ($exportFileName) {
80+
$this->exportFileName = $exportFileName;
81+
}
82+
83+
if ($timeStampFormat) {
84+
$this->timeStampFormat = $timeStampFormat;
85+
}
6286
}
6387

6488
/**
@@ -128,8 +152,7 @@ public function getURLHandlers($gridField)
128152
*/
129153
public function handleExport($gridField, $request = null)
130154
{
131-
$now = date("d-m-Y-H-i");
132-
$fileName = "export-$now.csv";
155+
$fileName = $this->getExportFileName($gridField);
133156

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

tests/php/Forms/GridField/GridFieldExportButtonTest.php

+75-5
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('yyyyMMdd-HHmmss');
275+
276+
$this->assertEquals(
277+
'team-export-20241231-221059.csv',
278+
$this->exportButton->getExportFileName($this->gridField)
279+
);
280+
281+
$this->exportButton->setTimeStampFormat('dd-MM-yyyy');
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)