From 2d923c7e46820a5a764a57096c603b1997fc70cc Mon Sep 17 00:00:00 2001 From: madflow Date: Fri, 20 May 2016 18:32:47 +0200 Subject: [PATCH] Fix issue #218 (#222) --- .../Reader/ODS/Helper/CellValueFormatter.php | 3 +++ tests/Spout/Reader/ODS/ReaderTest.php | 17 +++++++++++++++++ tests/resources/ods/sheet_with_hyperlinks.ods | Bin 0 -> 9905 bytes 3 files changed, 20 insertions(+) create mode 100644 tests/resources/ods/sheet_with_hyperlinks.ods diff --git a/src/Spout/Reader/ODS/Helper/CellValueFormatter.php b/src/Spout/Reader/ODS/Helper/CellValueFormatter.php index bd21576..3eb1918 100644 --- a/src/Spout/Reader/ODS/Helper/CellValueFormatter.php +++ b/src/Spout/Reader/ODS/Helper/CellValueFormatter.php @@ -23,6 +23,7 @@ class CellValueFormatter /** Definition of XML nodes names used to parse data */ const XML_NODE_P = 'p'; const XML_NODE_S = 'text:s'; + const XML_NODE_A = 'text:a'; /** Definition of XML attribute used to parse data */ const XML_ATTRIBUTE_TYPE = 'office:value-type'; @@ -98,6 +99,8 @@ class CellValueFormatter $spaceAttribute = $childNode->getAttribute(self::XML_ATTRIBUTE_C); $numSpaces = (!empty($spaceAttribute)) ? intval($spaceAttribute) : 1; $currentPValue .= str_repeat(' ', $numSpaces); + } else if ($childNode->nodeName === self::XML_NODE_A) { + $currentPValue .= $childNode->nodeValue; } } diff --git a/tests/Spout/Reader/ODS/ReaderTest.php b/tests/Spout/Reader/ODS/ReaderTest.php index 8683459..4c95fd9 100644 --- a/tests/Spout/Reader/ODS/ReaderTest.php +++ b/tests/Spout/Reader/ODS/ReaderTest.php @@ -436,6 +436,23 @@ class ReaderTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expectedRows, $allRows, 'Cell values should not be trimmed'); } + /** + * https://github.com/box/spout/issues/218 + * @return void + */ + public function testReaderShouldReadTextInHyperlinks() + { + $allRows = $this->getAllRowsForFile('sheet_with_hyperlinks.ods'); + + $expectedRows = [ + ['email', 'text'], + ['1@example.com', 'text'], + ['2@example.com', 'text and https://github.com/box/spout/issues/218 and text'], + ]; + + $this->assertEquals($expectedRows, $allRows, 'Text in hyperlinks should be read'); + } + /** * @param string $fileName * @return array All the read rows the given file diff --git a/tests/resources/ods/sheet_with_hyperlinks.ods b/tests/resources/ods/sheet_with_hyperlinks.ods new file mode 100644 index 0000000000000000000000000000000000000000..7246db5580e7ceb2f85e502efa60baa0d53a6ec9 GIT binary patch literal 9905 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