Skip to content

Commit

Permalink
ENH GridFieldExportButton improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
3Dgoo committed Nov 7, 2024
1 parent d871f40 commit 3ab48a2
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 10 deletions.
97 changes: 93 additions & 4 deletions src/Forms/GridField/GridFieldExportButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use LogicException;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\ArrayList;
Expand Down Expand Up @@ -42,6 +43,16 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
*/
protected $targetFragment;

/**
* Export file name
*/
protected $exportFileName = '[classname]-export-[timestamp].csv';

/**
* Export file name timestamp format
*/
protected $timeStampFormat = 'Y-m-d-H-i';

/**
* Set to true to disable XLS sanitisation
* [SS-2017-007] Ensure all cells with leading [@=+] have a leading tab
Expand All @@ -54,11 +65,25 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
/**
* @param string $targetFragment The HTML fragment to write the button into
* @param array $exportColumns The columns to include in the export
* @param string $exportFileName Export file name
* @param string $timeStampFormat Export file name timestamp format
*/
public function __construct($targetFragment = "after", $exportColumns = null)
{
public function __construct(
$targetFragment = 'after',
$exportColumns = null,
$exportFileName = null,
$timeStampFormat = null
) {
$this->targetFragment = $targetFragment;
$this->exportColumns = $exportColumns;

if ($exportFileName) {
$this->exportFileName = $exportFileName;
}

if ($timeStampFormat) {
$this->timeStampFormat = $timeStampFormat;
}
}

/**
Expand Down Expand Up @@ -128,8 +153,7 @@ public function getURLHandlers($gridField)
*/
public function handleExport($gridField, $request = null)
{
$now = date("d-m-Y-H-i");
$fileName = "export-$now.csv";
$fileName = $this->getExportFileName($gridField);

if ($fileData = $this->generateExportFileData($gridField)) {
return HTTPRequest::send_file($fileData, $fileName, 'text/csv');
Expand Down Expand Up @@ -351,4 +375,69 @@ public function setCsvHasHeader($bool)
$this->csvHasHeader = $bool;
return $this;
}

/**
* @param string $exportFileName
*
* @return $this
*/
public function setExportFileName($exportFileName): GridFieldExportButton
{
$this->exportFileName = $exportFileName;

return $this;
}

/**
* @param GridField $gridField
*
* @return string
*/
public function getExportFileName(GridField $gridField): string
{
$exportFileName = $this->exportFileName;

if (!$exportFileName) {
return null;
}

if (str_contains($exportFileName, '[classname]')) {
$className = strtolower(
preg_replace(
'/(?<!^)[A-Z]/',
'-$0',
ClassInfo::shortName(
$gridField->getModelClass()
)
)
);
$exportFileName = str_replace(
'[classname]',
$className,
$exportFileName
);
}

if (str_contains($exportFileName, '[timestamp]')) {
$exportFileName = str_replace(
'[timestamp]',
date($this->timeStampFormat),
$exportFileName
);
}

return $exportFileName;
}

/**
* @param string $timeStampFormat
*
* @return $this
*/
public function setTimeStampFormat($timeStampFormat): GridFieldExportButton
{
$this->timeStampFormat = $timeStampFormat;

return $this;
}
}
82 changes: 76 additions & 6 deletions tests/php/Forms/GridField/GridFieldExportButtonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
use SilverStripe\Forms\Tests\GridField\GridFieldExportButtonTest\Team;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldExportButton;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\GridField\GridFieldPaginator;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\View\ArrayData;

Expand All @@ -32,6 +32,16 @@ class GridFieldExportButtonTest extends SapphireTest
*/
protected $gridField;

/**
* @var GridFieldConfig
*/
protected $gridFieldConfig;

/**
* @var GridFieldExportButton
*/
protected $exportButton;

protected static $fixture_file = 'GridFieldExportButtonTest.yml';

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

$this->list = new DataList(Team::class);
$this->list = $this->list->sort('Name');
$config = GridFieldConfig::create()->addComponent(new GridFieldExportButton());
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
$this->gridFieldConfig = GridFieldConfig::create()->addComponent(
$this->exportButton = new GridFieldExportButton()
);
$this->gridField = new GridField('testfield', 'testfield', $this->list, $this->gridFieldConfig);
}

public function testCanView()
Expand Down Expand Up @@ -161,8 +173,8 @@ public function testArrayListInput()
$button = new GridFieldExportButton();
$columns = new GridFieldDataColumns();
$columns->setDisplayFields(['ID' => 'ID']);
$this->gridField->getConfig()->addComponent($columns);
$this->gridField->getConfig()->addComponent(new GridFieldPaginator());
$this->gridFieldConfig->addComponent($columns);
$this->gridFieldConfig->addComponent(new GridFieldPaginator());

//Create an ArrayList 1 greater the Paginator's default 15 rows
$arrayList = new ArrayList();
Expand Down Expand Up @@ -203,7 +215,7 @@ public function testGetExportColumnsForGridFieldThrowsException()
{
$component = new GridFieldExportButton();
$gridField = new GridField('dummy', 'dummy', new ArrayList());
$gridField->getConfig()->removeComponentsByType(GridFieldDataColumns::class);
$gridFieldConfig->removeComponentsByType(GridFieldDataColumns::class);
$modelClass = ArrayData::class;
$gridField->setModelClass($modelClass);

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

public function testSetExportFileName()
{
$this->exportButton->setExportFileName('export.csv');

$this->assertEquals(
'export.csv',
$this->exportButton->getExportFileName()
);

$this->exportButton->setExportFileName('[classname]-export.csv');

$this->assertEquals(
'team-export.csv',
$this->exportButton->getExportFileName()
);

$mockDate = '2024-12-31 22:10:59';
DBDatetime::set_mock_now($mockDate);

$this->exportButton->setExportFileName('export-[timestamp].csv');

$this->assertEquals(
'export-2024-12-31-22-10.csv',
$this->exportButton->getExportFileName()
);

$this->exportButton->setExportFileName('[classname]-export-[timestamp].csv');

$this->assertEquals(
'team-export-2024-12-31-22-10.csv',
$this->exportButton->getExportFileName()
);

DBDatetime::clear_mock_now();
}

public function testSetTimeStampFormat()
{
$mockDate = '2024-12-31 22:10:59';
DBDatetime::set_mock_now($mockDate);

$this->exportButton->setTimeStampFormat('Ymd-Hi');

$this->assertEquals(
'export-20241231-2210.csv',
$this->exportButton->getExportFileName()
);

$this->exportButton->setTimeStampFormat('d-m-Y');

$this->assertEquals(
'team-export-31-12-2024.csv',
$this->exportButton->getExportFileName()
);

DBDatetime::clear_mock_now();
}

protected function createReader($string)
{
$reader = Reader::createFromString($string);
Expand Down

0 comments on commit 3ab48a2

Please sign in to comment.