Xlsx Reader Theme Support Broken After 17.1 (#2403)

Fix #2387. Fix #2075. There was substantial refactoring of Writer Xlsx styles in 18.0. An existing static property `$theme` was intended to be shared by both Writer Xlsx and the new Writer Xlsx Styles. However, the initialization of the property in the latter happened later than it should have. This PR makes that initialization happen as soon as the theme has been read. Also, declaring that property as static seems questionable; I have made it an instance member. This small re-factoring makes it possible to now support Themes in tab colors.

Since this PR changes Reader/Xlsx/Styles, add type-hinting throughout that module to eliminate Phpstan/Scrutinizer problems. I also removed method readStyle from Reader/Xlsx, since it was essentially duplicated in Reader/Xlsx/Styles. And I added a small number of tests to ensure that Styles is 100% covered. All of this is necessary in preparation for Namespacing phase 2.
This commit is contained in:
oleibman 2021-11-26 09:38:09 -08:00 committed by GitHub
parent 3257ae5c90
commit 290c18e4db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 186 additions and 207 deletions

View File

@ -4460,106 +4460,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:dxfs\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:dxfs\\(\\) has parameter \\$readDataOnly with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:getArrayItem\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:getArrayItem\\(\\) has parameter \\$array with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:getArrayItem\\(\\) has parameter \\$key with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readColor\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readColor\\(\\) has parameter \\$background with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readColor\\(\\) has parameter \\$color with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readProtectionHidden\\(\\) has parameter \\$style with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readProtectionLocked\\(\\) has parameter \\$style with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readStyle\\(\\) has parameter \\$style with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:setStyleBaseData\\(\\) has parameter \\$cellStyles with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:setStyleBaseData\\(\\) has parameter \\$styles with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:styles\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Parameter \\#1 \\$hexColourValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Color\\:\\:changeBrightness\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Parameter \\#2 \\$alignmentXml of static method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readAlignmentStyle\\(\\) expects SimpleXMLElement, object given\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$cellStyles has no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$styleXml has no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$styles has no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Static property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$theme \\(PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Theme\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Theme\\|null\\.$#"
count: 1
path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
-
message: "#^Parameter \\#1 \\$haystack of function strpos expects string, string\\|false given\\.$#"
count: 1

View File

@ -19,6 +19,7 @@ use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Properties as PropertyReader;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\SheetViewOptions;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\SheetViews;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Styles;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Theme;
use PhpOffice\PhpSpreadsheet\ReferenceHelper;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Settings;
@ -34,7 +35,6 @@ use PhpOffice\PhpSpreadsheet\Style\Style;
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use SimpleXMLElement;
use stdClass;
use Throwable;
use XMLReader;
use ZipArchive;
@ -50,18 +50,14 @@ class Xlsx extends BaseReader
*/
private $referenceHelper;
/**
* Xlsx\Theme instance.
*
* @var Xlsx\Theme
*/
private static $theme;
/**
* @var ZipArchive
*/
private $zip;
/** @var Styles */
private $styleReader;
/**
* Create a new Xlsx Reader instance.
*/
@ -406,6 +402,8 @@ class Xlsx extends BaseReader
// Read the theme first, because we need the colour scheme when reading the styles
[$workbookBasename, $xmlNamespaceBase] = $this->getWorkbookBaseName();
$wbRels = $this->loadZip("xl/_rels/${workbookBasename}.rels", Namespaces::RELATIONSHIPS);
$theme = null;
$this->styleReader = new Styles();
foreach ($wbRels->Relationship as $relx) {
$rel = self::getAttributes($relx);
$relTarget = (string) $rel['Target'];
@ -438,7 +436,8 @@ class Xlsx extends BaseReader
$themeColours[$themePos] = (string) $xmlColourData['val'];
}
}
self::$theme = new Xlsx\Theme($themeName, $colourSchemeName, $themeColours);
$theme = new Theme($themeName, $colourSchemeName, $themeColours);
$this->styleReader->setTheme($theme);
break;
}
@ -599,7 +598,7 @@ class Xlsx extends BaseReader
// add style to cellXf collection
$objStyle = new Style();
self::readStyle($objStyle, $style);
$this->styleReader->readStyle($objStyle, $style);
if ($addingFirstCellXf) {
$excel->removeCellXfByIndex(0); // remove the default style
$addingFirstCellXf = false;
@ -634,7 +633,7 @@ class Xlsx extends BaseReader
// add style to cellStyleXf collection
$objStyle = new Style();
self::readStyle($objStyle, $cellStyle);
$this->styleReader->readStyle($objStyle, $cellStyle);
if ($addingFirstCellStyleXf) {
$excel->removeCellStyleXfByIndex(0); // remove the default style
$addingFirstCellStyleXf = false;
@ -642,10 +641,10 @@ class Xlsx extends BaseReader
$excel->addCellStyleXf($objStyle);
}
}
$styleReader = new Styles($xmlStyles);
$styleReader->setStyleBaseData(self::$theme, $styles, $cellStyles);
$dxfs = $styleReader->dxfs($this->readDataOnly);
$styles = $styleReader->styles();
$this->styleReader->setStyleXml($xmlStyles);
$this->styleReader->setStyleBaseData($theme, $styles, $cellStyles);
$dxfs = $this->styleReader->dxfs($this->readDataOnly);
$styles = $this->styleReader->styles();
$xmlWorkbook = $this->loadZipNoNamespace($relTarget, $mainNS);
$xmlWorkbookNS = $this->loadZip($relTarget, $mainNS);
@ -718,7 +717,7 @@ class Xlsx extends BaseReader
}
$sheetViewOptions = new SheetViewOptions($docSheet, $xmlSheet);
$sheetViewOptions->load($this->getReadDataOnly());
$sheetViewOptions->load($this->getReadDataOnly(), $this->styleReader);
(new ColumnAndRowAttributes($docSheet, $xmlSheet))
->load($this->getReadFilter(), $this->getReadDataOnly());
@ -1618,45 +1617,6 @@ class Xlsx extends BaseReader
return $excel;
}
/**
* @param SimpleXMLElement|stdClass $style
*/
private static function readStyle(Style $docStyle, $style): void
{
$docStyle->getNumberFormat()->setFormatCode($style->numFmt);
// font
if (isset($style->font)) {
Styles::readFontStyle($docStyle->getFont(), $style->font);
}
// fill
if (isset($style->fill)) {
Styles::readFillStyle($docStyle->getFill(), $style->fill);
}
// border
if (isset($style->border)) {
Styles::readBorderStyle($docStyle->getBorders(), $style->border);
}
// alignment
if (isset($style->alignment)) {
Styles::readAlignmentStyle($docStyle->getAlignment(), $style->alignment);
}
// protection
if (isset($style->protection)) {
Styles::readProtectionLocked($docStyle, $style);
Styles::readProtectionHidden($docStyle, $style);
}
// top-level style settings
if (isset($style->quotePrefix)) {
$docStyle->setQuotePrefix((bool) $style->quotePrefix);
}
}
/**
* @return RichText
*/
@ -1685,7 +1645,7 @@ class Xlsx extends BaseReader
$objText->getFont()->setSize((float) $attr['val']);
}
if (isset($run->rPr->color)) {
$objText->getFont()->setColor(new Color(Styles::readColor($run->rPr->color)));
$objText->getFont()->setColor(new Color($this->styleReader->readColor($run->rPr->color)));
}
if (isset($run->rPr->b)) {
$attr = $run->rPr->b->attributes();

View File

@ -17,17 +17,14 @@ class SheetViewOptions extends BaseParserClass
$this->worksheetXml = $worksheetXml;
}
/**
* @param bool $readDataOnly
*/
public function load($readDataOnly = false): void
public function load(bool $readDataOnly, Styles $styleReader): void
{
if ($this->worksheetXml === null) {
return;
}
if (isset($this->worksheetXml->sheetPr)) {
$this->tabColor($this->worksheetXml->sheetPr);
$this->tabColor($this->worksheetXml->sheetPr, $styleReader);
$this->codeName($this->worksheetXml->sheetPr);
$this->outlines($this->worksheetXml->sheetPr);
$this->pageSetup($this->worksheetXml->sheetPr);
@ -42,10 +39,10 @@ class SheetViewOptions extends BaseParserClass
}
}
private function tabColor(SimpleXMLElement $sheetPr): void
private function tabColor(SimpleXMLElement $sheetPr, Styles $styleReader): void
{
if (isset($sheetPr->tabColor, $sheetPr->tabColor['rgb'])) {
$this->worksheet->getTabColor()->setARGB((string) $sheetPr->tabColor['rgb']);
if (isset($sheetPr->tabColor)) {
$this->worksheet->getTabColor()->setARGB($styleReader->readColor($sheetPr->tabColor));
}
}

View File

@ -13,35 +13,44 @@ use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Protection;
use PhpOffice\PhpSpreadsheet\Style\Style;
use SimpleXMLElement;
use stdClass;
class Styles extends BaseParserClass
{
/**
* Theme instance.
*
* @var Theme
* @var ?Theme
*/
private static $theme;
private $theme;
/** @var array */
private $styles = [];
/** @var array */
private $cellStyles = [];
/** @var SimpleXMLElement */
private $styleXml;
public function __construct(SimpleXMLElement $styleXml)
public function setStyleXml(SimpleXmlElement $styleXml): void
{
$this->styleXml = $styleXml;
}
public function setStyleBaseData(?Theme $theme = null, $styles = [], $cellStyles = []): void
public function setTheme(Theme $theme): void
{
self::$theme = $theme;
$this->theme = $theme;
}
public function setStyleBaseData(?Theme $theme = null, array $styles = [], array $cellStyles = []): void
{
$this->theme = $theme;
$this->styles = $styles;
$this->cellStyles = $cellStyles;
}
public static function readFontStyle(Font $fontStyle, SimpleXMLElement $fontStyleXml): void
public function readFontStyle(Font $fontStyle, SimpleXMLElement $fontStyleXml): void
{
if (isset($fontStyleXml->name, $fontStyleXml->name['val'])) {
$fontStyle->setName((string) $fontStyleXml->name['val']);
@ -60,7 +69,7 @@ class Styles extends BaseParserClass
!isset($fontStyleXml->strike['val']) || self::boolean((string) $fontStyleXml->strike['val'])
);
}
$fontStyle->getColor()->setARGB(self::readColor($fontStyleXml->color));
$fontStyle->getColor()->setARGB($this->readColor($fontStyleXml->color));
if (isset($fontStyleXml->u) && !isset($fontStyleXml->u['val'])) {
$fontStyle->setUnderline(Font::UNDERLINE_SINGLE);
@ -78,7 +87,7 @@ class Styles extends BaseParserClass
}
}
private static function readNumberFormat(NumberFormat $numfmtStyle, SimpleXMLElement $numfmtStyleXml): void
private function readNumberFormat(NumberFormat $numfmtStyle, SimpleXMLElement $numfmtStyleXml): void
{
if ($numfmtStyleXml->count() === 0) {
return;
@ -89,7 +98,7 @@ class Styles extends BaseParserClass
}
}
public static function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml): void
public function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml): void
{
if ($fillStyleXml->gradientFill) {
/** @var SimpleXMLElement $gradientFill */
@ -99,16 +108,16 @@ class Styles extends BaseParserClass
}
$fillStyle->setRotation((float) ($gradientFill['degree']));
$gradientFill->registerXPathNamespace('sml', Namespaces::MAIN);
$fillStyle->getStartColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color));
$fillStyle->getEndColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color));
$fillStyle->getStartColor()->setARGB($this->readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color));
$fillStyle->getEndColor()->setARGB($this->readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color));
} elseif ($fillStyleXml->patternFill) {
$defaultFillStyle = Fill::FILL_NONE;
if ($fillStyleXml->patternFill->fgColor) {
$fillStyle->getStartColor()->setARGB(self::readColor($fillStyleXml->patternFill->fgColor, true));
$fillStyle->getStartColor()->setARGB($this->readColor($fillStyleXml->patternFill->fgColor, true));
$defaultFillStyle = Fill::FILL_SOLID;
}
if ($fillStyleXml->patternFill->bgColor) {
$fillStyle->getEndColor()->setARGB(self::readColor($fillStyleXml->patternFill->bgColor, true));
$fillStyle->getEndColor()->setARGB($this->readColor($fillStyleXml->patternFill->bgColor, true));
$defaultFillStyle = Fill::FILL_SOLID;
}
@ -120,7 +129,7 @@ class Styles extends BaseParserClass
}
}
public static function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderStyleXml): void
public function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderStyleXml): void
{
$diagonalUp = self::boolean((string) $borderStyleXml['diagonalUp']);
$diagonalDown = self::boolean((string) $borderStyleXml['diagonalDown']);
@ -134,24 +143,24 @@ class Styles extends BaseParserClass
$borderStyle->setDiagonalDirection(Borders::DIAGONAL_BOTH);
}
self::readBorder($borderStyle->getLeft(), $borderStyleXml->left);
self::readBorder($borderStyle->getRight(), $borderStyleXml->right);
self::readBorder($borderStyle->getTop(), $borderStyleXml->top);
self::readBorder($borderStyle->getBottom(), $borderStyleXml->bottom);
self::readBorder($borderStyle->getDiagonal(), $borderStyleXml->diagonal);
$this->readBorder($borderStyle->getLeft(), $borderStyleXml->left);
$this->readBorder($borderStyle->getRight(), $borderStyleXml->right);
$this->readBorder($borderStyle->getTop(), $borderStyleXml->top);
$this->readBorder($borderStyle->getBottom(), $borderStyleXml->bottom);
$this->readBorder($borderStyle->getDiagonal(), $borderStyleXml->diagonal);
}
private static function readBorder(Border $border, SimpleXMLElement $borderXml): void
private function readBorder(Border $border, SimpleXMLElement $borderXml): void
{
if (isset($borderXml['style'])) {
$border->setBorderStyle((string) $borderXml['style']);
}
if (isset($borderXml->color)) {
$border->getColor()->setARGB(self::readColor($borderXml->color));
$border->getColor()->setARGB($this->readColor($borderXml->color));
}
}
public static function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $alignmentXml): void
public function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $alignmentXml): void
{
$alignment->setHorizontal((string) $alignmentXml['horizontal']);
$alignment->setVertical((string) $alignmentXml['vertical']);
@ -174,43 +183,53 @@ class Styles extends BaseParserClass
);
}
private function readStyle(Style $docStyle, $style): void
/**
* Read style.
*
* @param SimpleXMLElement|stdClass $style
*/
public function readStyle(Style $docStyle, $style): void
{
if ($style->numFmt instanceof SimpleXMLElement) {
self::readNumberFormat($docStyle->getNumberFormat(), $style->numFmt);
$this->readNumberFormat($docStyle->getNumberFormat(), $style->numFmt);
} else {
$docStyle->getNumberFormat()->setFormatCode($style->numFmt);
}
if (isset($style->font)) {
self::readFontStyle($docStyle->getFont(), $style->font);
$this->readFontStyle($docStyle->getFont(), $style->font);
}
if (isset($style->fill)) {
self::readFillStyle($docStyle->getFill(), $style->fill);
$this->readFillStyle($docStyle->getFill(), $style->fill);
}
if (isset($style->border)) {
self::readBorderStyle($docStyle->getBorders(), $style->border);
$this->readBorderStyle($docStyle->getBorders(), $style->border);
}
if (isset($style->alignment->alignment)) {
self::readAlignmentStyle($docStyle->getAlignment(), $style->alignment);
if (isset($style->alignment)) {
$this->readAlignmentStyle($docStyle->getAlignment(), $style->alignment);
}
// protection
if (isset($style->protection)) {
self::readProtectionLocked($docStyle, $style);
self::readProtectionHidden($docStyle, $style);
$this->readProtectionLocked($docStyle, $style);
$this->readProtectionHidden($docStyle, $style);
}
// top-level style settings
if (isset($style->quotePrefix)) {
$docStyle->setQuotePrefix(true);
$docStyle->setQuotePrefix((bool) $style->quotePrefix);
}
}
public static function readProtectionLocked(Style $docStyle, $style): void
/**
* Read protection locked attribute.
*
* @param SimpleXMLElement|stdClass $style
*/
public function readProtectionLocked(Style $docStyle, $style): void
{
if (isset($style->protection['locked'])) {
if (self::boolean((string) $style->protection['locked'])) {
@ -221,7 +240,12 @@ class Styles extends BaseParserClass
}
}
public static function readProtectionHidden(Style $docStyle, $style): void
/**
* Read protection hidden attribute.
*
* @param SimpleXMLElement|stdClass $style
*/
public function readProtectionHidden(Style $docStyle, $style): void
{
if (isset($style->protection['hidden'])) {
if (self::boolean((string) $style->protection['hidden'])) {
@ -232,18 +256,18 @@ class Styles extends BaseParserClass
}
}
public static function readColor($color, $background = false)
public function readColor(SimpleXMLElement $color, bool $background = false): string
{
if (isset($color['rgb'])) {
return (string) $color['rgb'];
} elseif (isset($color['indexed'])) {
return Color::indexedColor($color['indexed'] - 7, $background)->getARGB();
return Color::indexedColor((int) ($color['indexed'] - 7), $background)->getARGB() ?? '';
} elseif (isset($color['theme'])) {
if (self::$theme !== null) {
$returnColour = self::$theme->getColourByIndex((int) $color['theme']);
if ($this->theme !== null) {
$returnColour = $this->theme->getColourByIndex((int) $color['theme']);
if (isset($color['tint'])) {
$tintAdjust = (float) $color['tint'];
$returnColour = Color::changeBrightness($returnColour, $tintAdjust);
$returnColour = Color::changeBrightness($returnColour ?? '', $tintAdjust);
}
return 'FF' . $returnColour;
@ -253,7 +277,7 @@ class Styles extends BaseParserClass
return ($background) ? 'FFFFFFFF' : 'FF000000';
}
public function dxfs($readDataOnly = false)
public function dxfs(bool $readDataOnly = false): array
{
$dxfs = [];
if (!$readDataOnly && $this->styleXml) {
@ -285,13 +309,20 @@ class Styles extends BaseParserClass
return $dxfs;
}
public function styles()
public function styles(): array
{
return $this->styles;
}
private static function getArrayItem($array, $key = 0)
/**
* Get array item.
*
* @param mixed $array (usually array, in theory can be false)
*
* @return stdClass
*/
private static function getArrayItem($array, int $key = 0)
{
return $array[$key] ?? null;
return is_array($array) ? ($array[$key] ?? null) : null;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PHPUnit\Framework\TestCase;
class ColorTabTest extends TestCase
{
public function testIssue2316(): void
{
$filename = 'tests/data/Reader/XLSX/colortabs.xlsx';
$reader = new Xlsx();
$spreadsheet = $reader->load($filename);
// theme color
self::assertSame('FF548135', $spreadsheet->getSheet(0)->getTabColor()->getArgb());
// rgb color
self::assertSame('FFFFC000', $spreadsheet->getSheet(1)->getTabColor()->getArgb());
$spreadsheet->disconnectWorksheets();
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Borders;
use PhpOffice\PhpSpreadsheet\Style\Protection;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class CoverageGapsTest extends AbstractFunctional
{
public function testCoverageGaps(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet
->getStyle('A1')
->getBorders()
->setDiagonalDirection(Borders::DIAGONAL_BOTH)
->getDiagonal()
->setBorderStyle(Border::BORDER_DASHDOTDOT);
$sheet
->getStyle('A2')
->getProtection()
->setLocked(Protection::PROTECTION_PROTECTED);
$sheet
->getStyle('A3')
->getAlignment()
->setTextRotation(Alignment::TEXTROTATION_STACK_EXCEL);
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx');
$spreadsheet->disconnectWorksheets();
$rsheet = $reloadedSpreadsheet->getActiveSheet();
self::assertSame(Borders::DIAGONAL_BOTH, $rsheet->getStyle('A1')->getBorders()->getDiagonalDirection());
self::assertSame(Border::BORDER_DASHDOTDOT, $rsheet->getStyle('A1')->getBorders()->getDiagonal()->getBorderStyle());
self::assertSame(Protection::PROTECTION_PROTECTED, $rsheet->getStyle('A2')->getProtection()->getLocked());
self::assertSame(Alignment::TEXTROTATION_STACK_PHPSPREADSHEET, $rsheet->getStyle('A3')->getAlignment()->getTextRotation());
$reloadedSpreadsheet->disconnectWorksheets();
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PHPUnit\Framework\TestCase;
class Issue2387Test extends TestCase
{
public function testIssue2387(): void
{
// Theme was not being handled.
$filename = 'tests/data/Reader/XLSX/issue.2387.xlsx';
$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load($filename);
$sheet = $spreadsheet->getActiveSheet();
self::assertSame('335593', $sheet->getCell('B2')->getStyle()->getFont()->getColor()->getRgb());
self::assertSame(Fill::FILL_NONE, $sheet->getCell('B2')->getStyle()->getFill()->getFillType());
self::assertSame('FFFFFF', $sheet->getCell('C2')->getStyle()->getFont()->getColor()->getRgb());
self::assertSame('000000', $sheet->getCell('C2')->getStyle()->getFill()->getStartColor()->getRgb());
self::assertSame(Fill::FILL_SOLID, $sheet->getCell('C2')->getStyle()->getFill()->getFillType());
$spreadsheet->disconnectWorksheets();
}
}

Binary file not shown.

Binary file not shown.