PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.0
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.0
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/Chart.php +72 -132 4.0.84.0.0 View file →
@@ -107,10 +107,11 @@
107 107 */
108 108 public function setJsonSchedule() {
109 109 check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_SCHEDULE . Visualizer_Plugin::VERSION, 'security' );
110 110
111 - $chart_id = isset( $_POST['chart'] ) ? filter_var(
112 - $_POST['chart'],
111 + $chart_id = filter_input(
112 + INPUT_POST,
113 + 'chart',
113 114 FILTER_VALIDATE_INT,
114 115 array(
115 116 'options' => array(
116 117 'min_range' => 1,
@@ -115,18 +116,14 @@
115 116 'options' => array(
116 117 'min_range' => 1,
117 118 ),
118 119 )
119 - ) : false;
120 + );
120 121
121 122 if ( ! $chart_id ) {
122 123 wp_send_json_error();
123 124 }
124 125
125 - if ( ! self::can_edit_chart( $chart_id ) ) {
126 - wp_send_json_error( array( 'msg' => esc_html__( 'You do not have permission to perform this action.', 'visualizer' ) ), 403 );
127 - }
128 -
129 126 $time = filter_input(
130 127 INPUT_POST,
131 128 'time',
132 129 FILTER_VALIDATE_INT,
@@ -172,12 +169,8 @@
172 169 */
173 170 public function getJsonRoots() {
174 171 check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_ROOTS . Visualizer_Plugin::VERSION, 'security' );
175 172
176 - if ( ! current_user_can( 'edit_posts' ) ) {
177 - wp_send_json_error( array( 'msg' => esc_html__( 'You do not have permission to perform this action.', 'visualizer' ) ) );
178 - }
179 -
180 173 $params = wp_parse_args( $_POST['params'] );
181 174
182 175 $source = new Visualizer_Source_Json( $params );
183 176
@@ -198,18 +191,13 @@
198 191 */
199 192 public function getJsonData() {
200 193 check_ajax_referer( Visualizer_Plugin::ACTION_JSON_GET_DATA . Visualizer_Plugin::VERSION, 'security' );
201 194
202 - if ( ! current_user_can( 'edit_posts' ) ) {
203 - wp_send_json_error( array( 'msg' => esc_html__( 'You do not have permission to perform this action.', 'visualizer' ) ) );
204 - }
205 -
206 195 $params = wp_parse_args( $_POST['params'] );
207 196
208 197 $chart_id = $params['chart'];
209 198
210 - $chart = $chart_id ? get_post( $chart_id ) : null;
211 - if ( ! $chart || Visualizer_Plugin::CPT_VISUALIZER !== $chart->post_type || ! current_user_can( 'edit_post', $chart_id ) ) {
199 + if ( empty( $chart_id ) ) {
212 200 wp_die();
213 201 }
214 202
215 203 $source = new Visualizer_Source_Json( $params );
@@ -234,12 +222,12 @@
234 222 public function setJsonData() {
235 223 check_ajax_referer( Visualizer_Plugin::ACTION_JSON_SET_DATA . Visualizer_Plugin::VERSION, 'security' );
236 224
237 225 $params = $_POST;
238 - $chart_id = isset( $_GET['chart'] ) ? absint( $_GET['chart'] ) : 0;
226 + $chart_id = $_GET['chart'];
239 227
240 - if ( ! self::can_edit_chart( $chart_id ) ) {
241 - wp_die( esc_html__( 'You do not have permission to perform this action.', 'visualizer' ), '', array( 'response' => 403 ) );
228 + if ( empty( $chart_id ) ) {
229 + wp_die();
242 230 }
243 231
244 232 $chart = get_post( $chart_id );
245 233
@@ -307,9 +295,9 @@
307 295 $render->data = json_encode( $source->getRawData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) ) );
308 296 $render->series = json_encode( $source->getSeries() );
309 297 $render->render();
310 298
311 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
299 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
312 300 }
313 301
314 302
315 303 /**
@@ -321,14 +309,8 @@
321 309 *
322 310 * @access public
323 311 */
324 312 public function getCharts() {
325 - check_ajax_referer( Visualizer_Plugin::ACTION_GET_CHARTS, 'nonce' );
326 -
327 - if ( ! current_user_can( 'edit_posts' ) ) {
328 - wp_send_json_error( array( 'msg' => esc_html__( 'You do not have permission to perform this action.', 'visualizer' ) ), 403 );
329 - }
330 -
331 313 $query_args = array(
332 314 'post_type' => Visualizer_Plugin::CPT_VISUALIZER,
333 315 'posts_per_page' => 9,
334 316 'paged' => filter_input(
@@ -342,11 +324,8 @@
342 324 ),
343 325 )
344 326 ),
345 327 );
346 - if ( ! current_user_can( 'edit_others_posts' ) ) {
347 - $query_args['author'] = get_current_user_id();
348 - }
349 328 $filter = filter_input( INPUT_GET, 's', FILTER_SANITIZE_STRING );
350 329 if ( empty( $filter ) ) {
351 330 // 'filter' is from the modal from the add media button.
352 331 $filter = filter_input( INPUT_GET, 'filter', FILTER_SANITIZE_STRING );
@@ -452,9 +431,9 @@
452 431 public static function _sendResponse( $results ) {
453 432 header( 'Content-type: application/json' );
454 433 nocache_headers();
455 434 echo json_encode( $results );
456 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
435 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
457 436 }
458 437
459 438 /**
460 439 * Deletes a chart from database.
@@ -465,14 +444,16 @@
465 444 * @access public
466 445 */
467 446 public function deleteChart() {
468 447 $is_post = $_SERVER['REQUEST_METHOD'] === 'POST';
469 - $input = $is_post ? $_POST : $_GET;
448 + $input_method = $is_post ? INPUT_POST : INPUT_GET;
470 449 $chart_id = $success = false;
471 - $nonce = isset( $input['nonce'] ) && wp_verify_nonce( $input['nonce'] );
472 - if ( $nonce ) {
473 - $chart_id = isset( $input['chart'] ) ? filter_var(
474 - $input['chart'],
450 + $nonce = wp_verify_nonce( filter_input( $input_method, 'nonce' ) );
451 + $capable = current_user_can( 'delete_posts' );
452 + if ( $nonce && $capable ) {
453 + $chart_id = filter_input(
454 + $input_method,
455 + 'chart',
475 456 FILTER_VALIDATE_INT,
476 457 array(
477 458 'options' => array(
478 459 'min_range' => 1,
@@ -477,17 +458,12 @@
477 458 'options' => array(
478 459 'min_range' => 1,
479 460 ),
480 461 )
481 - ) : false;
462 + );
482 463 if ( $chart_id ) {
483 464 $chart = get_post( $chart_id );
484 - $success = $chart
485 - && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER
486 - && (
487 - current_user_can( 'delete_post', $chart_id )
488 - || ( (int) $chart->post_author === get_current_user_id() && current_user_can( 'delete_posts' ) )
489 - );
465 + $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
490 466 }
491 467 }
492 468 if ( $success ) {
493 469 global $sitepress;
@@ -568,11 +544,8 @@
568 544 if ( ! empty( $_POST ) ) {
569 545 $_POST = map_deep( $_POST, 'wp_strip_all_tags' );
570 546 }
571 547 $chart = $chart_id ? get_post( $chart_id ) : null;
572 - if ( $chart && ! self::can_edit_chart( $chart_id ) ) {
573 - wp_die( esc_html__( 'You do not have permission to access this page.', 'visualizer' ), '', array( 'response' => 403 ) );
574 - }
575 548 if ( ! $chart_id || ! $chart || $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ) {
576 549 if ( empty( $_GET['lang'] ) || empty( $_GET['parent_chart_id'] ) ) {
577 550 $this->deleteOldCharts();
578 551 $default_type = isset( $_GET['type'] ) && ! empty( $_GET['type'] ) ? $_GET['type'] : 'line';
@@ -609,9 +582,9 @@
609 582 }
610 583 } else {
611 584 $parent_chart_id = filter_var( $_GET['parent_chart_id'], FILTER_VALIDATE_INT );
612 585 $success = false;
613 - if ( $parent_chart_id && self::can_edit_chart( $parent_chart_id ) ) {
586 + if ( $parent_chart_id ) {
614 587 $parent_chart = get_post( $parent_chart_id );
615 588 $success = $parent_chart && $parent_chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
616 589 }
617 590 if ( $success ) {
@@ -631,9 +604,9 @@
631 604 $post_meta = get_post_meta( $parent_chart_id );
632 605 $chart_id = $new_chart_id;
633 606 foreach ( $post_meta as $key => $value ) {
634 607 if ( strpos( $key, 'visualizer-' ) !== false ) {
635 - add_post_meta( $new_chart_id, $key, self::maybe_decode_content( $value[0] ) );
608 + add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
636 609 }
637 610 }
638 611 }
639 612 }
@@ -640,9 +613,9 @@
640 613 do_action( 'visualizer_pro_new_chart_defaults', $chart_id );
641 614 }
642 615 wp_redirect( esc_url_raw( add_query_arg( 'chart', (int) $chart_id ) ) );
643 616
644 - if ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) {
617 + if ( defined( 'WP_TESTS_DOMAIN' ) ) {
645 618 wp_die();
646 619 }
647 620 exit();
648 621 }
@@ -738,9 +711,9 @@
738 711 default:
739 712 // this should never happen.
740 713 break;
741 714 }
742 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
715 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
743 716 }
744 717
745 718 /**
746 719 * Load code editor assets.
@@ -817,16 +790,16 @@
817 790 /**
818 791 * Handle data and settings page
819 792 */
820 793 private function _handleDataAndSettingsPage() {
794 + if ( isset( $_POST['map_api_key'] ) ) {
795 + update_option( 'visualizer-map-api-key', $_POST['map_api_key'] );
796 + }
797 +
821 798 if ( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'] ) ) {
822 799 $is_canceled = isset( $_POST['cancel'] ) && 1 === intval( $_POST['cancel'] );
823 800 $is_newly_created = $this->_chart->post_status === 'auto-draft';
824 801
825 - if ( isset( $_POST['map_api_key'] ) && current_user_can( 'manage_options' ) ) {
826 - update_option( 'visualizer-map-api-key', sanitize_text_field( wp_unslash( $_POST['map_api_key'] ) ) );
827 - }
828 -
829 802 if ( $is_newly_created && ! $is_canceled ) {
830 803 $this->_chart->post_status = 'publish';
831 804
832 805 // 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.
@@ -841,9 +814,8 @@
841 814 $existing = get_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, true );
842 815 if ( isset( $existing['colors'] ) && is_array( $existing['colors'] ) && ! isset( $post_settings['colors'] ) ) {
843 816 $post_settings['colors'] = $existing['colors'];
844 817 }
845 - $post_settings = $this->sanitizeSettings( $post_settings );
846 818 update_post_meta( $this->_chart->ID, Visualizer_Plugin::CF_SETTINGS, $post_settings );
847 819
848 820 // we will keep a parameter called 'internal_title' that will be set to the given title or, if empty, the chart ID
849 821 // this will help in searching with the chart id.
@@ -1034,35 +1006,8 @@
1034 1006 wp_iframe( array( $render, 'render' ) );
1035 1007 }
1036 1008
1037 1009 /**
1038 - * Sanitize settings data from the request.
1039 - *
1040 - * @param array<string, mixed> $post_data The POST data to sanitize.
1041 - * @return array<string, mixed> The sanitized settings data.
1042 - */
1043 - private function sanitizeSettings( $post_data ): array {
1044 - $chart_img = '';
1045 - if ( isset( $post_data['chart-img'] ) ) {
1046 - $chart_img = wp_unslash( $post_data['chart-img'] );
1047 - unset( $post_data['chart-img'] );
1048 - }
1049 -
1050 - $post_data = map_deep(
1051 - $post_data,
1052 - 'sanitize_textarea_field'
1053 - );
1054 -
1055 - // The value is a client-side canvas export; keep it only when it is a
1056 - // base64 image data URI so nothing else is ever stored unsanitized.
1057 - if ( is_string( $chart_img ) && preg_match( '#^data:image/(png|jpeg|webp);base64,[A-Za-z0-9+/ ]+=*$#', $chart_img ) ) {
1058 - $post_data['chart-img'] = $chart_img;
1059 - }
1060 -
1061 - return $post_data;
1062 - }
1063 -
1064 - /**
1065 1010 * Renders flattr script in the iframe <head>
1066 1011 *
1067 1012 * @since 1.4.2
1068 1013 * @action admin_head
@@ -1083,9 +1028,9 @@
1083 1028 *
1084 1029 * Used as a fallback when the URL path has no recognisable file extension
1085 1030 * (e.g. SharePoint, signed S3 URLs, or "download?id=…" endpoints).
1086 1031 *
1087 - * Uses the shared remote-fetch policy to block non-public destinations,
1032 + * Uses wp_safe_remote_get() to block requests to private/loopback addresses,
1088 1033 * and streams the response to a temp file so no body data is held in memory
1089 1034 * regardless of whether the server honours the Range header.
1090 1035 *
1091 1036 * The check relies on the ZIP magic number (PK\x03\x04) that every XLSX
@@ -1102,17 +1047,16 @@
1102 1047 if ( ! $tmpfile ) {
1103 1048 return false;
1104 1049 }
1105 1050
1106 - $response = Visualizer_Remote_Fetch::request(
1051 + $response = wp_safe_remote_get(
1107 1052 $url,
1108 1053 array(
1109 - 'timeout' => 10,
1110 - 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ),
1111 - 'headers' => array( 'Range' => 'bytes=0-3' ),
1112 - 'stream' => true,
1113 - 'filename' => $tmpfile,
1114 - 'limit_response_size' => 4,
1054 + 'timeout' => 10,
1055 + 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ),
1056 + 'headers' => array( 'Range' => 'bytes=0-3' ),
1057 + 'stream' => true,
1058 + 'filename' => $tmpfile,
1115 1059 )
1116 1060 );
1117 1061
1118 1062 if ( is_wp_error( $response ) ) {
@@ -1277,15 +1221,14 @@
1277 1221 public function uploadData() {
1278 1222 // if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set.
1279 1223 // otherwise, assume this is a normal web request.
1280 1224 $can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
1281 - // $can_die also gates the capability checks below, so VISUALIZER_DO_NOT_DIE must stay internal-only (never set from request input or globally).
1282 1225
1283 - // validate nonce; capability check applies to web requests only, not trusted internal calls.
1226 + // validate nonce
1284 1227 if (
1285 1228 ! isset( $_GET['nonce'] ) ||
1286 1229 ! wp_verify_nonce( $_GET['nonce'], 'visualizer-upload-data' ) ||
1287 - ( $can_die && ! current_user_can( 'edit_posts' ) )
1230 + ! current_user_can( 'edit_posts' )
1288 1231 ) {
1289 1232 if ( ! $can_die ) {
1290 1233 return;
1291 1234 }
@@ -1300,9 +1243,9 @@
1300 1243 if (
1301 1244 ! $chart_id ||
1302 1245 ! $chart ||
1303 1246 $chart->post_type !== Visualizer_Plugin::CPT_VISUALIZER ||
1304 - ( $can_die && ! current_user_can( 'edit_post', $chart_id ) )
1247 + ! current_user_can( 'edit_post', $chart_id )
1305 1248 ) {
1306 1249 if ( ! $can_die ) {
1307 1250 return;
1308 1251 }
@@ -1384,10 +1327,10 @@
1384 1327 if ( $source ) {
1385 1328 if ( $source->fetch() ) {
1386 1329 $content = $source->getData( get_post_meta( $chart_id, Visualizer_Plugin::CF_EDITABLE_TABLE, true ) );
1387 1330 $populate = true;
1388 - $json = self::decode_content( $content );
1389 - if ( is_array( $json ) ) {
1331 + if ( is_string( $content ) && is_array( unserialize( $content ) ) ) {
1332 + $json = unserialize( $content );
1390 1333 // if source exists, so should data. if source exists but data is blank, do not populate the chart.
1391 1334 // if we populate the data even if it is empty, the chart will show "Table has no columns".
1392 1335 if ( array_key_exists( 'source', $json ) && ! empty( $json['source'] ) && ( ! array_key_exists( 'data', $json ) || empty( $json['data'] ) ) ) {
1393 1336 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__ );
@@ -1438,9 +1381,9 @@
1438 1381 $render->render();
1439 1382 if ( ! $can_die ) {
1440 1383 return;
1441 1384 }
1442 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1385 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1443 1386 }
1444 1387
1445 1388 /**
1446 1389 * Clones the chart.
@@ -1451,11 +1394,12 @@
1451 1394 */
1452 1395 public function cloneChart() {
1453 1396 $chart_id = $success = false;
1454 1397 $nonce = isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], Visualizer_Plugin::ACTION_CLONE_CHART );
1455 - if ( $nonce ) {
1398 + $capable = current_user_can( 'edit_posts' );
1399 + if ( $nonce && $capable ) {
1456 1400 $chart_id = isset( $_GET['chart'] ) ? filter_var( $_GET['chart'], FILTER_VALIDATE_INT ) : '';
1457 - if ( $chart_id && self::can_edit_chart( $chart_id ) ) {
1401 + if ( $chart_id ) {
1458 1402 $chart = get_post( $chart_id );
1459 1403 $success = $chart && $chart->post_type === Visualizer_Plugin::CPT_VISUALIZER;
1460 1404 }
1461 1405 }
@@ -1475,9 +1419,9 @@
1475 1419 } else {
1476 1420 $post_meta = get_post_meta( $chart_id );
1477 1421 foreach ( $post_meta as $key => $value ) {
1478 1422 if ( strpos( $key, 'visualizer-' ) !== false ) {
1479 - add_post_meta( $new_chart_id, $key, self::maybe_decode_content( $value[0] ) );
1423 + add_post_meta( $new_chart_id, $key, maybe_unserialize( $value[0] ) );
1480 1424 }
1481 1425 }
1482 1426 $redirect = esc_url(
1483 1427 add_query_arg(
@@ -1493,9 +1437,9 @@
1493 1437 );
1494 1438 }
1495 1439 }
1496 1440
1497 - if ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) {
1441 + if ( defined( 'WP_TESTS_DOMAIN' ) ) {
1498 1442 wp_die();
1499 1443 }
1500 1444 wp_redirect( $redirect );
1501 1445 exit;
@@ -1509,25 +1453,28 @@
1509 1453 * @access public
1510 1454 */
1511 1455 public function exportData() {
1512 1456 check_ajax_referer( Visualizer_Plugin::ACTION_EXPORT_DATA . Visualizer_Plugin::VERSION, 'security' );
1513 - $chart_id = isset( $_GET['chart'] ) ? filter_var(
1514 - $_GET['chart'],
1515 - FILTER_VALIDATE_INT,
1516 - array(
1517 - 'options' => array(
1518 - 'min_range' => 1,
1519 - ),
1520 - )
1521 - ) : '';
1522 - if ( $chart_id && self::can_edit_chart( $chart_id ) ) {
1523 - $data = $this->_getDataAs( $chart_id, 'csv' );
1524 - if ( $data ) {
1525 - echo wp_send_json_success( $data );
1457 + $capable = current_user_can( 'edit_posts' );
1458 + if ( $capable ) {
1459 + $chart_id = isset( $_GET['chart'] ) ? filter_var(
1460 + $_GET['chart'],
1461 + FILTER_VALIDATE_INT,
1462 + array(
1463 + 'options' => array(
1464 + 'min_range' => 1,
1465 + ),
1466 + )
1467 + ) : '';
1468 + if ( $chart_id ) {
1469 + $data = $this->_getDataAs( $chart_id, 'csv' );
1470 + if ( $data ) {
1471 + echo wp_send_json_success( $data );
1472 + }
1526 1473 }
1527 1474 }
1528 1475
1529 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1476 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1530 1477 }
1531 1478
1532 1479 /**
1533 1480 * Handles chart data page.
@@ -1690,9 +1637,9 @@
1690 1637 }
1691 1638 }
1692 1639 $render->render();
1693 1640 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1694 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1641 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1695 1642 }
1696 1643 }
1697 1644
1698 1645
@@ -1703,10 +1650,11 @@
1703 1650 */
1704 1651 public function saveFilter() {
1705 1652 check_ajax_referer( Visualizer_Plugin::ACTION_SAVE_FILTER_QUERY . Visualizer_Plugin::VERSION, 'security' );
1706 1653
1707 - $chart_id = isset( $_GET['chart'] ) ? filter_var(
1708 - $_GET['chart'],
1654 + $chart_id = filter_input(
1655 + INPUT_GET,
1656 + 'chart',
1709 1657 FILTER_VALIDATE_INT,
1710 1658 array(
1711 1659 'options' => array(
1712 1660 'min_range' => 1,
@@ -1711,14 +1659,10 @@
1711 1659 'options' => array(
1712 1660 'min_range' => 1,
1713 1661 ),
1714 1662 )
1715 - ) : false;
1663 + );
1716 1664
1717 - if ( ! self::can_edit_chart( $chart_id ) ) {
1718 - wp_send_json_error( array( 'msg' => esc_html__( 'You do not have permission to perform this action.', 'visualizer' ) ), 403 );
1719 - }
1720 -
1721 1665 $hours = filter_input(
1722 1666 INPUT_POST,
1723 1667 'refresh',
1724 1668 FILTER_VALIDATE_FLOAT,
@@ -1736,9 +1680,9 @@
1736 1680
1737 1681 do_action( 'visualizer_save_filter', $chart_id, $hours );
1738 1682
1739 1683 if ( ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE ) ) {
1740 - ( defined( 'WP_TESTS_DOMAIN' ) && function_exists( 'tests_add_filter' ) ) ? wp_die() : exit();
1684 + defined( 'WP_TESTS_DOMAIN' ) ? wp_die() : exit();
1741 1685 }
1742 1686 }
1743 1687
1744 1688 /**
@@ -1746,9 +1690,9 @@
1746 1690 *
1747 1691 * @param string $base64_img Chart image.
1748 1692 * @param int $chart_id Chart ID.
1749 1693 * @param bool $save_attachment Save attachment.
1750 - * @return int Attachment ID, or 0 when no attachment was saved.
1694 + * @return attachment ID
1751 1695 */
1752 1696 public function save_chart_image( $base64_img, $chart_id, $save_attachment = true ) {
1753 1697 // Delete old chart image.
1754 1698 $old_attachment_id = get_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_IMAGE, true );
@@ -1763,15 +1707,11 @@
1763 1707 // Upload dir.
1764 1708 $upload_dir = wp_upload_dir();
1765 1709 $upload_path = str_replace( '/', DIRECTORY_SEPARATOR, $upload_dir['path'] ) . DIRECTORY_SEPARATOR;
1766 1710
1767 - $img = str_replace( 'data:image/png;base64,', '', (string) $base64_img );
1768 - $img = str_replace( ' ', '+', $img );
1769 - $decoded = base64_decode( $img, true );
1770 - // The value comes from an untrusted request; only write real PNG bytes to uploads.
1771 - if ( false === $decoded || 0 !== strncmp( $decoded, "\x89PNG\r\n\x1a\n", 8 ) ) {
1772 - return 0;
1773 - }
1711 + $img = str_replace( 'data:image/png;base64,', '', $base64_img );
1712 + $img = str_replace( ' ', '+', $img );
1713 + $decoded = base64_decode( $img );
1774 1714 $filename = 'visualization-' . $chart_id . '.png';
1775 1715 $file_type = 'image/png';
1776 1716 $hashed_filename = $filename;
1777 1717