diff --git a/CHANGELOG.md b/CHANGELOG.md index df24ba1f..ca0ce021 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Fixed +- Fix bug when deleting cells with hyperlinks, where the hyperlink was then being "inherited" by whatever cell moved to that cell address. - Fix bug in Conditional Formatting in the Xls Writer that resulted in a broken file when there were multiple conditional ranges in a worksheet. - Fix Conditional Formatting in the Xls Writer to work with rules that contain string literals, cell references and formulae. - Fix for setting Active Sheet to the first loaded worksheet when bookViews element isn't defined [Issue #2666](https://github.com/PHPOffice/PhpSpreadsheet/issues/2666) [PR #2669](https://github.com/PHPOffice/PhpSpreadsheet/pull/2669) diff --git a/src/PhpSpreadsheet/ReferenceHelper.php b/src/PhpSpreadsheet/ReferenceHelper.php index 8c55c766..e8fb9057 100644 --- a/src/PhpSpreadsheet/ReferenceHelper.php +++ b/src/PhpSpreadsheet/ReferenceHelper.php @@ -189,7 +189,9 @@ class ReferenceHelper foreach ($aHyperlinkCollection as $cellAddress => $value) { $newReference = $this->updateCellReference($cellAddress); - if ($cellAddress !== $newReference) { + if ($this->cellReferenceHelper->cellAddressInDeleteRange($cellAddress) === true) { + $worksheet->setHyperlink($cellAddress, null); + } elseif ($cellAddress !== $newReference) { $worksheet->setHyperlink($newReference, $value); $worksheet->setHyperlink($cellAddress, null); } diff --git a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php index 2c016b0b..e38ba286 100644 --- a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php +++ b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php @@ -3,8 +3,11 @@ namespace PhpOffice\PhpSpreadsheetTests; use PhpOffice\PhpSpreadsheet\Cell\DataType; +use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; +use PhpOffice\PhpSpreadsheet\Comment; use PhpOffice\PhpSpreadsheet\ReferenceHelper; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PHPUnit\Framework\TestCase; class ReferenceHelperTest extends TestCase @@ -177,4 +180,120 @@ class ReferenceHelperTest extends TestCase self::assertNull($cells[1][1]); self::assertArrayNotHasKey(2, $cells[1]); } + + public function testInsertRowsWithPageBreaks(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true); + $sheet->setBreak('A2', Worksheet::BREAK_ROW); + $sheet->setBreak('A5', Worksheet::BREAK_ROW); + + $sheet->insertNewRowBefore(2, 2); + + $breaks = $sheet->getBreaks(); + ksort($breaks); + self::assertSame(['A4' => Worksheet::BREAK_ROW, 'A7' => Worksheet::BREAK_ROW], $breaks); + } + + public function testDeleteRowsWithPageBreaks(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true); + $sheet->setBreak('A2', Worksheet::BREAK_ROW); + $sheet->setBreak('A5', Worksheet::BREAK_ROW); + + $sheet->removeRow(2, 2); + + $breaks = $sheet->getBreaks(); + self::assertSame(['A3' => Worksheet::BREAK_ROW], $breaks); + } + + public function testInsertRowsWithComments(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true); + $sheet->getComment('A2')->getText()->createText('First Comment'); + $sheet->getComment('A5')->getText()->createText('Second Comment'); + + $sheet->insertNewRowBefore(2, 2); + + $comments = array_map( + function (Comment $value) { + return $value->getText()->getPlainText(); + }, + $sheet->getComments() + ); + + self::assertSame(['A4' => 'First Comment', 'A7' => 'Second Comment'], $comments); + } + + public function testDeleteRowsWithComments(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true); + $sheet->getComment('A2')->getText()->createText('First Comment'); + $sheet->getComment('A5')->getText()->createText('Second Comment'); + + $sheet->removeRow(2, 2); + + $comments = array_map( + function (Comment $value) { + return $value->getText()->getPlainText(); + }, + $sheet->getComments() + ); + + self::assertSame(['A3' => 'Second Comment'], $comments); + } + + public function testInsertRowsWithHyperlinks(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true); + $sheet->getCell('A2')->getHyperlink()->setUrl('https://github.com/PHPOffice/PhpSpreadsheet'); + $sheet->getCell('A5')->getHyperlink()->setUrl('https://phpspreadsheet.readthedocs.io/en/latest/'); + + $sheet->insertNewRowBefore(2, 2); + + $hyperlinks = array_map( + function (Hyperlink $value) { + return $value->getUrl(); + }, + $sheet->getHyperlinkCollection() + ); + ksort($hyperlinks); + + self::assertSame( + [ + 'A4' => 'https://github.com/PHPOffice/PhpSpreadsheet', + 'A7' => 'https://phpspreadsheet.readthedocs.io/en/latest/', + ], + $hyperlinks + ); + } + + public function testDeleteRowsWithHyperlinks(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true); + $sheet->getCell('A2')->getHyperlink()->setUrl('https://github.com/PHPOffice/PhpSpreadsheet'); + $sheet->getCell('A5')->getHyperlink()->setUrl('https://phpspreadsheet.readthedocs.io/en/latest/'); + + $sheet->removeRow(2, 2); + + $hyperlinks = array_map( + function (Hyperlink $value) { + return $value->getUrl(); + }, + $sheet->getHyperlinkCollection() + ); + + self::assertSame(['A3' => 'https://phpspreadsheet.readthedocs.io/en/latest/'], $hyperlinks); + } }