PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Reader / Xlsx / ColumnAndRowAttributes.php

ColumnAndRowAttributes.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php

253 lines 9.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Cell\AddressRange;
6 use TablePress\PhpOffice\PhpSpreadsheet\Cell\Coordinate;
7 use TablePress\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter;
8 use TablePress\PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
9 use TablePress\PhpOffice\PhpSpreadsheet\Shared\StringHelper;
10 use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
11 use SimpleXMLElement;
12
13 class ColumnAndRowAttributes extends BaseParserClass
14 {
15 private Worksheet $worksheet;
16
17 private ?SimpleXMLElement $worksheetXml;
18
19 public function __construct(Worksheet $workSheet, ?SimpleXMLElement $worksheetXml = null)
20 {
21 $this->worksheet = $workSheet;
22 $this->worksheetXml = $worksheetXml;
23 }
24
25 /**
26 * Set Worksheet column attributes by attributes array passed.
27 *
28 * @param string $columnAddress A, B, ... DX, ...
29 * @param array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float, width?: int} $columnAttributes array of attributes (indexes are attribute name, values are value)
30 */
31 private function setColumnAttributes(string $columnAddress, array $columnAttributes): void
32 {
33 if (isset($columnAttributes['xfIndex'])) {
34 $this->worksheet->getColumnDimension($columnAddress)->setXfIndex($columnAttributes['xfIndex']);
35 }
36 if (isset($columnAttributes['visible'])) {
37 $this->worksheet->getColumnDimension($columnAddress)->setVisible($columnAttributes['visible']);
38 }
39 if (isset($columnAttributes['collapsed'])) {
40 $this->worksheet->getColumnDimension($columnAddress)->setCollapsed($columnAttributes['collapsed']);
41 }
42 if (isset($columnAttributes['outlineLevel'])) {
43 $this->worksheet->getColumnDimension($columnAddress)->setOutlineLevel($columnAttributes['outlineLevel']);
44 }
45 if (isset($columnAttributes['width'])) {
46 $this->worksheet->getColumnDimension($columnAddress)->setWidth($columnAttributes['width']);
47 }
48 }
49
50 /**
51 * Set Worksheet row attributes by attributes array passed.
52 *
53 * @param int $rowNumber 1, 2, 3, ... 99, ...
54 * @param array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float, customFormat?: bool, ht?: float} $rowAttributes array of attributes (indexes are attribute name, values are value)
55 * 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ?
56 */
57 private function setRowAttributes(int $rowNumber, array $rowAttributes): void
58 {
59 if (isset($rowAttributes['xfIndex'])) {
60 $this->worksheet->getRowDimension($rowNumber)
61 ->setXfIndex($rowAttributes['xfIndex']);
62 }
63 if (isset($rowAttributes['visible'])) {
64 $this->worksheet->getRowDimension($rowNumber)
65 ->setVisible($rowAttributes['visible']);
66 }
67 if (isset($rowAttributes['collapsed'])) {
68 $this->worksheet->getRowDimension($rowNumber)
69 ->setCollapsed($rowAttributes['collapsed']);
70 }
71 if (isset($rowAttributes['outlineLevel'])) {
72 $this->worksheet->getRowDimension($rowNumber)
73 ->setOutlineLevel($rowAttributes['outlineLevel']);
74 }
75 if (isset($rowAttributes['customFormat'], $rowAttributes['rowHeight'])) {
76 $this->worksheet->getRowDimension($rowNumber)
77 ->setCustomFormat($rowAttributes['customFormat'], $rowAttributes['rowHeight']);
78 } elseif (isset($rowAttributes['rowHeight'])) {
79 $this->worksheet->getRowDimension($rowNumber)
80 ->setRowHeight($rowAttributes['rowHeight']);
81 }
82 }
83
84 public function load(?IReadFilter $readFilter = null, bool $readDataOnly = false, bool $ignoreRowsWithNoCells = false): bool
85 {
86 if ($this->worksheetXml === null) {
87 return false;
88 }
89 if ($readFilter !== null && get_class($readFilter) === DefaultReadFilter::class) {
90 $readFilter = null;
91 }
92
93 $columnsAttributes = [];
94 $rowsAttributes = [];
95 if (isset($this->worksheetXml->cols)) {
96 $columnsAttributes = $this->readColumnAttributes($this->worksheetXml->cols, $readDataOnly);
97 }
98
99 if ($this->worksheetXml->sheetData && $this->worksheetXml->sheetData->row) {
100 $rowsAttributes = $this->readRowAttributes($this->worksheetXml->sheetData->row, $readDataOnly, $ignoreRowsWithNoCells, $readFilter !== null);
101 }
102
103 // set columns/rows attributes
104 $columnsAttributesAreSet = [];
105 foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
106 if (
107 $readFilter === null
108 || !$this->isFilteredColumn($readFilter, $columnCoordinate, $rowsAttributes)
109 ) {
110 if (!isset($columnsAttributesAreSet[$columnCoordinate])) {
111 /** @var array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float, width?: int} $columnAttributes */
112 $this->setColumnAttributes($columnCoordinate, $columnAttributes);
113 $columnsAttributesAreSet[$columnCoordinate] = true;
114 }
115 }
116 }
117
118 $rowsAttributesAreSet = [];
119 foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
120 if (
121 $readFilter === null
122 || !$this->isFilteredRow($readFilter, $rowCoordinate, $columnsAttributes)
123 ) {
124 if (!isset($rowsAttributesAreSet[$rowCoordinate])) {
125 /** @var array{xfIndex?: int, visible?: bool, collapsed?: bool, collapsed?: bool, outlineLevel?: int, rowHeight?: float} $rowAttributes */
126 $this->setRowAttributes($rowCoordinate, $rowAttributes);
127 $rowsAttributesAreSet[$rowCoordinate] = true;
128 }
129 }
130 }
131
132 return true;
133 }
134
135 /** @param mixed[] $rowsAttributes */
136 private function isFilteredColumn(IReadFilter $readFilter, string $columnCoordinate, array $rowsAttributes): bool
137 {
138 foreach ($rowsAttributes as $rowCoordinate => $rowAttributes) {
139 if ($readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
140 return false;
141 }
142 }
143
144 return true;
145 }
146
147 /** @return mixed[] */
148 private function readColumnAttributes(SimpleXMLElement $worksheetCols, bool $readDataOnly): array
149 {
150 $columnAttributes = [];
151
152 foreach ($worksheetCols->col as $columnx) {
153 $column = $columnx->attributes();
154 if ($column !== null) {
155 $startColumn = Coordinate::stringFromColumnIndex((int) $column['min']);
156 $endColumn = Coordinate::stringFromColumnIndex((int) $column['max']);
157 StringHelper::stringIncrement($endColumn);
158 for ($columnAddress = $startColumn; $columnAddress !== $endColumn; StringHelper::stringIncrement($columnAddress)) {
159 $columnAttributes[$columnAddress] = $this->readColumnRangeAttributes($column, $readDataOnly);
160
161 if ((int) ($column['max']) === AddressRange::MAX_COLUMN_INT) {
162 break;
163 }
164 }
165 }
166 }
167
168 return $columnAttributes;
169 }
170
171 /** @return mixed[] */
172 private function readColumnRangeAttributes(?SimpleXMLElement $column, bool $readDataOnly): array
173 {
174 $columnAttributes = [];
175 if ($column !== null) {
176 if (isset($column['style']) && !$readDataOnly) {
177 $columnAttributes['xfIndex'] = (int) $column['style'];
178 }
179 if (isset($column['hidden']) && self::boolean($column['hidden'])) {
180 $columnAttributes['visible'] = false;
181 }
182 if (isset($column['collapsed']) && self::boolean($column['collapsed'])) {
183 $columnAttributes['collapsed'] = true;
184 }
185 if (isset($column['outlineLevel']) && ((int) $column['outlineLevel']) > 0) {
186 $columnAttributes['outlineLevel'] = (int) $column['outlineLevel'];
187 }
188 if (isset($column['width'])) {
189 $columnAttributes['width'] = (float) $column['width'];
190 }
191 }
192
193 return $columnAttributes;
194 }
195
196 /** @param mixed[] $columnsAttributes */
197 private function isFilteredRow(IReadFilter $readFilter, int $rowCoordinate, array $columnsAttributes): bool
198 {
199 foreach ($columnsAttributes as $columnCoordinate => $columnAttributes) {
200 if (!$readFilter->readCell($columnCoordinate, $rowCoordinate, $this->worksheet->getTitle())) {
201 return true;
202 }
203 }
204
205 return false;
206 }
207
208 /** @return mixed[] */
209 private function readRowAttributes(SimpleXMLElement $worksheetRow, bool $readDataOnly, bool $ignoreRowsWithNoCells, bool $readFilterIsNotNull): array
210 {
211 $rowAttributes = [];
212
213 $rowIndex = 0;
214 foreach ($worksheetRow as $rowx) {
215 $row = $rowx->attributes();
216 ++$rowIndex;
217 if ($row !== null && (!$ignoreRowsWithNoCells || isset($rowx->c))) {
218 if (isset($row['r'])) {
219 $rowIndex = (int) $row['r'];
220 }
221 if ($rowIndex < 1 || $rowIndex > AddressRange::MAX_ROW) {
222 continue;
223 }
224 if (!$readDataOnly) {
225 if (isset($row['ht'])) {
226 $rowAttributes[$rowIndex]['rowHeight'] = (float) $row['ht'];
227 }
228 if (isset($row['customFormat']) && self::boolean($row['customFormat'])) {
229 $rowAttributes[$rowIndex]['customFormat'] = true;
230 }
231 if (isset($row['hidden']) && self::boolean($row['hidden'])) {
232 $rowAttributes[$rowIndex]['visible'] = false;
233 }
234 if (isset($row['collapsed']) && self::boolean($row['collapsed'])) {
235 $rowAttributes[$rowIndex]['collapsed'] = true;
236 }
237 if (isset($row['outlineLevel']) && (int) $row['outlineLevel'] > 0) {
238 $rowAttributes[$rowIndex]['outlineLevel'] = (int) $row['outlineLevel'];
239 }
240 if (isset($row['s'])) {
241 $rowAttributes[$rowIndex]['xfIndex'] = (int) $row['s'];
242 }
243 }
244 if ($readFilterIsNotNull && empty($rowAttributes[$rowIndex])) {
245 $rowAttributes[$rowIndex]['exists'] = true;
246 }
247 }
248 }
249
250 return $rowAttributes;
251 }
252 }
253