Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d4796b0
Add AI-powered chart creation and configuration assistant
vytisbulkevicius Mar 2, 2026
7e4ec2b
Fix PHPCS coding standards violations
vytisbulkevicius Mar 2, 2026
e822326
Fix PHPStan type errors and coding standards
vytisbulkevicius Mar 2, 2026
3916959
Fix PHPCS docblock spacing alignment
vytisbulkevicius Mar 2, 2026
a31a9a8
Fix AI features visibility and menu registration
vytisbulkevicius Mar 2, 2026
5bdad42
Fix AI feature UX issues in chart creation flow
vytisbulkevicius Mar 2, 2026
c173f76
Refine UX: center lock icon and force scroll to top
vytisbulkevicius Mar 2, 2026
7d7b35b
Fix scroll position and secure API key display
vytisbulkevicius Mar 2, 2026
4e52b89
Make API keys non-retrievable and fix scroll locking
vytisbulkevicius Mar 2, 2026
e901194
Fix scroll to top and restore masked API key display
vytisbulkevicius Mar 2, 2026
9c7161f
Fix API keys (remove button) and scroll (prevent checked radio autosc…
vytisbulkevicius Mar 2, 2026
20ff363
NUCLEAR FIX: Override scroll APIs to block WordPress auto-scroll
vytisbulkevicius Mar 2, 2026
85b6213
Fix layout shift - The REAL root cause (remove all scroll-blocking)
vytisbulkevicius Mar 2, 2026
9d67c67
Remove inline scroll script - IT was causing the modal jump
vytisbulkevicius Mar 2, 2026
94733a7
Improve AI vision prompt for accurate chart recognition and data extr…
vytisbulkevicius Mar 2, 2026
fdec9e7
Make AI image upload section border consistent when locked
vytisbulkevicius Mar 2, 2026
e44b1cd
Remove WP_Post type hint for compatibility with development branch
vytisbulkevicius Mar 4, 2026
17f93a9
Add capability check to renderChartPages for security
vytisbulkevicius Mar 4, 2026
6cf58f2
Trigger fresh build with cleared cache
vytisbulkevicius Mar 4, 2026
3eab534
Revert type hint to match pre-security PR state
vytisbulkevicius Mar 4, 2026
8005bfa
Add explicit comment for nonce creation without action parameter
vytisbulkevicius Mar 4, 2026
212c69c
Merge development branch with security fixes
vytisbulkevicius Mar 4, 2026
e0f4658
Restore ChartJS support and API key management features
vytisbulkevicius Mar 4, 2026
1c8f527
Fix API key notifications and ChartJS detection
vytisbulkevicius Mar 4, 2026
bfe80e8
Add debug logging for ChartJS detection and remove preview logic
vytisbulkevicius Mar 4, 2026
fa361ec
Fix $typeVsLibrary undefined error and add extensive AI logging
vytisbulkevicius Mar 4, 2026
18a8456
Add detailed logging for system prompt generation
vytisbulkevicius Mar 4, 2026
5e5e522
Add comprehensive debugging for chart_library issue
vytisbulkevicius Mar 4, 2026
0580582
Fix ChartJS library detection and remove debug logging
vytisbulkevicius Mar 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,770 changes: 1,770 additions & 0 deletions classes/Visualizer/Module/AI.php

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions classes/Visualizer/Module/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,16 @@ public function registerAdminMenu() {
'admin.php?page=' . Visualizer_Plugin::NAME . '&vaction=addnew'
);

// Add AI Settings submenu
add_submenu_page(
Visualizer_Plugin::NAME,
__( 'AI Settings', 'visualizer' ),
__( 'AI Settings', 'visualizer' ),
'edit_posts',
'visualizer-ai-settings',
array( $this, 'renderAISettingsPage' )
);

$this->_supportPage = add_submenu_page(
Visualizer_Plugin::NAME,
__( 'Support', 'visualizer' ),
Expand Down Expand Up @@ -969,6 +979,19 @@ public function renderSupportPage() {
include_once VISUALIZER_ABSPATH . '/templates/support.php';
}

/**
* Renders AI Settings page.
*
* @since 3.12.0
*
* @access public
* @return void
*/
public function renderAISettingsPage() {
$render = new Visualizer_Render_Page_AISettings();
$render->render();
}

/**
* Renders visualizer library page.
*
Expand Down
61 changes: 57 additions & 4 deletions classes/Visualizer/Module/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ public function getCharts() {
*
* @access private
*
* @param WP_Post|null $chart The chart object.
* @param WP_Post $chart The chart object.
*
* @return array The array of chart data.
*/
Expand Down Expand Up @@ -638,6 +638,9 @@ public function renderChartPages() {

wp_register_style( 'visualizer-frame', VISUALIZER_ABSURL . 'css/frame.css', array( 'visualizer-chosen' ), Visualizer_Plugin::VERSION );
wp_register_script( 'visualizer-frame', VISUALIZER_ABSURL . 'js/frame.js', array( 'visualizer-chosen', 'jquery-ui-accordion', 'jquery-ui-tabs' ), Visualizer_Plugin::VERSION, true );
wp_register_script( 'visualizer-ai-config', VISUALIZER_ABSURL . 'js/ai-config.js', array( 'jquery', 'visualizer-frame' ), Visualizer_Plugin::VERSION, true );
wp_register_script( 'visualizer-ai-chart-from-image', VISUALIZER_ABSURL . 'js/ai-chart-from-image.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
wp_register_script( 'visualizer-ai-chart-data-populate', VISUALIZER_ABSURL . 'js/ai-chart-data-populate.js', array( 'jquery' ), Visualizer_Plugin::VERSION, true );
wp_register_script( 'visualizer-customization', $this->get_user_customization_js(), array(), null, true );
wp_register_script(
'visualizer-render',
Expand Down Expand Up @@ -853,6 +856,8 @@ private function _handleDataAndSettingsPage() {
wp_enqueue_script( 'visualizer-preview' );
wp_enqueue_script( 'visualizer-chosen' );
wp_enqueue_script( 'visualizer-render' );
wp_enqueue_script( 'visualizer-ai-config' );
wp_enqueue_script( 'visualizer-ai-chart-data-populate' );

if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
wp_enqueue_script( 'visualizer-editor-simple' );
Expand Down Expand Up @@ -920,6 +925,17 @@ private function _handleDataAndSettingsPage() {
)
);

wp_localize_script(
'visualizer-ai-config',
'visualizerAI',
array(
'nonce' => wp_create_nonce( 'visualizer-ai-generate' ),
'chart_type' => $data['type'],
'chart_library' => isset( $data['library'] ) && ! empty( $data['library'] ) ? $data['library'] : 'Google Charts',
'ajaxurl' => admin_url( 'admin-ajax.php' ),
)
);

$render = new Visualizer_Render_Page_Data();
$render->chart = $this->_chart;
$render->type = $data['type'];
Expand Down Expand Up @@ -961,7 +977,14 @@ private function _handleTypesPage() {
if ( Visualizer_Module_Admin::checkChartStatus( $type ) ) {
if ( empty( $library ) ) {
// library cannot be empty.
error_log( 'Visualizer: Library is empty! Available POST data: ' . print_r( $_POST, true ) );
do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, 'Chart library empty while creating the chart! Aborting...', 'error', __FILE__, __LINE__ );
// Show error message instead of blank screen
echo '<div style="padding: 20px; color: red;">';
echo '<h2>Error: Chart Library Not Selected</h2>';
echo '<p>Please select a chart library and try again.</p>';
echo '<p><a href="javascript:history.back()">Go Back</a></p>';
echo '</div>';
return;
}

Expand All @@ -980,9 +1003,15 @@ private function _handleTypesPage() {
Visualizer_Module_Utility::set_defaults( $this->_chart );

// redirect to next tab
// changed by Ash/Upwork
wp_redirect( esc_url_raw( add_query_arg( 'tab', 'settings' ) ) );

$redirect_url = esc_url_raw( add_query_arg( 'tab', 'settings' ) );
wp_redirect( $redirect_url );
exit;
} else {
echo '<div style="padding: 20px; color: red;">';
echo '<h2>Error: Invalid Chart Type</h2>';
echo '<p>The selected chart type is not available.</p>';
echo '<p><a href="javascript:history.back()">Go Back</a></p>';
echo '</div>';
return;
}
}
Expand All @@ -992,6 +1021,27 @@ private function _handleTypesPage() {
$render->chart = $this->_chart;
wp_enqueue_style( 'visualizer-frame' );
wp_enqueue_script( 'visualizer-frame' );
wp_enqueue_script( 'visualizer-ai-chart-from-image' );

// Localize script for AI image analysis
$has_openai = ! empty( get_option( 'visualizer_openai_api_key', '' ) );
$has_gemini = ! empty( get_option( 'visualizer_gemini_api_key', '' ) );
$has_claude = ! empty( get_option( 'visualizer_claude_api_key', '' ) );

wp_localize_script(
'visualizer-ai-chart-from-image',
'visualizerAI',
array(
'nonce_image' => wp_create_nonce( 'visualizer-ai-image' ),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'has_openai' => $has_openai,
'has_gemini' => $has_gemini,
'has_claude' => $has_claude,
'chart_types' => Visualizer_Module_Admin::_getChartTypesLocalized( false, false, false, 'types' ),
'pro_url' => tsdk_utmify( Visualizer_Plugin::PRO_TEASER_URL, 'aichartimage', 'chartfromimage' ),
)
);

wp_iframe( array( $render, 'render' ) );
}

Expand Down Expand Up @@ -1136,6 +1186,9 @@ private function handleTabularData() {
* @access public
*/
public function uploadData() {
// Prevent any PHP warnings/errors from contaminating the response
ini_set( 'display_errors', '0' );

// if this is being called internally from pro and VISUALIZER_DO_NOT_DIE is set.
// otherwise, assume this is a normal web request.
$can_die = ! ( defined( 'VISUALIZER_DO_NOT_DIE' ) && VISUALIZER_DO_NOT_DIE );
Expand Down
Loading
Loading