PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.1.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.1.1
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/Module.php +221 -1 3.0.53.1.1 View file →
@@ -62,8 +62,12 @@
62 62 global $wpdb;
63 63
64 64 $this->_wpdb = $wpdb;
65 65 $this->_plugin = $plugin;
66 +
67 + $this->_addFilter( Visualizer_Plugin::FILTER_UNDO_REVISIONS, 'undoRevisions', 10, 2 );
68 + $this->_addFilter( Visualizer_Plugin::FILTER_HANDLE_REVISIONS, 'handleExistingRevisions', 10, 2 );
69 +
66 70 }
67 71
68 72 /**
69 73 * Registers an action hook.
@@ -256,9 +260,9 @@
256 260 $xlsData = '';
257 261 if ( class_exists( 'PHPExcel' ) ) {
258 262 $doc = new PHPExcel();
259 263 $doc->getActiveSheet()->fromArray( $rows, null, 'A1' );
260 - $doc->getActiveSheet()->setTitle( $chart );
264 + $doc->getActiveSheet()->setTitle( sanitize_title( $chart ) );
261 265 $doc = apply_filters( 'visualizer_excel_doc', $doc );
262 266 $writer = PHPExcel_IOFactory::createWriter( $doc, 'Excel2007' );
263 267 ob_start();
264 268 $writer->save( 'php://output' );
@@ -320,7 +324,223 @@
320 324 </html>';
321 325 return array(
322 326 'csv' => $html,
323 327 );
328 + }
329 +
330 + /**
331 + * Undo revisions for the chart, and if necessary, restore the earliest version.
332 + *
333 + * @return bool If any revisions were found.
334 + */
335 + public final function undoRevisions( $chart_id, $restore = false ) {
336 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'undoRevisions for %d with%s restore', $chart_id, ( $restore ? '' : 'out' ) ), 'debug', __FILE__, __LINE__ );
337 +
338 + $revisions = wp_get_post_revisions( $chart_id, array( 'order' => 'ASC' ) );
339 + if ( count( $revisions ) > 1 ) {
340 + $revision_ids = array_keys( $revisions );
341 +
342 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'found %d revisions = %s', count( $revisions ), print_r( $revision_ids, true ) ), 'debug', __FILE__, __LINE__ );
343 +
344 + // when we restore, a new revision is likely to be created. so, let's disable revisions for the time being.
345 + add_filter( 'wp_revisions_to_keep', '__return_false' );
346 +
347 + if ( $restore ) {
348 + // restore to the oldest one i.e. the first one.
349 + wp_restore_post_revision( array_shift( $revision_ids ) );
350 + }
351 +
352 + // delete all revisions.
353 + foreach ( $revision_ids as $id ) {
354 + wp_delete_post_revision( $id );
355 + }
356 +
357 + return true;
358 + }
359 + return false;
360 + }
361 +
362 + /**
363 + * If existing revisions exist for the chart, restore the earliest version and then create a new revision to initiate editing.
364 + */
365 + public final function handleExistingRevisions( $chart_id, $chart ) {
366 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'handleExistingRevisions for %d', $chart_id ), 'debug', __FILE__, __LINE__ );
367 +
368 + // undo revisions.
369 + $revisions_found = $this->undoRevisions( $chart_id, true );
370 +
371 + // create revision for the edit action.
372 + wp_save_post_revision( $chart_id );
373 +
374 + if ( $revisions_found ) {
375 + // fetch chart data again in case it was updated by an earlier revision.
376 + $chart = get_post( $chart_id );
377 + }
378 + return $chart;
379 + }
380 +
381 + /**
382 + * Returns the language of the locale.
383 + *
384 + * @access protected
385 + */
386 + protected function get_language() {
387 + $locale = get_locale();
388 + if ( empty( $locale ) ) {
389 + return '';
390 + }
391 + $array = explode( '_', $locale );
392 + if ( count( $array ) < 2 ) {
393 + return '';
394 + }
395 + return reset( $array );
396 + }
397 +
398 + /**
399 + * Gets/creates the JS where user-specific customizations can be/have been added.
400 + */
401 + protected function get_user_customization_js() {
402 + // use this as the JS file in case we are not able to create the file in uploads.
403 + $default = VISUALIZER_ABSURL . 'js/customization.js';
404 +
405 + $uploads = wp_get_upload_dir();
406 + $specific = $uploads['baseurl'] . '/visualizer/customization.js';
407 +
408 + // for testing on user sites (before we send them the correctly customized file).
409 + if ( VISUALIZER_TEST_JS_CUSTOMIZATION ) {
410 + return $default;
411 + }
412 +
413 + require_once( ABSPATH . 'wp-admin/includes/file.php' );
414 + WP_Filesystem();
415 + global $wp_filesystem;
416 +
417 + $dir = $wp_filesystem->wp_content_dir() . 'uploads/visualizer';
418 + $file = $wp_filesystem->wp_content_dir() . 'uploads/visualizer/customization.js';
419 +
420 + if ( $wp_filesystem->is_readable( $file ) ) {
421 + return $specific;
422 + }
423 +
424 + if ( $wp_filesystem->exists( $file ) && ! $wp_filesystem->is_readable( $file ) ) {
425 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unable to read file %s', $file ), 'error', __FILE__, __LINE__ );
426 + return $default;
427 + }
428 +
429 + if ( ! $wp_filesystem->exists( $dir ) ) {
430 + if ( ( $done = $wp_filesystem->mkdir( $dir ) ) === false ) {
431 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unable to create directory %s', $dir ), 'error', __FILE__, __LINE__ );
432 + return $default;
433 + }
434 + }
435 +
436 + // if file does not exist, copy.
437 + if ( ! $wp_filesystem->exists( $file ) ) {
438 + $src = str_replace( ABSPATH, $wp_filesystem->abspath(), VISUALIZER_ABSPATH . '/js/customization.js' );
439 + if ( ( $done = $wp_filesystem->copy( $src, $file ) ) === false ) {
440 + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Unable to copy file %s to %s', $src, $file ), 'error', __FILE__, __LINE__ );
441 + return $default;
442 + }
443 + }
444 +
445 + return $specific;
446 + }
447 +
448 + /**
449 + * Load the class for the given chart's chart type so that its assets can be loaded.
450 + */
451 + protected function load_chart_type( $chart_id ) {
452 + $type = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, true );
453 + $name = 'Visualizer_Render_Sidebar_Type_' . ucwords( $type );
454 + $class = null;
455 + if ( class_exists( $name ) || true === apply_filters( 'visualizer_load_chart', false, $name ) ) {
456 + $class = new $name;
457 + }
458 +
459 + if ( is_null( $class ) && VISUALIZER_PRO ) {
460 + // lets see if this type exists in pro. New Lite(3.1.0+) & old Pro(1.8.0-).
461 + $class = apply_filters( 'visualizer_pro_chart_type_sidebar', null, array( 'type' => $type, 'settings' => get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true ) ) );
462 + }
463 +
464 + return is_null( $class ) ? null : $class->getLibrary();
465 + }
466 +
467 + /**
468 + * Generates the inline CSS to apply to the chart and adds these classes to the settings.
469 + *
470 + * @access public
471 + * @param int $id The id of the chart.
472 + * @param array $settings The settings of the chart.
473 + */
474 + protected function get_inline_custom_css( $id, $settings ) {
475 + $css = '';
476 +
477 + $arguments = array( '', $settings );
478 + if ( ! isset( $settings['customcss'] ) ) {
479 + return $arguments;
480 + }
481 +
482 + $classes = array();
483 + $css = '<style type="text/css" name="visualizer-custom-css" id="customcss-' . $id . '">';
484 + foreach ( $settings['customcss'] as $name => $element ) {
485 + $attributes = array();
486 + foreach ( $element as $property => $value ) {
487 + $attributes[] = $this->handle_css_property( $property, $value );
488 + }
489 + $class_name = $id . $name;
490 + $properties = implode( '; ', array_filter( $attributes ) );
491 + if ( ! empty( $properties ) ) {
492 + $css .= '.' . $class_name . ' {' . $properties . ' !important;}';
493 + $classes[ $name ] = $class_name;
494 + }
495 + }
496 + $css .= '</style>';
497 +
498 + $settings['cssClassNames'] = $classes;
499 +
500 + $arguments = array( $css, $settings );
501 + apply_filters_ref_array( 'visualizer_inline_css', array( &$arguments ) );
502 +
503 + return $arguments;
504 + }
505 +
506 + /**
507 + * Handles CSS properties that might need special syntax.
508 + *
509 + * @access private
510 + * @param string $property The name of the css property.
511 + * @param string $value The value of the css property.
512 + */
513 + private function handle_css_property( $property, $value ) {
514 + if ( empty( $property ) || empty( $value ) ) {
515 + return '';
516 + }
517 +
518 + switch ( $property ) {
519 + case 'transform':
520 + $value = 'rotate(' . $value . 'deg)';
521 + break;
522 + }
523 + return $property . ': ' . $value;
524 + }
525 +
526 + /**
527 + * Determines if charts have been created of the particular chart type.
528 + */
529 + protected static function hasChartType( $type ) {
530 + $args = array(
531 + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
532 + 'fields' => 'ids',
533 + 'post_status' => 'publish',
534 + 'meta_query' => array(
535 + array(
536 + 'key' => Visualizer_Plugin::CF_CHART_TYPE,
537 + 'value' => $type,
538 + ),
539 + ),
540 + );
541 +
542 + $q = new WP_Query( $args );
543 + return $q->found_posts > 0;
324 544 }
325 545
326 546 }