PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 1.5.3
Visualizer – Tables & Charts Manager with Built-in AI Generator v1.5.3
4.0.8 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 All 149 releases
← All changes | classes/Visualizer/Source.php +205 -477 4.0.71.5.3 View file →
@@ -1,477 +1,205 @@
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 - abstract public 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 - abstract public 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( $fetch_from_editable_table = false ) {
145 - if ( $fetch_from_editable_table ) {
146 - $this->_fetchDataFromEditableTable();
147 - }
148 - return serialize( $this->_data );
149 - }
150 -
151 - /**
152 - * Returns raw data array.
153 - *
154 - * @since 1.1.0
155 - *
156 - * @access public
157 - * @return array
158 - */
159 - public function getRawData( $fetch_from_editable_table = false ) {
160 - if ( $fetch_from_editable_table ) {
161 - $this->_fetchDataFromEditableTable();
162 - }
163 - return $this->_data;
164 - }
165 -
166 - /**
167 - * Re populates series if the source is dynamic.
168 - *
169 - * @since 1.1.0
170 - *
171 - * @access public
172 - *
173 - * @param array $series The actual array of series.
174 - * @param int $chart_id The chart id.
175 - *
176 - * @return array The re populated array of series or old one.
177 - */
178 - public function repopulateSeries( $series, $chart_id ) {
179 - return $series;
180 - }
181 -
182 - /**
183 - * Re populates data if the source is dynamic.
184 - *
185 - * @since 1.1.0
186 - *
187 - * @access public
188 - *
189 - * @param array $data The actual array of data.
190 - * @param int $chart_id The chart id.
191 - *
192 - * @return array The re populated array of data or old one.
193 - */
194 - public function repopulateData( $data, $chart_id ) {
195 - return $data;
196 - }
197 -
198 - /**
199 - * Normalizes values according to series' type.
200 - *
201 - * @since 1.0.0
202 - *
203 - * @access protected
204 - *
205 - * @param array $data The row of data.
206 - *
207 - * @return array Normalized row of data.
208 - */
209 - protected function _normalizeData( $data ) {
210 - // normalize values
211 - foreach ( $this->_series as $i => $series ) {
212 - // if no value exists for the seires, then add null
213 - if ( ! isset( $data[ $i ] ) ) {
214 - $data[ $i ] = null;
215 - }
216 - if ( is_null( $data[ $i ] ) ) {
217 - continue;
218 - }
219 - switch ( $series['type'] ) {
220 - case 'number':
221 - $data[ $i ] = preg_replace( '/[\x{200B}-\x{200D}\x{FEFF}]/u', '', $data[ $i ] );
222 - $data[ $i ] = ( is_numeric( $data[ $i ] ) ) ? floatval( $data[ $i ] ) : ( is_numeric( str_replace( ',', '', $data[ $i ] ) ) ? floatval( str_replace( ',', '', $data[ $i ] ) ) : null );
223 - break;
224 - case 'boolean':
225 - $datum = trim( strval( $data[ $i ] ) );
226 - $data[ $i ] = in_array( $datum, array( 'true', 'yes', '1' ), true ) ? 'true' : 'false';
227 - break;
228 - case 'timeofday':
229 - $date = new DateTime( '1984-03-16T' . $data[ $i ] );
230 - if ( $date ) {
231 - $data[ $i ] = array(
232 - intval( $date->format( 'H' ) ),
233 - intval( $date->format( 'i' ) ),
234 - intval( $date->format( 's' ) ),
235 - 0,
236 - );
237 - }
238 - break;
239 - case 'datetime':
240 - // let's check if the date is a Unix epoch
241 - $value = DateTime::createFromFormat( 'U', $data[ $i ] );
242 - if ( $value !== false && ! is_wp_error( $value ) ) {
243 - $data[ $i ] = $value->format( 'Y-m-d H:i:s' );
244 - }
245 - break;
246 - case 'string':
247 - // if a ' is provided, strip the backslash
248 - $data[ $i ] = stripslashes( $this->toUTF8( $data[ $i ] ) );
249 - break;
250 - }
251 - }
252 -
253 - return apply_filters( 'visualizer_format_data', $data, $this->_series );
254 - }
255 -
256 -
257 - /**
258 - * Converts values to UTF8, if required.
259 - *
260 - * @access protected
261 - *
262 - * @param string $datum The data to convert.
263 - *
264 - * @return string The converted data.
265 - */
266 - final protected function toUTF8( $datum ) {
267 - if ( ! function_exists( 'mb_detect_encoding' ) || mb_detect_encoding( $datum ) !== 'ASCII' ) {
268 - $datum = \ForceUTF8\Encoding::toUTF8( $datum );
269 - }
270 - return $datum;
271 - }
272 -
273 - /**
274 - * Determines the formats of date/time columns.
275 - *
276 - * @access public
277 - *
278 - * @param array $series The actual array of series.
279 - * @param array $data The actual array of data.
280 - *
281 - * @return array
282 - */
283 - final public static function get_date_formats_if_exists( $series, $data ) {
284 - $date_formats = array();
285 - $types = array();
286 - $index = 0;
287 - foreach ( $series as $column ) {
288 - if ( in_array( $column['type'], array( 'date', 'datetime', 'timeofday' ), true ) ) {
289 - $types[] = array( 'index' => $index, 'type' => $column['type'] );
290 - }
291 - ++$index;
292 - }
293 -
294 - if ( ! $types ) {
295 - return $date_formats;
296 - }
297 -
298 - $random = $data;
299 - // let's randomly pick 5 data points instead of cycling through the entire data set.
300 - if ( count( $data ) > 5 ) {
301 - $random = array();
302 - for ( $x = 0; $x < 5; $x++ ) {
303 - $random[] = $data[ rand( 0, count( $data ) - 1 ) ];
304 - }
305 - }
306 -
307 - foreach ( $types as $type ) {
308 - $formats = array();
309 - foreach ( $random as $datum ) {
310 - $f = self::determine_date_format( $datum[ $type['index'] ], $type['type'] );
311 - if ( $f ) {
312 - $formats[] = $f;
313 - }
314 - }
315 - // if there are multiple formats, use the most frequent format.
316 - $formats = array_filter( $formats );
317 - if ( $formats ) {
318 - $formats = array_count_values( $formats );
319 - arsort( $formats );
320 - $formats = array_keys( $formats );
321 - $final_format = reset( $formats );
322 - // we have determined the PHP format; now we have to change this into the JS format where m = MM, d = DD etc.
323 - $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 ) );
324 - }
325 - }
326 - return $date_formats;
327 - }
328 -
329 - /**
330 - * Determines the date/time format of the given string.
331 - *
332 - * @access private
333 - *
334 - * @param string $value The string.
335 - * @param string $type 'date', 'timeofday' or 'datetime'.
336 - *
337 - * @return string|null
338 - */
339 - private static function determine_date_format( $value, $type ) {
340 - if ( version_compare( phpversion(), '5.3.0', '<' ) ) {
341 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'PHP version %s not supported', phpversion() ), 'error', __FILE__, __LINE__ );
342 - return null;
343 - }
344 -
345 - $formats = array(
346 - 'Y/m/d',
347 - 'Y-m-d',
348 - 'm/d/Y',
349 - 'm-d-Y',
350 - 'd-m-Y',
351 - 'd/m/Y',
352 - );
353 -
354 - switch ( $type ) {
355 - case 'datetime':
356 - $formats = array_merge(
357 - $formats, array(
358 - 'U',
359 - 'Y/m/d H:i:s',
360 - 'Y-m-d H:i:s',
361 - 'm/d/Y H:i:s',
362 - 'm-d-Y H:i:s',
363 - )
364 - );
365 - break;
366 - case 'timeofday':
367 - $formats = array_merge(
368 - $formats, array(
369 - 'H:i:s',
370 - 'H:i',
371 - )
372 - );
373 - break;
374 - }
375 -
376 - $formats = apply_filters( 'visualizer_date_formats', $formats, $type );
377 -
378 - foreach ( $formats as $format ) {
379 - $return = DateTime::createFromFormat( $format, $value );
380 - if ( $return !== false && ! is_wp_error( $return ) ) {
381 - return $format;
382 - }
383 - }
384 - // invalid format
385 - return null;
386 - }
387 -
388 - /**
389 - * Returns the error, if any.
390 - *
391 - * @access public
392 - * @return string
393 - */
394 - public function get_error() {
395 - return $this->_error;
396 - }
397 -
398 - /**
399 - * Fetches information from the editable table and parses it to build series and data arrays.
400 - *
401 - * @since ?
402 - *
403 - * @access public
404 - * @return boolean TRUE on success, otherwise FALSE.
405 - */
406 - public function fetchFromEditableTable() {
407 - if ( empty( $this->_args ) ) {
408 - return false;
409 - }
410 -
411 - $this->_fetchSeriesFromEditableTable();
412 - $this->_fetchDataFromEditableTable();
413 - return true;
414 - }
415 -
416 - /**
417 - * Fetches series information from the editable table. This is fetched only through the UI and not while refreshing the chart data.
418 - *
419 - * @since 1.0.0
420 - *
421 - * @access private
422 - */
423 - private function _fetchSeriesFromEditableTable() {
424 - $params = $this->_args;
425 - $headers = array_filter( $params['header'] );
426 - $types = array_filter( $params['type'] );
427 - $header_row = $type_row = array();
428 - if ( $headers ) {
429 - foreach ( $headers as $header ) {
430 - if ( ! empty( $types[ $header ] ) ) {
431 - $this->_series[] = array(
432 - 'label' => sanitize_text_field( wp_strip_all_tags( $header ) ),
433 - 'type' => $types[ $header ],
434 - );
435 - }
436 - }
437 - }
438 -
439 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Series found for %s = %s', print_r( $this->_args, true ), print_r( $this->_series, true ) ), 'debug', __FILE__, __LINE__ );
440 -
441 - return true;
442 - }
443 -
444 -
445 - /**
446 - * Fetches data information from the editable table.
447 - *
448 - * @since 1.0.0
449 - *
450 - * @access private
451 - */
452 - private function _fetchDataFromEditableTable() {
453 - $headers = wp_list_pluck( $this->_series, 'label' );
454 - $this->fetch();
455 -
456 - $data = $this->_data;
457 - $this->_data = array();
458 -
459 - foreach ( $data as $line ) {
460 - $data_row = array();
461 - // we have to make sure we are fetching the data in the right order
462 - // in case the columns have been reordered
463 - foreach ( $headers as $header ) {
464 - $value = $line[ $header ];
465 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
466 - if ( in_array( $header, $headers ) ) {
467 - $data_row[] = $value;
468 - }
469 - }
470 - $this->_data[] = $this->_normalizeData( $data_row );
471 - }
472 -
473 - do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Data found for %s = %s', print_r( $this->_args, true ), print_r( $this->_data, true ) ), 'debug', __FILE__, __LINE__ );
474 -
475 - return true;
476 - }
477 -}
1 +<?php
2 +
3 +// +----------------------------------------------------------------------+
4 +// | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
5 +// +----------------------------------------------------------------------+
6 +// | This program is free software; you can redistribute it and/or modify |
7 +// | it under the terms of the GNU General Public License, version 2, as |
8 +// | published by the Free Software Foundation. |
9 +// | |
10 +// | This program is distributed in the hope that it will be useful, |
11 +// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 +// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 +// | GNU General Public License for more details. |
14 +// | |
15 +// | You should have received a copy of the GNU General Public License |
16 +// | along with this program; if not, write to the Free Software |
17 +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
18 +// | MA 02110-1301 USA |
19 +// +----------------------------------------------------------------------+
20 +// | Author: Eugene Manuilov <eugene@manuilov.org> |
21 +// +----------------------------------------------------------------------+
22 +
23 +/**
24 + * The abstract class for source managers.
25 + *
26 + * @category Visualizer
27 + * @package Source
28 + *
29 + * @since 1.0.0
30 + * @abstract
31 + */
32 +abstract class Visualizer_Source {
33 +
34 + /**
35 + * The array of data.
36 + *
37 + * @since 1.0.0
38 + *
39 + * @access protected
40 + * @var array
41 + */
42 + protected $_data = array();
43 +
44 + /**
45 + * The array of series.
46 + *
47 + * @since 1.0.0
48 + *
49 + * @access protected
50 + * @var array
51 + */
52 + protected $_series = array();
53 +
54 + /**
55 + * Returns source name.
56 + *
57 + * @since 1.0.0
58 + *
59 + * @abstract
60 + * @access public
61 + * @return string The name of source.
62 + */
63 + public abstract function getSourceName();
64 +
65 + /**
66 + * Fetches information from source, parses it and builds series and data arrays.
67 + *
68 + * @since 1.0.0
69 + *
70 + * @abstract
71 + * @access public
72 + */
73 + public abstract function fetch();
74 +
75 + /**
76 + * Returns series parsed from source.
77 + *
78 + * @since 1.0.0
79 + *
80 + * @access public
81 + * @return array The array of series.
82 + */
83 + public function getSeries() {
84 + return $this->_series;
85 + }
86 +
87 + /**
88 + * Returns data parsed from source.
89 + *
90 + * @since 1.0.0
91 + *
92 + * @access public
93 + * @return string The serialized array of data.
94 + */
95 + public function getData() {
96 + return serialize( $this->_data );
97 + }
98 +
99 + /**
100 + * Returns raw data array.
101 + *
102 + * @since 1.1.0
103 + *
104 + * @access public
105 + * @return array
106 + */
107 + public function getRawData() {
108 + return $this->_data;
109 + }
110 +
111 + /**
112 + * Normalizes values according to series' type.
113 + *
114 + * @since 1.0.0
115 + *
116 + * @access protected
117 + * @param array $data The row of data.
118 + * @return array Normalized row of data.
119 + */
120 + protected function _normalizeData( $data ) {
121 + // normalize values
122 + //print_r($data);
123 + foreach ( $this->_series as $i => $series ) {
124 + // if no value exists for the seires, then add null
125 + if ( !isset( $data[$i] ) ) {
126 + $data[$i] = null;
127 + }
128 +
129 + if ( is_null( $data[$i] ) && !is_numeric($data[$i])) {
130 + continue;
131 + }
132 +
133 + switch ( $series['type'] ) {
134 + case 'number':
135 + $data[$i] = ( is_numeric($data[$i]) ) ? floatval( $data[$i] ) : null;
136 + break;
137 + case 'boolean':
138 + $data[$i] = !empty( $data[$i] ) ? filter_validate( $data[$i], FILTER_VALIDATE_BOOLEAN ) : null;
139 + break;
140 + case 'timeofday':
141 + $date = new DateTime( '1984-03-16T' . $data[$i] );
142 + if ( $date ) {
143 + $data[$i] = array(
144 + intval( $date->format( 'H' ) ),
145 + intval( $date->format( 'i' ) ),
146 + intval( $date->format( 's' ) ),
147 + 0,
148 + );
149 + }
150 + break;
151 + }
152 + }
153 + return $data;
154 + }
155 +
156 + /**
157 + * Validates series tyeps.
158 + *
159 + * @since 1.0.1
160 + *
161 + * @static
162 + * @access protected
163 + * @param array $types The icoming series types.
164 + * @return boolean TRUE if sereis types are valid, otherwise FALSE.
165 + */
166 + protected static function _validateTypes( $types ) {
167 + $allowed_types = array( 'string', 'number', 'boolean', 'date', 'datetime', 'timeofday' );
168 + foreach ( $types as $type ) {
169 + if ( !in_array( $type, $allowed_types ) ) {
170 + return false;
171 + }
172 + }
173 +
174 + return true;
175 + }
176 +
177 + /**
178 + * Re populates series if the source is dynamic.
179 + *
180 + * @since 1.1.0
181 + *
182 + * @access public
183 + * @param array $series The actual array of series.
184 + * @param int $chart_id The chart id.
185 + * @return array The re populated array of series or old one.
186 + */
187 + public function repopulateSeries( $series, $chart_id ) {
188 + return $series;
189 + }
190 +
191 + /**
192 + * Re populates data if the source is dynamic.
193 + *
194 + * @since 1.1.0
195 + *
196 + * @access public
197 + * @param array $data The actual array of data.
198 + * @param int $chart_id The chart id.
199 + * @return array The re populated array of data or old one.
200 + */
201 + public function repopulateData( $data, $chart_id ) {
202 + return $data;
203 + }
204 +
205 +}