@@ -62,8 +62,20 @@ public function __construct( $filename = null ) {
62
62
private function _fetchSeries ( &$ handle ) {
63
63
// read column titles
64
64
$ labels = fgetcsv ( $ handle , 0 , VISUALIZER_CSV_DELIMITER , VISUALIZER_CSV_ENCLOSURE );
65
- // read series types
66
- $ types = fgetcsv ( $ handle , 0 , VISUALIZER_CSV_DELIMITER , VISUALIZER_CSV_ENCLOSURE );
65
+ $ types = null ;
66
+
67
+ if ( false !== strpos ( $ this ->_filename , 'tqx=out:csv ' ) ) {
68
+ $ attributes = $ this ->_fetchSeriesForGoogleQueryLanguage ( $ labels );
69
+ if ( ! $ attributes ['abort ' ] ) {
70
+ $ labels = $ attributes ['labels ' ];
71
+ $ types = $ attributes ['types ' ];
72
+ }
73
+ }
74
+
75
+ if ( is_null ( $ types ) ) {
76
+ // read series types
77
+ $ types = fgetcsv ( $ handle , 0 , VISUALIZER_CSV_DELIMITER , VISUALIZER_CSV_ENCLOSURE );
78
+ }
67
79
68
80
if ( ! $ labels || ! $ types ) {
69
81
return false ;
@@ -158,4 +170,45 @@ public function getSourceName() {
158
170
return __CLASS__ ;
159
171
}
160
172
173
+ /**
174
+ * Adds support for QueryLanguage https://developers.google.com/chart/interactive/docs/querylanguage
175
+ * where the user can provide something like /gviz/tq?tq=select%20A%2C%20B%20&tqx=out:csv after the URL of the raw spreadsheet
176
+ * to get the subset of data specified by the query
177
+ * this will conflate the heading and the type into one value viz. for heading XXX and type string, the value will become "XXX string"
178
+ * so we need to split them apart logically
179
+ * also the $types variable now contains the first row because the header and the type got conflated
180
+ */
181
+ private function _fetchSeriesForGoogleQueryLanguage ( $ labels , $ types = array () ) {
182
+ $ new_labels = array ();
183
+ $ new_types = array ();
184
+ $ abort = false ;
185
+ foreach ( $ labels as $ label ) {
186
+ // get the index of the last space
187
+ $ index = strrpos ( $ label , ' ' );
188
+ if ( $ index === false ) {
189
+ // no space here? something has gone wrong; abort the entire process.
190
+ $ abort = true ;
191
+ break ;
192
+ }
193
+ $ type = trim ( substr ( $ label , $ index + 1 ) );
194
+ if ( ! self ::_validateTypes ( array ( $ type ) ) ) {
195
+ // some other data type? abort the entire process.
196
+ $ abort = true ;
197
+ break ;
198
+ }
199
+ $ label = substr ( $ label , 0 , $ index );
200
+ $ new_labels [] = $ label ;
201
+ $ new_types [] = $ type ;
202
+ }
203
+ if ( ! $ abort ) {
204
+ $ labels = $ new_labels ;
205
+ $ types = $ new_types ;
206
+ }
207
+
208
+ return array (
209
+ 'abort ' => $ abort ,
210
+ 'labels ' => $ labels ,
211
+ 'types ' => $ types ,
212
+ );
213
+ }
161
214
}
0 commit comments