| @@ -57,13 +57,18 @@ | ||
| 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 | 60 | $this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' ); |
| 61 | + | |
| 62 | + $this->_addAjaxAction( Visualizer_Plugin::ACTION_FETCH_DB_DATA, 'getQueryData' ); | |
| 63 | + $this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_DB_QUERY, 'saveQuery' ); | |
| 61 | 64 | } |
| 62 | 65 | |
| 63 | 66 | /** |
| 64 | 67 | * Fetches charts from database. |
| 65 | 68 | * |
| 69 | + * This method is also called from the media pop-up (classic editor: create a post and add chart from insert content). | |
| 70 | + * | |
| 66 | 71 | * @since 1.0.0 |
| 67 | 72 | * |
| 68 | 73 | * @access public |
| 69 | 74 | */ |
| @@ -103,8 +108,18 @@ | ||
| 103 | 108 | while ( $query->have_posts() ) { |
| 104 | 109 | $chart = $query->next_post(); |
| 105 | 110 | $chart_data = $this->_getChartArray( $chart ); |
| 106 | 111 | $chart_data['id'] = $chart->ID; |
| 112 | + $chart_data['library'] = $this->load_chart_type( $chart->ID ); | |
| 113 | + $css = ''; | |
| 114 | + $settings = $chart_data['settings']; | |
| 115 | + $arguments = $this->get_inline_custom_css( 'visualizer-chart-' . $chart->ID, $settings ); | |
| 116 | + if ( ! empty( $arguments ) ) { | |
| 117 | + $css = $arguments[0]; | |
| 118 | + $settings = $arguments[1]; | |
| 119 | + } | |
| 120 | + $chart_data['settings'] = $settings; | |
| 121 | + $chart_data['css'] = $css; | |
| 107 | 122 | $charts[] = $chart_data; |
| 108 | 123 | } |
| 109 | 124 | self::_sendResponse( |
| 110 | 125 | array( |
| @@ -132,14 +147,30 @@ | ||
| 132 | 147 | } |
| 133 | 148 | $type = get_post_meta( $chart->ID, Visualizer_Plugin::CF_CHART_TYPE, true ); |
| 134 | 149 | $series = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SERIES, get_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, true ), $chart->ID, $type ); |
| 135 | 150 | $data = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_DATA, unserialize( $chart->post_content ), $chart->ID, $type ); |
| 151 | + $library = $this->load_chart_type( $chart->ID ); | |
| 136 | 152 | |
| 153 | + $settings = get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ); | |
| 154 | + $settings = apply_filters( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS, $settings, $chart->ID, $type ); | |
| 155 | + if ( ! empty( $atts['settings'] ) ) { | |
| 156 | + $settings = apply_filters( $atts['settings'], $settings, $chart->ID, $type ); | |
| 157 | + } | |
| 158 | + | |
| 159 | + $css = ''; | |
| 160 | + $arguments = $this->get_inline_custom_css( 'visualizer-' . $chart->ID, $settings ); | |
| 161 | + if ( ! empty( $arguments ) ) { | |
| 162 | + $css = $arguments[0]; | |
| 163 | + $settings = $arguments[1]; | |
| 164 | + } | |
| 165 | + | |
| 137 | 166 | return array( |
| 138 | 167 | 'type' => $type, |
| 139 | 168 | 'series' => $series, |
| 140 | - 'settings' => get_post_meta( $chart->ID, Visualizer_Plugin::CF_SETTINGS, true ), | |
| 169 | + 'settings' => $settings, | |
| 141 | 170 | 'data' => $data, |
| 171 | + 'library' => $library, | |
| 172 | + 'css' => $css, | |
| 142 | 173 | ); |
| 143 | 174 | } |
| 144 | 175 | |
| 145 | 176 | /** |
| @@ -243,8 +274,11 @@ | ||
| 243 | 274 | } |
| 244 | 275 | wp_redirect( add_query_arg( 'chart', (int) $chart_id ) ); |
| 245 | 276 | defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit(); |
| 246 | 277 | } |
| 278 | + | |
| 279 | + $this->load_chart_type( $chart_id ); | |
| 280 | + | |
| 247 | 281 | // enqueue and register scripts and styles |
| 248 | 282 | wp_register_script( 'visualizer-chosen', VISUALIZER_ABSURL . 'js/lib/chosen.jquery.min.js', array( 'jquery' ), Visualizer_Plugin::VERSION ); |
| 249 | 283 | wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION ); |
| 250 | 284 | |
| @@ -249,20 +283,13 @@ | ||
| 249 | 283 | wp_register_style( 'visualizer-chosen', VISUALIZER_ABSURL . 'css/lib/chosen.min.css', array(), Visualizer_Plugin::VERSION ); |
| 250 | 284 | |
| 251 | 285 | wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION ); |
| 252 | 286 | wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION, true ); |
| 253 | - wp_register_script( 'google-jsapi-new', '//www.gstatic.com/charts/loader.js', array(), null, true ); | |
| 254 | - wp_register_script( 'google-jsapi-old', '//www.google.com/jsapi', array( 'google-jsapi-new' ), null, true ); | |
| 255 | 287 | wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true ); |
| 256 | 288 | wp_register_script( |
| 257 | 289 | 'visualizer-render', |
| 258 | - VISUALIZER_ABSURL . 'js/render.js', | |
| 259 | - array( | |
| 260 | - 'google-jsapi-old', | |
| 261 | - 'google-jsapi-new', | |
| 262 | - 'visualizer-frame', | |
| 263 | - 'visualizer-customization', | |
| 264 | - ), | |
| 290 | + VISUALIZER_ABSURL . 'js/render-facade.js', | |
| 291 | + apply_filters( 'visualizer_assets_render', array( 'visualizer-frame', 'visualizer-customization' ), false ), | |
| 265 | 292 | Visualizer_Plugin::VERSION, |
| 266 | 293 | true |
| 267 | 294 | ); |
| 268 | 295 | wp_register_script( |
| @@ -315,8 +342,62 @@ | ||
| 315 | 342 | defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit(); |
| 316 | 343 | } |
| 317 | 344 | |
| 318 | 345 | /** |
| 346 | + * Load code editor assets. | |
| 347 | + */ | |
| 348 | + private function loadCodeEditorAssets() { | |
| 349 | + global $wp_version; | |
| 350 | + | |
| 351 | + if ( ! VISUALIZER_PRO ) { | |
| 352 | + return; | |
| 353 | + } | |
| 354 | + | |
| 355 | + $table_col_mapping = Visualizer_Source_Query_Params::get_all_db_tables_column_mapping(); | |
| 356 | + | |
| 357 | + // data tables assets. | |
| 358 | + wp_register_script( 'visualizer-datatables', '//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js', array( 'jquery-ui-core' ), Visualizer_Plugin::VERSION ); | |
| 359 | + wp_register_style( 'visualizer-datatables', '//cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css', array(), Visualizer_Plugin::VERSION ); | |
| 360 | + wp_register_style( 'visualizer-datatables-ui', '//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css', array( 'visualizer-datatables' ), Visualizer_Plugin::VERSION ); | |
| 361 | + | |
| 362 | + wp_enqueue_script( 'visualizer-datatables' ); | |
| 363 | + wp_enqueue_style( 'visualizer-datatables-ui' ); | |
| 364 | + | |
| 365 | + if ( version_compare( $wp_version, '4.9.0', '<' ) ) { | |
| 366 | + // code mirror assets. | |
| 367 | + wp_register_script( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.js', array( 'jquery' ), Visualizer_Plugin::VERSION ); | |
| 368 | + wp_register_script( 'visualizer-codemirror-placeholder', '//codemirror.net/addon/display/placeholder.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION ); | |
| 369 | + wp_register_script( 'visualizer-codemirror-matchbrackets', '//codemirror.net/addon/edit/matchbrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION ); | |
| 370 | + wp_register_script( 'visualizer-codemirror-closebrackets', '//codemirror.net/addon/edit/closebrackets.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION ); | |
| 371 | + wp_register_script( 'visualizer-codemirror-sql', '//codemirror.net/mode/sql/sql.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION ); | |
| 372 | + wp_register_script( 'visualizer-codemirror-sql-hint', '//codemirror.net/addon/hint/sql-hint.js', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION ); | |
| 373 | + wp_register_script( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.js', array( 'visualizer-codemirror-sql', 'visualizer-codemirror-sql-hint', 'visualizer-codemirror-placeholder', 'visualizer-codemirror-matchbrackets', 'visualizer-codemirror-closebrackets' ), Visualizer_Plugin::VERSION ); | |
| 374 | + wp_register_style( 'visualizer-codemirror-core', '//codemirror.net/lib/codemirror.css', array(), Visualizer_Plugin::VERSION ); | |
| 375 | + wp_register_style( 'visualizer-codemirror-hint', '//codemirror.net/addon/hint/show-hint.css', array( 'visualizer-codemirror-core' ), Visualizer_Plugin::VERSION ); | |
| 376 | + | |
| 377 | + wp_enqueue_script( 'visualizer-codemirror-hint' ); | |
| 378 | + wp_enqueue_style( 'visualizer-codemirror-hint' ); | |
| 379 | + } else { | |
| 380 | + wp_enqueue_code_editor( | |
| 381 | + array( | |
| 382 | + 'type' => 'sql', | |
| 383 | + 'codemirror' => array( | |
| 384 | + 'autofocus' => true, | |
| 385 | + 'lineWrapping' => true, | |
| 386 | + 'dragDrop' => false, | |
| 387 | + 'matchBrackets' => true, | |
| 388 | + 'autoCloseBrackets' => true, | |
| 389 | + 'extraKeys' => array( 'Ctrl-Space' => 'autocomplete' ), | |
| 390 | + 'hintOptions' => array( 'tables' => $table_col_mapping ), | |
| 391 | + ), | |
| 392 | + ) | |
| 393 | + ); | |
| 394 | + } | |
| 395 | + | |
| 396 | + return $table_col_mapping; | |
| 397 | + } | |
| 398 | + | |
| 399 | + /** | |
| 319 | 400 | * Handle data and settings page |
| 320 | 401 | */ |
| 321 | 402 | private function _handleDataAndSettingsPage() { |
| 322 | 403 | if ( isset( $_POST['map_api_key'] ) ) { |
| @@ -355,13 +436,16 @@ | ||
| 355 | 436 | $sidebar->__data = $data['data']; |
| 356 | 437 | } |
| 357 | 438 | } |
| 358 | 439 | unset( $data['settings']['width'], $data['settings']['height'] ); |
| 359 | - wp_enqueue_style( 'visualizer-frame' ); | |
| 360 | 440 | wp_enqueue_style( 'wp-color-picker' ); |
| 361 | 441 | wp_enqueue_style( 'visualizer-frame' ); |
| 362 | 442 | wp_enqueue_script( 'visualizer-preview' ); |
| 443 | + wp_enqueue_script( 'visualizer-chosen' ); | |
| 363 | 444 | wp_enqueue_script( 'visualizer-render' ); |
| 445 | + | |
| 446 | + $table_col_mapping = $this->loadCodeEditorAssets(); | |
| 447 | + | |
| 364 | 448 | wp_localize_script( |
| 365 | 449 | 'visualizer-render', |
| 366 | 450 | 'visualizer', |
| 367 | 451 | array( |
| @@ -370,25 +454,35 @@ | ||
| 370 | 454 | 'loading' => esc_html__( 'Loading...', 'visualizer' ), |
| 371 | 455 | ), |
| 372 | 456 | 'charts' => array( |
| 373 | 457 | 'canvas' => $data, |
| 458 | + 'id' => $this->_chart->ID, | |
| 374 | 459 | ), |
| 375 | 460 | 'language' => $this->get_language(), |
| 376 | 461 | 'map_api_key' => get_option( 'visualizer-map-api-key' ), |
| 377 | - 'ajax' => array( | |
| 462 | + 'ajax' => array( | |
| 378 | 463 | 'url' => admin_url( 'admin-ajax.php' ), |
| 379 | 464 | 'nonces' => array( |
| 380 | 465 | 'permissions' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA ), |
| 466 | + 'db_get_data' => wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION ), | |
| 381 | 467 | ), |
| 382 | 468 | 'actions' => array( |
| 383 | 469 | 'permissions' => Visualizer_Plugin::ACTION_FETCH_PERMISSIONS_DATA, |
| 470 | + 'db_get_data' => Visualizer_Plugin::ACTION_FETCH_DB_DATA, | |
| 384 | 471 | ), |
| 385 | 472 | ), |
| 473 | + 'db_query' => array( | |
| 474 | + 'tables' => $table_col_mapping, | |
| 475 | + ), | |
| 476 | + 'is_pro' => VISUALIZER_PRO, | |
| 477 | + 'page_type' => 'chart', | |
| 386 | 478 | ) |
| 387 | 479 | ); |
| 480 | + | |
| 388 | 481 | $render = new Visualizer_Render_Page_Data(); |
| 389 | 482 | $render->chart = $this->_chart; |
| 390 | 483 | $render->type = $data['type']; |
| 484 | + $render->custom_css = $data['css']; | |
| 391 | 485 | $render->sidebar = $sidebar; |
| 392 | 486 | if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) { |
| 393 | 487 | $render->button = filter_input( INPUT_GET, 'action' ) == Visualizer_Plugin::ACTION_EDIT_CHART |
| 394 | 488 | ? esc_html__( 'Save Chart', 'visualizer' ) |
| @@ -495,8 +589,12 @@ | ||
| 495 | 589 | |
| 496 | 590 | if ( ! isset( $_POST['chart_data_src'] ) || Visualizer_Plugin::CF_SOURCE_FILTER !== $_POST['chart_data_src'] ) { |
| 497 | 591 | // delete the filters in case this chart is being uploaded from other data sources |
| 498 | 592 | delete_post_meta( $chart_id, 'visualizer-filter-config' ); |
| 593 | + | |
| 594 | + // delete "import from db" specific parameters. | |
| 595 | + delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY ); | |
| 596 | + delete_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE ); | |
| 499 | 597 | } |
| 500 | 598 | |
| 501 | 599 | $source = null; |
| 502 | 600 | $render = new Visualizer_Render_Page_Update(); |
| @@ -531,8 +629,9 @@ | ||
| 531 | 629 | wp_update_post( $chart->to_array() ); |
| 532 | 630 | update_post_meta( $chart->ID, Visualizer_Plugin::CF_SERIES, $source->getSeries() ); |
| 533 | 631 | update_post_meta( $chart->ID, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() ); |
| 534 | 632 | update_post_meta( $chart->ID, Visualizer_Plugin::CF_DEFAULT_DATA, 0 ); |
| 633 | + $render->id = $chart->ID; | |
| 535 | 634 | $render->data = json_encode( $source->getRawData() ); |
| 536 | 635 | $render->series = json_encode( $source->getSeries() ); |
| 537 | 636 | } else { |
| 538 | 637 | $render->message = esc_html__( 'CSV file is broken or invalid. Please, try again.', 'visualizer' ); |
| @@ -670,5 +769,78 @@ | ||
| 670 | 769 | $this->_addAction( 'admin_head', 'renderFlattrScript' ); |
| 671 | 770 | wp_iframe( array( $render, 'render' ) ); |
| 672 | 771 | } |
| 673 | 772 | |
| 773 | + /** | |
| 774 | + * Returns the data for the query. | |
| 775 | + * | |
| 776 | + * @access public | |
| 777 | + */ | |
| 778 | + public function getQueryData() { | |
| 779 | + check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' ); | |
| 780 | + | |
| 781 | + $params = wp_parse_args( $_POST['params'] ); | |
| 782 | + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) ); | |
| 783 | + $html = $source->fetch( true ); | |
| 784 | + $error = ''; | |
| 785 | + if ( empty( $html ) ) { | |
| 786 | + $error = $source->get_error(); | |
| 787 | + wp_send_json_error( array( 'msg' => $error ) ); | |
| 788 | + } | |
| 789 | + wp_send_json_success( array( 'table' => $html ) ); | |
| 790 | + } | |
| 791 | + | |
| 792 | + /** | |
| 793 | + * Saves the query and the schedule. | |
| 794 | + * | |
| 795 | + * @access public | |
| 796 | + */ | |
| 797 | + public function saveQuery() { | |
| 798 | + check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_DB_QUERY . Visualizer_Plugin::VERSION, 'security' ); | |
| 799 | + | |
| 800 | + $chart_id = filter_input( | |
| 801 | + INPUT_GET, | |
| 802 | + 'chart', | |
| 803 | + FILTER_VALIDATE_INT, | |
| 804 | + array( | |
| 805 | + 'options' => array( | |
| 806 | + 'min_range' => 1, | |
| 807 | + ), | |
| 808 | + ) | |
| 809 | + ); | |
| 810 | + | |
| 811 | + $render = new Visualizer_Render_Page_Update(); | |
| 812 | + if ( $chart_id ) { | |
| 813 | + $params = wp_parse_args( $_POST['params'] ); | |
| 814 | + $source = new Visualizer_Source_Query( stripslashes( $params['query'] ) ); | |
| 815 | + $source->fetch( false ); | |
| 816 | + $error = $source->get_error(); | |
| 817 | + if ( empty( $error ) ) { | |
| 818 | + $hours = $_POST['refresh']; | |
| 819 | + update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_QUERY, stripslashes( $params['query'] ) ); | |
| 820 | + update_post_meta( $chart_id, Visualizer_Plugin::CF_SOURCE, $source->getSourceName() ); | |
| 821 | + update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, $source->getSeries() ); | |
| 822 | + update_post_meta( $chart_id, Visualizer_Plugin::CF_DB_SCHEDULE, $hours ); | |
| 823 | + update_post_meta( $chart_id, Visualizer_Plugin::CF_DEFAULT_DATA, 0 ); | |
| 824 | + | |
| 825 | + $schedules = get_option( Visualizer_Plugin::CF_DB_SCHEDULE, array() ); | |
| 826 | + $schedules[ $chart_id ] = time() + $hours * HOUR_IN_SECONDS; | |
| 827 | + update_option( Visualizer_Plugin::CF_DB_SCHEDULE, $schedules ); | |
| 828 | + | |
| 829 | + wp_update_post( | |
| 830 | + array( | |
| 831 | + 'ID' => $chart_id, | |
| 832 | + 'post_content' => $source->getData(), | |
| 833 | + ) | |
| 834 | + ); | |
| 835 | + $render->data = json_encode( $source->getRawData() ); | |
| 836 | + $render->series = json_encode( $source->getSeries() ); | |
| 837 | + } else { | |
| 838 | + $render->message = $error; | |
| 839 | + } | |
| 840 | + } | |
| 841 | + $render->render(); | |
| 842 | + if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) { | |
| 843 | + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit(); | |
| 844 | + } | |
| 845 | + } | |
| 674 | 846 | } |