Skip to content

Commit 1aa58ad

Browse files
committed
Separate DataValidations from Other ReferenceHelper Tests
Also add first tests that DV formulas are updated correctly after row/column insert/delete. Many more tests are still needed.
1 parent 44651e0 commit 1aa58ad

File tree

3 files changed

+164
-93
lines changed

3 files changed

+164
-93
lines changed

src/PhpSpreadsheet/ReferenceHelper.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,40 @@ protected function adjustConditionalFormatting(Worksheet $worksheet, int $number
248248
* @param int $numberOfColumns Number of columns to insert/delete (negative values indicate deletion)
249249
* @param int $numberOfRows Number of rows to insert/delete (negative values indicate deletion)
250250
*/
251-
protected function adjustDataValidations(Worksheet $worksheet, int $numberOfColumns, int $numberOfRows): void
251+
protected function adjustDataValidations(Worksheet $worksheet, int $numberOfColumns, int $numberOfRows, string $beforeCellAddress): void
252252
{
253253
$aDataValidationCollection = $worksheet->getDataValidationCollection();
254254
($numberOfColumns > 0 || $numberOfRows > 0)
255255
? uksort($aDataValidationCollection, [self::class, 'cellReverseSort'])
256256
: uksort($aDataValidationCollection, [self::class, 'cellSort']);
257257

258258
foreach ($aDataValidationCollection as $cellAddress => $dataValidation) {
259+
$formula = $dataValidation->getFormula1();
260+
if ($formula !== '') {
261+
$dataValidation->setFormula1(
262+
$this->updateFormulaReferences(
263+
$formula,
264+
$beforeCellAddress,
265+
$numberOfColumns,
266+
$numberOfRows,
267+
$worksheet->getTitle(),
268+
true
269+
)
270+
);
271+
}
272+
$formula = $dataValidation->getFormula2();
273+
if ($formula !== '') {
274+
$dataValidation->setFormula2(
275+
$this->updateFormulaReferences(
276+
$formula,
277+
$beforeCellAddress,
278+
$numberOfColumns,
279+
$numberOfRows,
280+
$worksheet->getTitle(),
281+
true
282+
)
283+
);
284+
}
259285
$newReference = $this->updateCellReference($cellAddress);
260286
if ($cellAddress !== $newReference) {
261287
$dataValidation->setSqref($newReference);
@@ -491,7 +517,7 @@ public function insertNewBefore(
491517
$this->adjustConditionalFormatting($worksheet, $numberOfColumns, $numberOfRows);
492518

493519
// Update worksheet: data validations
494-
$this->adjustDataValidations($worksheet, $numberOfColumns, $numberOfRows);
520+
$this->adjustDataValidations($worksheet, $numberOfColumns, $numberOfRows, $beforeCellAddress);
495521

496522
// Update worksheet: merge cells
497523
$this->adjustMergeCells($worksheet);
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests;
6+
7+
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
8+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
9+
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class ReferenceHelperDVTest extends TestCase
13+
{
14+
15+
public function testInsertRowsWithDataValidation(): void
16+
{
17+
$spreadsheet = new Spreadsheet();
18+
$sheet = $spreadsheet->getActiveSheet();
19+
20+
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
21+
$cellAddress = 'E5';
22+
$this->setDataValidation($sheet, $cellAddress);
23+
24+
$sheet->insertNewRowBefore(2, 2);
25+
26+
self::assertFalse(
27+
$sheet->getCell($cellAddress)->hasDataValidation()
28+
);
29+
self::assertTrue($sheet->getCell('E7')->hasDataValidation());
30+
self::assertSame('E7', $sheet->getDataValidation('E7')->getSqref());
31+
self::assertSame('$A$7:$A$10', $sheet->getDataValidation('E7')->getFormula1());
32+
$spreadsheet->disconnectWorksheets();
33+
}
34+
35+
public function testDeleteRowsWithDataValidation(): void
36+
{
37+
$spreadsheet = new Spreadsheet();
38+
$sheet = $spreadsheet->getActiveSheet();
39+
40+
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
41+
$cellAddress = 'E5';
42+
$this->setDataValidation($sheet, $cellAddress);
43+
44+
$sheet->removeRow(2, 2);
45+
46+
self::assertFalse(
47+
$sheet->getCell($cellAddress)->hasDataValidation()
48+
);
49+
self::assertTrue($sheet->getCell('E3')->hasDataValidation());
50+
self::assertSame('E3', $sheet->getDataValidation('E3')->getSqref());
51+
self::assertSame('$A$3:$A$6', $sheet->getDataValidation('E3')->getFormula1());
52+
53+
$spreadsheet->disconnectWorksheets();
54+
}
55+
56+
public function testDeleteColumnsWithDataValidation(): void
57+
{
58+
$spreadsheet = new Spreadsheet();
59+
$sheet = $spreadsheet->getActiveSheet();
60+
61+
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
62+
$cellAddress = 'E5';
63+
$this->setDataValidation($sheet, $cellAddress);
64+
65+
$sheet->removeColumn('B', 2);
66+
67+
self::assertFalse(
68+
$sheet->getCell($cellAddress)->hasDataValidation()
69+
);
70+
self::assertTrue($sheet->getCell('C5')->hasDataValidation());
71+
self::assertSame('C5', $sheet->getDataValidation('C5')->getSqref());
72+
self::assertSame('$A$5:$A$8', $sheet->getDataValidation('C5')->getFormula1());
73+
$spreadsheet->disconnectWorksheets();
74+
}
75+
76+
public function testInsertColumnsWithDataValidation(): void
77+
{
78+
$spreadsheet = new Spreadsheet();
79+
$sheet = $spreadsheet->getActiveSheet();
80+
81+
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
82+
$cellAddress = 'E5';
83+
$this->setDataValidation($sheet, $cellAddress);
84+
85+
$sheet->insertNewColumnBefore('C', 2);
86+
87+
self::assertFalse(
88+
$sheet->getCell($cellAddress)->hasDataValidation()
89+
);
90+
self::assertTrue($sheet->getCell('G5')->hasDataValidation());
91+
self::assertSame('G5', $sheet->getDataValidation('G5')->getSqref());
92+
self::assertSame('$A$5:$A$8', $sheet->getDataValidation('G5')->getFormula1());
93+
$spreadsheet->disconnectWorksheets();
94+
}
95+
96+
public function testInsertColumnsWithDataValidation2(): void
97+
{
98+
$spreadsheet = new Spreadsheet();
99+
$sheet = $spreadsheet->getActiveSheet();
100+
101+
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
102+
$cellAddress = 'E5';
103+
$this->setDataValidation($sheet, $cellAddress);
104+
105+
$sheet->insertNewColumnBefore('A', 2);
106+
107+
self::assertFalse(
108+
$sheet->getCell($cellAddress)->hasDataValidation()
109+
);
110+
self::assertTrue($sheet->getCell('G5')->hasDataValidation());
111+
self::assertSame('G5', $sheet->getDataValidation('G5')->getSqref());
112+
self::assertSame('$C$5:$C$8', $sheet->getDataValidation('G5')->getFormula1());
113+
$spreadsheet->disconnectWorksheets();
114+
}
115+
116+
private function setDataValidation(Worksheet $sheet, string $cellAddress): void
117+
{
118+
$validation = $sheet->getCell($cellAddress)
119+
->getDataValidation();
120+
$validation->setType(DataValidation::TYPE_LIST);
121+
$validation->setErrorStyle(
122+
DataValidation::STYLE_STOP
123+
);
124+
$validation->setAllowBlank(false);
125+
$validation->setShowInputMessage(true);
126+
$validation->setShowErrorMessage(true);
127+
$validation->setShowDropDown(true);
128+
$validation->setErrorTitle('Input error');
129+
$validation->setError('Value is not in list.');
130+
$validation->setPromptTitle('Pick from list');
131+
$validation->setPrompt('Please pick a value from the drop-down list.');
132+
$validation->setFormula1('$A$5:$A$8');
133+
}
134+
}

tests/PhpSpreadsheetTests/ReferenceHelperTest.php

Lines changed: 2 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,7 @@ public function testCellReverseSort(): void
102102
}
103103
}
104104

105-
/**
106-
* @dataProvider providerFormulaUpdates
107-
*/
105+
#[\PHPUnit\Framework\Attributes\DataProvider('providerFormulaUpdates')]
108106
public function testUpdateFormula(string $formula, int $insertRows, int $insertColumns, string $worksheet, string $expectedResult): void
109107
{
110108
$referenceHelper = ReferenceHelper::getInstance();
@@ -119,9 +117,7 @@ public static function providerFormulaUpdates(): array
119117
return require 'tests/data/ReferenceHelperFormulaUpdates.php';
120118
}
121119

122-
/**
123-
* @dataProvider providerMultipleWorksheetFormulaUpdates
124-
*/
120+
#[\PHPUnit\Framework\Attributes\DataProvider('providerMultipleWorksheetFormulaUpdates')]
125121
public function testUpdateFormulaForMultipleWorksheets(string $formula, int $insertRows, int $insertColumns, string $expectedResult): void
126122
{
127123
$referenceHelper = ReferenceHelper::getInstance();
@@ -298,91 +294,6 @@ public function testDeleteRowsWithHyperlinks(): void
298294
$spreadsheet->disconnectWorksheets();
299295
}
300296

301-
public function testInsertRowsWithDataValidation(): void
302-
{
303-
$spreadsheet = new Spreadsheet();
304-
$sheet = $spreadsheet->getActiveSheet();
305-
306-
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
307-
$cellAddress = 'E5';
308-
$this->setDataValidation($sheet, $cellAddress);
309-
310-
$sheet->insertNewRowBefore(2, 2);
311-
312-
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
313-
self::assertTrue($sheet->getCell('E7')->hasDataValidation());
314-
self::assertSame('E7', $sheet->getDataValidation('E7')->getSqref());
315-
$spreadsheet->disconnectWorksheets();
316-
}
317-
318-
public function testDeleteRowsWithDataValidation(): void
319-
{
320-
$spreadsheet = new Spreadsheet();
321-
$sheet = $spreadsheet->getActiveSheet();
322-
323-
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
324-
$cellAddress = 'E5';
325-
$this->setDataValidation($sheet, $cellAddress);
326-
327-
$sheet->removeRow(2, 2);
328-
329-
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
330-
self::assertTrue($sheet->getCell('E3')->hasDataValidation());
331-
self::assertSame('E3', $sheet->getDataValidation('E3')->getSqref());
332-
$spreadsheet->disconnectWorksheets();
333-
}
334-
335-
public function testDeleteColumnsWithDataValidation(): void
336-
{
337-
$spreadsheet = new Spreadsheet();
338-
$sheet = $spreadsheet->getActiveSheet();
339-
340-
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
341-
$cellAddress = 'E5';
342-
$this->setDataValidation($sheet, $cellAddress);
343-
344-
$sheet->removeColumn('B', 2);
345-
346-
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
347-
self::assertTrue($sheet->getCell('C5')->hasDataValidation());
348-
self::assertSame('C5', $sheet->getDataValidation('C5')->getSqref());
349-
$spreadsheet->disconnectWorksheets();
350-
}
351-
352-
public function testInsertColumnsWithDataValidation(): void
353-
{
354-
$spreadsheet = new Spreadsheet();
355-
$sheet = $spreadsheet->getActiveSheet();
356-
357-
$sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
358-
$cellAddress = 'E5';
359-
$this->setDataValidation($sheet, $cellAddress);
360-
361-
$sheet->insertNewColumnBefore('C', 2);
362-
363-
self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
364-
self::assertTrue($sheet->getCell('G5')->hasDataValidation());
365-
self::assertSame('G5', $sheet->getDataValidation('G5')->getSqref());
366-
$spreadsheet->disconnectWorksheets();
367-
}
368-
369-
private function setDataValidation(Worksheet $sheet, string $cellAddress): void
370-
{
371-
$validation = $sheet->getCell($cellAddress)
372-
->getDataValidation();
373-
$validation->setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST);
374-
$validation->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION);
375-
$validation->setAllowBlank(false);
376-
$validation->setShowInputMessage(true);
377-
$validation->setShowErrorMessage(true);
378-
$validation->setShowDropDown(true);
379-
$validation->setErrorTitle('Input error');
380-
$validation->setError('Value is not in list.');
381-
$validation->setPromptTitle('Pick from list');
382-
$validation->setPrompt('Please pick a value from the drop-down list.');
383-
$validation->setFormula1('$A5:$A8');
384-
}
385-
386297
public function testInsertRowsWithConditionalFormatting(): void
387298
{
388299
$spreadsheet = new Spreadsheet();

0 commit comments

Comments
 (0)