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:
Sean Harvey 2012-04-20 09:48:14 +12:00 committed by Sean Harvey
parent dc71df74e0
commit bb20587f01
4 changed files with 128 additions and 12 deletions

View File

@ -6,9 +6,6 @@
/**
* 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 {
@ -95,8 +92,11 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
}
/**
* Export core.
*/
* Generate export fields for CSV.
*
* @param GridField $gridField
* @return array
*/
function generateExportFileData($gridField) {
$separator = $this->csvSeparator;
$csvColumns = ($this->exportColumns) ? $this->exportColumns : singleton($gridField->getModelClass())->summaryFields();
@ -105,20 +105,42 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP
$fieldItems = new ArrayList();
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";
}
$items = $gridField->getList();
// @todo should GridFieldComponents change behaviour based on whether others are available in the config?
foreach($gridField->getConfig()->getComponents() as $component){
if($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) {
$items = $component->getManipulatedData($gridField, $items);
}
}
foreach($items as $item) {
$columnData = array();
foreach($csvColumns as $columnSource => $columnHeader) {
$value = $item->relField($columnSource);
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 = str_replace(array("\r", "\n"), "\n", $value);
$columnData[] = '"' . str_replace('"', '\"', $value) . '"';
}

View File

@ -6,9 +6,6 @@
/**
* 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 {

View 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;
}
}

View File

@ -0,0 +1,8 @@
GridFieldExportButtonTest_Team:
test-team-1:
Name: Test
City: City
test-team-2:
Name: Test2
City: City2