Skip to content

Commit 6938fcb

Browse files
committed
Numeric Data Validation Formats Only Worked for Constants
Change to evaluate formulas when applicable.
1 parent bbc069e commit 6938fcb

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

src/PhpSpreadsheet/Cell/DataValidator.php

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,58 @@ public function isValid(Cell $cell): bool
3737
if (!is_numeric($cellValue) || fmod((float) $cellValue, 1) != 0) {
3838
$returnValue = false;
3939
} else {
40-
$returnValue = $this->numericOperator($dataValidation, (int) $cellValue);
40+
$returnValue = $this->numericOperator($dataValidation, (int) $cellValue, $cell);
4141
}
4242
} elseif ($type === DataValidation::TYPE_DECIMAL || $type === DataValidation::TYPE_DATE || $type === DataValidation::TYPE_TIME) {
4343
if (!is_numeric($cellValue)) {
4444
$returnValue = false;
4545
} else {
46-
$returnValue = $this->numericOperator($dataValidation, (float) $cellValue);
46+
$returnValue = $this->numericOperator($dataValidation, (float) $cellValue, $cell);
4747
}
4848
} elseif ($type === DataValidation::TYPE_TEXTLENGTH) {
49-
$returnValue = $this->numericOperator($dataValidation, mb_strlen($cell->getValueString()));
49+
$returnValue = $this->numericOperator($dataValidation, mb_strlen($cell->getValueString()), $cell);
5050
}
5151

5252
return $returnValue;
5353
}
5454

55-
private function numericOperator(DataValidation $dataValidation, int|float $cellValue): bool
55+
private function numericOperator(DataValidation $dataValidation, int|float $cellValue, Cell $cell): bool
5656
{
57+
$calculation = null;
5758
$operator = $dataValidation->getOperator();
5859
$formula1 = $dataValidation->getFormula1();
59-
$formula2 = $dataValidation->getFormula2();
60+
if (!is_numeric($formula1)) {
61+
$calculation = Calculation::getInstance($cell->getWorksheet()->getParent());
62+
63+
try {
64+
$result = $calculation
65+
->calculateFormula("=$formula1", $cell->getCoordinate(), $cell);
66+
while (is_array($result)) {
67+
$result = array_pop($result);
68+
}
69+
$formula1 = $result;
70+
} catch (Exception) {
71+
// do nothing
72+
}
73+
}
74+
$formula2 = 0;
75+
if ($operator === DataValidation::OPERATOR_BETWEEN || $operator === DataValidation::OPERATOR_NOTBETWEEN) {
76+
$formula2 = $dataValidation->getFormula2();
77+
if (!is_numeric($formula2)) {
78+
$calculation ??= Calculation::getInstance($cell->getWorksheet()->getParent());
79+
80+
try {
81+
$result = $calculation
82+
->calculateFormula("=$formula2", $cell->getCoordinate(), $cell);
83+
while (is_array($result)) {
84+
$result = array_pop($result);
85+
}
86+
$formula2 = $result;
87+
} catch (Exception) {
88+
// do nothing
89+
}
90+
}
91+
}
6092
$returnValue = false;
6193
if ($operator === DataValidation::OPERATOR_BETWEEN) {
6294
$returnValue = $cellValue >= $formula1 && $cellValue <= $formula2;

tests/PhpSpreadsheetTests/ReferenceHelperDVTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,32 @@ public function testWholeRow(): void
216216
self::assertSame(DataValidation::TYPE_NONE, $sheet->getDataValidation('H1')->getType());
217217
$spreadsheet->disconnectWorksheets();
218218
}
219+
220+
public function testFormula2(): void
221+
{
222+
$spreadsheet = new Spreadsheet();
223+
$sheet = $spreadsheet->getActiveSheet();
224+
$sheet->getCell('A1')->setValue(5);
225+
$sheet->getCell('A5')->setValue(9);
226+
$dv = new DataValidation();
227+
$dv->setType(DataValidation::TYPE_WHOLE)
228+
->setOperator(DataValidation::OPERATOR_BETWEEN)
229+
->setFormula1('$A$1')
230+
->setFormula2('$A$5')
231+
->setErrorStyle(DataValidation::STYLE_STOP)
232+
->setShowErrorMessage(true)
233+
->setErrorTitle('Input Error')
234+
->setError('Value is not whole number within bounds');
235+
$sheet->setDataValidation('B2', $dv);
236+
$sheet->insertNewRowBefore(2);
237+
$dv2 = $sheet->getCell('B3')->getDataValidation();
238+
self::assertSame('$A$1', $dv2->getFormula1());
239+
self::assertSame('$A$6', $dv2->getFormula2());
240+
241+
$sheet->getCell('B3')->setValue(7);
242+
self::assertTrue($sheet->getCell('B3')->hasValidValue());
243+
$sheet->getCell('B3')->setValue(1);
244+
self::assertFalse($sheet->getCell('B3')->hasValidValue());
245+
$spreadsheet->disconnectWorksheets();
246+
}
219247
}

0 commit comments

Comments
 (0)