PluginProbe
SQL Chart Builder / 3.0.3
SQL Chart Builder v3.0.3
3.0.5 3.0.4 3.0.3 3.0.2 3.0.1 trunk 1.0.2 1.0.3 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.7.1 2.3.7.2 2.3.8 3.0.0
← All changes | functions.php +134 -32 3.0.03.0.3 View file →
@@ -444,9 +444,10 @@
444 444 "guaven_sqlcharts_begin_with_0_y",
445 445 "guaven_sqlcharts_round_y_values",
446 446 "guaven_sqlcharts_legend_position",
447 447 "guaven_sqlcharts_nostacked",
448 - "guaven_sqlcharts_forcetooltips"
448 + "guaven_sqlcharts_forcetooltips",
449 + "guaven_sqlcharts_timeaxis"
449 450 );
450 451 foreach ($fields as $key => $value) {
451 452 if(isset($_POST[$value]))$newval=esc_attr($_POST[$value]);
452 453 else $newval='';
@@ -456,10 +457,26 @@
456 457 if(!empty($_POST["guaven_sqlcharts_dbpass"])){
457 458 $encpass=guaven_sqlcharts_encrypt_decrypt('encrypt',$_POST["guaven_sqlcharts_dbpass"]);
458 459 update_post_meta($post->ID, 'guaven_sqlcharts_dbpass', ['encrypted',$encpass]);
459 460 }
460 - update_post_meta($post->ID, 'guaven_sqlcharts_code', esc_attr(str_replace("'",'"',stripslashes($_POST['guaven_sqlcharts_code']))) );
461 + // Store the SQL as typed. Do not HTML-encode it and do not rewrite quotes:
462 + // the editor escapes it on output and the front end decodes entities before running it.
463 + $sql_code = isset($_POST['guaven_sqlcharts_code']) ? wp_check_invalid_utf8(wp_unslash($_POST['guaven_sqlcharts_code'])) : '';
464 + update_post_meta($post->ID, 'guaven_sqlcharts_code', $sql_code);
465 + // Flag that this chart stores raw SQL. Charts without the flag were saved by
466 + // versions before 3.0.1, which HTML-encoded the query, and still need decoding.
467 + update_post_meta($post->ID, 'guaven_sqlcharts_code_raw', 1);
461 468 }
469 +
470 +// Returns the stored SQL query exactly as the user typed it.
471 +function guaven_sqlcharts_get_code($post_id)
472 +{
473 + $sql = get_post_meta($post_id, 'guaven_sqlcharts_code', true);
474 + if (get_post_meta($post_id, 'guaven_sqlcharts_code_raw', true) != 1) {
475 + $sql = html_entity_decode($sql, ENT_QUOTES, 'UTF-8');
476 + }
477 + return $sql;
478 +}
462 479 add_action('save_post', 'guaven_sqlcharts_save_metabox_area', 1, 2);
463 480 // save the custom fields
464 481
465 482
@@ -475,11 +492,13 @@
475 492 {
476 493 $values = array();
477 494 $labels = array();
478 495 $xarg_s = get_post_meta($id, 'guaven_sqlcharts_xarg_s', true);
479 - $xarg_l = get_post_meta($id, 'guaven_sqlcharts_xarg_l', true);
480 496 $yarg_s = get_post_meta($id, 'guaven_sqlcharts_yarg_s', true);
481 - $yarg_l = get_post_meta($id, 'guaven_sqlcharts_yarg_l', true);
497 + // labels are saved through esc_attr, so "&" is stored as "&"; decode before splitting on ";"
498 + // or the entity's own ";" would be taken as a series separator
499 + $xarg_l = html_entity_decode((string) get_post_meta($id, 'guaven_sqlcharts_xarg_l', true), ENT_QUOTES, 'UTF-8');
500 + $yarg_l = html_entity_decode((string) get_post_meta($id, 'guaven_sqlcharts_yarg_l', true), ENT_QUOTES, 'UTF-8');
482 501 foreach ($fvs as $key => $value) {
483 502 $values[$value->$xarg_s] = $value->$yarg_s;
484 503 $labels[$value->$xarg_s] = '"' . $value->$xarg_s . '"';
485 504 }
@@ -673,9 +692,9 @@
673 692 }
674 693
675 694 $GLOBALS["guaven_sqlcharts_atts"]=$atts;
676 695
677 - $sql = html_entity_decode(get_post_meta($atts['id'], 'guaven_sqlcharts_code', true));
696 + $sql = guaven_sqlcharts_get_code($atts['id']);
678 697 if(empty($sql))return 'SQL query is missing.';
679 698 $sql=gvn_chart_put_variables($sql,$atts['id']);
680 699
681 700
@@ -684,19 +703,24 @@
684 703 $blacklister_f = gvn_chart_check_sql_query($sql);
685 704 if ($blacklister_f == 1)return 'You given SQL code contains forbidden commands. Remember that you should only use SELECT queries';
686 705 $tip_g = guaven_sqlcharts_normalize_type(get_post_meta($atts['id'], 'guaven_sqlcharts_graphtype', true));
687 706
707 + // {arg1}..{arg19} come from shortcode attributes: [gvn_schart_2 id="1" arg1="41"].
708 + // Substituted directly (not via wpdb::prepare) so the same tag may appear any number of times,
709 + // e.g. in every query of a ";"-separated comparison chart. Numbers are inserted as-is, anything
710 + // else is escaped and quoted; a tag already wrapped in quotes ('{arg1}') is not double-quoted.
688 711 for($i=1;$i<20;$i++){
689 - if(strpos($sql,"{arg".$i."}")!==false){
690 - $replacearg=!empty($atts["arg".$i])?$atts["arg".$i]:0;
691 - $sql = str_replace("{arg".$i."}", "%s", $sql);
692 - $sql=$wpdb->prepare($sql,$replacearg);
693 - }
694 -
712 + $tag = '{arg'.$i.'}';
713 + if (strpos($sql, $tag) === false) continue;
714 + $replacearg = !empty($atts['arg'.$i]) ? $atts['arg'.$i] : 0;
715 + if (is_numeric($replacearg)) $replacearg = $replacearg + 0;
716 + else $replacearg = "'" . esc_sql($replacearg) . "'";
717 + $sql = str_replace(array("'".$tag."'", '"'.$tag.'"', $tag), $replacearg, $sql);
695 718 }
696 719
697 720 $sql_split = explode(';', $sql);
698 721 $labels_and_values = array();
722 + $labels = $values = $ylabel = $xlabel = array();
699 723 $post_g = get_post($atts['id']);
700 724
701 725 global $sqlcharts_inserted_script;
702 726 ob_start();
@@ -771,17 +795,24 @@
771 795 if (!shortcode_exists('gvn_schart')) {
772 796 add_shortcode('gvn_schart', 'guaven_sqlcharts_local_shortcode');
773 797 }
774 798
799 +// [gvn_schart_2_cached id="1" expire="3600" arg1=".."] – same as gvn_schart_2 but the output is kept in a
800 +// transient. All other attributes (argN, width, height, table, params) are passed through, and each
801 +// distinct set of attributes gets its own cache entry. Append ?force_sql_cache_reload to the URL to bypass.
775 802 add_shortcode("gvn_schart_2_cached",function($atts){
776 803 if(empty($atts["id"]))return;
777 804 $atts["id"]=intval($atts["id"]);
778 805 $is_logged_in=is_user_logged_in()?'':'_guest';
779 806 $expire=!empty($atts["expire"])?intval($atts["expire"]):3600;
780 - $cached=get_transient('cached_sql_charts_'.$atts["id"].$is_logged_in);
807 + $inner_atts=$atts;
808 + unset($inner_atts['expire']);
809 + $key='cached_sql_charts_'.$atts["id"].$is_logged_in;
810 + if (count($inner_atts) > 1) $key .= '_'.md5(serialize($inner_atts));
811 + $cached=get_transient($key);
781 812 if(!empty($cached) and !isset($_GET["force_sql_cache_reload"]) )return $cached;
782 - $tobecached=do_shortcode('[gvn_schart_2 id="'.$atts["id"].'"]');
783 - set_transient('cached_sql_charts_'.$atts["id"].$is_logged_in, $tobecached,$expire);//you can change 3600 yourself
813 + $tobecached=guaven_sqlcharts_local_shortcode($inner_atts);
814 + set_transient($key, $tobecached,$expire);
784 815 return $tobecached;
785 816 });
786 817
787 818 // fixed, colorblind-friendly default palette (Tableau 10) used when no custom colors are set
@@ -811,16 +842,76 @@
811 842 $h = !empty($atts['height']) ? $atts['height'] : get_post_meta($pid, 'guaven_sqlcharts_chartheight', true);
812 843 return $h != '' ? 'maintainAspectRatio: false,' : '';
813 844 }
814 845
846 +// outputs 'showAllTooltips: true,' when "Value labels" is checked; the values are drawn by the
847 +// gvnShowAllValues plugin in asset/front.js (works for every chart type)
848 +function guaven_sqlcharts_value_labels($pid){
849 + return get_post_meta($pid, 'guaven_sqlcharts_forcetooltips', true) != '' ? 'showAllTooltips: true,' : '';
850 +}
851 +
852 +// Chart.js scale title block built from the "X axis label" / "Y axis label" fields.
853 +// $which is 'x' or 'y' (the *field* to use, not the scale). The Y label is only used as an axis
854 +// title for single-series charts; with several ";"-separated series the legend names them instead.
855 +function guaven_sqlcharts_axis_title($pid, $which){
856 + $key = $which == 'x' ? 'guaven_sqlcharts_xarg_l' : 'guaven_sqlcharts_yarg_l';
857 + $text = trim(html_entity_decode((string) get_post_meta($pid, $key, true), ENT_QUOTES, 'UTF-8'));
858 + if ($text === '' or ($which == 'y' and strpos($text, ';') !== false)) return '';
859 + return 'title: {display: true, text: ' . wp_json_encode($text) . '},';
860 +}
861 +
862 +// dataset label as a safe JS string literal (labels saved before 3.0.1 may hold HTML entities)
863 +function guaven_sqlcharts_js_label($label){
864 + return wp_json_encode(html_entity_decode((string) $label, ENT_QUOTES, 'UTF-8'));
865 +}
866 +
867 +// Parses an X value for the "time axis" option. Accepts YYYY, YYYY-MM, YYYY-MM-DD, optionally followed
868 +// by HH:MM or HH:MM:SS. Returns a UTC timestamp in milliseconds, or false when the value is not a date.
869 +function guaven_sqlcharts_parse_date($str){
870 + $str = trim((string) $str);
871 + if (!preg_match('/^(\d{4})(?:-(\d{1,2})(?:-(\d{1,2})(?:[ T](\d{1,2}):(\d{2})(?::(\d{2}))?)?)?)?$/', $str, $m)) return false;
872 + $y = (int) $m[1]; $mo = isset($m[2]) ? (int) $m[2] : 1; $d = isset($m[3]) ? (int) $m[3] : 1;
873 + $h = isset($m[4]) ? (int) $m[4] : 0; $mi = isset($m[5]) ? (int) $m[5] : 0; $sec = isset($m[6]) ? (int) $m[6] : 0;
874 + if (!checkdate($mo, $d, $y) or $h > 23 or $mi > 59 or $sec > 59) return false;
875 + return gmmktime($h, $mi, $sec, $mo, $d, $y) * 1000;
876 +}
877 +
878 +// "Scale X axis by date/time" option. Returns, per dataset, a list of "{x:<ms>,y:<value>}" JS point
879 +// literals when the option is on and every X value is a date; false otherwise (normal category axis).
880 +function guaven_sqlcharts_time_axis_points($pid, $values){
881 + if (get_post_meta($pid, 'guaven_sqlcharts_timeaxis', true) != 1) return false;
882 + $out = array();
883 + $has_point = false;
884 + foreach ($values as $key_ak => $series) {
885 + $out[$key_ak] = array();
886 + foreach ($series as $x => $y) {
887 + $ts = guaven_sqlcharts_parse_date($x);
888 + if ($ts === false) return false;
889 + $out[$key_ak][] = '{x:' . $ts . ',y:' . (is_numeric($y) ? $y + 0 : 'null') . '}';
890 + $has_point = true;
891 + }
892 + }
893 + return $has_point ? $out : false;
894 +}
895 +
896 +// X scale options for time-axis mode; gvnSqlChartsTimeTick (asset/front.js) formats the ticks as dates
897 +function guaven_sqlcharts_time_axis_scale(){
898 + return "type: 'linear', offset: true, ticks: {callback: gvnSqlChartsTimeTick, maxRotation: 45},";
899 +}
900 +// extra entry for the Chart.js "plugins" object in time-axis mode (tooltip title shown as a date)
901 +function guaven_sqlcharts_time_axis_plugins($time_points){
902 + return $time_points !== false ? 'tooltip: {callbacks: {title: gvnSqlChartsTimeTooltipTitle}}' : '';
903 +}
904 +
815 905 function guaven_sqlcharts_bardata($title, $labels, $values, $ylabel, $type = 'bar', $pid = null)
816 906 {
817 907 $horizontal = ($type == 'horizontalBar');
818 908 $forcestack = ($type == 'stackedBar');
819 909 $stacked = ($forcestack or get_post_meta($pid, 'guaven_sqlcharts_nostacked', true) != 1) ? 'true' : 'false';
910 + $time_points = $horizontal ? false : guaven_sqlcharts_time_axis_points($pid, $values);
820 911 ?>
821 912 var data = {
822 - labels: [<?php guaven_sqlcharts_merge_labeldata($labels);?>],
913 + <?php if ($time_points === false) { ?>labels: [<?php guaven_sqlcharts_merge_labeldata($labels);?>],<?php } ?>
823 914 datasets: [
824 915 <?php
825 916 $values_new=guaven_sqlcharts_key_normalizer($values,$labels,$ylabel)[0];
826 917 $i=-1;
@@ -825,8 +916,9 @@
825 916 $values_new=guaven_sqlcharts_key_normalizer($values,$labels,$ylabel)[0];
826 917 $i=-1;
827 918 foreach ($values_new as $key_ak=>$value_ak) {
828 919 $i++;
920 + $points = $time_points !== false ? $time_points[$key_ak] : $values_new[$key_ak];
829 921 ?>
830 922 {
831 923 <?php
832 924 if(!empty($GLOBALS["guaven_sqlcharts_atts"]["params"])){
@@ -833,24 +925,23 @@
833 925 //passing chartJS params via the shortcode
834 926 echo wp_kses($GLOBALS["guaven_sqlcharts_atts"]["params"],[]);
835 927 }
836 928 ?>
837 - label: "<?php
838 - echo wp_kses($ylabel[$key_ak],[]);
839 -?>",
929 + label: <?php echo guaven_sqlcharts_js_label($ylabel[$key_ak]); ?>,
840 930 backgroundColor: [
841 931 <?php
842 - echo wp_kses(guaven_sqlcharts_colorgenerator(count($values_new[$key_ak]), 0, 0, guaven_sqlcharts_colors($i, $pid)),[]);
932 + echo wp_kses(guaven_sqlcharts_colorgenerator(count($points), 0, 0, guaven_sqlcharts_colors($i, $pid)),[]);
843 933 ?>
844 934 ],
845 935 borderColor: [
846 936 <?php
847 - echo wp_kses(guaven_sqlcharts_colorgenerator(count($values_new[$key_ak]), 0, 0.2, guaven_sqlcharts_colors($i, $pid)),[]);
937 + echo wp_kses(guaven_sqlcharts_colorgenerator(count($points), 0, 0.2, guaven_sqlcharts_colors($i, $pid)),[]);
848 938 ?>
849 939 ],
850 940 borderWidth: 1,
941 + <?php if ($time_points !== false) echo 'maxBarThickness: 48,'; ?>
851 942 data: [<?php
852 - echo wp_kses(implode(",", $values_new[$key_ak]),[]);
943 + echo wp_kses(implode(",", $points),[]);
853 944 ?>],
854 945 },
855 946 <?php
856 947 }
@@ -859,15 +950,19 @@
859 950 };
860 951 var options={
861 952 responsive: true,
862 953 <?php echo wp_kses(guaven_sqlcharts_mar($pid),[]); ?>
954 + <?php echo wp_kses(guaven_sqlcharts_value_labels($pid),[]); ?>
863 955 <?php if ($horizontal) echo "indexAxis: 'y',"; ?>
864 956 scales: {
865 957 x: {
958 + <?php if ($time_points !== false) echo guaven_sqlcharts_time_axis_scale(); ?>
959 + <?php echo guaven_sqlcharts_axis_title($pid, $horizontal ? 'y' : 'x'); ?>
866 960 stacked: <?php echo esc_js($stacked); ?>,
867 961 beginAtZero: <?php echo (get_post_meta($pid, 'guaven_sqlcharts_begin_with_0_x', true) == 1) ? 'true':'false'; ?>
868 962 },
869 963 y: {
964 + <?php echo guaven_sqlcharts_axis_title($pid, $horizontal ? 'x' : 'y'); ?>
870 965 stacked: <?php echo esc_js($stacked); ?>,
871 966 beginAtZero: <?php echo (get_post_meta($pid, 'guaven_sqlcharts_begin_with_0_y', true) == 1) ? 'true':'false'; ?>,
872 967 ticks: {
873 968 <?php if(get_post_meta($pid, 'guaven_sqlcharts_round_y_values', true) == 1) echo 'precision: 0,'; ?>
@@ -874,9 +969,9 @@
874 969 }
875 970 }
876 971 }
877 972 <?php
878 - guaven_sqlcharts_maybe_additional_parameters($pid);
973 + guaven_sqlcharts_maybe_additional_parameters($pid, guaven_sqlcharts_time_axis_plugins($time_points));
879 974 ?>
880 975 };
881 976 var myBarChart = new Chart(ctx, {
882 977 type: 'bar',
@@ -896,11 +991,12 @@
896 991 }
897 992
898 993 function guaven_sqlcharts_linedata($title, $labels, $values, $ylabel, $type = 'false', $pid = null, $charttype = 'line', $stepped = false)
899 994 {
995 + $time_points = ($charttype == 'radar') ? false : guaven_sqlcharts_time_axis_points($pid, $values);
900 996 ?>
901 997 var data = {
902 - labels: [<?php guaven_sqlcharts_merge_labeldata($labels);?>],
998 + <?php if ($time_points === false) { ?>labels: [<?php guaven_sqlcharts_merge_labeldata($labels);?>],<?php } ?>
903 999 datasets: [
904 1000 <?php
905 1001 $values_new=guaven_sqlcharts_key_normalizer($values,$labels,$ylabel)[0];
906 1002 $dataset_count=count($values_new);
@@ -906,8 +1002,9 @@
906 1002 $dataset_count=count($values_new);
907 1003 $i=-1;
908 1004 foreach ($values_new as $key_ak=>$value_ak) {
909 1005 $i++;
1006 + $points = $time_points !== false ? $time_points[$key_ak] : $values_new[$key_ak];
910 1007 if ($type == 'radarfill') $fill = "'origin'";
911 1008 elseif ($type == 'false') $fill = 'false';
912 1009 else $fill = ($i == 0 and $dataset_count > 1) ? '"+1"' : '"origin"';
913 1010 ?>
@@ -917,11 +1014,9 @@
917 1014 //passing chartJS params via the shortcode
918 1015 echo wp_kses($GLOBALS["guaven_sqlcharts_atts"]["params"],[]);
919 1016 }
920 1017 ?>
921 - label: "<?php
922 - echo esc_attr($ylabel[$key_ak]);
923 -?>",
1018 + label: <?php echo guaven_sqlcharts_js_label($ylabel[$key_ak]); ?>,
924 1019 fill: <?php echo wp_kses($fill,[]);
925 1020 ?>,
926 1021 tension: 0.1,
927 1022 <?php if ($stepped) echo 'stepped: true,'; ?>
@@ -940,9 +1035,9 @@
940 1035 pointHoverBorderColor: <?php
941 1036 echo wp_kses_post(guaven_sqlcharts_colorgenerator(1, 1, 0.2, guaven_sqlcharts_colors($i, $pid)));
942 1037 ?>
943 1038 data: [<?php
944 - echo wp_kses_post(implode(",", $values_new[$key_ak]));
1039 + echo wp_kses_post(implode(",", $points));
945 1040 ?>],
946 1041 spanGaps: false,
947 1042 },
948 1043 <?php
@@ -955,8 +1050,9 @@
955 1050 data: data,
956 1051 options: {
957 1052 responsive: true,
958 1053 <?php echo wp_kses(guaven_sqlcharts_mar($pid),[]); ?>
1054 + <?php echo wp_kses(guaven_sqlcharts_value_labels($pid),[]); ?>
959 1055 <?php if ($charttype == 'radar') { ?>
960 1056 scales: {
961 1057 r: {
962 1058 beginAtZero: <?php echo (get_post_meta($pid, 'guaven_sqlcharts_begin_with_0_y', true) == 1) ? 'true':'false'; ?>
@@ -965,11 +1061,14 @@
965 1061 <?php } else { ?>
966 1062 scales: {
967 1063 x: {
968 1064 display: true,
1065 + <?php if ($time_points !== false) echo guaven_sqlcharts_time_axis_scale(); ?>
1066 + <?php echo guaven_sqlcharts_axis_title($pid, 'x'); ?>
969 1067 beginAtZero: <?php echo (get_post_meta($pid, 'guaven_sqlcharts_begin_with_0_x', true) == 1) ? 'true':'false'; ?>
970 1068 },
971 1069 y: {
1070 + <?php echo guaven_sqlcharts_axis_title($pid, 'y'); ?>
972 1071 beginAtZero: <?php echo (get_post_meta($pid, 'guaven_sqlcharts_begin_with_0_y', true) == 1) ? 'true':'false'; ?>,
973 1072 ticks: {
974 1073 <?php if(get_post_meta($pid, 'guaven_sqlcharts_round_y_values', true) == 1) echo 'precision: 0,'; ?>
975 1074 }
@@ -976,9 +1075,9 @@
976 1075 }
977 1076 }
978 1077 <?php } ?>
979 1078 <?php
980 - guaven_sqlcharts_maybe_additional_parameters($pid);
1079 + guaven_sqlcharts_maybe_additional_parameters($pid, guaven_sqlcharts_time_axis_plugins($time_points));
981 1080 ?>
982 1081
983 1082 }
984 1083 });
@@ -1007,9 +1106,9 @@
1007 1106 //passing chartJS params via the shortcode
1008 1107 echo wp_kses($GLOBALS["guaven_sqlcharts_atts"]["params"],[]);
1009 1108 }
1010 1109 ?>
1011 - label: "<?php echo esc_attr(isset($ylabel[$key_ak])?$ylabel[$key_ak]:''); ?>",
1110 + label: <?php echo guaven_sqlcharts_js_label(isset($ylabel[$key_ak])?$ylabel[$key_ak]:''); ?>,
1012 1111 backgroundColor: <?php
1013 1112 echo wp_kses_post(guaven_sqlcharts_colorgenerator(1, 1, 0.2, guaven_sqlcharts_colors($i, $pid)));
1014 1113 ?>
1015 1114 borderColor: <?php
@@ -1027,13 +1126,16 @@
1027 1126 data: data,
1028 1127 options: {
1029 1128 responsive: true,
1030 1129 <?php echo wp_kses(guaven_sqlcharts_mar($pid),[]); ?>
1130 + <?php echo wp_kses(guaven_sqlcharts_value_labels($pid),[]); ?>
1031 1131 scales: {
1032 1132 x: {
1133 + <?php echo guaven_sqlcharts_axis_title($pid, 'x'); ?>
1033 1134 beginAtZero: <?php echo (get_post_meta($pid, 'guaven_sqlcharts_begin_with_0_x', true) == 1) ? 'true':'false'; ?>
1034 1135 },
1035 1136 y: {
1137 + <?php echo guaven_sqlcharts_axis_title($pid, 'y'); ?>
1036 1138 beginAtZero: <?php echo (get_post_meta($pid, 'guaven_sqlcharts_begin_with_0_y', true) == 1) ? 'true':'false'; ?>,
1037 1139 ticks: {
1038 1140 <?php if(get_post_meta($pid, 'guaven_sqlcharts_round_y_values', true) == 1) echo 'precision: 0,'; ?>
1039 1141 }
@@ -1047,9 +1149,9 @@
1047 1149 <?php
1048 1150 }
1049 1151
1050 1152
1051 -function guaven_sqlcharts_maybe_additional_parameters($pid){
1153 +function guaven_sqlcharts_maybe_additional_parameters($pid, $extra_plugins = ''){
1052 1154 if(function_exists('guaven_sqlcharts_maybe_additional_parameters_custom')){
1053 1155 wp_kses(guaven_sqlcharts_maybe_additional_parameters_custom($pid),[]);
1054 1156 return;
1055 1157 }
@@ -1059,9 +1161,9 @@
1059 1161 }
1060 1162 else {
1061 1163 $display='false';$position='top';
1062 1164 }
1063 - echo wp_kses( ",plugins: {legend: {display: ".$display.",position:'".$position."'}}",[]);
1165 + echo wp_kses( ",plugins: {legend: {display: ".$display.",position:'".$position."'}".($extra_plugins !== '' ? ','.$extra_plugins : '')."}",[]);
1064 1166 }
1065 1167
1066 1168
1067 1169
@@ -1069,9 +1171,9 @@
1069 1171 function guaven_sqlcharts_piedata($title, $labels, $values, $ylabel, $pid, $type = 'pie')
1070 1172 {
1071 1173 ?>
1072 1174 var options={
1073 - <?php if(get_post_meta($pid,'guaven_sqlcharts_forcetooltips',true)!='') echo 'showAllTooltips: true,'.PHP_EOL; ?>
1175 + <?php echo wp_kses(guaven_sqlcharts_value_labels($pid),[]); ?>
1074 1176 responsive: true
1075 1177 <?php echo get_post_meta($pid,'guaven_sqlcharts_chartheight',true)!=''||!empty($GLOBALS["guaven_sqlcharts_atts"]['height'])?',maintainAspectRatio: false':''; ?>
1076 1178 <?php
1077 1179 guaven_sqlcharts_maybe_additional_parameters($pid);