From 9f5a4724268557344043384ffceb884892dfef5a Mon Sep 17 00:00:00 2001 From: Stronati Andrea Date: Wed, 15 Jan 2020 15:49:24 +0100 Subject: [PATCH] Fix XLSX file loading with autofilter containing '$' The `setRange` method of the `Xlsx/AutoFilter` class expects a filter range format like "A1:E10". The returned value from `$this->worksheetXml->autoFilter['ref']` could contain "$" and returning a value like "$A$1:$E$10". Fixes #687 Fixes #1325 Closes #1326 --- CHANGELOG.md | 1 + src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php | 3 +- .../Reader/Xlsx/AutoFilterTest.php | 69 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 tests/PhpSpreadsheetTests/Reader/Xlsx/AutoFilterTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 4286fa9c..354ec8d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). - Fix for issue by removing test code mistakenly left in [#1328](https://github.com/PHPOffice/PhpSpreadsheet/pull/1328) - Fix for Xls writer wrong selected cells and active sheet [#1256](https://github.com/PHPOffice/PhpSpreadsheet/pull/1256) - Fix active cell when freeze pane is used [#1323](https://github.com/PHPOffice/PhpSpreadsheet/pull/1323) +- Fix XLSX file loading with autofilter containing '$' [#1326](https://github.com/PHPOffice/PhpSpreadsheet/pull/1326) ## [1.10.1] - 2019-12-02 diff --git a/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php b/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php index 6929758d..69d5f69e 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php +++ b/src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php @@ -20,7 +20,8 @@ class AutoFilter public function load() { - $autoFilterRange = (string) $this->worksheetXml->autoFilter['ref']; + // Remove all "$" in the auto filter range + $autoFilterRange = preg_replace('/\$/', '', $this->worksheetXml->autoFilter['ref']); if (strpos($autoFilterRange, ':') !== false) { $this->readAutoFilter($autoFilterRange, $this->worksheetXml); } diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/AutoFilterTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/AutoFilterTest.php new file mode 100644 index 00000000..90ea17aa --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/AutoFilterTest.php @@ -0,0 +1,69 @@ +getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + } + + private function getXMLInstance($ref) + { + return new \SimpleXMLElement( + '' . + '' . + '' . + '' + ); + } + + private function getAutoFilterInstance() + { + $instance = $this->getMockBuilder(WorksheetAutoFilter::class) + ->disableOriginalConstructor() + ->getMock(); + + return $instance; + } + + public function loadDataProvider() + { + return [ + ['$B3$E8', 0, 'B3E8'], + ['$B3:$E8', 1, 'B3:E8'], + ]; + } + + /** + * @dataProvider loadDataProvider + * + * @param string $ref + * @param int $expectedReadAutoFilterCalled + * @param string $expectedRef + */ + public function testLoad($ref, $expectedReadAutoFilterCalled, $expectedRef) + { + $worksheetAutoFilter = $this->getAutoFilterInstance(); + $worksheetAutoFilter->expects($this->exactly($expectedReadAutoFilterCalled ? 1 : 0)) + ->method('setRange') + ->with($expectedRef); + + $worksheet = $this->getWorksheetInstance(); + $worksheet->expects($this->exactly($expectedReadAutoFilterCalled ? 1 : 0)) + ->method('getAutoFilter') + ->willReturn($worksheetAutoFilter); + + $autoFilter = new AutoFilter($worksheet, $this->getXMLInstance($ref)); + + $autoFilter->load(); + } +}