Skip to content

Commit

Permalink
Change hash code for worksheet
Browse files Browse the repository at this point in the history
Backport of [PR PHPOffice#4207](PHPOffice#4207)
  • Loading branch information
oleibman committed Jan 7, 2025
1 parent 51635f6 commit b5ef72c
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
'no_unneeded_final_method' => true,
'no_unreachable_default_argument_value' => true,
'no_unset_cast' => true,
'no_unset_on_property' => true,
'no_unset_on_property' => false,
'no_unused_imports' => true,
'no_useless_else' => true,
'no_useless_return' => true,
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com)
and this project adheres to [Semantic Versioning](https://semver.org).

# TBD - 1.29.8

### Deprecated

- Worksheet::getHashCode is no longer needed.

### Fixed

- Change hash code for worksheet. Backport of [PR #4207](https://github.com/PHPOffice/PhpSpreadsheet/pull/4207)

# 2024-12-26 - 1.29.7

### Deprecated
Expand Down
4 changes: 2 additions & 2 deletions src/PhpSpreadsheet/ReferenceHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ private function updateNamedRange(DefinedName $definedName, Worksheet $worksheet
{
$cellAddress = $definedName->getValue();
$asFormula = ($cellAddress[0] === '=');
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashInt() === $worksheet->getHashInt()) {
/**
* If we delete the entire range that is referenced by a Named Range, MS Excel sets the value to #REF!
* PhpSpreadsheet still only does a basic adjustment, so the Named Range will still reference Cells.
Expand All @@ -932,7 +932,7 @@ private function updateNamedRange(DefinedName $definedName, Worksheet $worksheet

private function updateNamedFormula(DefinedName $definedName, Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void
{
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashInt() === $worksheet->getHashInt()) {
/**
* If we delete the entire range that is referenced by a Named Formula, MS Excel sets the value to #REF!
* PhpSpreadsheet still only does a basic adjustment, so the Named Formula will still reference Cells.
Expand Down
8 changes: 6 additions & 2 deletions src/PhpSpreadsheet/Spreadsheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -750,13 +750,17 @@ public function getSheetByNameOrThrow(string $worksheetName): Worksheet
*
* @return int index
*/
public function getIndex(Worksheet $worksheet)
public function getIndex(Worksheet $worksheet, bool $noThrow = false)
{
$wsHash = $worksheet->getHashInt();
foreach ($this->workSheetCollection as $key => $value) {
if ($value->getHashCode() === $worksheet->getHashCode()) {
if ($value->getHashInt() === $wsHash) {
return $key;
}
}
if ($noThrow) {
return -1;
}

throw new Exception('Sheet does not exist.');
}
Expand Down
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Worksheet/BaseDrawing.php
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ public function getHashCode()
return md5(
$this->name .
$this->description .
(($this->worksheet === null) ? '' : $this->worksheet->getHashCode()) .
(($this->worksheet === null) ? '' : (string) $this->worksheet->getHashInt()) .
$this->coordinates .
$this->offsetX .
$this->offsetY .
Expand Down
37 changes: 19 additions & 18 deletions src/PhpSpreadsheet/Worksheet/Worksheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use PhpOffice\PhpSpreadsheet\Comment;
use PhpOffice\PhpSpreadsheet\DefinedName;
use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\IComparable;
use PhpOffice\PhpSpreadsheet\ReferenceHelper;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Shared;
Expand All @@ -31,7 +30,7 @@
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Style;

class Worksheet implements IComparable
class Worksheet
{
// Break types
public const BREAK_NONE = 0;
Expand Down Expand Up @@ -338,17 +337,10 @@ class Worksheet implements IComparable
*/
private $tabColor;

/**
* Dirty flag.
*
* @var bool
*/
private $dirty = true;

/**
* Hash.
*
* @var string
* @var int
*/
private $hash;

Expand All @@ -368,6 +360,7 @@ public function __construct(?Spreadsheet $parent = null, $title = 'Worksheet')
{
// Set parent and title
$this->parent = $parent;
$this->hash = spl_object_id($this);
$this->setTitle($title, false);
// setTitle can change $pTitle
$this->setCodeName($this->getTitle());
Expand Down Expand Up @@ -424,6 +417,12 @@ public function __destruct()
$this->rowDimensions = [];
}

public function __wakeup(): void
{
$this->hash = spl_object_id($this);
$this->parent = null;
}

/**
* Return the cell collection.
*
Expand Down Expand Up @@ -943,7 +942,6 @@ public function setTitle($title, $updateFormulaCellReferences = true, $validate

// Set title
$this->title = $title;
$this->dirty = true;

if ($this->parent && $this->parent->getCalculationEngine()) {
// New title
Expand Down Expand Up @@ -1088,7 +1086,6 @@ public function getProtection()
public function setProtection(Protection $protection)
{
$this->protection = $protection;
$this->dirty = true;

return $this;
}
Expand Down Expand Up @@ -3137,7 +3134,7 @@ private function validateNamedRange(string $definedName, bool $returnNullIfInval

if ($namedRange->getLocalOnly()) {
$worksheet = $namedRange->getWorksheet();
if ($worksheet === null || $this->getHashCode() !== $worksheet->getHashCode()) {
if ($worksheet === null || $this->getHashInt() !== $worksheet->getHashInt()) {
if ($returnNullIfInvalid) {
return null;
}
Expand Down Expand Up @@ -3278,17 +3275,20 @@ public function garbageCollect()
}

/**
* Get hash code.
* @deprecated 3.5.0 use getHashInt instead.
*
* @return string Hash code
*/
public function getHashCode()
{
if ($this->dirty) {
$this->hash = md5($this->title . $this->autoFilter . ($this->protection->isProtectionEnabled() ? 't' : 'f') . __CLASS__);
$this->dirty = false;
}
return (string) $this->hash;
}

/**
* @return int Hash code
*/
public function getHashInt()
{
return $this->hash;
}

Expand Down Expand Up @@ -3620,6 +3620,7 @@ public function __clone()
}
}
}
$this->hash = spl_object_id($this);
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/PhpSpreadsheet/Writer/Xlsx/Style.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public function writeStyles(Spreadsheet $spreadsheet)

// dxf
for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) {
/** @var ?Conditional */
$thisstyle = $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i);
if ($thisstyle !== null) {
$this->writeCellStyleDxf($objWriter, $thisstyle->getStyle());
Expand Down
4 changes: 3 additions & 1 deletion tests/PhpSpreadsheetTests/Shared/DateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DateTimeZone;
use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -230,7 +231,7 @@ public function testVarious(): void
$date = Date::PHPToExcel('2020-01-01');
self::assertEquals(43831.0, $date);

$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('B1', 'x');
$val = $sheet->getCell('B1')->getValue();
Expand Down Expand Up @@ -271,5 +272,6 @@ public function testVarious(): void
->getNumberFormat()
->setFormatCode('yyyy-mm-dd');
self::assertFalse(Date::isDateTime($cella4));
$spreadsheet->disconnectWorksheets();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ public function testInvalidChar(): void
$sheet->getCell("A$row")->getValue()
);
}
$spreadsheet->disconnectWorksheets();
}
}
2 changes: 2 additions & 0 deletions tests/PhpSpreadsheetTests/Style/BorderRangeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public function testBorderRangeInAction(): void
}
}
}
$spreadsheet->disconnectWorksheets();
}

