| @@ -56,11 +56,9 @@ | ||
| 56 | 56 | $this->_addAjaxAction( Visualizer_Plugin::ACTION_CREATE_CHART, 'renderChartPages' ); |
| 57 | 57 | $this->_addAjaxAction( Visualizer_Plugin::ACTION_EDIT_CHART, 'renderChartPages' ); |
| 58 | 58 | $this->_addAjaxAction( Visualizer_Plugin::ACTION_UPLOAD_DATA, 'uploadData' ); |
| 59 | 59 | $this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' ); |
| 60 | - // Added by Ash/Upwork | |
| 61 | 60 | $this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' ); |
| 62 | - // Added by Ash/Upwork | |
| 63 | 61 | } |
| 64 | 62 | |
| 65 | 63 | /** |
| 66 | 64 | * Fetches charts from database. |
| @@ -73,9 +71,12 @@ | ||
| 73 | 71 | $query_args = array( |
| 74 | 72 | 'post_type' => Visualizer_Plugin::CPT_VISUALIZER, |
| 75 | 73 | 'posts_per_page' => 9, |
| 76 | 74 | 'paged' => filter_input( |
| 77 | - INPUT_GET, 'page', FILTER_VALIDATE_INT, array( | |
| 75 | + INPUT_GET, | |
| 76 | + 'page', | |
| 77 | + FILTER_VALIDATE_INT, | |
| 78 | + array( | |
| 78 | 79 | 'options' => array( |
| 79 | 80 | 'min_range' => 1, |
| 80 | 81 | 'default' => 1, |
| 81 | 82 | ), |
| @@ -172,9 +173,12 @@ | ||
| 172 | 173 | $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) ); |
| 173 | 174 | $capable = current_user_can( 'delete_posts' ); |
| 174 | 175 | if ( $nonce && $capable ) { |
| 175 | 176 | $chart_id = filter_input( |
| 176 | - $input_method, 'chart', FILTER_VALIDATE_INT, array( | |
| 177 | + $input_method, | |
| 178 | + 'chart', | |
| 179 | + FILTER_VALIDATE_INT, | |
| 180 | + array( | |
| 177 | 181 | 'options' => array( |
| 178 | 182 | 'min_range' => 1, |
| 179 | 183 | ), |
| 180 | 184 | ) |
| @@ -210,9 +214,9 @@ | ||
| 210 | 214 | defined( 'IFRAME_REQUEST' ) || define( 'IFRAME_REQUEST', 1 ); |
| 211 | 215 | // check chart, if chart not exists, will create new one and redirects to the same page with proper chart id |
| 212 | 216 | $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : ''; |
| 213 | 217 | if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) { |
| 214 | - $default_type = 'line'; | |
| 218 | + $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line'; | |
| 215 | 219 | $source = new Visualizer_Source_Csv( VISUALIZER_ABSPATH . DIRECTORY_SEPARATOR . 'samples' . DIRECTORY_SEPARATOR . $default_type . '.csv' ); |
| 216 | 220 | $source->fetch(); |
| 217 | 221 | $chart_id = wp_insert_post( |
| 218 | 222 | array( |
| @@ -228,9 +232,11 @@ | ||
| 228 | 232 | add_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 1 ); |
| 229 | 233 | add_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() ); |
| 230 | 234 | add_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() ); |
| 231 | 235 | add_post_meta( |
| 232 | - $chart_id, Visualizer_Plugin::CF_SETTINGS, array( | |
| 236 | + $chart_id, | |
| 237 | + Visualizer_Plugin::CF_SETTINGS, | |
| 238 | + array( | |
| 233 | 239 | 'focusTarget' => 'datum', |
| 234 | 240 | ) |
| 235 | 241 | ); |
| 236 | 242 | do_action( 'visualizer_pro_new_chart_defaults', $chart_id ); |
| @@ -245,20 +251,30 @@ | ||
| 245 | 251 | wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION ); |
| 246 | 252 | wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true ); |
| 247 | 253 | wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true ); |
| 248 | 254 | wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true ); |
| 255 | + wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true ); | |
| 249 | 256 | wp_register_script( |
| 250 | - 'visualizer-render', VISUALIZER_ABSURL . 'js/render.js', array( | |
| 257 | + 'visualizer-render', | |
| 258 | + VISUALIZER_ABSURL . 'js/render.js', | |
| 259 | + array( | |
| 251 | 260 | 'google-jsapi-old', |
| 252 | 261 | 'google-jsapi-new', |
| 253 | 262 | 'visualizer-frame', |
| 254 | - ), Visualizer_Plugin::VERSION, true | |
| 263 | + 'visualizer-customization', | |
| 264 | + ), | |
| 265 | + Visualizer_Plugin::VERSION, | |
| 266 | + true | |
| 255 | 267 | ); |
| 256 | 268 | wp_register_script( |
| 257 | - 'visualizer-preview', VISUALIZER_ABSURL . 'js/preview.js', array( | |
| 269 | + 'visualizer-preview', | |
| 270 | + VISUALIZER_ABSURL . 'js/preview.js', | |
| 271 | + array( | |
| 258 | 272 | 'wp-color-picker', |
| 259 | 273 | 'visualizer-render', |
| 260 | - ), Visualizer_Plugin::VERSION, true | |
| 274 | + ), | |
| 275 | + Visualizer_Plugin::VERSION, | |
| 276 | + true | |
| 261 | 277 | ); |
| 262 | 278 | // added by Ash/Upwork |
| 263 | 279 | if ( VISUALIZER_PRO ) { |
| 264 | 280 | global $Visualizer_Pro; |
| @@ -268,12 +284,23 @@ | ||
| 268 | 284 | $this->_chart = get_post( $chart_id ); |
| 269 | 285 | $tab = isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'visualizer'; |
| 270 | 286 | |
| 271 | 287 | // skip chart type pages only for existing charts. |
| 272 | - if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status ) { | |
| 288 | + if ( VISUALIZER_SKIP_CHART_TYPE_PAGE && 'auto-draft' !== $this->_chart->post_status && ( ! empty( $_GET['tab'] ) && 'visualizer' === $_GET['tab'] ) ) { | |
| 273 | 289 | $tab = 'settings'; |
| 274 | 290 | } |
| 275 | 291 | |
| 292 | + if ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) { | |
| 293 | + // if the cancel button is clicked. | |
| 294 | + $this->undoRevisions( $chart_id, true ); | |
| 295 | + } elseif ( isset( $_POST['save'] ) && 1 === intval( $_POST['save'] ) ) { | |
| 296 | + // if the save button is clicked. | |
| 297 | + $this->undoRevisions( $chart_id, false ); | |
| 298 | + } else { | |
| 299 | + // if the edit button is clicked. | |
| 300 | + $this->_chart = $this->handleExistingRevisions( $chart_id, $this->_chart ); | |
| 301 | + } | |
| 302 | + | |
| 276 | 303 | switch ( $tab ) { |
| 277 | 304 | case 'settings': |
| 278 | 305 | $this->_handleDataAndSettingsPage(); |
| 279 | 306 | break; |
| @@ -297,11 +324,18 @@ | ||
| 297 | 324 | } |
| 298 | 325 | if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) { |
| 299 | 326 | if ( $this->_chart->post_status == 'auto-draft' ) { |
| 300 | 327 | $this->_chart->post_status = 'publish'; |
| 328 | + | |
| 329 | + // ensure that a revision is not created. If a revision is created it will have the proper data and the parent of the revision will have default data. | |
| 330 | + // we do not want any difference in data so disable revisions temporarily. | |
| 331 | + add_filter( 'wp_revisions_to_keep', '__return_false' ); | |
| 301 | 332 | wp_update_post( $this->_chart->to_array() ); |
| 302 | 333 | } |
| 303 | - update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST ); | |
| 334 | + // save meta data only when it is NOT being canceled. | |
| 335 | + if ( ! ( isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] ) ) ) { | |
| 336 | + update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $_POST ); | |
| 337 | + } | |
| 304 | 338 | $render = new Visualizer_Render_Page_Send(); |
| 305 | 339 | $render->text = sprintf( '[visualizer id="%d"]', $this->_chart->ID ); |
| 306 | 340 | wp_iframe( array( $render, 'render' ) ); |
| 307 | 341 | |
| @@ -327,9 +361,11 @@ | ||
| 327 | 361 | wp_enqueue_style( 'visualizer-frame' ); |
| 328 | 362 | wp_enqueue_script( 'visualizer-preview' ); |
| 329 | 363 | wp_enqueue_script( 'visualizer-render' ); |
| 330 | 364 | wp_localize_script( |
| 331 | - 'visualizer-render', 'visualizer', array( | |
| 365 | + 'visualizer-render', | |
| 366 | + 'visualizer', | |
| 367 | + array( | |
| 332 | 368 | 'l10n' => array( |
| 333 | 369 | 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ), |
| 334 | 370 | 'loading' => esc_html__( 'Loading...', 'visualizer' ), |
| 335 | 371 | ), |
| @@ -356,8 +392,11 @@ | ||
| 356 | 392 | if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) { |
| 357 | 393 | $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART |
| 358 | 394 | ? esc_html__( 'Save Chart', 'visualizer' ) |
| 359 | 395 | : esc_html__( 'Create Chart', 'visualizer' ); |
| 396 | + if ( filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART ) { | |
| 397 | + $render->cancel_button = esc_html__( 'Cancel', 'visualizer' ); | |
| 398 | + } | |
| 360 | 399 | } else { |
| 361 | 400 | $render->button = esc_attr__( 'Insert Chart', 'visualizer' ); |
| 362 | 401 | } |
| 363 | 402 | if ( VISUALIZER_PRO ) { |
| @@ -425,20 +464,32 @@ | ||
| 425 | 464 | * |
| 426 | 465 | * @access public |
| 427 | 466 | */ |
| 428 | 467 | public function uploadData() { |
| 468 | + // if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set. | |
| 469 | + // otherwise, assume this is a normal web request. | |
| 470 | + $can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ); | |
| 471 | + | |
| 429 | 472 | // validate nonce |
| 430 | - // do not use filter_input as it does not work for phpunit test cases, use filter_var instead | |
| 431 | 473 | if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( $_GET['nonce'] ) ) { |
| 474 | + if ( ! $can_die ) { | |
| 475 | + return; | |
| 476 | + } | |
| 432 | 477 | status_header( 403 ); |
| 433 | 478 | exit; |
| 434 | 479 | } |
| 480 | + | |
| 435 | 481 | // check chart, if chart exists |
| 482 | + // do not use filter_input as it does not work for phpunit test cases, use filter_var instead | |
| 436 | 483 | $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : ''; |
| 437 | 484 | if ( ! $chart_id || ! ( $chart = get_post( $chart_id ) ) || $chart->post_type != Visualizer_Plugin::CPT_VISUALIZER ) { |
| 485 | + if ( ! $can_die ) { | |
| 486 | + return; | |
| 487 | + } | |
| 438 | 488 | status_header( 400 ); |
| 439 | 489 | exit; |
| 440 | 490 | } |
| 491 | + | |
| 441 | 492 | if ( ! isset( $_POST['vz-import-time'] ) ) { |
| 442 | 493 | apply_filters( 'visualizer_pro_remove_schedule', $chart_id ); |
| 443 | 494 | } |
| 444 | 495 | |
| @@ -455,18 +506,29 @@ | ||
| 455 | 506 | apply_filters( 'visualizer_pro_chart_schedule', $chart_id, $_POST['remote_data'], $_POST['vz-import-time'] ); |
| 456 | 507 | } |
| 457 | 508 | } elseif ( isset( $_FILES['local_data'] ) && $_FILES['local_data']['error'] == 0 ) { |
| 458 | 509 | $source = new Visualizer_Source_Csv( $_FILES['local_data']['tmp_name'] ); |
| 459 | - // Added by Ash/Upwork | |
| 460 | 510 | } elseif ( isset( $_POST['chart_data'] ) && strlen( $_POST['chart_data'] ) > 0 ) { |
| 461 | 511 | $source = apply_filters( 'visualizer_pro_handle_chart_data', $_POST['chart_data'], '' ); |
| 462 | - // Added by Ash/Upwork | |
| 463 | 512 | } else { |
| 464 | 513 | $render->message = esc_html__( 'CSV file with chart data was not uploaded. Please, try again.', 'visualizer' ); |
| 465 | 514 | } |
| 466 | 515 | if ( $source ) { |
| 467 | 516 | if ( $source->fetch() ) { |
| 468 | - $chart->post_content = $source->getData(); | |
| 517 | + $content = $source->getData(); | |
| 518 | + $populate = true; | |
| 519 | + if ( is_string( $content ) && is_array( unserialize( $content ) ) ) { | |
| 520 | + $json = unserialize( $content ); | |
| 521 | + // if source exists, so should data. if source exists but data is blank, do not populate the chart. | |
| 522 | + // if we populate the data even if it is empty, the chart will show "Table has no columns". | |
| 523 | + if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) { | |
| 524 | + do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'Not populating chart data as source exists (%s) but data is empty!', $json['source'] ), 'warn', __FILE__, __LINE__ ); | |
| 525 | + $populate = false; | |
| 526 | + } | |
| 527 | + } | |
| 528 | + if ( $populate ) { | |
| 529 | + $chart->post_content = $content; | |
| 530 | + } | |
| 469 | 531 | wp_update_post( $chart->to_array() ); |
| 470 | 532 | update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() ); |
| 471 | 533 | update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() ); |
| 472 | 534 | update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 ); |
| @@ -476,11 +538,12 @@ | ||
| 476 | 538 | $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' ); |
| 477 | 539 | } |
| 478 | 540 | } |
| 479 | 541 | $render->render(); |
| 480 | - if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) { | |
| 481 | - defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit(); | |
| 542 | + if ( ! $can_die ) { | |
| 543 | + return; | |
| 482 | 544 | } |
| 545 | + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit(); | |
| 483 | 546 | } |
| 484 | 547 | |
| 485 | 548 | /** |
| 486 | 549 | * Clones the chart. |
| @@ -494,9 +557,12 @@ | ||
| 494 | 557 | $nonce = wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), Visualizer_Plugin::ACTION_CLONE_CHART ); |
| 495 | 558 | $capable = current_user_can( 'edit_posts' ); |
| 496 | 559 | if ( $nonce && $capable ) { |
| 497 | 560 | $chart_id = filter_input( |
| 498 | - INPUT_GET, 'chart', FILTER_VALIDATE_INT, array( | |
| 561 | + INPUT_GET, | |
| 562 | + 'chart', | |
| 563 | + FILTER_VALIDATE_INT, | |
| 564 | + array( | |
| 499 | 565 | 'options' => array( |
| 500 | 566 | 'min_range' => 1, |
| 501 | 567 | ), |
| 502 | 568 | ) |
| @@ -526,9 +592,10 @@ | ||
| 526 | 592 | $redirect = add_query_arg( |
| 527 | 593 | array( |
| 528 | 594 | 'page' => 'visualizer', |
| 529 | 595 | 'type' => filter_input( INPUT_GET, 'type' ), |
| 530 | - ), admin_url( 'upload.php' ) | |
| 596 | + ), | |
| 597 | + admin_url( 'upload.php' ) | |
| 531 | 598 | ); |
| 532 | 599 | } |
| 533 | 600 | } |
| 534 | 601 | wp_redirect( $redirect ); |
| @@ -546,9 +613,11 @@ | ||
| 546 | 613 | check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' ); |
| 547 | 614 | $capable = current_user_can( 'edit_posts' ); |
| 548 | 615 | if ( $capable ) { |
| 549 | 616 | $chart_id = isset( $_GET['chart'] ) ? filter_var( |
| 550 | - $_GET['chart'], FILTER_VALIDATE_INT, array( | |
| 617 | + $_GET['chart'], | |
| 618 | + FILTER_VALIDATE_INT, | |
| 619 | + array( | |
| 551 | 620 | 'options' => array( |
| 552 | 621 | 'min_range' => 1, |
| 553 | 622 | ), |
| 554 | 623 | ) |
| @@ -579,9 +648,11 @@ | ||
| 579 | 648 | unset( $data['settings']['width'], $data['settings']['height'] ); |
| 580 | 649 | wp_enqueue_style( 'visualizer-frame' ); |
| 581 | 650 | wp_enqueue_script( 'visualizer-render' ); |
| 582 | 651 | wp_localize_script( |
| 583 | - 'visualizer-render', 'visualizer', array( | |
| 652 | + 'visualizer-render', | |
| 653 | + 'visualizer', | |
| 654 | + array( | |
| 584 | 655 | 'l10n' => array( |
| 585 | 656 | 'invalid_source' => esc_html__( 'You have entered invalid URL. Please, insert proper URL.', 'visualizer' ), |
| 586 | 657 | 'loading' => esc_html__( 'Loading...', 'visualizer' ), |
| 587 | 658 | ), |
| @@ -598,5 +669,6 @@ | ||
| 598 | 669 | // Added by Ash/Upwork |
| 599 | 670 | $this->_addAction( 'admin_head', 'renderFlattrScript' ); |
| 600 | 671 | wp_iframe( array( $render, 'render' ) ); |
| 601 | 672 | } |
| 673 | + | |
| 602 | 674 | } |