• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PHPOffice / PhpSpreadsheet / 18014029598

25 Sep 2025 04:20PM UTC coverage: 95.867% (+0.3%) from 95.602%
18014029598

push

github

web-flow
Merge pull request #4663 from oleibman/tweakcoveralls

Tweak Coveralls

45116 of 47061 relevant lines covered (95.87%)

373.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.39
/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/WizardAbstract.php
1
<?php
2

3
namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard;
4

5
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
7
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard;
8
use PhpOffice\PhpSpreadsheet\Style\Style;
9

10
abstract class WizardAbstract
11
{
12
    protected ?Style $style = null;
13

14
    protected string $expression;
15

16
    protected string $cellRange;
17

18
    protected string $referenceCell;
19

20
    protected int $referenceRow;
21

22
    protected bool $stopIfTrue = false;
23

24
    protected int $referenceColumn;
25

26
    public function __construct(string $cellRange)
99✔
27
    {
28
        $this->setCellRange($cellRange);
99✔
29
    }
30

31
    public function getCellRange(): string
17✔
32
    {
33
        return $this->cellRange;
17✔
34
    }
35

36
    public function setCellRange(string $cellRange): void
99✔
37
    {
38
        $this->cellRange = $cellRange;
99✔
39
        $this->setReferenceCellForExpressions($cellRange);
99✔
40
    }
41

42
    protected function setReferenceCellForExpressions(string $conditionalRange): void
99✔
43
    {
44
        $conditionalRange = Coordinate::splitRange(str_replace('$', '', strtoupper($conditionalRange)));
99✔
45
        [$this->referenceCell] = $conditionalRange[0];
99✔
46

47
        [$this->referenceColumn, $this->referenceRow] = Coordinate::indexesFromString($this->referenceCell);
99✔
48
    }
49

50
    public function getStopIfTrue(): bool
81✔
51
    {
52
        return $this->stopIfTrue;
81✔
53
    }
54

55
    public function setStopIfTrue(bool $stopIfTrue): void
×
56
    {
57
        $this->stopIfTrue = $stopIfTrue;
×
58
    }
59

60
    public function getStyle(): Style
81✔
61
    {
62
        return $this->style ?? new Style(false, true);
81✔
63
    }
64

65
    public function setStyle(Style $style): void
66✔
66
    {
67
        $this->style = $style;
66✔
68
    }
69

70
    protected function validateOperand(string $operand, string $operandValueType = Wizard::VALUE_TYPE_LITERAL): string
35✔
71
    {
72
        if (
73
            $operandValueType === Wizard::VALUE_TYPE_LITERAL
35✔
74
            && str_starts_with($operand, '"')
35✔
75
            && str_ends_with($operand, '"')
35✔
76
        ) {
77
            $operand = str_replace('""', '"', substr($operand, 1, -1));
×
78
        } elseif ($operandValueType === Wizard::VALUE_TYPE_FORMULA && str_starts_with($operand, '=')) {
35✔
79
            $operand = substr($operand, 1);
1✔
80
        }
81

82
        return $operand;
35✔
83
    }
84

85
    /** @param string[] $matches */
86
    protected static function reverseCellAdjustment(array $matches, int $referenceColumn, int $referenceRow): string
22✔
87
    {
88
        $worksheet = $matches[1];
22✔
89
        $column = $matches[6];
22✔
90
        $row = $matches[7];
22✔
91

92
        if (!str_contains($column, '$')) {
22✔
93
            $column = Coordinate::columnIndexFromString($column);
10✔
94
            $column -= $referenceColumn - 1;
10✔
95
            $column = Coordinate::stringFromColumnIndex($column);
10✔
96
        }
97

98
        if (!str_contains($row, '$')) {
22✔
99
            $row = (int) $row - ($referenceRow - 1);
14✔
100
        }
101

102
        return "{$worksheet}{$column}{$row}";
22✔
103
    }
104

105
    public static function reverseAdjustCellRef(string $condition, string $cellRange): string
26✔
106
    {
107
        $conditionalRange = Coordinate::splitRange(str_replace('$', '', strtoupper($cellRange)));
26✔
108
        [$referenceCell] = $conditionalRange[0];
26✔
109
        [$referenceColumnIndex, $referenceRow] = Coordinate::indexesFromString($referenceCell);
26✔
110

111
        $splitCondition = explode(Calculation::FORMULA_STRING_QUOTE, $condition);
26✔
112
        $i = false;
26✔
113
        foreach ($splitCondition as &$value) {
26✔
114
            //    Only count/replace in alternating array entries (ie. not in quoted strings)
115
            $i = $i === false;
26✔
116
            if ($i) {
26✔
117
                $value = (string) preg_replace_callback(
26✔
118
                    '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i',
26✔
119
                    fn ($matches): string => self::reverseCellAdjustment($matches, $referenceColumnIndex, $referenceRow),
26✔
120
                    $value
26✔
121
                );
26✔
122
            }
123
        }
124
        unset($value);
26✔
125

126
        //    Then rebuild the condition string to return it
127
        return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition);
26✔
128
    }
129

130
    /** @param string[] $matches */
131
    protected function conditionCellAdjustment(array $matches): string
27✔
132
    {
133
        $worksheet = $matches[1];
27✔
134
        $column = $matches[6];
27✔
135
        $row = $matches[7];
27✔
136

137
        if (!str_contains($column, '$')) {
27✔
138
            $column = Coordinate::columnIndexFromString($column);
11✔
139
            $column += $this->referenceColumn - 1;
11✔
140
            $column = Coordinate::stringFromColumnIndex($column);
11✔
141
        }
142

143
        if (!str_contains($row, '$')) {
27✔
144
            $row = (int) $row + ($this->referenceRow - 1);
16✔
145
        }
146

147
        return "{$worksheet}{$column}{$row}";
27✔
148
    }
149

150
    protected function cellConditionCheck(string $condition): string
28✔
151
    {
152
        $splitCondition = explode(Calculation::FORMULA_STRING_QUOTE, $condition);
28✔
153
        $i = false;
28✔
154
        foreach ($splitCondition as &$value) {
28✔
155
            //    Only count/replace in alternating array entries (ie. not in quoted strings)
156
            $i = $i === false;
28✔
157
            if ($i) {
28✔
158
                $value = (string) preg_replace_callback(
28✔
159
                    '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i',
28✔
160
                    [$this, 'conditionCellAdjustment'],
28✔
161
                    $value
28✔
162
                );
28✔
163
            }
164
        }
165
        unset($value);
28✔
166

167
        //    Then rebuild the condition string to return it
168
        return implode(Calculation::FORMULA_STRING_QUOTE, $splitCondition);
28✔
169
    }
170

171
    /**
172
     * @param mixed[] $conditions
173
     *
174
     * @return mixed[]
175
     */
176
    protected function adjustConditionsForCellReferences(array $conditions): array
6✔
177
    {
178
        return array_map(
6✔
179
            [$this, 'cellConditionCheck'],
6✔
180
            $conditions
6✔
181
        );
6✔
182
    }
183
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc