2
2
3
3
namespace PhpOffice \PhpSpreadsheet \Reader \Xlsx ;
4
4
5
+ use PhpOffice \PhpSpreadsheet \Reader \Xlsx ;
5
6
use PhpOffice \PhpSpreadsheet \Worksheet \AutoFilter \Column ;
6
7
use PhpOffice \PhpSpreadsheet \Worksheet \AutoFilter \Column \Rule ;
7
8
use PhpOffice \PhpSpreadsheet \Worksheet \Table ;
@@ -32,36 +33,40 @@ public function __construct($parent, SimpleXMLElement $worksheetXml)
32
33
public function load (): void
33
34
{
34
35
// Remove all "$" in the auto filter range
35
- $ autoFilterRange = (string ) preg_replace ('/\$/ ' , '' , $ this ->worksheetXml ->autoFilter ['ref ' ] ?? '' );
36
+ $ attrs = $ this ->worksheetXml ->autoFilter ->attributes () ?? [];
37
+ // Mysterious 'Node no longer exists' warning for Php7.4 only.
38
+ $ autoFilterRange = (string ) @preg_replace ('/\$/ ' , '' , $ attrs ['ref ' ] ?? '' );
36
39
if (strpos ($ autoFilterRange , ': ' ) !== false ) {
37
- $ this ->readAutoFilter ($ autoFilterRange, $ this -> worksheetXml );
40
+ $ this ->readAutoFilter ($ autoFilterRange );
38
41
}
39
42
}
40
43
41
- private function readAutoFilter (string $ autoFilterRange, SimpleXMLElement $ xmlSheet ): void
44
+ private function readAutoFilter (string $ autoFilterRange ): void
42
45
{
43
46
$ autoFilter = $ this ->parent ->getAutoFilter ();
44
47
$ autoFilter ->setRange ($ autoFilterRange );
45
48
46
- foreach ($ xmlSheet ->autoFilter ->filterColumn as $ filterColumn ) {
47
- $ column = $ autoFilter ->getColumnByOffset ((int ) $ filterColumn ['colId ' ]);
49
+ foreach ($ this ->worksheetXml ->autoFilter ->filterColumn as $ filterColumn ) {
50
+ $ attributes = $ filterColumn ->/** @scrutinizer ignore-call */ attributes () ?? [];
51
+ $ column = $ autoFilter ->getColumnByOffset ((int ) ($ attributes ['colId ' ] ?? 0 ));
48
52
// Check for standard filters
49
53
if ($ filterColumn ->filters ) {
50
54
$ column ->setFilterType (Column::AUTOFILTER_FILTERTYPE_FILTER );
51
- $ filters = $ filterColumn ->filters ;
55
+ $ filters = Xlsx:: testSimpleXml ( $ filterColumn ->filters -> attributes ()) ;
52
56
if ((isset ($ filters ['blank ' ])) && ((int ) $ filters ['blank ' ] == 1 )) {
53
57
// Operator is undefined, but always treated as EQUAL
54
58
$ column ->createRule ()->setRule ('' , '' )->setRuleType (Rule::AUTOFILTER_RULETYPE_FILTER );
55
59
}
56
60
// Standard filters are always an OR join, so no join rule needs to be set
57
61
// Entries can be either filter elements
58
- foreach ($ filters ->filter as $ filterRule ) {
62
+ foreach ($ filterColumn -> filters ->filter as $ filterRule ) {
59
63
// Operator is undefined, but always treated as EQUAL
60
- $ column ->createRule ()->setRule ('' , (string ) $ filterRule ['val ' ])->setRuleType (Rule::AUTOFILTER_RULETYPE_FILTER );
64
+ $ attr2 = $ filterRule ->/** @scrutinizer ignore-call */ attributes () ?? ['val ' => '' ];
65
+ $ column ->createRule ()->setRule ('' , (string ) $ attr2 ['val ' ])->setRuleType (Rule::AUTOFILTER_RULETYPE_FILTER );
61
66
}
62
67
63
68
// Or Date Group elements
64
- $ this ->readDateRangeAutoFilter ($ filters , $ column );
69
+ $ this ->readDateRangeAutoFilter ($ filterColumn -> filters , $ column );
65
70
}
66
71
67
72
// Check for custom filters
@@ -76,20 +81,23 @@ private function readAutoFilter(string $autoFilterRange, SimpleXMLElement $xmlSh
76
81
77
82
private function readDateRangeAutoFilter (SimpleXMLElement $ filters , Column $ column ): void
78
83
{
79
- foreach ($ filters ->dateGroupItem as $ dateGroupItem ) {
84
+ foreach ($ filters ->dateGroupItem as $ dateGroupItemx ) {
80
85
// Operator is undefined, but always treated as EQUAL
81
- $ column ->createRule ()->setRule (
82
- '' ,
83
- [
84
- 'year ' => (string ) $ dateGroupItem ['year ' ],
85
- 'month ' => (string ) $ dateGroupItem ['month ' ],
86
- 'day ' => (string ) $ dateGroupItem ['day ' ],
87
- 'hour ' => (string ) $ dateGroupItem ['hour ' ],
88
- 'minute ' => (string ) $ dateGroupItem ['minute ' ],
89
- 'second ' => (string ) $ dateGroupItem ['second ' ],
90
- ],
91
- (string ) $ dateGroupItem ['dateTimeGrouping ' ]
92
- )->setRuleType (Rule::AUTOFILTER_RULETYPE_DATEGROUP );
86
+ $ dateGroupItem = $ dateGroupItemx ->/** @scrutinizer ignore-call */ attributes ();
87
+ if ($ dateGroupItem !== null ) {
88
+ $ column ->createRule ()->setRule (
89
+ '' ,
90
+ [
91
+ 'year ' => (string ) $ dateGroupItem ['year ' ],
92
+ 'month ' => (string ) $ dateGroupItem ['month ' ],
93
+ 'day ' => (string ) $ dateGroupItem ['day ' ],
94
+ 'hour ' => (string ) $ dateGroupItem ['hour ' ],
95
+ 'minute ' => (string ) $ dateGroupItem ['minute ' ],
96
+ 'second ' => (string ) $ dateGroupItem ['second ' ],
97
+ ],
98
+ (string ) $ dateGroupItem ['dateTimeGrouping ' ]
99
+ )->setRuleType (Rule::AUTOFILTER_RULETYPE_DATEGROUP );
100
+ }
93
101
}
94
102
}
95
103
@@ -98,15 +106,17 @@ private function readCustomAutoFilter(?SimpleXMLElement $filterColumn, Column $c
98
106
if (isset ($ filterColumn , $ filterColumn ->customFilters )) {
99
107
$ column ->setFilterType (Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER );
100
108
$ customFilters = $ filterColumn ->customFilters ;
109
+ $ attributes = $ customFilters ->attributes ();
101
110
// Custom filters can an AND or an OR join;
102
111
// and there should only ever be one or two entries
103
- if ((isset ($ customFilters ['and ' ])) && ((string ) $ customFilters ['and ' ] === '1 ' )) {
112
+ if ((isset ($ attributes ['and ' ])) && ((string ) $ attributes ['and ' ] === '1 ' )) {
104
113
$ column ->setJoin (Column::AUTOFILTER_COLUMN_JOIN_AND );
105
114
}
106
115
foreach ($ customFilters ->customFilter as $ filterRule ) {
116
+ $ attr2 = $ filterRule ->/** @scrutinizer ignore-call */ attributes () ?? ['operator ' => '' , 'val ' => '' ];
107
117
$ column ->createRule ()->setRule (
108
- (string ) $ filterRule ['operator ' ],
109
- (string ) $ filterRule ['val ' ]
118
+ (string ) $ attr2 ['operator ' ],
119
+ (string ) $ attr2 ['val ' ]
110
120
)->setRuleType (Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER );
111
121
}
112
122
}
@@ -119,16 +129,17 @@ private function readDynamicAutoFilter(?SimpleXMLElement $filterColumn, Column $
119
129
// We should only ever have one dynamic filter
120
130
foreach ($ filterColumn ->dynamicFilter as $ filterRule ) {
121
131
// Operator is undefined, but always treated as EQUAL
132
+ $ attr2 = $ filterRule ->/** @scrutinizer ignore-call */ attributes () ?? [];
122
133
$ column ->createRule ()->setRule (
123
134
'' ,
124
- (string ) $ filterRule ['val ' ],
125
- (string ) $ filterRule ['type ' ]
135
+ (string ) ( $ attr2 ['val ' ] ?? '' ) ,
136
+ (string ) ( $ attr2 ['type ' ] ?? '' )
126
137
)->setRuleType (Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER );
127
- if (isset ($ filterRule ['val ' ])) {
128
- $ column ->setAttribute ('val ' , (string ) $ filterRule ['val ' ]);
138
+ if (isset ($ attr2 ['val ' ])) {
139
+ $ column ->setAttribute ('val ' , (string ) $ attr2 ['val ' ]);
129
140
}
130
- if (isset ($ filterRule ['maxVal ' ])) {
131
- $ column ->setAttribute ('maxVal ' , (string ) $ filterRule ['maxVal ' ]);
141
+ if (isset ($ attr2 ['maxVal ' ])) {
142
+ $ column ->setAttribute ('maxVal ' , (string ) $ attr2 ['maxVal ' ]);
132
143
}
133
144
}
134
145
}
@@ -140,15 +151,16 @@ private function readTopTenAutoFilter(?SimpleXMLElement $filterColumn, Column $c
140
151
$ column ->setFilterType (Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER );
141
152
// We should only ever have one top10 filter
142
153
foreach ($ filterColumn ->top10 as $ filterRule ) {
154
+ $ attr2 = $ filterRule ->/** @scrutinizer ignore-call */ attributes () ?? [];
143
155
$ column ->createRule ()->setRule (
144
156
(
145
- ((isset ($ filterRule ['percent ' ])) && ((string ) $ filterRule ['percent ' ] === '1 ' ))
157
+ ((isset ($ attr2 ['percent ' ])) && ((string ) $ attr2 ['percent ' ] === '1 ' ))
146
158
? Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT
147
159
: Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE
148
160
),
149
- (string ) $ filterRule ['val ' ],
161
+ (string ) ( $ attr2 ['val ' ] ?? '' ) ,
150
162
(
151
- ((isset ($ filterRule ['top ' ])) && ((string ) $ filterRule ['top ' ] === '1 ' ))
163
+ ((isset ($ attr2 ['top ' ])) && ((string ) $ attr2 ['top ' ] === '1 ' ))
152
164
? Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP
153
165
: Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM
154
166
)
0 commit comments