| 1 |
<?php |
| 2 |
/** |
| 3 |
* Ability: wpdatatables/get-chart-info |
| 4 |
* |
| 5 |
* Returns the full configuration of a single wpDataTables chart by ID, |
| 6 |
* including chart engine, type, linked table, selected columns, series, |
| 7 |
* display options, and layout properties. |
| 8 |
* |
| 9 |
* Uses WPDataChart::getChartDataById() to stay in sync with the parent plugin. |
| 10 |
* |
| 11 |
* @package wpDataTables_MCP_Server |
| 12 |
*/ |
| 13 |
|
| 14 |
defined( 'ABSPATH' ) or die('Access denied.'); |
| 15 |
|
| 16 |
add_action( 'wp_abilities_api_init', 'wdtmcp_register_get_chart_info_ability' ); |
| 17 |
|
| 18 |
function wdtmcp_register_get_chart_info_ability() { |
| 19 |
wp_register_ability( |
| 20 |
'wpdatatables/get-chart-info', |
| 21 |
array( |
| 22 |
'label' => __( 'Get wpDataChart Info', 'wpdatatables' ), |
| 23 |
'description' => __( 'Returns the full configuration of a single wpDataTables chart by ID, including its rendering engine, chart type, linked source table, selected columns, series configuration, axis labels, dimensions, and display flags. Use this after list-charts to understand a chart\'s structure. WHEN TO CALL: when you need details about an existing chart — which table it uses, which columns are plotted, engine (google, chartjs, highcharts, apexcharts), type (line, pie, column, etc.), or layout settings. REQUIRED INPUT: chart_id (integer) from list-charts. RETURNS: id, title, engine, type, wpdatatable_id, selected_columns, range_type, dimensions, axes, series, and display flags. TYPICAL WORKFLOW: list-charts → get-chart-info. To see the underlying data, also call get-table-info / get-table-data using wpdatatable_id from the response.', 'wpdatatables' ), |
| 24 |
'category' => 'wpdatatables-data', |
| 25 |
|
| 26 |
'input_schema' => array( |
| 27 |
'type' => 'object', |
| 28 |
'properties' => array( |
| 29 |
'chart_id' => array( |
| 30 |
'type' => 'integer', |
| 31 |
'description' => 'The unique chart ID (as returned by list-charts).', |
| 32 |
), |
| 33 |
), |
| 34 |
'required' => array( 'chart_id' ), |
| 35 |
), |
| 36 |
|
| 37 |
'output_schema' => array( |
| 38 |
'type' => 'object', |
| 39 |
'properties' => array( |
| 40 |
'id' => array( 'type' => 'integer', 'description' => 'Chart ID.' ), |
| 41 |
'title' => array( 'type' => 'string', 'description' => 'Chart title.' ), |
| 42 |
'engine' => array( 'type' => 'string', 'description' => 'Rendering engine (google, chartjs, highcharts, apexcharts).' ), |
| 43 |
'type' => array( 'type' => 'string', 'description' => 'Chart type (line, area, column, bar, pie, scatter, bubble, etc.).' ), |
| 44 |
'wpdatatable_id' => array( 'type' => 'integer', 'description' => 'ID of the source wpDataTable this chart visualises.' ), |
| 45 |
'selected_columns' => array( |
| 46 |
'type' => 'array', |
| 47 |
'description' => 'Column original headers selected for this chart.', |
| 48 |
'items' => array( 'type' => 'string' ), |
| 49 |
), |
| 50 |
'range_type' => array( 'type' => 'string', 'description' => 'Row range type: all, pick_rows, range.' ), |
| 51 |
'row_range' => array( |
| 52 |
'type' => 'array', |
| 53 |
'description' => 'Row range boundaries (varies by range_type).', |
| 54 |
'items' => array( 'type' => 'integer' ), |
| 55 |
), |
| 56 |
'follow_filtering' => array( 'type' => 'boolean', 'description' => 'Whether the chart reacts to table front-end filters.' ), |
| 57 |
'group_chart' => array( 'type' => 'boolean', 'description' => 'Whether data grouping is enabled.' ), |
| 58 |
'series_type' => array( 'type' => 'string', 'description' => 'Series type (empty for default, or combo type name).' ), |
| 59 |
'show_title' => array( 'type' => 'boolean', 'description' => 'Whether the chart title is displayed.' ), |
| 60 |
'show_grid' => array( 'type' => 'boolean', 'description' => 'Whether grid lines are shown.' ), |
| 61 |
'tooltip_enabled' => array( 'type' => 'boolean', 'description' => 'Whether tooltips are enabled.' ), |
| 62 |
'responsive_width' => array( 'type' => 'boolean', 'description' => 'Whether the chart uses responsive width.' ), |
| 63 |
'width' => array( 'type' => 'integer', 'description' => 'Chart width in pixels.' ), |
| 64 |
'height' => array( 'type' => 'integer', 'description' => 'Chart height in pixels.' ), |
| 65 |
'background_color' => array( 'type' => 'string', 'description' => 'Chart background colour (hex).' ), |
| 66 |
'axes' => array( |
| 67 |
'type' => 'object', |
| 68 |
'description' => 'Axis label configuration.', |
| 69 |
'properties' => array( |
| 70 |
'major_label' => array( 'type' => 'string', 'description' => 'Major (X / horizontal) axis label.' ), |
| 71 |
'minor_label' => array( 'type' => 'string', 'description' => 'Minor (Y / vertical) axis label.' ), |
| 72 |
), |
| 73 |
), |
| 74 |
'series' => array( |
| 75 |
'type' => 'array', |
| 76 |
'description' => 'Per-series customisation (colours, labels, types).', |
| 77 |
'items' => array( |
| 78 |
'type' => 'object', |
| 79 |
'properties' => array( |
| 80 |
'color' => array( 'type' => 'string', 'description' => 'Series colour.' ), |
| 81 |
'label' => array( 'type' => 'string', 'description' => 'Series label override.' ), |
| 82 |
'type' => array( 'type' => 'string', 'description' => 'Series chart sub-type (for combo charts).' ), |
| 83 |
), |
| 84 |
), |
| 85 |
), |
| 86 |
), |
| 87 |
), |
| 88 |
|
| 89 |
'execute_callback' => 'wdtmcp_execute_get_chart_info', |
| 90 |
|
| 91 |
'permission_callback' => function () { |
| 92 |
return current_user_can( 'manage_options' ); |
| 93 |
}, |
| 94 |
|
| 95 |
'meta' => array( |
| 96 |
'annotations' => array( |
| 97 |
'instructions' => __( 'Requires chart_id from list-charts. Use wpdatatable_id from the response to inspect the linked source table.', 'wpdatatables' ), |
| 98 |
'readonly' => true, |
| 99 |
'destructive' => false, |
| 100 |
'idempotent' => true, |
| 101 |
), |
| 102 |
), |
| 103 |
) |
| 104 |
); |
| 105 |
} |
| 106 |
|
| 107 |
/** |
| 108 |
* Execute callback for wpdatatables/get-chart-info. |
| 109 |
* |
| 110 |
* @param array $input { chart_id: int } |
| 111 |
* @return array|WP_Error |
| 112 |
*/ |
| 113 |
function wdtmcp_execute_get_chart_info( $input ) { |
| 114 |
$chart_id = isset( $input['chart_id'] ) ? (int) $input['chart_id'] : 0; |
| 115 |
|
| 116 |
if ( $chart_id <= 0 ) { |
| 117 |
return new \WP_Error( |
| 118 |
'wdtmcp_invalid_input', |
| 119 |
__( 'A valid chart_id (positive integer) is required.', 'wpdatatables' ) |
| 120 |
); |
| 121 |
} |
| 122 |
|
| 123 |
if ( ! class_exists( 'WPDataChart' ) ) { |
| 124 |
return new \WP_Error( |
| 125 |
'wdtmcp_missing_class', |
| 126 |
__( 'wpDataTables core class WPDataChart is not available.', 'wpdatatables' ) |
| 127 |
); |
| 128 |
} |
| 129 |
|
| 130 |
$chart_data = \WPDataChart::getChartDataById( $chart_id ); |
| 131 |
|
| 132 |
if ( empty( $chart_data ) ) { |
| 133 |
return new \WP_Error( |
| 134 |
'wdtmcp_not_found', |
| 135 |
sprintf( __( 'Chart with ID %d was not found.', 'wpdatatables' ), $chart_id ) |
| 136 |
); |
| 137 |
} |
| 138 |
|
| 139 |
$render = array(); |
| 140 |
if ( ! empty( $chart_data->json_render_data ) ) { |
| 141 |
$decoded = json_decode( $chart_data->json_render_data, true ); |
| 142 |
if ( is_array( $decoded ) ) { |
| 143 |
$render = $decoded; |
| 144 |
} |
| 145 |
} |
| 146 |
|
| 147 |
$options = isset( $render['render_data']['options'] ) ? $render['render_data']['options'] : array(); |
| 148 |
|
| 149 |
$selected_columns = array(); |
| 150 |
if ( ! empty( $render['selected_columns'] ) && is_array( $render['selected_columns'] ) ) { |
| 151 |
$selected_columns = array_values( array_map( 'strval', $render['selected_columns'] ) ); |
| 152 |
} |
| 153 |
|
| 154 |
$row_range = array(); |
| 155 |
if ( ! empty( $render['row_range'] ) && is_array( $render['row_range'] ) ) { |
| 156 |
$row_range = array_values( array_map( 'intval', $render['row_range'] ) ); |
| 157 |
} |
| 158 |
|
| 159 |
$series = array(); |
| 160 |
if ( ! empty( $options['series'] ) && is_array( $options['series'] ) ) { |
| 161 |
foreach ( $options['series'] as $s ) { |
| 162 |
$series[] = array( |
| 163 |
'color' => isset( $s['color'] ) ? (string) $s['color'] : '', |
| 164 |
'label' => isset( $s['label'] ) ? (string) $s['label'] : '', |
| 165 |
'type' => isset( $s['type'] ) ? (string) $s['type'] : '', |
| 166 |
); |
| 167 |
} |
| 168 |
} |
| 169 |
|
| 170 |
$width = isset( $options['width'] ) ? (int) $options['width'] : 400; |
| 171 |
$height = isset( $options['height'] ) ? (int) $options['height'] : 400; |
| 172 |
|
| 173 |
$responsive_width = false; |
| 174 |
if ( isset( $options['responsive_width'] ) ) { |
| 175 |
$responsive_width = (bool) $options['responsive_width']; |
| 176 |
} |
| 177 |
|
| 178 |
$background_color = '#FFFFFF'; |
| 179 |
if ( ! empty( $options['backgroundColor'] ) ) { |
| 180 |
$background_color = (string) $options['backgroundColor']; |
| 181 |
} |
| 182 |
|
| 183 |
$tooltip_enabled = true; |
| 184 |
if ( isset( $options['tooltip_enabled'] ) ) { |
| 185 |
$tooltip_enabled = (bool) $options['tooltip_enabled']; |
| 186 |
} |
| 187 |
|
| 188 |
$major_label = ''; |
| 189 |
$minor_label = ''; |
| 190 |
if ( ! empty( $options['hAxis']['title'] ) ) { |
| 191 |
$major_label = (string) $options['hAxis']['title']; |
| 192 |
} |
| 193 |
if ( ! empty( $options['vAxis']['title'] ) ) { |
| 194 |
$minor_label = (string) $options['vAxis']['title']; |
| 195 |
} |
| 196 |
|
| 197 |
return array( |
| 198 |
'id' => (int) $chart_data->id, |
| 199 |
'title' => (string) $chart_data->title, |
| 200 |
'engine' => isset( $chart_data->engine ) ? (string) $chart_data->engine : '', |
| 201 |
'type' => isset( $chart_data->type ) ? (string) $chart_data->type : '', |
| 202 |
'wpdatatable_id' => isset( $chart_data->wpdatatable_id ) ? (int) $chart_data->wpdatatable_id : 0, |
| 203 |
'selected_columns' => $selected_columns, |
| 204 |
'range_type' => isset( $render['range_type'] ) ? (string) $render['range_type'] : 'all', |
| 205 |
'row_range' => $row_range, |
| 206 |
'follow_filtering' => ! empty( $render['follow_filtering'] ), |
| 207 |
'group_chart' => ! empty( $options['group_chart'] ), |
| 208 |
'series_type' => isset( $render['series_type'] ) ? (string) $render['series_type'] : '', |
| 209 |
'show_title' => ! empty( $render['show_title'] ), |
| 210 |
'show_grid' => ! empty( $render['show_grid'] ), |
| 211 |
'tooltip_enabled' => $tooltip_enabled, |
| 212 |
'responsive_width' => $responsive_width, |
| 213 |
'width' => $width, |
| 214 |
'height' => $height, |
| 215 |
'background_color' => $background_color, |
| 216 |
'axes' => array( |
| 217 |
'major_label' => $major_label, |
| 218 |
'minor_label' => $minor_label, |
| 219 |
), |
| 220 |
'series' => $series, |
| 221 |
); |
| 222 |
} |
| 223 |
|