PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.3.4
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.3.4
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / classes / Visualizer / Source.php

Source.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.3.4, at classes/Visualizer/Source.php

391 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // +----------------------------------------------------------------------+
3 // | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
4 // +----------------------------------------------------------------------+
5 // | This program is free software; you can redistribute it and/or modify |
6 // | it under the terms of the GNU General Public License, version 2, as |
7 // | published by the Free Software Foundation. |
8 // | |
9 // | This program is distributed in the hope that it will be useful, |
10 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 // | GNU General Public License for more details. |
13 // | |
14 // | You should have received a copy of the GNU General Public License |
15 // | along with this program; if not, write to the Free Software |
16 // | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
17 // | MA 02110-1301 USA |
18 // +----------------------------------------------------------------------+
19 // | Author: Eugene Manuilov <eugene@manuilov.org> |
20 // +----------------------------------------------------------------------+
21 /**
22 * The abstract class for source managers.
23 *
24 * @category Visualizer
25 * @package Source
26 *
27 * @since 1.0.0
28 * @abstract
29 */
30 abstract class Visualizer_Source {
31
32 /**
33 * The array of allowed types.
34 *
35 * @since 1.0.0
36 *
37 * @access protected
38 * @var array
39 */
40 protected static $allowed_types = array( 'string', 'number', 'boolean', 'date', 'datetime', 'timeofday' );
41 /**
42 * The array of data.
43 *
44 * @since 1.0.0
45 *
46 * @access protected
47 * @var array
48 */
49 protected $_data = array();
50 /**
51 * The array of series.
52 *
53 * @since 1.0.0
54 *
55 * @access protected
56 * @var array
57 */
58 protected $_series = array();
59
60 /**
61 * The error message.
62 *
63 * @access protected
64 * @var string
65 */
66 protected $_error;
67
68 /**
69 * Return allowed types
70 *
71 * @since 1.0.1
72 *
73 * @static
74 * @access public
75 * @return array the allowed types
76 */
77 public static function getAllowedTypes() {
78 return self::$allowed_types;
79 }
80
81 /**
82 * Validates series tyeps.
83 *
84 * @since 1.0.1
85 *
86 * @static
87 * @access protected
88 *
89 * @param array $types The icoming series types.
90 *
91 * @return boolean TRUE if sereis types are valid, otherwise FALSE.
92 */
93 protected static function _validateTypes( $types ) {
94 foreach ( $types as $type ) {
95 if ( ! in_array( $type, self::$allowed_types, true ) ) {
96 return false;
97 }
98 }
99
100 return true;
101 }
102
103 /**
104 * Returns source name.
105 *
106 * @since 1.0.0
107 *
108 * @abstract
109 * @access public
110 * @return string The name of source.
111 */
112 public abstract function getSourceName();
113
114 /**
115 * Fetches information from source, parses it and builds series and data arrays.
116 *
117 * @since 1.0.0
118 *
119 * @abstract
120 * @access public
121 */
122 public abstract function fetch();
123
124 /**
125 * Returns series parsed from source.
126 *
127 * @since 1.0.0
128 *
129 * @access public
130 * @return array The array of series.
131 */
132 public function getSeries() {
133 return $this->_series;
134 }
135
136 /**
137 * Returns data parsed from source.
138 *
139 * @since 1.0.0
140 *
141 * @access public
142 * @return string The serialized array of data.
143 */
144 public function getData() {
145 return serialize( $this->_data );
146 }
147
148 /**
149 * Returns raw data array.
150 *
151 * @since 1.1.0
152 *
153 * @access public
154 * @return array
155 */
156 public function getRawData() {
157 return $this->_data;
158 }
159
160 /**
161 * Re populates series if the source is dynamic.
162 *
163 * @since 1.1.0
164 *
165 * @access public
166 *
167 * @param array $series The actual array of series.
168 * @param int $chart_id The chart id.
169 *
170 * @return array The re populated array of series or old one.
171 */
172 public function repopulateSeries( $series, $chart_id ) {
173 return $series;
174 }
175
176 /**
177 * Re populates data if the source is dynamic.
178 *
179 * @since 1.1.0
180 *
181 * @access public
182 *
183 * @param array $data The actual array of data.
184 * @param int $chart_id The chart id.
185 *
186 * @return array The re populated array of data or old one.
187 */
188 public function repopulateData( $data, $chart_id ) {
189 return $data;
190 }
191
192 /**
193 * Normalizes values according to series' type.
194 *
195 * @since 1.0.0
196 *
197 * @access protected
198 *
199 * @param array $data The row of data.
200 *
201 * @return array Normalized row of data.
202 */
203 protected function _normalizeData( $data ) {
204 // normalize values
205 foreach ( $this->_series as $i => $series ) {
206 // if no value exists for the seires, then add null
207 if ( ! isset( $data[ $i ] ) ) {
208 $data[ $i ] = null;
209 }
210 if ( is_null( $data[ $i ] ) ) {
211 continue;
212 }
213 switch ( $series['type'] ) {
214 case 'number':
215 $data[ $i ] = ( is_numeric( $data[ $i ] ) ) ? floatval( $data[ $i ] ) : ( is_numeric( str_replace( ',', '', $data[ $i ] ) ) ? floatval( str_replace( ',', '', $data[ $i ] ) ) : null );
216 break;
217 case 'boolean':
218 $data[ $i ] = ! empty( $data[ $i ] ) ? filter_var( $data[ $i ], FILTER_VALIDATE_BOOLEAN ) : null;
219 break;
220 case 'timeofday':
221 $date = new DateTime( '1984-03-16T' . $data[ $i ] );
222 if ( $date ) {
223 $data[ $i ] = array(
224 intval( $date->format( 'H' ) ),
225 intval( $date->format( 'i' ) ),
226 intval( $date->format( 's' ) ),
227 0,
228 );
229 }
230 break;
231 case 'datetime':
232 // let's check if the date is a Unix epoch
233 $value = DateTime::createFromFormat( 'U', $data[ $i ] );
234 if ( $value !== false && ! is_wp_error( $value ) ) {
235 $data[ $i ] = $value->format( 'Y-m-d H:i:s' );
236 }
237 break;
238 case 'string':
239 $data[ $i ] = $this->toUTF8( $data[ $i ] );
240 break;
241 }
242 }
243
244 return apply_filters( 'visualizer_format_data', $data, $this->_series );
245 }
246
247
248 /**
249 * Converts values to UTF8, if required.
250 *
251 * @access protected
252 *
253 * @param string $datum The data to convert.
254 *
255 * @return string The converted data.
256 */
257 protected final function toUTF8( $datum ) {
258 if ( ! function_exists( 'mb_detect_encoding' ) || mb_detect_encoding( $datum ) !== 'ASCII' ) {
259 $datum = \ForceUTF8\Encoding::toUTF8( $datum );
260 }
261 return $datum;
262 }
263
264 /**
265 * Determines the formats of date/time columns.
266 *
267 * @access public
268 *
269 * @param array $series The actual array of series.
270 * @param array $data The actual array of data.
271 *
272 * @return array
273 */
274 public static final function get_date_formats_if_exists( $series, $data ) {
275 $date_formats = array();
276 $types = array();
277 $index = 0;
278 foreach ( $series as $column ) {
279 if ( in_array( $column['type'], array( 'date', 'datetime', 'timeofday' ), true ) ) {
280 $types[] = array( 'index' => $index, 'type' => $column['type'] );
281 }
282 $index++;
283 }
284
285 if ( ! $types ) {
286 return $date_formats;
287 }
288
289 $random = $data;
290 // let's randomly pick 5 data points instead of cycling through the entire data set.
291 if ( count( $data ) > 5 ) {
292 $random = array();
293 for ( $x = 0; $x < 5; $x++ ) {
294 $random[] = $data[ rand( 0, count( $data ) - 1 ) ];
295 }
296 }
297
298 foreach ( $types as $type ) {
299 $formats = array();
300 foreach ( $random as $datum ) {
301 $f = self::determine_date_format( $datum[ $type['index'] ], $type['type'] );
302 if ( $f ) {
303 $formats[] = $f;
304 }
305 }
306 // if there are multiple formats, use the most frequent format.
307 $formats = array_filter( $formats );
308 if ( $formats ) {
309 $formats = array_count_values( $formats );
310 arsort( $formats );
311 $formats = array_keys( $formats );
312 $final_format = reset( $formats );
313 // we have determined the PHP format; now we have to change this into the JS format where m = MM, d = DD etc.
314 $date_formats[] = array( 'index' => $type['index'], 'format' => str_replace( array( 'Y', 'm', 'd', 'H', 'i', 's' ), array( 'YYYY', 'MM', 'DD', 'HH', 'mm', 'ss' ), $final_format ) );
315 }
316 }
317 return $date_formats;
318 }
319
320 /**
321 * Determines the date/time format of the given string.
322 *
323 * @access private
324 *
325 * @param string $value The string.
326 * @param string $type 'date', 'timeofday' or 'datetime'.
327 *
328 * @return string|null
329 */
330 private static final function determine_date_format( $value, $type ) {
331 if ( version_compare( phpversion(), '5.3.0', '<' ) ) {
332 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'PHP version %s not supported', phpversion() ), 'error', __FILE__, __LINE__ );
333 return null;
334 }
335
336 $formats = array(
337 'Y/m/d',
338 'Y-m-d',
339 'm/d/Y',
340 'm-d-Y',
341 'd-m-Y',
342 'd/m/Y',
343 );
344
345 switch ( $type ) {
346 case 'datetime':
347 $formats = array_merge(
348 $formats, array(
349 'U',
350 'Y/m/d H:i:s',
351 'Y-m-d H:i:s',
352 'm/d/Y H:i:s',
353 'm-d-Y H:i:s',
354 )
355 );
356 break;
357 case 'timeofday':
358 $formats = array_merge(
359 $formats, array(
360 'H:i:s',
361 'H:i',
362 )
363 );
364 break;
365 }
366
367 $formats = apply_filters( 'visualizer_date_formats', $formats, $type );
368
369 foreach ( $formats as $format ) {
370 $return = DateTime::createFromFormat( $format, $value );
371 if ( $return !== false && ! is_wp_error( $return ) ) {
372 return $format;
373 }
374 }
375 // invalid format
376 return null;
377 }
378
379 /**
380 * Returns the error, if any.
381 *
382 * @access public
383 * @return string
384 */
385 public function get_error() {
386 return $this->_error;
387 }
388
389
390 }
391