Skip to content

Commit b13b2a0

Browse files
author
Mark Baker
authored
Allow single-cell checks on conditional styles, even when the style is configured for a range of cells (#2483)
* Allow single-cell checks on conditional styles, even when the style is configured for a range of cells
1 parent 778e24c commit b13b2a0

File tree

2 files changed

+124
-6
lines changed

2 files changed

+124
-6
lines changed

src/PhpSpreadsheet/Worksheet/Worksheet.php

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,30 +1432,57 @@ public function getStyle($cellCoordinate)
14321432
/**
14331433
* Get conditional styles for a cell.
14341434
*
1435-
* @param string $coordinate eg: 'A1'
1435+
* @param string $coordinate eg: 'A1' or 'A1:A3'.
1436+
* If a single cell is referenced, then the array of conditional styles will be returned if the cell is
1437+
* included in a conditional style range.
1438+
* If a range of cells is specified, then the styles will only be returned if the range matches the entire
1439+
* range of the conditional.
14361440
*
14371441
* @return Conditional[]
14381442
*/
14391443
public function getConditionalStyles($coordinate)
14401444
{
14411445
$coordinate = strtoupper($coordinate);
1442-
if (!isset($this->conditionalStylesCollection[$coordinate])) {
1443-
$this->conditionalStylesCollection[$coordinate] = [];
1446+
if (strpos($coordinate, ':') !== false) {
1447+
return $this->conditionalStylesCollection[$coordinate] ?? [];
1448+
}
1449+
1450+
$cell = $this->getCell($coordinate);
1451+
foreach (array_keys($this->conditionalStylesCollection) as $conditionalRange) {
1452+
if ($cell->isInRange($conditionalRange)) {
1453+
return $this->conditionalStylesCollection[$conditionalRange];
1454+
}
14441455
}
14451456

1446-
return $this->conditionalStylesCollection[$coordinate];
1457+
return [];
14471458
}
14481459

14491460
/**
14501461
* Do conditional styles exist for this cell?
14511462
*
1452-
* @param string $coordinate eg: 'A1'
1463+
* @param string $coordinate eg: 'A1' or 'A1:A3'.
1464+
* If a single cell is specified, then this method will return true if that cell is included in a
1465+
* conditional style range.
1466+
* If a range of cells is specified, then true will only be returned if the range matches the entire
1467+
* range of the conditional.
14531468
*
14541469
* @return bool
14551470
*/
14561471
public function conditionalStylesExists($coordinate)
14571472
{
1458-
return isset($this->conditionalStylesCollection[strtoupper($coordinate)]);
1473+
$coordinate = strtoupper($coordinate);
1474+
if (strpos($coordinate, ':') !== false) {
1475+
return isset($this->conditionalStylesCollection[strtoupper($coordinate)]);
1476+
}
1477+
1478+
$cell = $this->getCell($coordinate);
1479+
foreach (array_keys($this->conditionalStylesCollection) as $conditionalRange) {
1480+
if ($cell->isInRange($conditionalRange)) {
1481+
return true;
1482+
}
1483+
}
1484+
1485+
return false;
14591486
}
14601487

14611488
/**
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
4+
5+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
6+
use PhpOffice\PhpSpreadsheet\Style\Color;
7+
use PhpOffice\PhpSpreadsheet\Style\Conditional;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class ConditionalStyleTest extends TestCase
11+
{
12+
/**
13+
* @var Spreadsheet
14+
*/
15+
protected $spreadsheet;
16+
17+
protected function setUp(): void
18+
{
19+
parent::setUp();
20+
21+
$this->spreadsheet = new Spreadsheet();
22+
23+
$conditional1 = new Conditional();
24+
$conditional1->setConditionType(Conditional::CONDITION_CELLIS);
25+
$conditional1->setOperatorType(Conditional::OPERATOR_LESSTHAN);
26+
$conditional1->addCondition('0');
27+
$conditional1->getStyle()->getFont()->getColor()->setARGB(Color::COLOR_RED);
28+
$conditional1->getStyle()->getFont()->setBold(true);
29+
30+
$conditional2 = new Conditional();
31+
$conditional2->setConditionType(Conditional::CONDITION_CELLIS);
32+
$conditional2->setOperatorType(Conditional::OPERATOR_EQUAL);
33+
$conditional2->addCondition('0');
34+
$conditional2->getStyle()->getFont()->getColor()->setARGB(Color::COLOR_YELLOW);
35+
$conditional2->getStyle()->getFont()->setBold(true);
36+
37+
$conditional3 = new Conditional();
38+
$conditional3->setConditionType(Conditional::CONDITION_CELLIS);
39+
$conditional3->setOperatorType(Conditional::OPERATOR_GREATERTHAN);
40+
$conditional3->addCondition('0');
41+
$conditional3->getStyle()->getFont()->getColor()->setARGB(Color::COLOR_GREEN);
42+
$conditional3->getStyle()->getFont()->setBold(true);
43+
44+
$conditionalStyles = $this->spreadsheet->getActiveSheet()->getStyle('A1:C3')->getConditionalStyles();
45+
$conditionalStyles[] = $conditional1;
46+
$conditionalStyles[] = $conditional2;
47+
$conditionalStyles[] = $conditional3;
48+
49+
$this->spreadsheet->getActiveSheet()->getStyle('A1:C3')->setConditionalStyles($conditionalStyles);
50+
51+
$this->spreadsheet->getActiveSheet()
52+
->duplicateConditionalStyle(
53+
$this->spreadsheet->getActiveSheet()->getConditionalStyles('A1:C3'),
54+
'F1'
55+
);
56+
}
57+
58+
/**
59+
* @dataProvider cellConditionalStylesProvider
60+
*/
61+
public function testCellHasConditionalStyles(string $cellReference, bool $expectedHasConditionalStyles): void
62+
{
63+
$cellHasConditionalStyles = $this->spreadsheet->getActiveSheet()->conditionalStylesExists($cellReference);
64+
65+
self::assertSame($expectedHasConditionalStyles, $cellHasConditionalStyles);
66+
}
67+
68+
/**
69+
* @dataProvider cellConditionalStylesProvider
70+
*/
71+
public function testCellGetConditionalStyles(string $cellReference, bool $expectedGetConditionalStyles): void
72+
{
73+
$cellHasConditionalStyles = $this->spreadsheet->getActiveSheet()->getConditionalStyles($cellReference);
74+
75+
self::assertSame($expectedGetConditionalStyles, !empty($cellHasConditionalStyles));
76+
}
77+
78+
public function cellConditionalStylesProvider(): array
79+
{
80+
return [
81+
['A1', true],
82+
['B2', true],
83+
['B4', false],
84+
['A1:C3', true],
85+
['A1:B2', false],
86+
['F1', true],
87+
['F2', false],
88+
['A1:F1', false],
89+
];
90+
}
91+
}

0 commit comments

Comments
 (0)