Failed Conditions
Push — master ( 454d94...b2070f )
by Adrien
27:46
created

ColumnAndRowAttributes::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
6
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
7
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
8
9
class ColumnAndRowAttributes extends BaseParserClass
10
{
11
    private $worksheet;
12
13
    private $worksheetXml;
14
15 47
    public function __construct(Worksheet $workSheet, \SimpleXMLElement $worksheetXml = null)
16
    {
17 47
        $this->worksheet = $workSheet;
18 47
        $this->worksheetXml = $worksheetXml;
19 47
    }
20
21
    /**
22
     * Set Worksheet column attributes by attributes array passed.
23
     *
24
     * @param string $columnAddress A, B, ... DX, ...
25
     * @param array $columnAttributes array of attributes (indexes are attribute name, values are value)
26
     *                               'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'width', ... ?
27
     */
28 11
    private function setColumnAttributes($columnAddress, array $columnAttributes)
29
    {
30 11
        if (isset($columnAttributes['xfIndex'])) {
31 4
            $this->worksheet->getColumnDimension($columnAddress)->setXfIndex($columnAttributes['xfIndex']);
32
        }
33 11
        if (isset($columnAttributes['visible'])) {
34 2
            $this->worksheet->getColumnDimension($columnAddress)->setVisible($columnAttributes['visible']);
35
        }
36 11
        if (isset($columnAttributes['collapsed'])) {
37 1
            $this->worksheet->getColumnDimension($columnAddress)->setCollapsed($columnAttributes['collapsed']);
38
        }
39 11
        if (isset($columnAttributes['outlineLevel'])) {
40 1
            $this->worksheet->getColumnDimension($columnAddress)->setOutlineLevel($columnAttributes['outlineLevel']);
41
        }
42 11
        if (isset($columnAttributes['width'])) {
43 11
            $this->worksheet->getColumnDimension($columnAddress)->setWidth($columnAttributes['width']);
44
        }
45 11
    }
46
47
    /**
48
     * Set Worksheet row attributes by attributes array passed.
49
     *
50
     * @param int $rowNumber 1, 2, 3, ... 99, ...
51
     * @param array $rowAttributes array of attributes (indexes are attribute name, values are value)
52
     *                               'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ?
53
     */
54 5
    private function setRowAttributes($rowNumber, array $rowAttributes)
55
    {
56 5
        if (isset($rowAttributes['xfIndex'])) {
57
            $this->worksheet->getRowDimension($rowNumber)->setXfIndex($rowAttributes['xfIndex']);
58
        }
59 5
        if (isset($rowAttributes['visible'])) {
60 2
            $this->worksheet->getRowDimension($rowNumber)->setVisible($rowAttributes['visible']);
61
        }
62 5
        if (isset($rowAttributes['collapsed'])) {
63
            $this->worksheet->getRowDimension($rowNumber)->setCollapsed($rowAttributes['collapsed']);
64
        }
65 5
        if (isset($rowAttributes['outlineLevel'])) {
66
            $this->worksheet->getRowDimension($rowNumber)->setOutlineLevel($rowAttributes['outlineLevel']);
67
        }
68 5
        if (isset($rowAttributes['rowHeight'])) {
69 4
            $this->worksheet->getRowDimension($rowNumber)->setRowHeight($rowAttributes['rowHeight']);
70
        }
71 5
    }
72
73
    /**
74
     * @param IReadFilter $readFilter
75
     * @param bool $readDataOnly
76
     */
77 47
    public function load(IReadFilter $readFilter = null, $readDataOnly = false)
78
    {
79 47
        if ($this->worksheetXml === null) {
80
            return;
81
        }
82
83 47
        $columnsAttributes = [];
84 47
        $rowsAttributes = [];
85 47
        if (isset($this->worksheetXml->cols)) {
86 11
            $columnsAttributes = $this->readColumnAttributes($this->worksheetXml->cols, $readDataOnly);
87
        }
88
89 47
        if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) {
90 40
            $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly);
91
        }
92
93
        // set columns/rows attributes
94 47
        $columnsAttributesAreSet = [];
95 47
        foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
96 11
            if ($readFilter === null ||
97 11
                !$this->isFilteredColumn($readFilter, $columnCoordinate, $rowsAttributes)) {
98 11
                if (!isset($columnsAttributesAreSet[$columnCoordinate])) {
99 11
                    $this->setColumnAttributes($columnCoordinate, $columnAttributes);
100 11
                    $columnsAttributesAreSet[$columnCoordinate] = true;
101
                }
102
            }
103
        }
104
105 47
        $rowsAttributesAreSet = [];
106 47
        foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
107 6
            if ($readFilter === null ||
108 6
                !$this->isFilteredRow($readFilter, $rowCoordinate, $columnsAttributes)) {
109 5
                if (!isset($rowsAttributesAreSet[$rowCoordinate])) {
110 5
                    $this->setRowAttributes($rowCoordinate, $rowAttributes);
111 5
                    $rowsAttributesAreSet[$rowCoordinate] = true;
112
                }
113
            }
114
        }
115 47
    }
116
117 11
    private function isFilteredColumn(IReadFilter $readFilter, $columnCoordinate, array $rowsAttributes)
118
    {
119 11
        foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
120 4
            if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
121 1
                return true;
122
            }
123
        }
124
125 11
        return false;
126
    }
127
128 11
    private function readColumnAttributes(\SimpleXMLElement $worksheetCols, $readDataOnly)
129
    {
130 11
        $columnAttributes = [];
131
132 11
        foreach ($worksheetCols->col as $column) {
133 11
            $startColumn = Coordinate::stringFromColumnIndex((int) $column['min']);
134 11
            $endColumn = Coordinate::stringFromColumnIndex((int) $column['max']);
135 11
            ++$endColumn;
136 11
            for ($columnAddress = $startColumn; $columnAddress !== $endColumn; ++$columnAddress) {
137 11
                $columnAttributes[$columnAddress] = $this->readColumnRangeAttributes($column, $readDataOnly);
138
139 11
                if ((int) ($column['max']) == 16384) {
140
                    break;
141
                }
142
            }
143
        }
144
145 11
        return $columnAttributes;
146
    }
147
148 11
    private function readColumnRangeAttributes(\SimpleXMLElement $column, $readDataOnly)
149
    {
150 11
        $columnAttributes = [];
151
152 11
        if ($column['style'] && !$readDataOnly) {
153 4
            $columnAttributes['xfIndex'] = (int) $column['style'];
154
        }
155 11
        if (self::boolean($column['hidden'])) {
156 2
            $columnAttributes['visible'] = false;
157
        }
158 11
        if (self::boolean($column['collapsed'])) {
159 1
            $columnAttributes['collapsed'] = true;
160
        }
161 11
        if (((int) $column['outlineLevel']) > 0) {
162 1
            $columnAttributes['outlineLevel'] = (int) $column['outlineLevel'];
163
        }
164 11
        $columnAttributes['width'] = (float) $column['width'];
165
166 11
        return $columnAttributes;
167
    }
168
169 6
    private function isFilteredRow(IReadFilter $readFilter, $rowCoordinate, array $columnsAttributes)
170
    {
171 6
        foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
172 4
            if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
173 1
                return true;
174
            }
175
        }
176
177 5
        return false;
178
    }
179
180 40
    private function readRowAttributes(\SimpleXMLElement $worksheetRow, $readDataOnly)
181
    {
182 40
        $rowAttributes = [];
183
184 40
        foreach ($worksheetRow as $row) {
185 40
            if ($row['ht'] && !$readDataOnly) {
186 5
                $rowAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht'];
187
            }
188 40
            if (self::boolean($row['hidden'])) {
189 2
                $rowAttributes[(int) $row['r']]['visible'] = false;
190
            }
191 40
            if (self::boolean($row['collapsed'])) {
192
                $rowAttributes[(int) $row['r']]['collapsed'] = true;
193
            }
194 40
            if ((int) $row['outlineLevel'] > 0) {
195
                $rowAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel'];
196
            }
197 40
            if ($row['s'] && !$readDataOnly) {
198
                $rowAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s'];
199
            }
200
        }
201
202 40
        return $rowAttributes;
203
    }
204
}
205