Skip to content

Commit

Permalink
Fix XLSX file loading with autofilter containing '$'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
astronati authored and PowerKiKi committed Mar 2, 2020
1 parent fb37938 commit 8be76ce
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public function __construct(Worksheet $workSheet, \SimpleXMLElement $worksheetXm

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);
}
Expand Down
69 changes: 69 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/Xlsx/AutoFilterTest.php
Original file line number Diff line number Diff line change
@@ -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();
}
}

0 comments on commit 8be76ce

Please sign in to comment.