Skip to content

Commit c2bf9cd

Browse files
authored
Restore Cyclic Error Messages (#3170)
Fix #3169. Insufficient detail when calculation fails due to cyclic reference.
1 parent 525384e commit c2bf9cd

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3470,11 +3470,15 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true)
34703470
'cell' => $cell->getCoordinate(),
34713471
];
34723472

3473+
$cellAddressAttempted = false;
3474+
$cellAddress = null;
3475+
34733476
try {
34743477
$result = self::unwrapResult($this->_calculateFormulaValue($cell->getValue(), $cell->getCoordinate(), $cell));
34753478
if ($this->spreadsheet === null) {
34763479
throw new Exception('null spreadsheet in calculateCellValue');
34773480
}
3481+
$cellAddressAttempted = true;
34783482
$cellAddress = array_pop($this->cellStack);
34793483
if ($cellAddress === null) {
34803484
throw new Exception('null cellAddress in calculateCellValue');
@@ -3485,6 +3489,16 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true)
34853489
}
34863490
$testSheet->getCell($cellAddress['cell']);
34873491
} catch (\Exception $e) {
3492+
if (!$cellAddressAttempted) {
3493+
$cellAddress = array_pop($this->cellStack);
3494+
}
3495+
if ($this->spreadsheet !== null && is_array($cellAddress) && array_key_exists('sheet', $cellAddress)) {
3496+
$testSheet = $this->spreadsheet->getSheetByName($cellAddress['sheet']);
3497+
if ($testSheet !== null && array_key_exists('cell', $cellAddress)) {
3498+
$testSheet->getCell($cellAddress['cell']);
3499+
}
3500+
}
3501+
34883502
throw new Exception($e->getMessage());
34893503
}
34903504

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
4+
5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6+
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcException;
7+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class CyclicTest extends TestCase
11+
{
12+
public function testCyclicReference(): void
13+
{
14+
// Issue 3169
15+
$spreadsheet = new Spreadsheet();
16+
17+
$table_data = [
18+
['abc', 'def', 'ghi'],
19+
['1', '4', '=B3+A3'],
20+
['=SUM(A2:C2)', '2', '=A2+B2'],
21+
];
22+
// Don't allow cyclic references.
23+
Calculation::getInstance($spreadsheet)->cyclicFormulaCount = 0;
24+
25+
$worksheet = $spreadsheet->getActiveSheet();
26+
$worksheet->fromArray($table_data, '');
27+
28+
try {
29+
$result = $worksheet->getCell('C2')->getCalculatedValue();
30+
} catch (CalcException $e) {
31+
$result = $e->getMessage();
32+
}
33+
self::assertSame(
34+
'Worksheet!C2 -> Worksheet!A3 -> Worksheet!C2 -> Cyclic Reference in Formula',
35+
$result
36+
);
37+
38+
try {
39+
$result = $worksheet->getCell('A3')->getCalculatedValue();
40+
} catch (CalcException $e) {
41+
$result = $e->getMessage();
42+
}
43+
self::assertSame(
44+
'Worksheet!A3 -> Worksheet!C2 -> Worksheet!A3 -> Cyclic Reference in Formula',
45+
$result
46+
);
47+
$spreadsheet->disconnectWorksheets();
48+
}
49+
}

0 commit comments

Comments
 (0)