public function testBorderRangeDirectly(): void
Expand All @@ -69,5 +70,6 @@ public function testBorderRangeDirectly(): void
$sheet = $spreadsheet->getActiveSheet();
$style = $sheet->getStyle('A1:C1')->getBorders()->getTop()->setBorderStyle(Border::BORDER_THIN);
self::assertSame('A1:C1', $style->getSelectedCells(), 'getSelectedCells should not change after a style operation on a border range');
$spreadsheet->disconnectWorksheets();
}
}
9 changes: 9 additions & 0 deletions tests/PhpSpreadsheetTests/Style/BorderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function testAllBorders(): void
self::assertSame(Border::BORDER_THIN, $borders->getRight()->getBorderStyle());
self::assertSame(Border::BORDER_THIN, $borders->getLeft()->getBorderStyle());
self::assertSame(Border::BORDER_NONE, $borders->getDiagonal()->getBorderStyle());
$spreadsheet->disconnectWorksheets();
}

public function testAllBordersArray(): void
Expand All @@ -43,6 +44,7 @@ public function testAllBordersArray(): void
self::assertSame(Border::BORDER_THIN, $borders->getRight()->getBorderStyle());
self::assertSame(Border::BORDER_THIN, $borders->getLeft()->getBorderStyle());
self::assertSame(Border::BORDER_NONE, $borders->getDiagonal()->getBorderStyle());
$spreadsheet->disconnectWorksheets();
}

public function testAllBordersArrayNotSupervisor(): void
Expand Down Expand Up @@ -84,6 +86,7 @@ public function testOutline(): void
self::assertSame(Border::BORDER_THIN, $sheet->getCell('B2')->getStyle()->getBorders()->getBottom()->getBorderStyle());
self::assertSame(Border::BORDER_NONE, $sheet->getCell('B2')->getStyle()->getBorders()->getLeft()->getBorderStyle());
self::assertSame(Border::BORDER_NONE, $sheet->getCell('B2')->getStyle()->getBorders()->getTop()->getBorderStyle());
$spreadsheet->disconnectWorksheets();
}

public function testInside(): void
Expand Down Expand Up @@ -113,6 +116,7 @@ public function testInside(): void
self::assertSame(Border::BORDER_NONE, $sheet->getCell('B2')->getStyle()->getBorders()->getBottom()->getBorderStyle());
self::assertSame(Border::BORDER_THIN, $sheet->getCell('B2')->getStyle()->getBorders()->getLeft()->getBorderStyle());
self::assertSame(Border::BORDER_THIN, $sheet->getCell('B2')->getStyle()->getBorders()->getTop()->getBorderStyle());
$spreadsheet->disconnectWorksheets();
}

public function testHorizontal(): void
Expand Down Expand Up @@ -142,6 +146,7 @@ public function testHorizontal(): void
self::assertSame(Border::BORDER_NONE, $sheet->getCell('B2')->getStyle()->getBorders()->getBottom()->getBorderStyle());
self::assertSame(Border::BORDER_NONE, $sheet->getCell('B2')->getStyle()->getBorders()->getLeft()->getBorderStyle());
self::assertSame(Border::BORDER_THIN, $sheet->getCell('B2')->getStyle()->getBorders()->getTop()->getBorderStyle());
$spreadsheet->disconnectWorksheets();
}

public function testVertical(): void
Expand Down Expand Up @@ -171,6 +176,7 @@ public function testVertical(): void
self::assertSame(Border::BORDER_NONE, $sheet->getCell('B2')->getStyle()->getBorders()->getBottom()->getBorderStyle());
self::assertSame(Border::BORDER_THIN, $sheet->getCell('B2')->getStyle()->getBorders()->getLeft()->getBorderStyle());
self::assertSame(Border::BORDER_NONE, $sheet->getCell('B2')->getStyle()->getBorders()->getTop()->getBorderStyle());
$spreadsheet->disconnectWorksheets();
}

public function testNoSupervisorAllBorders(): void
Expand Down Expand Up @@ -215,6 +221,7 @@ public function testGetSharedComponentPseudo(): void
$sheet = $spreadsheet->getActiveSheet();
$sheet->getStyle('A1')->getBorders()->getHorizontal()->setBorderStyle(Border::BORDER_MEDIUM);
$sheet->getStyle('A1')->getBorders()->getHorizontal()->getSharedComponent();
$spreadsheet->disconnectWorksheets();
}

public function testBorderStyle(): void
Expand All @@ -231,6 +238,7 @@ public function testBorderStyle(): void
$border->setBorderStyle(Border::BORDER_THIN)->setColor(new Color('FFFF0000'));
self::assertEquals('FFFF0000', $border->getColor()->getARGB());
self::assertEquals(Border::BORDER_THIN, $border->getBorderStyle());
$spreadsheet->disconnectWorksheets();
}

public function testDiagonalDirection(): void
Expand All @@ -243,5 +251,6 @@ public function testDiagonalDirection(): void

