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
This commit is contained in:
Stronati Andrea 2020-01-15 15:49:24 +01:00 committed by Adrien Crivelli
parent fb379385e0
commit 9f5a472426
3 changed files with 72 additions and 1 deletions

View File

@ -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 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 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 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 ## [1.10.1] - 2019-12-02

View File

@ -20,7 +20,8 @@ class AutoFilter
public function load() 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) { if (strpos($autoFilterRange, ':') !== false) {
$this->readAutoFilter($autoFilterRange, $this->worksheetXml); $this->readAutoFilter($autoFilterRange, $this->worksheetXml);
} }

View File

@ -0,0 +1,69 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\AutoFilter;
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter as WorksheetAutoFilter;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PHPUnit\Framework\TestCase;
class AutoFilterTest extends TestCase
{
private function getWorksheetInstance()
{
return $this->getMockBuilder(Worksheet::class)
->disableOriginalConstructor()
->getMock();
}
private function getXMLInstance($ref)
{
return new \SimpleXMLElement(
'<?xml version="1.0" encoding="UTF-8"?>' .
'<root>' .
'<autoFilter ref="' . $ref . '"></autoFilter>' .
'</root>'
);
}
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();
}
}