diff --git a/src/PhpSpreadsheet/Style/Alignment.php b/src/PhpSpreadsheet/Style/Alignment.php index a50229930d..605bcb91b3 100644 --- a/src/PhpSpreadsheet/Style/Alignment.php +++ b/src/PhpSpreadsheet/Style/Alignment.php @@ -223,6 +223,7 @@ public function applyFromArray(array $styleArray): static $this->setReadOrder($styleArray['readOrder']); } } + $this->updateHashBeforeUse(); return $this; } @@ -259,6 +260,7 @@ public function setHorizontal(string $horizontalAlignment): static } else { $this->horizontal = $horizontalAlignment; } + $this->updateHashBeforeUse(); return $this; } @@ -288,6 +290,7 @@ public function setJustifyLastLine(bool $justifyLastLine): static } else { $this->justifyLastLine = $justifyLastLine; } + $this->updateHashBeforeUse(); return $this; } @@ -321,6 +324,7 @@ public function setVertical(string $verticalAlignment): static } else { $this->vertical = $verticalAlignment; } + $this->updateHashBeforeUse(); return $this; } @@ -360,6 +364,7 @@ public function setTextRotation(int $angleInDegrees): static } else { throw new PhpSpreadsheetException('Text rotation should be a value between -90 and 90.'); } + $this->updateHashBeforeUse(); return $this; } @@ -392,6 +397,7 @@ public function setWrapText(bool $wrapped): static } else { $this->wrapText = $wrapped; } + $this->updateHashBeforeUse(); return $this; } @@ -424,6 +430,7 @@ public function setShrinkToFit(bool $shrink): static } else { $this->shrinkToFit = $shrink; } + $this->updateHashBeforeUse(); return $this; } @@ -463,6 +470,7 @@ public function setIndent(int $indent): static } else { $this->indent = $indent; } + $this->updateHashBeforeUse(); return $this; } @@ -495,22 +503,17 @@ public function setReadOrder(int $readOrder): static } else { $this->readOrder = $readOrder; } + $this->updateHashBeforeUse(); return $this; } /** - * Get hash code. - * - * @return string Hash code + * Update Hash when something changes. */ - public function getHashCode(): string + protected function updateHash(): void { - if ($this->isSupervisor) { - return $this->getSharedComponent()->getHashCode(); - } - - return md5( + $this->md5Sum = md5( $this->horizontal . (($this->justifyLastLine === null) ? 'null' : ($this->justifyLastLine ? 't' : 'f')) . $this->vertical @@ -521,6 +524,25 @@ public function getHashCode(): string . $this->readOrder . __CLASS__ ); + $this->updateMd5Sum = false; + } + + /** + * Get hash code. + * + * @return string Hash code + */ + public function getHashCode(): string + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } protected function exportArray1(): array diff --git a/src/PhpSpreadsheet/Style/Border.php b/src/PhpSpreadsheet/Style/Border.php index 07162566db..9c7fba043e 100644 --- a/src/PhpSpreadsheet/Style/Border.php +++ b/src/PhpSpreadsheet/Style/Border.php @@ -122,6 +122,7 @@ public function applyFromArray(array $styleArray): static $this->getColor()->applyFromArray($styleArray['color']); } } + $this->updateHashBeforeUse(); return $this; } @@ -160,6 +161,7 @@ public function setBorderStyle(bool|string $style): static } else { $this->borderStyle = $style; } + $this->updateHashBeforeUse(); return $this; } @@ -188,10 +190,24 @@ public function setColor(Color $color): static } else { $this->color = $color; } + $this->updateHashBeforeUse(); return $this; } + /** + * Update Hash when something changes. + */ + protected function updateHash(): void + { + $this->md5Sum = md5( + $this->borderStyle + . $this->color->getHashCode() + . __CLASS__ + ); + $this->updateMd5Sum = false; + } + /** * Get hash code. * @@ -203,11 +219,11 @@ public function getHashCode(): string return $this->getSharedComponent()->getHashCode(); } - return md5( - $this->borderStyle - . $this->color->getHashCode() - . __CLASS__ - ); + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } protected function exportArray1(): array diff --git a/src/PhpSpreadsheet/Style/Borders.php b/src/PhpSpreadsheet/Style/Borders.php index 1d23af3b4c..e8b29eca5a 100644 --- a/src/PhpSpreadsheet/Style/Borders.php +++ b/src/PhpSpreadsheet/Style/Borders.php @@ -199,6 +199,7 @@ public function applyFromArray(array $styleArray): static $this->getBottom()->applyFromArray($styleArray['allBorders']); } } + $this->updateHashBeforeUse(); return $this; } @@ -330,22 +331,17 @@ public function setDiagonalDirection(int $direction): static } else { $this->diagonalDirection = $direction; } + $this->updateHashBeforeUse(); return $this; } /** - * Get hash code. - * - * @return string Hash code + * Update Hash when something changes. */ - public function getHashCode(): string + protected function updateHash(): void { - if ($this->isSupervisor) { - return $this->getSharedComponent()->getHashcode(); - } - - return md5( + $this->md5Sum = md5( $this->getLeft()->getHashCode() . $this->getRight()->getHashCode() . $this->getTop()->getHashCode() @@ -356,6 +352,24 @@ public function getHashCode(): string ); } + /** + * Get hash code. + * + * @return string Hash code + */ + public function getHashCode(): string + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getHashcode(); + } + + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; + } + protected function exportArray1(): array { $exportedArray = []; diff --git a/src/PhpSpreadsheet/Style/Color.php b/src/PhpSpreadsheet/Style/Color.php index 8aa4734fc9..3c80cd8674 100644 --- a/src/PhpSpreadsheet/Style/Color.php +++ b/src/PhpSpreadsheet/Style/Color.php @@ -246,6 +246,7 @@ public function setARGB(?string $colorValue = self::COLOR_BLACK, bool $nullStrin } else { $this->argb = $colorValue; } + $this->updateHashBeforeUse(); return $this; } @@ -384,6 +385,18 @@ public static function indexedColor(int $colorIndex, bool $background = false, ? return ($background) ? new self(self::COLOR_WHITE) : new self(self::COLOR_BLACK); } + /** + * Update Hash when something changes. + */ + protected function updateHash(): void + { + $this->md5Sum = md5( + $this->argb + . __CLASS__ + ); + $this->updateMd5Sum = false; + } + /** * Get hash code. * @@ -395,10 +408,11 @@ public function getHashCode(): string return $this->getSharedComponent()->getHashCode(); } - return md5( - $this->argb - . __CLASS__ - ); + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } protected function exportArray1(): array diff --git a/src/PhpSpreadsheet/Style/Fill.php b/src/PhpSpreadsheet/Style/Fill.php index 9ec5d7336e..d0de784744 100644 --- a/src/PhpSpreadsheet/Style/Fill.php +++ b/src/PhpSpreadsheet/Style/Fill.php @@ -177,6 +177,7 @@ public function setFillType(string $fillType): static } else { $this->fillType = $fillType; } + $this->updateHashBeforeUse(); return $this; } @@ -206,6 +207,7 @@ public function setRotation(float $angleInDegrees): static } else { $this->rotation = $angleInDegrees; } + $this->updateHashBeforeUse(); return $this; } @@ -235,6 +237,7 @@ public function setStartColor(Color $color): static } else { $this->startColor = $color; } + $this->updateHashBeforeUse(); return $this; } @@ -264,6 +267,7 @@ public function setEndColor(Color $color): static } else { $this->endColor = $color; } + $this->updateHashBeforeUse(); return $this; } @@ -279,6 +283,18 @@ public function getColorsChanged(): bool return $changed || $this->startColor->getHasChanged() || $this->endColor->getHasChanged(); } + protected function updateHash(): void + { + $this->md5Sum = md5( + $this->getFillType() + . $this->getRotation() + . ($this->getFillType() !== self::FILL_NONE ? $this->getStartColor()->getHashCode() : '') + . ($this->getFillType() !== self::FILL_NONE ? $this->getEndColor()->getHashCode() : '') + . ((string) $this->getColorsChanged()) + . __CLASS__ + ); + } + /** * Get hash code. * @@ -290,16 +306,11 @@ public function getHashCode(): string return $this->getSharedComponent()->getHashCode(); } - // Note that we don't care about colours for fill type NONE, but could have duplicate NONEs with - // different hashes if we don't explicitly prevent this - return md5( - $this->getFillType() - . $this->getRotation() - . ($this->getFillType() !== self::FILL_NONE ? $this->getStartColor()->getHashCode() : '') - . ($this->getFillType() !== self::FILL_NONE ? $this->getEndColor()->getHashCode() : '') - . ((string) $this->getColorsChanged()) - . __CLASS__ - ); + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } protected function exportArray1(): array diff --git a/src/PhpSpreadsheet/Style/Font.php b/src/PhpSpreadsheet/Style/Font.php index 7d70dc4f7a..5fd1997b0f 100644 --- a/src/PhpSpreadsheet/Style/Font.php +++ b/src/PhpSpreadsheet/Style/Font.php @@ -217,6 +217,7 @@ public function applyFromArray(array $styleArray): static $this->setCap($styleArray['cap']); } } + $this->updateHashBeforeUse(); return $this; } @@ -274,6 +275,7 @@ public function setName(string $fontname): self } else { $this->name = $fontname; } + $this->updateHashBeforeUse(); return $this->setScheme(''); } @@ -292,6 +294,7 @@ public function setLatin(string $fontname): self $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } + $this->updateHashBeforeUse(); return $this; } @@ -310,6 +313,7 @@ public function setEastAsian(string $fontname): self $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } + $this->updateHashBeforeUse(); return $this; } @@ -328,6 +332,7 @@ public function setComplexScript(string $fontname): self $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } + $this->updateHashBeforeUse(); return $this; } @@ -371,6 +376,7 @@ public function setSize(mixed $sizeInPoints, bool $nullOk = false): static } else { $this->size = $sizeInPoints; } + $this->updateHashBeforeUse(); return $this; } @@ -403,6 +409,7 @@ public function setBold(bool $bold): static } else { $this->bold = $bold; } + $this->updateHashBeforeUse(); return $this; } @@ -435,6 +442,7 @@ public function setItalic(bool $italic): static } else { $this->italic = $italic; } + $this->updateHashBeforeUse(); return $this; } @@ -467,6 +475,7 @@ public function setSuperscript(bool $superscript): static $this->subscript = false; } } + $this->updateHashBeforeUse(); return $this; } @@ -499,6 +508,7 @@ public function setSubscript(bool $subscript): static $this->superscript = false; } } + $this->updateHashBeforeUse(); return $this; } @@ -523,6 +533,7 @@ public function setBaseLine(int $baseLine): self $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } + $this->updateHashBeforeUse(); return $this; } @@ -547,6 +558,7 @@ public function setStrikeType(string $strikeType): self $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } + $this->updateHashBeforeUse(); return $this; } @@ -571,6 +583,7 @@ public function setUnderlineColor(array $colorArray): self $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } + $this->updateHashBeforeUse(); return $this; } @@ -595,6 +608,7 @@ public function setChartColor(array $colorArray): self $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); // @codeCoverageIgnoreEnd } + $this->updateHashBeforeUse(); return $this; } @@ -602,6 +616,7 @@ public function setChartColor(array $colorArray): self public function setChartColorFromObject(?ChartColor $chartColor): self { $this->chartColor = $chartColor; + $this->updateHashBeforeUse(); return $this; } @@ -640,6 +655,7 @@ public function setUnderline($underlineStyle): static } else { $this->underline = $underlineStyle; } + $this->updateHashBeforeUse(); return $this; } @@ -673,6 +689,7 @@ public function setStrikethrough(bool $strikethru): static } else { $this->strikethrough = $strikethru; } + $this->updateHashBeforeUse(); return $this; } @@ -701,6 +718,7 @@ public function setColor(Color $color): static } else { $this->color = $color; } + $this->updateHashBeforeUse(); return $this; } @@ -718,17 +736,11 @@ private function hashChartColor(?ChartColor $underlineColor): string } /** - * Get hash code. - * - * @return string Hash code + * Update Hash when something changes. */ - public function getHashCode(): string + protected function updateHash(): void { - if ($this->isSupervisor) { - return $this->getSharedComponent()->getHashCode(); - } - - return md5( + $this->md5Sum = md5( $this->name . $this->size . ($this->bold ? 't' : 'f') @@ -754,6 +766,25 @@ public function getHashCode(): string ) . __CLASS__ ); + $this->updateMd5Sum = false; + } + + /** + * Get hash code. + * + * @return string Hash code + */ + public function getHashCode(): string + { + if ($this->isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } protected function exportArray1(): array @@ -800,6 +831,7 @@ public function setScheme(string $scheme): self $this->scheme = $scheme; } } + $this->updateHashBeforeUse(); return $this; } @@ -814,6 +846,7 @@ public function setScheme(string $scheme): self public function setCap(string $cap): self { $this->cap = in_array($cap, self::VALID_CAPS, true) ? $cap : null; + $this->updateHashBeforeUse(); return $this; } diff --git a/src/PhpSpreadsheet/Style/NumberFormat.php b/src/PhpSpreadsheet/Style/NumberFormat.php index 9c9a54560e..1c1a8163de 100644 --- a/src/PhpSpreadsheet/Style/NumberFormat.php +++ b/src/PhpSpreadsheet/Style/NumberFormat.php @@ -256,6 +256,7 @@ public function setFormatCode(string $formatCode): static $this->formatCode = $formatCode; $this->builtInFormatCode = self::builtInFormatCodeIndex($formatCode); } + $this->updateHashBeforeUse(); return $this; } @@ -290,6 +291,7 @@ public function setBuiltInFormatCode(int $formatCodeIndex): static $this->builtInFormatCode = $formatCodeIndex; $this->formatCode = self::builtInFormatCode($formatCodeIndex); } + $this->updateHashBeforeUse(); return $this; } @@ -434,6 +436,19 @@ public static function builtInFormatCodeIndex(string $formatCodeIndex) return false; } + /** + * Update Hash when something changes. + */ + protected function updateHash(): void + { + $this->md5Sum = md5( + $this->formatCode + . $this->builtInFormatCode + . __CLASS__ + ); + $this->updateMd5Sum = false; + } + /** * Get hash code. * @@ -445,11 +460,11 @@ public function getHashCode(): string return $this->getSharedComponent()->getHashCode(); } - return md5( - $this->formatCode - . $this->builtInFormatCode - . __CLASS__ - ); + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } /** diff --git a/src/PhpSpreadsheet/Style/Protection.php b/src/PhpSpreadsheet/Style/Protection.php index 55a6526c88..3bc970b6da 100644 --- a/src/PhpSpreadsheet/Style/Protection.php +++ b/src/PhpSpreadsheet/Style/Protection.php @@ -89,6 +89,7 @@ public function applyFromArray(array $styleArray): static $this->setHidden($styleArray['hidden']); } } + $this->updateHashBeforeUse(); return $this; } @@ -120,6 +121,7 @@ public function setLocked(string $lockType): static } else { $this->locked = $lockType; } + $this->updateHashBeforeUse(); return $this; } @@ -151,10 +153,24 @@ public function setHidden(string $hiddenType): static } else { $this->hidden = $hiddenType; } + $this->updateHashBeforeUse(); return $this; } + /** + * Update Hash when something changes. + */ + protected function updateHash(): void + { + $this->md5Sum = md5( + $this->locked + . $this->hidden + . __CLASS__ + ); + $this->updateMd5Sum = false; + } + /** * Get hash code. * @@ -166,11 +182,11 @@ public function getHashCode(): string return $this->getSharedComponent()->getHashCode(); } - return md5( - $this->locked - . $this->hidden - . __CLASS__ - ); + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } protected function exportArray1(): array diff --git a/src/PhpSpreadsheet/Style/Style.php b/src/PhpSpreadsheet/Style/Style.php index 7d36489af6..0f403e5ceb 100644 --- a/src/PhpSpreadsheet/Style/Style.php +++ b/src/PhpSpreadsheet/Style/Style.php @@ -340,6 +340,7 @@ public function applyFromArray(array $styleArray, bool $advancedBorders = true): // restore initial cell selection range $this->getActiveSheet()->getStyle($pRange); + $this->updateHashBeforeUse(); return $this; } @@ -485,6 +486,7 @@ public function applyFromArray(array $styleArray, bool $advancedBorders = true): $this->quotePrefix = $styleArray['quotePrefix']; } } + $this->updateHashBeforeUse(); return $this; } @@ -562,6 +564,7 @@ public function getFont(): Font public function setFont(Font $font): static { $this->font = $font; + $this->updateHashBeforeUse(); return $this; } @@ -650,18 +653,17 @@ public function setQuotePrefix(bool $quotePrefix): static } else { $this->quotePrefix = (bool) $quotePrefix; } + $this->updateHashBeforeUse(); return $this; } /** - * Get hash code. - * - * @return string Hash code + * Update Hash when something changes. */ - public function getHashCode(): string + protected function updateHash(): void { - return md5( + $this->md5Sum = md5( $this->fill->getHashCode() . $this->font->getHashCode() . $this->borders->getHashCode() @@ -671,6 +673,21 @@ public function getHashCode(): string . ($this->quotePrefix ? 't' : 'f') . __CLASS__ ); + $this->updateMd5Sum = false; + } + + /** + * Get hash code. + * + * @return string Hash code + */ + public function getHashCode(): string + { + if ($this->updateMd5Sum) { + $this->updateHash(); + } + + return $this->md5Sum; } /** diff --git a/src/PhpSpreadsheet/Style/Supervisor.php b/src/PhpSpreadsheet/Style/Supervisor.php index 8388ef6cd7..4487dc47fa 100644 --- a/src/PhpSpreadsheet/Style/Supervisor.php +++ b/src/PhpSpreadsheet/Style/Supervisor.php @@ -20,6 +20,16 @@ abstract class Supervisor implements IComparable */ protected $parent; + /** + * md5sum. + */ + protected string $md5Sum = ''; + + /** + * do we need to recalculate the md5sum when next asked. + */ + protected bool $updateMd5Sum = true; + /** * Parent property name. */ @@ -51,6 +61,14 @@ public function bindParent(Spreadsheet|self $parent, ?string $parentPropertyName return $this; } + /** + * update the md5sum before next use. + */ + public function updateHashBeforeUse(): void + { + $this->updateMd5Sum = true; + } + /** * Is this a supervisor or a cell style component? */ @@ -89,6 +107,11 @@ public function getActiveCell(): string return $this->getActiveSheet()->getActiveCell(); } + /** + * Update Hash when something changes. + */ + abstract protected function updateHash(): void; + /** * Implement PHP __clone to create a deep clone, not just a shallow copy. */