self::assertSame(Border::BORDER_MEDIUM, $borders->getDiagonal()->getBorderStyle());
self::assertSame(Borders::DIAGONAL_BOTH, $borders->getDiagonalDirection());
$spreadsheet->disconnectWorksheets();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public function testWizardFromConditional(string $sheetName, string $cellAddress
$wizard = Wizard::fromConditional($conditional);
self::assertEquals($expectedWizads[$index], get_class($wizard));
}
$spreadsheet->disconnectWorksheets();
}

public static function conditionalProvider(): array
Expand Down
9 changes: 9 additions & 0 deletions tests/PhpSpreadsheetTests/Style/StyleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function testStyleOddMethods(): void
$styleArray = ['alignment' => ['textRotation' => 45]];
$outArray = $cell1style->getStyleArray($styleArray);
self::assertEquals($styleArray, $outArray['quotePrefix']);
$spreadsheet->disconnectWorksheets();
}

public function testStyleColumn(): void
Expand Down Expand Up @@ -56,6 +57,7 @@ public function testStyleColumn(): void
self::assertTrue($sheet->getStyle('A1')->getFont()->getItalic());
self::assertTrue($sheet->getStyle('B2')->getFont()->getItalic());
self::assertFalse($sheet->getStyle('C3')->getFont()->getItalic());
$spreadsheet->disconnectWorksheets();
}

public function testStyleIsReused(): void
Expand All @@ -79,6 +81,7 @@ public function testStyleIsReused(): void
$spreadsheet->garbageCollect();

self::assertCount(3, $spreadsheet->getCellXfCollection());
$spreadsheet->disconnectWorksheets();
}

public function testStyleRow(): void
Expand Down Expand Up @@ -113,6 +116,7 @@ public function testStyleRow(): void
self::assertFalse($sheet->getStyle('A1')->getFont()->getItalic());
self::assertTrue($sheet->getStyle('B2')->getFont()->getItalic());
self::assertTrue($sheet->getStyle('C3')->getFont()->getItalic());
$spreadsheet->disconnectWorksheets();
}

public function testIssue1712A(): void
Expand All @@ -135,6 +139,7 @@ public function testIssue1712A(): void
->setRGB($rgb);
self::assertEquals($rgb, $sheet->getCell('A1')->getStyle()->getFill()->getStartColor()->getRGB());
self::assertEquals($rgb, $sheet->getCell('B1')->getStyle()->getFill()->getStartColor()->getRGB());
$spreadsheet->disconnectWorksheets();
}

public function testIssue1712B(): void
Expand All @@ -157,6 +162,7 @@ public function testIssue1712B(): void
$sheet->fromArray(['OK', 'KO']);
self::assertEquals($rgb, $sheet->getCell('A1')->getStyle()->getFill()->getStartColor()->getRGB());
self::assertEquals($rgb, $sheet->getCell('B1')->getStyle()->getFill()->getStartColor()->getRGB());
$spreadsheet->disconnectWorksheets();
}

public function testStyleLoopUpwards(): void
Expand All @@ -182,6 +188,7 @@ public function testStyleLoopUpwards(): void
self::assertFalse($sheet->getStyle('A1')->getFont()->getBold());
self::assertFalse($sheet->getStyle('B2')->getFont()->getBold());
self::assertTrue($sheet->getStyle('C3')->getFont()->getBold());
$spreadsheet->disconnectWorksheets();
}

public function testStyleCellAddressObject(): void
Expand All @@ -193,6 +200,7 @@ public function testStyleCellAddressObject(): void
$style->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);

self::assertSame(NumberFormat::FORMAT_DATE_YYYYMMDDSLASH, $style->getNumberFormat()->getFormatCode());
$spreadsheet->disconnectWorksheets();
}

public function testStyleCellRangeObject(): void
Expand All @@ -206,5 +214,6 @@ public function testStyleCellRangeObject(): void
$style->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);

self::assertSame(NumberFormat::FORMAT_DATE_YYYYMMDDSLASH, $style->getNumberFormat()->getFormatCode());
$spreadsheet->disconnectWorksheets();
}
}
Loading

0 comments on commit b5ef72c

Please sign in to comment.