-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Validate Input to SetSelectedCells (#2280)
* Validate Input to SetSelectedCells See issue #2279. User requests an enhancement so that you can set a Style on a Named Range. The attempt is failing because setting the style causes a call to setSelectedCells, which does not account for Named Ranges. Although not related to the issue, it is worth noting that setSelectedCells does nothing to attempt to validate its input. The request seems reasonable, even if it is probably more than Excel itself offers. I have added code to setSelectedCells to recognize Named Ranges (if and only if they are defined on the sheet in question). It will throw an exception if the string passed as coordinates cannot be parsed as a range of cells or an appropriate Named Range, e.e.g. a Named Range on a different sheet, a non-existent named range, named formulas, formulas, use of sheet name qualifiers (even for the same sheet). Tests are, of course, added for all of those and for the original issue. The code in setSelectedCells is tested in a very large number of cases in the test suite, none of which showed any problems after this change. * Scrutinizer 2 minor (non-fatal) corrections, including 1 where Phpstan and Scrutinizer have a different idea about return values from preg_replace.
- Loading branch information
Showing
3 changed files
with
161 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
<?php | ||
|
||
namespace PhpOffice\PhpSpreadsheetTests; | ||
|
||
use PhpOffice\PhpSpreadsheet\DefinedName; | ||
use PhpOffice\PhpSpreadsheet\Exception as Except; | ||
use PhpOffice\PhpSpreadsheet\NamedRange; | ||
use PhpOffice\PhpSpreadsheet\Spreadsheet; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class NamedRange2Test extends TestCase | ||
{ | ||
/** @var ?Spreadsheet */ | ||
private $spreadsheet; | ||
|
||
protected function setUp(): void | ||
{ | ||
$spreadsheet = $this->spreadsheet = new Spreadsheet(); | ||
|
||
$worksheet1 = $spreadsheet->getActiveSheet(); | ||
$worksheet1->setTitle('SheetOne'); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('FirstRel', $worksheet1, '=A1') | ||
); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('FirstAbs', $worksheet1, '=$B$1') | ||
); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('FirstRelMult', $worksheet1, '=C1:D2') | ||
); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('FirstAbsMult', $worksheet1, '$E$3:$F$4') | ||
); | ||
|
||
$worksheet2 = $spreadsheet->createSheet(); | ||
$worksheet2->setTitle('SheetTwo'); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('SecondRel', $worksheet2, '=A1') | ||
); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('SecondAbs', $worksheet2, '=$B$1') | ||
); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('SecondRelMult', $worksheet2, '=C1:D2') | ||
); | ||
$spreadsheet->addNamedRange( | ||
new NamedRange('SecondAbsMult', $worksheet2, '$E$3:$F$4') | ||
); | ||
|
||
$spreadsheet->addDefinedName(DefinedName::createInstance('FirstFormula', $worksheet1, '=TODAY()-1')); | ||
$spreadsheet->addDefinedName(DefinedName::createInstance('SecondFormula', $worksheet2, '=TODAY()-2')); | ||
|
||
$this->spreadsheet->setActiveSheetIndex(0); | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
if ($this->spreadsheet !== null) { | ||
$this->spreadsheet->disconnectWorksheets(); | ||
$this->spreadsheet = null; | ||
} | ||
} | ||
|
||
private function getSpreadsheet(): Spreadsheet | ||
{ | ||
if ($this->spreadsheet !== null) { | ||
return $this->spreadsheet; | ||
} | ||
$this->spreadsheet = new Spreadsheet(); | ||
|
||
return $this->spreadsheet; | ||
} | ||
|
||
public function testNamedRangeSetStyle(): void | ||
{ | ||
$spreadsheet = $this->getSpreadsheet(); | ||
$sheet = $spreadsheet->getSheet(0); | ||
$sheet->getStyle('FirstRel')->getNumberFormat()->setFormatCode('yyyy-mm-dd'); | ||
self::assertSame('yyyy-mm-dd', $sheet->getStyle('A1')->getNumberFormat()->getFormatCode()); | ||
$sheet->getStyle('FirstAbs')->getFont()->setName('Georgia'); | ||
self::assertSame('Georgia', $sheet->getStyle('B1')->getFont()->getName()); | ||
$sheet->getStyle('FirstRelMult')->getFont()->setItalic(true); | ||
self::assertTrue($sheet->getStyle('D2')->getFont()->getItalic()); | ||
$sheet->getStyle('FirstAbsMult')->getFill()->setFillType('gray125'); | ||
self::assertSame('gray125', $sheet->getStyle('F4')->getFill()->getFillType()); | ||
self::assertSame('none', $sheet->getStyle('A1')->getFill()->getFillType()); | ||
$sheet = $spreadsheet->getSheet(1); | ||
$sheet->getStyle('SecondAbsMult')->getFill()->setFillType('lightDown'); | ||
self::assertSame('lightDown', $sheet->getStyle('E3')->getFill()->getFillType()); | ||
} | ||
|
||
/** | ||
* @dataProvider providerRangeOrFormula | ||
*/ | ||
public function testNamedRangeSetStyleBad(string $name): void | ||
{ | ||
$this->expectException(Except::class); | ||
$spreadsheet = $this->getSpreadsheet(); | ||
$sheet = $spreadsheet->getSheet(0); | ||
$sheet->getStyle($name)->getNumberFormat()->setFormatCode('yyyy-mm-dd'); | ||
self::assertSame('yyyy-mm-dd', $sheet->getStyle('A1')->getNumberFormat()->getFormatCode()); | ||
} | ||
|
||
public function providerRangeOrFormula(): array | ||
{ | ||
return [ | ||
'wrong sheet rel' => ['SecondRel'], | ||
'wrong sheet abs' => ['SecondAbs'], | ||
'wrong sheet relmult' => ['SecondRelMult'], | ||
'wrong sheet absmult' => ['SecondAbsMult'], | ||
'wrong sheet formula' => ['SecondFormula'], | ||
'right sheet formula' => ['FirstFormula'], | ||
'non-existent name' => ['NonExistentName'], | ||
'this sheet name' => ['SheetOne!G7'], | ||
'other sheet name' => ['SheetTwo!G7'], | ||
'non-existent sheet name' => ['SheetAbc!G7'], | ||
'unnamed formula' => ['=2+3'], | ||
]; | ||
} | ||
} |