Failed Conditions
Push — master ( e55052...5b4b12 )
by Adrien
09:31
created

ColumnAndRowAttributes::load()   C

Complexity

Conditions 15
Paths 129

Size

Total Lines 43
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 15.0144

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 15
eloc 26
c 1
b 0
f 0
nc 129
nop 2
dl 0
loc 43
ccs 24
cts 25
cp 0.96
crap 15.0144
rs 5.675

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
6
use PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter;
7
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
8
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
9
use SimpleXMLElement;
10
11
class ColumnAndRowAttributes extends BaseParserClass
12
{
13
    private $worksheet;
14
15
    private $worksheetXml;
16
17 175
    public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null)
18
    {
19 175
        $this->worksheet = $workSheet;
20 175
        $this->worksheetXml = $worksheetXml;
21 175
    }
22
23
    /**
24
     * Set Worksheet column attributes by attributes array passed.
25
     *
26
     * @param string $columnAddress A, B, ... DX, ...
27
     * @param array $columnAttributes array of attributes (indexes are attribute name, values are value)
28
     *                               'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'width', ... ?
29
     */
30 35
    private function setColumnAttributes($columnAddress, array $columnAttributes): void
31
    {
32 35
        if (isset($columnAttributes['xfIndex'])) {
33 16
            $this->worksheet->getColumnDimension($columnAddress)->setXfIndex($columnAttributes['xfIndex']);
34
        }
35 35
        if (isset($columnAttributes['visible'])) {
36 3
            $this->worksheet->getColumnDimension($columnAddress)->setVisible($columnAttributes['visible']);
37
        }
38 35
        if (isset($columnAttributes['collapsed'])) {
39 1
            $this->worksheet->getColumnDimension($columnAddress)->setCollapsed($columnAttributes['collapsed']);
40
        }
41 35
        if (isset($columnAttributes['outlineLevel'])) {
42 1
            $this->worksheet->getColumnDimension($columnAddress)->setOutlineLevel($columnAttributes['outlineLevel']);
43
        }
44 35
        if (isset($columnAttributes['width'])) {
45 35
            $this->worksheet->getColumnDimension($columnAddress)->setWidth($columnAttributes['width']);
46
        }
47 35
    }
48
49
    /**
50
     * Set Worksheet row attributes by attributes array passed.
51
     *
52
     * @param int $rowNumber 1, 2, 3, ... 99, ...
53
     * @param array $rowAttributes array of attributes (indexes are attribute name, values are value)
54
     *                               'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ?
55
     */
56 26
    private function setRowAttributes($rowNumber, array $rowAttributes): void
57
    {
58 26
        if (isset($rowAttributes['xfIndex'])) {
59 3
            $this->worksheet->getRowDimension($rowNumber)->setXfIndex($rowAttributes['xfIndex']);
60
        }
61 26
        if (isset($rowAttributes['visible'])) {
62 5
            $this->worksheet->getRowDimension($rowNumber)->setVisible($rowAttributes['visible']);
63
        }
64 26
        if (isset($rowAttributes['collapsed'])) {
65
            $this->worksheet->getRowDimension($rowNumber)->setCollapsed($rowAttributes['collapsed']);
66
        }
67 26
        if (isset($rowAttributes['outlineLevel'])) {
68
            $this->worksheet->getRowDimension($rowNumber)->setOutlineLevel($rowAttributes['outlineLevel']);
69
        }
70 26
        if (isset($rowAttributes['rowHeight'])) {
71 21
            $this->worksheet->getRowDimension($rowNumber)->setRowHeight($rowAttributes['rowHeight']);
72
        }
73 26
    }
74
75
    /**
76
     * @param IReadFilter $readFilter
77
     * @param bool $readDataOnly
78
     */
79 175
    public function load(?IReadFilter $readFilter = null, $readDataOnly = false): void
80
    {
81 175
        if ($this->worksheetXml === null) {
82
            return;
83
        }
84
85 175
        $columnsAttributes = [];
86 175
        $rowsAttributes = [];
87 175
        if (isset($this->worksheetXml->cols)) {
88 35
            $columnsAttributes = $this->readColumnAttributes($this->worksheetXml->cols, $readDataOnly);
89
        }
90
91 175
        if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) {
92 160
            $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly);
93
        }
94
95 175
        if ($readFilter !== null && get_class($readFilter) === DefaultReadFilter::class) {
96 172
            $readFilter = null;
97
        }
98
99
        // set columns/rows attributes
100 175
        $columnsAttributesAreSet = [];
101 175
        foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
