mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENHANCEMENT GridFieldExportButton allows an anon function to return the
value of a related object. Useful for handling has_many/many_many data in a single CSV column.
This commit is contained in:
parent
dc71df74e0
commit
bb20587f01
@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an "Export list" button to the bottom of a GridField.
|
* Adds an "Export list" button to the bottom of a GridField.
|
||||||
*
|
|
||||||
* WARNING: This is experimental and its API is subject to change. Feel free to use it as long as you are happy of
|
|
||||||
* refactoring your code in the future.
|
|
||||||
*/
|
*/
|
||||||
class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
|
class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
|
||||||
|
|
||||||
@ -95,7 +92,10 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export core.
|
* Generate export fields for CSV.
|
||||||
|
*
|
||||||
|
* @param GridField $gridField
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
function generateExportFileData($gridField) {
|
function generateExportFileData($gridField) {
|
||||||
$separator = $this->csvSeparator;
|
$separator = $this->csvSeparator;
|
||||||
@ -105,20 +105,42 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
$fieldItems = new ArrayList();
|
$fieldItems = new ArrayList();
|
||||||
|
|
||||||
if($this->csvHasHeader) {
|
if($this->csvHasHeader) {
|
||||||
$fileData .= "\"" . implode("\"{$separator}\"", array_values($csvColumns)) . "\"";
|
$headers = array();
|
||||||
|
|
||||||
|
// determine the CSV headers. If a field is callable (e.g. anonymous function) then use the
|
||||||
|
// source name as the header instead
|
||||||
|
foreach($csvColumns as $columnSource => $columnHeader) {
|
||||||
|
$headers[] = (!is_string($columnHeader) && is_callable($columnHeader)) ? $columnSource : $columnHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileData .= "\"" . implode("\"{$separator}\"", array_values($headers)) . "\"";
|
||||||
$fileData .= "\n";
|
$fileData .= "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = $gridField->getList();
|
$items = $gridField->getList();
|
||||||
|
|
||||||
|
// @todo should GridFieldComponents change behaviour based on whether others are available in the config?
|
||||||
foreach($gridField->getConfig()->getComponents() as $component){
|
foreach($gridField->getConfig()->getComponents() as $component){
|
||||||
if($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) {
|
if($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) {
|
||||||
$items = $component->getManipulatedData($gridField, $items);
|
$items = $component->getManipulatedData($gridField, $items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($items as $item) {
|
foreach($items as $item) {
|
||||||
$columnData = array();
|
$columnData = array();
|
||||||
foreach($csvColumns as $columnSource => $columnHeader) {
|
foreach($csvColumns as $columnSource => $columnHeader) {
|
||||||
|
if(!is_string($columnHeader) && is_callable($columnHeader)) {
|
||||||
|
if($item->hasMethod($columnSource)) {
|
||||||
|
$relObj = $item->{$columnSource}();
|
||||||
|
} else {
|
||||||
|
$relObj = $item->relObject($columnSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $columnHeader($relObj);
|
||||||
|
} else {
|
||||||
$value = $item->relField($columnSource);
|
$value = $item->relField($columnSource);
|
||||||
|
}
|
||||||
|
|
||||||
$value = str_replace(array("\r", "\n"), "\n", $value);
|
$value = str_replace(array("\r", "\n"), "\n", $value);
|
||||||
$columnData[] = '"' . str_replace('"', '\"', $value) . '"';
|
$columnData[] = '"' . str_replace('"', '\"', $value) . '"';
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an "Print" button to the bottom or top of a GridField.
|
* Adds an "Print" button to the bottom or top of a GridField.
|
||||||
*
|
|
||||||
* WARNING: This is experimental and its API is subject to change. Feel free to use it as long as you are happy of
|
|
||||||
* refactoring your code in the future.
|
|
||||||
*/
|
*/
|
||||||
class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
|
class GridFieldPrintButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler {
|
||||||
|
|
||||||
|
89
tests/forms/gridfield/GridFieldExportButtonTest.php
Normal file
89
tests/forms/gridfield/GridFieldExportButtonTest.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
class GridFieldExportButtonTest extends SapphireTest {
|
||||||
|
|
||||||
|
protected $list;
|
||||||
|
|
||||||
|
protected $gridField;
|
||||||
|
|
||||||
|
protected $form;
|
||||||
|
|
||||||
|
public static $fixture_file = 'GridFieldExportButtonTest.yml';
|
||||||
|
|
||||||
|
protected $extraDataObjects = array(
|
||||||
|
'GridFieldExportButtonTest_Team'
|
||||||
|
);
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->list = new DataList('GridFieldExportButtonTest_Team');
|
||||||
|
$config = GridFieldConfig::create()->addComponent(new GridFieldExportButton());
|
||||||
|
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGenerateFileDataBasicFields() {
|
||||||
|
$button = new GridFieldExportButton();
|
||||||
|
$button->setExportColumns(array('Name' => 'My Name'));
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
"\"My Name\"\n\"Test\"\n\"Test2\"\n",
|
||||||
|
$button->generateExportFileData($this->gridField)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGenerateFileDataAnonymousFunctionField() {
|
||||||
|
$button = new GridFieldExportButton();
|
||||||
|
$button->setExportColumns(array(
|
||||||
|
'Name' => 'Name',
|
||||||
|
'City' => function($obj) {
|
||||||
|
return $obj->getValue() . ' city';
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
"\"Name\",\"City\"\n\"Test\",\"City city\"\n\"Test2\",\"City2 city\"\n",
|
||||||
|
$button->generateExportFileData($this->gridField)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuiltInFunctionNameCanBeUsedAsHeader() {
|
||||||
|
$button = new GridFieldExportButton();
|
||||||
|
$button->setExportColumns(array(
|
||||||
|
'Name' => 'Name',
|
||||||
|
'City' => 'strtolower'
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
"\"Name\",\"strtolower\"\n\"Test\",\"City\"\n\"Test2\",\"City2\"\n",
|
||||||
|
$button->generateExportFileData($this->gridField)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNoCsvHeaders() {
|
||||||
|
$button = new GridFieldExportButton();
|
||||||
|
$button->setExportColumns(array(
|
||||||
|
'Name' => 'Name',
|
||||||
|
'City' => 'City'
|
||||||
|
));
|
||||||
|
$button->setCsvHasHeader(false);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
"\"Test\",\"City\"\n\"Test2\",\"City2\"\n",
|
||||||
|
$button->generateExportFileData($this->gridField)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
class GridFieldExportButtonTest_Team extends DataObject implements TestOnly {
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'Name' => 'Varchar',
|
||||||
|
'City' => 'Varchar'
|
||||||
|
);
|
||||||
|
|
||||||
|
public function canView($member = null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
8
tests/forms/gridfield/GridFieldExportButtonTest.yml
Normal file
8
tests/forms/gridfield/GridFieldExportButtonTest.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
GridFieldExportButtonTest_Team:
|
||||||
|
test-team-1:
|
||||||
|
Name: Test
|
||||||
|
City: City
|
||||||
|
test-team-2:
|
||||||
|
Name: Test2
|
||||||
|
City: City2
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user