Passed
Pull Request — master (#3236)
by Mark
11:30
created

Column::updateStructuredReferences()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 15
rs 9.2222
ccs 0
cts 0
cp 0
cc 6
nc 4
nop 3
crap 42
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Worksheet\Table;
4
5
use PhpOffice\PhpSpreadsheet\Cell\DataType;
6
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
7
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
9
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
10
11
class Column
12
{
13
    /**
14
     * Table Column Index.
15
     *
16
     * @var string
17
     */
18
    private $columnIndex = '';
19
20
    /**
21
     * Show Filter Button.
22
     *
23
     * @var bool
24
     */
25
    private $showFilterButton = true;
26
27
    /**
28
     * Total Row Label.
29
     *
30
     * @var string
31
     */
32
    private $totalsRowLabel;
33
34
    /**
35
     * Total Row Function.
36
     *
37
     * @var string
38
     */
39
    private $totalsRowFunction;
40
41
    /**
42
     * Total Row Formula.
43
     *
44
     * @var string
45
     */
46
    private $totalsRowFormula;
47
48
    /**
49
     * Column Formula.
50
     *
51
     * @var string
52
     */
53
    private $columnFormula;
54
55
    /**
56
     * Table.
57
     *
58
     * @var null|Table
59
     */
60
    private $table;
61
62
    /**
63
     * Create a new Column.
64 21
     *
65
     * @param string $column Column (e.g. A)
66 21
     * @param Table $table Table for this column
67 21
     */
68
    public function __construct($column, ?Table $table = null)
69
    {
70
        $this->columnIndex = $column;
71
        $this->table = $table;
72
    }
73 4
74
    /**
75 4
     * Get Table column index as string eg: 'A'.
76
     */
77
    public function getColumnIndex(): string
78
    {
79
        return $this->columnIndex;
80
    }
81
82
    /**
83 2
     * Set Table column index as string eg: 'A'.
84
     *
85
     * @param string $column Column (e.g. A)
86 2
     */
87 2
    public function setColumnIndex($column): self
88 1
    {
89
        // Uppercase coordinate
90
        $column = strtoupper($column);
91 2
        if ($this->table !== null) {
92
            $this->table->isColumnInRange($column);
93 2
        }
94
95
        $this->columnIndex = $column;
96
97
        return $this;
98
    }
99 6
100
    /**
101 6
     * Get show Filter Button.
102
     */
103
    public function getShowFilterButton(): bool
104
    {
105
        return $this->showFilterButton;
106
    }
107 7
108
    /**
109 7
     * Set show Filter Button.
110
     */
111 7
    public function setShowFilterButton(bool $showFilterButton): self
112
    {
113
        $this->showFilterButton = $showFilterButton;
114
115
        return $this;
116
    }
117 3
118
    /**
119 3
     * Get total Row Label.
120
     */
121
    public function getTotalsRowLabel(): ?string
122
    {
123
        return $this->totalsRowLabel;
124
    }
125 3
126
    /**
127 3
     * Set total Row Label.
128
     */
129 3
    public function setTotalsRowLabel(string $totalsRowLabel): self
130
    {
131
        $this->totalsRowLabel = $totalsRowLabel;
132
133
        return $this;
134
    }
135 3
136
    /**
137 3
     * Get total Row Function.
138
     */
139
    public function getTotalsRowFunction(): ?string
140
    {
141
        return $this->totalsRowFunction;
142
    }
143 3
144
    /**
145 3
     * Set total Row Function.
146
     */
147 3
    public function setTotalsRowFunction(string $totalsRowFunction): self
148
    {
149
        $this->totalsRowFunction = $totalsRowFunction;
150
151
        return $this;
152
    }
153
154
    /**
155
     * Get total Row Formula.
156
     */
157
    public function getTotalsRowFormula(): ?string
158
    {
159
        return $this->totalsRowFormula;
160
    }
161
162
    /**
163
     * Set total Row Formula.
164
     */
165
    public function setTotalsRowFormula(string $totalsRowFormula): self
166
    {
167
        $this->totalsRowFormula = $totalsRowFormula;
168
169
        return $this;
170
    }
171 5
172
    /**
173 5
     * Get column Formula.
174
     */
175
    public function getColumnFormula(): ?string
176
    {
177
        return $this->columnFormula;
178
    }
179 3
180
    /**
181 3
     * Set column Formula.
182
     */
183 3
    public function setColumnFormula(string $columnFormula): self
184
    {
185
        $this->columnFormula = $columnFormula;
186
187
        return $this;
188
    }
189 1
190
    /**
191 1
     * Get this Column's Table.
192
     */
193
    public function getTable(): ?Table
194
    {
195
        return $this->table;
196
    }
197 4
198
    /**
199 4
     * Set this Column's Table.
200
     */
201 4
    public function setTable(?Table $table = null): self
202
    {
203
        $this->table = $table;
204
205
        return $this;
206
    }
207
208
    public static function updateStructuredReferences(?Worksheet $workSheet, ?string $oldTitle, string $newTitle): void
209
    {
210
        if ($workSheet === null || $oldTitle === null || $oldTitle === '') {
211
            return;
212
        }
213
214
        // Remember that table headings are case-insensitive
215
        if (StringHelper::strToLower($oldTitle) !== StringHelper::strToLower($newTitle)) {
216
            // We need to check all formula cells that might contain Structured References that refer
217
            //    to this column, and update those formulae to reference the new column text
218
            $spreadsheet = $workSheet->getParent();
219
            foreach ($spreadsheet->getWorksheetIterator() as $sheet) {
220
                self::updateStructuredReferencesInCells($sheet, $oldTitle, $newTitle);
221
            }
222
            self::updateStructuredReferencesInNamedFormulae($spreadsheet, $oldTitle, $newTitle);
223
        }
224
    }
225
226
    private static function updateStructuredReferencesInCells(Worksheet $worksheet, string $oldTitle, string $newTitle): void
227
    {
228
        $pattern = '/\[(@?)' . preg_quote($oldTitle) . '\]/mui';
229
230
        foreach ($worksheet->getCoordinates(false) as $coordinate) {
231
            $cell = $worksheet->getCell($coordinate);
232
            if ($cell->getDataType() === DataType::TYPE_FORMULA) {
233
                $formula = $cell->getValue();
234
                if (preg_match($pattern, $formula) === 1) {
235
                    $formula = preg_replace($pattern, "[$1{$newTitle}]", $formula);
236
                    $cell->setValueExplicit($formula, DataType::TYPE_FORMULA);
237
                }
238
            }
239
        }
240
    }
241
242
    private static function updateStructuredReferencesInNamedFormulae(Spreadsheet $spreadsheet, string $oldTitle, string $newTitle): void
243
    {
244
        $pattern = '/\[(@?)' . preg_quote($oldTitle) . '\]/mui';
245
246
        foreach ($spreadsheet->getNamedFormulae() as $namedFormula) {
247
            $formula = $namedFormula->getValue();
248
            if (preg_match($pattern, $formula) === 1) {
249
                $formula = preg_replace($pattern, "[$1{$newTitle}]", $formula);
250
                $namedFormula->setValue($formula); // @phpstan-ignore-line
251
            }
252
        }
253
    }
254
}
255