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 / PivotTableReader.php

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

142 lines 4.4 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\Worksheet\PivotTable\PivotCacheDefinition;
6 use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotField;
7 use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotTable;
8 use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
9 use SimpleXMLElement;
10
11 /**
12 * Reads a pivot table definition (and its associated cache definition) from
13 * the Xlsx parts into the read-only PivotTable object model.
14 *
15 * This only extracts metadata (name, location, source and field layout); the
16 * raw pivot XML parts continue to be preserved verbatim for write-back, so
17 * loading a pivot table here never changes what is written out.
18 */
19 class PivotTableReader
20 {
21 private Worksheet $worksheet;
22
23 private SimpleXMLElement $pivotTableXml;
24
25 private ?SimpleXMLElement $cacheDefinitionXml;
26
27 public function __construct(
28 Worksheet $worksheet,
29 SimpleXMLElement $pivotTableXml,
30 ?SimpleXMLElement $cacheDefinitionXml = null
31 ) {
32 $this->worksheet = $worksheet;
33 $this->pivotTableXml = $pivotTableXml;
34 $this->cacheDefinitionXml = $cacheDefinitionXml;
35 }
36
37 /**
38 * Parse the pivot table definition and add it to the worksheet.
39 */
40 public function load(): void
41 {
42 $attributes = $this->pivotTableXml->attributes();
43
44 $pivotTable = new PivotTable((string) ($attributes['name'] ?? ''));
45
46 if (isset($this->pivotTableXml->location)) {
47 $locationAttributes = $this->pivotTableXml->location->attributes();
48 $pivotTable->setLocation((string) ($locationAttributes['ref'] ?? ''));
49 }
50
51 $cacheDefinition = $this->readCacheDefinition(
52 isset($attributes['cacheId']) ? (int) $attributes['cacheId'] : null
53 );
54 $pivotTable->setCacheDefinition($cacheDefinition);
55
56 if (isset($this->pivotTableXml->pivotFields)) {
57 $this->readFields($pivotTable, $cacheDefinition);
58 }
59
60 $this->worksheet->addPivotTable($pivotTable);
61 }
62
63 /**
64 * Build the cache definition (source range + field names) if we have it.
65 */
66 private function readCacheDefinition(?int $cacheId): PivotCacheDefinition
67 {
68 $cacheDefinition = new PivotCacheDefinition($cacheId);
69
70 if ($this->cacheDefinitionXml !== null) {
71 $source = $this->cacheDefinitionXml->cacheSource;
72 if (isset($source->worksheetSource)) {
73 $sourceAttributes = $source->worksheetSource->attributes();
74 if (isset($sourceAttributes['sheet'])) {
75 $cacheDefinition->setSourceWorksheet((string) $sourceAttributes['sheet']);
76 }
77 if (isset($sourceAttributes['ref'])) {
78 $cacheDefinition->setSourceRange((string) $sourceAttributes['ref']);
79 }
80 }
81
82 if (isset($this->cacheDefinitionXml->cacheFields)) {
83 foreach ($this->cacheDefinitionXml->cacheFields->cacheField as $cacheField) {
84 $fieldAttributes = $cacheField->attributes();
85 $cacheDefinition->addCacheField((string) ($fieldAttributes['name'] ?? ''));
86 }
87 }
88 }
89
90 return $cacheDefinition;
91 }
92
93 /**
94 * Read the pivotFields and the axis/data placement sections into fields.
95 */
96 private function readFields(PivotTable $pivotTable, PivotCacheDefinition $cacheDefinition): void
97 {
98 $index = 0;
99 /** @var PivotField[] $fields */
100 $fields = [];
101 foreach ($this->pivotTableXml->pivotFields->pivotField as $pivotFieldXml) {
102 $field = new PivotField($index, (string) ($cacheDefinition->getCacheFieldName($index) ?? ''));
103
104 $fieldAttributes = $pivotFieldXml->attributes();
105 if (isset($fieldAttributes['axis'])) {
106 $field->setAxis((string) $fieldAttributes['axis']);
107 }
108
109 $fields[$index] = $field;
110 $pivotTable->addField($field);
111 ++$index;
112 }
113
114 $this->markDataFields($fields);
115 }
116
117 /**
118 * Flag the fields referenced by <dataFields> as value fields, and record
119 * their aggregation function.
120 *
121 * @param PivotField[] $fields keyed by field index
122 */
123 private function markDataFields(array $fields): void
124 {
125 if (isset($this->pivotTableXml->dataFields)) {
126 foreach ($this->pivotTableXml->dataFields->dataField as $dataFieldXml) {
127 $dataAttributes = $dataFieldXml->attributes();
128 if (isset($dataAttributes['fld'])) {
129 $fieldIndex = (int) $dataAttributes['fld'];
130 if (isset($fields[$fieldIndex])) {
131 $fields[$fieldIndex]->setDataField(true);
132 // "sum" is the default subtotal when the attribute is absent.
133 $fields[$fieldIndex]->setSubtotal(
134 isset($dataAttributes['subtotal']) ? (string) $dataAttributes['subtotal'] : 'sum'
135 );
136 }
137 }
138 }
139 }
140 }
141 }
142