Files
PhpSpreadsheet/tests/PhpSpreadsheetTests/Worksheet/CloneTest.php
T
oleibman 8af9963350 Allow Spreadsheet Serialization
Fix #4324. Serialization was explicity forbidden by PR #3199. This was in response to several issues, and concern that the Spreadsheet object contained non-serializable properties. This PR restores the ability to serialize a spreadsheet. Json serialization remains unsupported.

Fix #1757, closed in Nov. 2023 but just reopened. At the time, Cell property `formulaAttributes` was stored as a SimpleXmlElement. Dynamic arrays PR #3962 defined that property as `null|array<string, string>` in the doc block. However, it left the formal Php type for the property as `mixed`. This PR changes the formal type to `?array`.

Fix #1741, closed in Dec. 2020 but just reopened. Calculation property `referenceHelper` was defined as static, and, since static properties don't take part in serialization, this caused a problem after unserialization. There are at least 3 trivial ways to deal with this - make it an instance property, reinitialize it when unserialized using a wakeup method, or remove the property altogether. This PR uses the last of those 3.

Calculation does have other static properties. Almost all of these deal with locale. So serialize/unserialize might wind up using a default locale when non-default is desired (but not necessarily required). If that is a problem for end-users, it will be a new one, and I will work on a solution if and when the time comes.

Static property `returnArrayAsType` is potentially problematic. However, instance property `instanceArrayReturnType` is the preferred method of handling this, and using that will avoid any problems.

Issue #932 also dealt with serialization. I do not have the wherewithal to investigate that issue. If it is not solved by this and the earlier PR's, I will have to leave it to others to re-raise it.

Spreadsheet `copy` is now simplified to use serialize followed by unserialize. Formal tests are added. In addition, I have made a number of informal tests on very complicated spreadsheets, and it has performed correctly for all of them.
2025-01-25 19:13:55 -08:00

72 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PHPUnit\Framework\TestCase;
class CloneTest extends TestCase
{
public function testUnattachedIndex(): void
{
$spreadsheet = new Spreadsheet();
$sheet1 = $spreadsheet->getActiveSheet();
$sheet1->getCell('A1')->setValue(10);
$sheet2 = clone $sheet1;
$sheet2->getCell('A1')->setValue(20);
self::assertSame(0, $spreadsheet->getIndex($sheet1));
$idx = $spreadsheet->getIndex($sheet2, true);
self::assertSame(-1, $idx);
$sheet2->setTitle('clone');
$spreadsheet->addSheet($sheet2);
$idx = $spreadsheet->getIndex($sheet2, true);
self::assertSame(1, $idx);
self::assertSame(10, $spreadsheet->getSheet(0)->getCell('A1')->getValue());
self::assertSame(20, $spreadsheet->getSheet(1)->getCell('A1')->getValue());
$spreadsheet->disconnectWorksheets();
}
public function testGetCloneIndex(): void
{
$this->expectException(SpreadsheetException::class);
$this->expectExceptionMessage('Sheet does not exist');
$spreadsheet = new Spreadsheet();
$sheet1 = $spreadsheet->getActiveSheet();
$sheet1->getCell('A1')->setValue(10);
$sheet2 = clone $sheet1;
$spreadsheet->getSheet($spreadsheet->getIndex($sheet2))
->setCellValue('A1', 100);
}
public function testSerialize1(): void
{
$spreadsheet = new Spreadsheet();
$sheet1 = $spreadsheet->getActiveSheet();
$sheet1->getCell('A1')->setValue(10);
$serialized = serialize($sheet1);
$newSheet = unserialize($serialized);
self::assertInstanceOf(Worksheet::class, $newSheet);
self::assertSame(10, $newSheet->getCell('A1')->getValue());
self::assertNotEquals($newSheet->getHashInt(), $sheet1->getHashInt());
self::assertNotNull($newSheet->getParent());
self::assertNotSame($newSheet->getParent(), $sheet1->getParent());
$newSheet->getParent()->disconnectWorksheets();
$spreadsheet->disconnectWorksheets();
}
public function testSerialize2(): void
{
$sheet1 = new Worksheet();
$sheet1->getCell('A1')->setValue(10);
$serialized = serialize($sheet1);
$newSheet = unserialize($serialized);
self::assertInstanceOf(Worksheet::class, $newSheet);
self::assertSame(10, $newSheet->getCell('A1')->getValue());
self::assertNotEquals($newSheet->getHashInt(), $sheet1->getHashInt());
}
}