102
            if (
103 35
                $readFilter === null ||
104 35
                !$this->isFilteredColumn($readFilter, $columnCoordinate, $rowsAttributes)
105
            ) {
106 35
                if (!isset($columnsAttributesAreSet[$columnCoordinate])) {
107 35
                    $this->setColumnAttributes($columnCoordinate, $columnAttributes);
108 35
                    $columnsAttributesAreSet[$columnCoordinate] = true;
109
                }
110
            }
111
        }
112
113 175
        $rowsAttributesAreSet = [];
114 175
        foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
115
            if (
116 27
                $readFilter === null ||
117 27
                !$this->isFilteredRow($readFilter, $rowCoordinate, $columnsAttributes)
118
            ) {
119 26
                if (!isset($rowsAttributesAreSet[$rowCoordinate])) {
120 26
                    $this->setRowAttributes($rowCoordinate, $rowAttributes);
121 26
                    $rowsAttributesAreSet[$rowCoordinate] = true;
122
                }
123
            }
124
        }
125 175
    }
126
127 2
    private function isFilteredColumn(IReadFilter $readFilter, $columnCoordinate, array $rowsAttributes)
128
    {
129 2
        foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
130 1
            if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
131 1
                return true;
132
            }
133
        }
134
135 2
        return false;
136
    }
137
138 35
    private function readColumnAttributes(SimpleXMLElement $worksheetCols, $readDataOnly)
139
    {
140 35
        $columnAttributes = [];
141
142 35
        foreach ($worksheetCols->col as $column) {
143 35
            $startColumn = Coordinate::stringFromColumnIndex((int) $column['min']);
144 35
            $endColumn = Coordinate::stringFromColumnIndex((int) $column['max']);
145 35
            ++$endColumn;
146 35
            for ($columnAddress = $startColumn; $columnAddress !== $endColumn; ++$columnAddress) {
147 35
                $columnAttributes[$columnAddress] = $this->readColumnRangeAttributes($column, $readDataOnly);
1 ignored issue
show
Bug introduced by
It seems like $column can also be of type null; however, parameter $column of PhpOffice\PhpSpreadsheet...ColumnRangeAttributes() does only seem to accept SimpleXMLElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

147
                $columnAttributes[$columnAddress] = $this->readColumnRangeAttributes(/** @scrutinizer ignore-type */ $column, $readDataOnly);
Loading history...
148
149 35
                if ((int) ($column['max']) == 16384) {
150 1
                    break;
151
                }
152
            }
153
        }
154
155 35
        return $columnAttributes;
156
    }
157
158 35
    private function readColumnRangeAttributes(SimpleXMLElement $column, $readDataOnly)
159
    {
160 35
        $columnAttributes = [];
161
162 35
        if ($column['style'] && !$readDataOnly) {
163 16
            $columnAttributes['xfIndex'] = (int) $column['style'];
164
        }
165 35
        if (self::boolean($column['hidden'])) {
166 3
            $columnAttributes['visible'] = false;
167
        }
168 35
        if (self::boolean($column['collapsed'])) {
169 1
            $columnAttributes['collapsed'] = true;
170
        }
171 35
        if (((int) $column['outlineLevel']) > 0) {
172 1
            $columnAttributes['outlineLevel'] = (int) $column['outlineLevel'];
173
        }
174 35
        $columnAttributes['width'] = (float) $column['width'];
175
176 35
        return $columnAttributes;
177
    }
178
179 1
    private function isFilteredRow(IReadFilter $readFilter, $rowCoordinate, array $columnsAttributes)
180
    {
181 1
        foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
182 1
            if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
183 1
                return true;
184
            }
185
        }
186
187
        return false;
188
    }
189
190 160
    private function readRowAttributes(SimpleXMLElement $worksheetRow, $readDataOnly)
191
    {
192 160
        $rowAttributes = [];
193
194 160
        foreach ($worksheetRow as $row) {
195 160
            if ($row['ht'] && !$readDataOnly) {
196 22
                $rowAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht'];
197
            }
198 160
            if (self::boolean($row['hidden'])) {
199 5
                $rowAttributes[(int) $row['r']]['visible'] = false;
200
            }
201 160
            if (self::boolean($row['collapsed'])) {
202
                $rowAttributes[(int) $row['r']]['collapsed'] = true;
203
            }
204 160
            if ((int) $row['outlineLevel'] > 0) {
205
                $rowAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel'];
206
            }
207 160
            if ($row['s'] && !$readDataOnly) {
208 3
                $rowAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s'];
209
            }
210
        }
211
212 160
        return $rowAttributes;
213
    }
214
}
215