From bb20587f012e6bc870c76357ce01abc036281e76 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Fri, 20 Apr 2012 09:48:14 +1200 Subject: [PATCH] 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. --- forms/gridfield/GridFieldExportButton.php | 40 +++++++-- forms/gridfield/GridFieldPrintButton.php | 3 - .../gridfield/GridFieldExportButtonTest.php | 89 +++++++++++++++++++ .../gridfield/GridFieldExportButtonTest.yml | 8 ++ 4 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 tests/forms/gridfield/GridFieldExportButtonTest.php create mode 100644 tests/forms/gridfield/GridFieldExportButtonTest.yml diff --git a/forms/gridfield/GridFieldExportButton.php b/forms/gridfield/GridFieldExportButton.php index 9cf968419..971864431 100644 --- a/forms/gridfield/GridFieldExportButton.php +++ b/forms/gridfield/GridFieldExportButton.php @@ -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,30 +92,55 @@ 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(); $fileData = ''; $columnData = array(); $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) . '"'; } @@ -127,7 +149,7 @@ class GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionP $item->destroy(); } - + return $fileData; } diff --git a/forms/gridfield/GridFieldPrintButton.php b/forms/gridfield/GridFieldPrintButton.php index da086cf88..884c6b616 100644 --- a/forms/gridfield/GridFieldPrintButton.php +++ b/forms/gridfield/GridFieldPrintButton.php @@ -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 { diff --git a/tests/forms/gridfield/GridFieldExportButtonTest.php b/tests/forms/gridfield/GridFieldExportButtonTest.php new file mode 100644 index 000000000..96298bfd7 --- /dev/null +++ b/tests/forms/gridfield/GridFieldExportButtonTest.php @@ -0,0 +1,89 @@ +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; + } + +} + diff --git a/tests/forms/gridfield/GridFieldExportButtonTest.yml b/tests/forms/gridfield/GridFieldExportButtonTest.yml new file mode 100644 index 000000000..7b7a54d9e --- /dev/null +++ b/tests/forms/gridfield/GridFieldExportButtonTest.yml @@ -0,0 +1,8 @@ +GridFieldExportButtonTest_Team: + test-team-1: + Name: Test + City: City + test-team-2: + Name: Test2 + City: City2 +