\(\)])\s*/', '$1', $css);
// Final trims and unnecessary semicolons
$css = str_replace(';}', '}', $css);
return trim($css);
}
// Build or fetch a combined CSS file for plugin assets/css/*.css
function aibui_get_combined_css_url()
{
$css_dir = plugin_dir_path(__FILE__) . 'assets/css/';
$css_url_base = plugin_dir_url(__FILE__) . 'assets/css/';
// If directory missing, bail to original behavior
if (!is_dir($css_dir)) return '';
$files = glob($css_dir . '*.css');
if (!$files) return '';
// Compute a hash based on file mtimes and paths to invalidate cache when any source changes
$sig_parts = [];
foreach ($files as $path) {
$sig_parts[] = basename($path) . ':' . filemtime($path);
}
$signature = md5(implode('|', $sig_parts));
// Store in uploads to keep plugin dir clean and writable
$uploads = wp_upload_dir();
if (!empty($uploads['error'])) {
return '';
}
$cache_dir = rtrim($uploads['basedir'], '/').'/ai-builder-cache';
$cache_url = rtrim($uploads['baseurl'], '/').'/ai-builder-cache';
if (!is_dir($cache_dir)) {
wp_mkdir_p($cache_dir);
}
$combined_filename = 'combined-'.$signature.'.css';
$combined_path = $cache_dir.'/'.$combined_filename;
$combined_url = $cache_url.'/'.$combined_filename;
if (!file_exists($combined_path)) {
$buffer = '';
// Keep a stable order: alphabetical by filename
sort($files, SORT_STRING);
foreach ($files as $path) {
// Skip admin-only stylesheet to avoid leaking to frontend bundle
if (basename($path) === 'style-admin.css') continue;
$content = file_get_contents($path);
if ($content === false) continue;
$buffer .= "\n/* ".basename($path)." */\n".$content;
}
$minified = aibui_minify_css($buffer);
// Graceful write
if (is_writable($cache_dir)) {
file_put_contents($combined_path, $minified);
} else {
return '';
}
}
return $combined_url;
}
// Simple JS minifier (very conservative)
function aibui_minify_js($js)
{
if (!is_string($js) || $js === '') return '';
// Remove block comments but keep /*! license comments */
$js = preg_replace('#/(?!\!)(\*[^*]*\*+(?:[^/*][^*]*\*+)*/)#', '', $js);
// Remove line comments
$js = preg_replace('#(^|\s)//.*$#m', '$1', $js);
// Collapse whitespace
$js = preg_replace('/\s+/', ' ', $js);
return trim($js);
}
// Build a combined frontend JS bundle from selected plugin scripts
function aibui_get_combined_js_url()
{
$js_list = array(
'assets/js/carousel-frontend.js',
'assets/js/map-frontend.js',
'assets/js/tabs-frontend.js',
'assets/js/table-frontend.js',
'assets/js/stats-tooltips.js',
'assets/js/snackbar-frontend.js',
);
$sig_parts = array();
$contents = '';
foreach ($js_list as $rel) {
$path = plugin_dir_path(__FILE__) . $rel;
if (!file_exists($path)) continue;
$sig_parts[] = $rel . ':' . filemtime($path);
}
if (empty($sig_parts)) return '';
$signature = md5(implode('|', $sig_parts));
$uploads = wp_upload_dir();
if (!empty($uploads['error'])) {
return '';
}
$cache_dir = rtrim($uploads['basedir'], '/').'/ai-builder-cache';
$cache_url = rtrim($uploads['baseurl'], '/').'/ai-builder-cache';
if (!is_dir($cache_dir)) {
wp_mkdir_p($cache_dir);
}
$combined_filename = 'frontend-'.$signature.'.js';
$combined_path = $cache_dir.'/'.$combined_filename;
$combined_url = $cache_url.'/'.$combined_filename;
if (!file_exists($combined_path)) {
$buffer = '';
foreach ($js_list as $rel) {
$path = plugin_dir_path(__FILE__) . $rel;
if (!file_exists($path)) continue;
$content = file_get_contents($path);
if ($content === false) continue;
$buffer .= "\n/* ".$rel." */\n".$content."\n";
}
$minified = aibui_minify_js($buffer);
if (is_writable($cache_dir)) {
file_put_contents($combined_path, $minified);
} else {
return '';
}
}
return $combined_url;
}
/**
* Check if global AI personalization settings are still empty.
*
* We query the remote settings API (same as the Settings page) and consider the
* configuration "empty" when all settings (primaryColor, secondaryColor, siteName,
* siteDescription, designStyle, blockShapes, copywritingTone) are missing/empty.
*/
function aibui_are_personalization_settings_empty()
{
// Require an authenticated session with the cloud API.
$jwt_token = get_option('aibui_jwt_token', '');
if (empty($jwt_token)) {
return false;
}
$api_url = 'https://api.wordpress-ai-builder.com/api/settings';
$response = wp_remote_get($api_url, array(
'timeout' => 15,
'headers' => array(
'Authorization' => 'Bearer ' . $jwt_token,
'Content-Type' => 'application/json',
),
));
if (is_wp_error($response)) {
return false;
}
$code = wp_remote_retrieve_response_code($response);
if ($code !== 200) {
return false;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (!is_array($data)) {
return false;
}
$primaryColor = isset($data['primaryColor']) ? trim((string) $data['primaryColor']) : '';
$secondaryColor = isset($data['secondaryColor']) ? trim((string) $data['secondaryColor']) : '';
$siteName = isset($data['siteName']) ? trim((string) $data['siteName']) : '';
$siteDescription = isset($data['siteDescription']) ? trim((string) $data['siteDescription']) : '';
$designStyle = isset($data['designStyle']) ? trim((string) $data['designStyle']) : '';
$blockShapes = isset($data['blockShapes']) ? trim((string) $data['blockShapes']) : '';
$copywritingTone = isset($data['copywritingTone']) ? trim((string) $data['copywritingTone']) : '';
return ($primaryColor === '' && $secondaryColor === '' && $siteName === '' && $siteDescription === '' && $designStyle === '' && $blockShapes === '' && $copywritingTone === '');
}
/**
* Display a subtle onboarding banner on key AI Builder pages when
* personalization settings are still empty.
*/
function aibui_personalization_notice()
{
if (!is_admin() || !current_user_can('manage_options')) {
return;
}
$page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
$target_pages = array(
'aibui-assistant', // Account (main dashboard)
'aibui-credits', // Credits
'aibui-tuto', // Tutorial
'aibui-multi-page', // Multi Page Generator
'aibui-translation-settings', // Translations
);
if (!in_array($page, $target_pages, true)) {
return;
}
if (!aibui_are_personalization_settings_empty()) {
return;
}
$settings_url = admin_url('admin.php?page=aibui-settings');
?>
Make AI Builder more personal for your site.
Configure your site preferences in AI Builder Settings for better, more personalized results.
admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
// Flag to hint we are on the Site Editor (patterns/template parts)
'isPatternEditor' => ($hook === 'site-editor.php'),
)
);
// Enqueue Multi-Page apply script to support applying generations via URL param
wp_enqueue_script(
'ai-builder-multi-page-apply',
plugin_dir_url(__FILE__) . 'assets/js/multi-page-apply.js',
['ai-builder-config', 'chat-widget', 'wp-blocks', 'wp-data', 'wp-editor', 'wp-block-editor', 'wp-element'],
AIBUI_VERSION,
true
);
wp_localize_script(
'ai-builder-multi-page-apply',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
)
);
}
// Charger les styles et scripts pour la page account du plugin AI Builder
$current_screen = get_current_screen();
if ($current_screen && strpos($current_screen->id, 'aibui-assistant') !== false) {
wp_enqueue_style(
'ai-builder-account-style',
plugin_dir_url(__FILE__) . 'assets/css/account.css',
[],
filemtime(plugin_dir_path(__FILE__) . 'assets/css/account.css')
);
wp_enqueue_script(
'ai-builder-config',
plugin_dir_url(__FILE__) . 'config.js',
[],
AIBUI_VERSION,
true
);
wp_enqueue_script(
'ai-builder-account',
plugin_dir_url(__FILE__) . 'assets/js/account.js',
['ai-builder-config'],
AIBUI_VERSION,
true
);
// Injection des variables JS pour AJAX et le nonce
wp_localize_script(
'ai-builder-account',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
'accountUrl' => admin_url('admin.php?page=aibui-account'),
'siteDomain' => parse_url(home_url(), PHP_URL_HOST),
)
);
} else if ($current_screen && strpos($current_screen->id, 'aibui-credits') !== false) {
wp_enqueue_script(
'ai-builder-credits',
plugin_dir_url(__FILE__) . 'assets/js/credits.js',
['ai-builder-config'],
AIBUI_VERSION,
true
);
// Injection des variables JS pour AJAX et le nonce
wp_localize_script(
'ai-builder-credits',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
)
);
wp_enqueue_style(
'ai-builder-credits-additional-style',
plugin_dir_url(__FILE__) . 'assets/css/credits-additional.css',
[],
AIBUI_VERSION
);
wp_enqueue_style(
'ai-builder-credits-style',
plugin_dir_url(__FILE__) . 'assets/css/credits.css',
[],
AIBUI_VERSION
);
wp_enqueue_script(
'ai-builder-config',
plugin_dir_url(__FILE__) . 'config.js',
[],
AIBUI_VERSION,
true
);
} else if ($current_screen && strpos($current_screen->id, 'aibui-settings') !== false) {
wp_enqueue_style(
'ai-builder-settings-style',
plugin_dir_url(__FILE__) . 'assets/css/settings.css',
[],
AIBUI_VERSION
);
wp_enqueue_script(
'ai-builder-config',
plugin_dir_url(__FILE__) . 'config.js',
[],
AIBUI_VERSION,
true
);
wp_enqueue_script(
'ai-builder-settings',
plugin_dir_url(__FILE__) . 'assets/js/settings.js',
['ai-builder-config'],
AIBUI_VERSION,
true
);
// Injection des variables JS pour AJAX et le nonce
wp_localize_script(
'ai-builder-settings',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
)
);
} else if ($current_screen && strpos($current_screen->id, 'aibui-reset-password') !== false) {
wp_enqueue_style(
'ai-builder-reset-password-style',
plugin_dir_url(__FILE__) . 'assets/css/reset-password.css',
[],
AIBUI_VERSION
);
wp_enqueue_script(
'ai-builder-config',
plugin_dir_url(__FILE__) . 'config.js',
[],
AIBUI_VERSION,
true
);
wp_enqueue_script(
'ai-builder-reset-password',
plugin_dir_url(__FILE__) . 'assets/js/reset-password.js',
['ai-builder-config'],
AIBUI_VERSION,
true
);
// Injection des variables JS pour AJAX et le nonce
wp_localize_script(
'ai-builder-reset-password',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
'accountUrl' => admin_url('admin.php?page=aibui-account'),
)
);
} else if ($current_screen && strpos($current_screen->id, 'aibui-tuto') !== false) {
wp_enqueue_style(
'ai-builder-tutorial-style',
plugin_dir_url(__FILE__) . 'assets/css/tutorial.css',
[],
AIBUI_VERSION
);
wp_enqueue_script(
'ai-builder-config',
plugin_dir_url(__FILE__) . 'config.js',
[],
AIBUI_VERSION,
true
);
} else if ($current_screen && strpos($current_screen->id, 'aibui-multi-page') !== false) {
wp_enqueue_style(
'ai-builder-multi-page-style',
plugin_dir_url(__FILE__) . 'assets/css/multi-page.css',
[],
AIBUI_VERSION
);
wp_enqueue_script(
'ai-builder-config',
plugin_dir_url(__FILE__) . 'config.js',
[],
AIBUI_VERSION,
true
);
wp_enqueue_script(
'ai-builder-multi-page',
plugin_dir_url(__FILE__) . 'assets/js/multi-page.js',
['ai-builder-config'],
AIBUI_VERSION,
true
);
// Injection des variables JS pour AJAX et le nonce
wp_localize_script(
'ai-builder-multi-page',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
'adminBaseUrl' => admin_url(),
)
);
} else if ($current_screen && strpos($current_screen->id, 'aibui-agent-chat') !== false) {
// Agent Chat page scripts and styles
wp_enqueue_script(
'ai-builder-config',
plugin_dir_url(__FILE__) . 'config.js',
[],
AIBUI_VERSION,
true
);
wp_enqueue_script(
'ai-builder-agent-chat',
plugin_dir_url(__FILE__) . 'assets/js/agent-chat.js',
['ai-builder-config'],
AIBUI_VERSION,
true
);
// Localize with nonce - IMPORTANT: use a different nonce for agent actions
wp_localize_script(
'ai-builder-agent-chat',
'aibuiAgentVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_agent_nonce'),
'restBase' => esc_url_raw(rest_url()),
'wpRestDocsBase' => 'https://developer.wordpress.org/rest-api/reference/',
)
);
// Also expose standard AJAX nonce for shared endpoints like aibui_get_token
wp_localize_script(
'ai-builder-agent-chat',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
)
);
}
});
add_action('wp_enqueue_scripts', function () {
// Single combined frontend CSS
$combined_css = aibui_get_combined_css_url();
if ($combined_css) {
wp_enqueue_style(
'ai-builder-combined',
$combined_css,
[],
null
);
} else {
// Fallback: enqueue at least the essential stylesheet
wp_enqueue_style(
'aibui-force-alignfull',
plugin_dir_url(__FILE__) . 'assets/css/force-align-full.css',
[],
AIBUI_VERSION
);
}
// Charger les styles CSS du bloc AI Image côté frontend
wp_enqueue_style(
'ai-builder-ai-image-frontend',
plugin_dir_url(__FILE__) . 'assets/js/build/index.css',
[],
filemtime(plugin_dir_path(__FILE__) . 'assets/js/build/index.css')
);
// Frontend JS single bundle
$combined_js = aibui_get_combined_js_url();
if ($combined_js) {
wp_enqueue_script(
'ai-builder-frontend-bundle',
$combined_js,
[],
null,
true
);
} else {
// Fallback: at least enqueue carousel script if bundling failed
wp_enqueue_script(
'ai-builder-carousel-frontend',
plugin_dir_url(__FILE__) . 'assets/js/carousel-frontend.js',
[],
AIBUI_VERSION,
true
);
}
// Load fixed background group block CSS for frontend
wp_enqueue_style(
'ai-builder-fixed-bg-group-frontend',
plugin_dir_url(__FILE__) . 'assets/js/src/editor-blocks/fixed-bg-group/style.css',
[],
AIBUI_VERSION
);
// CSS above is covered by the combined bundle
// Other JS are included in the combined bundle above
// CSS above is covered by the combined bundle
// Included in combined bundle
// CSS above is covered by the combined bundle
// Included in combined bundle
});
// Enqueue contact form script only when the block is present
add_action('wp_enqueue_scripts', function () {
global $post;
$should_load = false;
// Check if current post has the block
if (is_a($post, 'WP_Post') && has_block('ai-builder/aibui-contact-form', $post)) {
$should_load = true;
}
// Fallback: check if we're on a page that might have the block
if (!$should_load && (is_page() || is_single() || is_home() || is_front_page())) {
$should_load = true;
}
if ($should_load) {
wp_enqueue_script(
'ai-builder-contact-form',
plugin_dir_url(__FILE__) . 'assets/js/contact-form.js',
[],
AIBUI_VERSION,
true
);
}
});
add_action('enqueue_block_editor_assets', function () {
// Single combined CSS for editor
$combined_css = aibui_get_combined_css_url();
if ($combined_css) {
wp_enqueue_style(
'ai-builder-combined-editor',
$combined_css,
[],
null
);
} else {
wp_enqueue_style(
'aibui-force-alignfull-editor',
plugin_dir_url(__FILE__) . 'assets/css/force-align-full.css',
[],
AIBUI_VERSION
);
}
// Charger les styles build des blocs dans l'éditeur
wp_enqueue_style(
'ai-builder-blocks-editor-build',
plugin_dir_url(__FILE__) . 'assets/js/build/index.css',
[],
filemtime(plugin_dir_path(__FILE__) . 'assets/js/build/index.css')
);
// Styles spécifiques d'aperçu du formulaire de contact
wp_enqueue_style(
'ai-builder-contact-form-editor',
plugin_dir_url(__FILE__) . 'assets/css/contact-form-editor.css',
[],
AIBUI_VERSION
);
// Covered by combined bundle
// Stats tooltips in editor preview
wp_enqueue_script(
'ai-builder-stats-tooltips-editor',
plugin_dir_url(__FILE__) . 'assets/js/stats-tooltips.js',
[],
AIBUI_VERSION,
true
);
});
add_action('enqueue_block_editor_assets', function () {
wp_enqueue_script(
'ai-builder-blocks',
plugin_dir_url(__FILE__) . 'assets/js/build/index.js',
[
'wp-blocks',
'wp-block-editor',
'wp-element',
'wp-components',
'wp-i18n',
'wp-api-fetch',
'wp-hooks'
],
filemtime(plugin_dir_path(__FILE__) . 'assets/js/build/index.js'),
true
);
// Injection des variables JS pour AJAX et le nonce (utilisées par les blocs éditeur)
wp_localize_script(
'ai-builder-blocks',
'aiBuilderVars',
array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('aibui_nonce'),
)
);
wp_enqueue_script(
'ai-builder-language-switcher-block',
plugin_dir_url(__FILE__) . 'assets/js/language-switcher-block.js',
array('wp-blocks', 'wp-block-editor', 'wp-element', 'wp-components', 'wp-i18n'),
filemtime(plugin_dir_path(__FILE__) . 'assets/js/language-switcher-block.js'),
true
);
$translation_settings = AIBUI_Translation_Settings::get_settings();
$supported_languages = AIBUI_Translation_Handler::get_supported_languages();
$available_langs = isset($translation_settings['available_langs']) && is_array($translation_settings['available_langs'])
? array_values(array_unique($translation_settings['available_langs']))
: array();
$default_lang = isset($translation_settings['default_lang']) ? $translation_settings['default_lang'] : 'en';
if ($default_lang && !in_array($default_lang, $available_langs, true)) {
array_unshift($available_langs, $default_lang);
}
$switcher_defaults = array(
'backgroundColor' => !empty($translation_settings['switcher_bg']) ? $translation_settings['switcher_bg'] : '',
'textColor' => !empty($translation_settings['switcher_text']) ? $translation_settings['switcher_text'] : '',
'minWidth' => !empty($translation_settings['switcher_min_width']) ? (int) $translation_settings['switcher_min_width'] : 90,
'minHeight' => !empty($translation_settings['switcher_min_height']) ? (int) $translation_settings['switcher_min_height'] : 30,
'borderRadius' => 22,
);
wp_localize_script(
'ai-builder-language-switcher-block',
'aiBuilderLangSwitch',
array(
'availableLangs' => $available_langs,
'defaultLang' => $default_lang,
'labels' => $supported_languages,
'switcherEnabled' => !empty($translation_settings['enable_switcher']),
'defaults' => $switcher_defaults,
)
);
});
// Enregistrer le bloc côté PHP
add_action('init', function () use ($translation_switcher) {
wp_register_style(
'ai-builder-language-switcher-style',
plugin_dir_url(__FILE__) . 'assets/css/language-switcher.css',
array(),
AIBUI_VERSION
);
// Bloc AI Block
register_block_type('ai-builder/ai-block', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
'render_callback' => function ($attributes) {
// Le bloc AI Block ne s'affiche pas côté frontend car il est remplacé par le contenu généré
return '';
}
]);
// Bloc stat-bar (statique, pas de render_callback)
register_block_type('ai-builder/stat-bar', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
]);
// Bloc aibui-stats (rendu simple côté éditeur, frontend statique)
register_block_type('ai-builder/aibui-stats', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
]);
// Bloc aibui-carousel
register_block_type('ai-builder/aibui-carousel', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
]);
// Bloc aibui-yt-video
register_block_type('ai-builder/aibui-yt-video', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
]);
// Bloc aibui-map
register_block_type('ai-builder/aibui-map', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
]);
// Bloc aibui-tabs
// Bloc aibui-table
register_block_type('ai-builder/aibui-table', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
]);
register_block_type('ai-builder/aibui-tabs', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
]);
// Bloc aibui-contact-form (rendu via callback PHP pour sécurité)
register_block_type('ai-builder/aibui-contact-form', [
'editor_script' => 'ai-builder-blocks',
'editor_style' => 'ai-builder-blocks-style',
'style' => 'ai-builder-blocks-style',
'render_callback' => function ($attributes, $content, $block) {
$recipient = isset($attributes['recipientEmail']) ? sanitize_email($attributes['recipientEmail']) : '';
if (empty($recipient) || !is_email($recipient)) {
$recipient = sanitize_email(get_option('admin_email'));
}
if (empty($recipient) || !is_email($recipient)) {
// Pas de destinataire valide disponible, n'arrête pas l'affichage, mais désactive l'envoi
$recipient = '';
}
$fields = isset($attributes['fields']) && is_array($attributes['fields']) ? $attributes['fields'] : [];
$fields = array_slice($fields, 0, 5);
$form_title = isset($attributes['formTitle']) ? wp_kses_post($attributes['formTitle']) : '';
$description = isset($attributes['description']) ? wp_kses_post($attributes['description']) : '';
$button_label = isset($attributes['buttonLabel']) ? sanitize_text_field($attributes['buttonLabel']) : __('Send', 'ai-builder');
$success_message = isset($attributes['successMessage']) ? sanitize_text_field($attributes['successMessage']) : __('Thank you, your message has been sent.', 'ai-builder');
$from_email_attr = isset($attributes['fromEmail']) ? sanitize_email($attributes['fromEmail']) : '';
$nonce = wp_create_nonce('aibui_contact_form');
$action = esc_url(admin_url('admin-ajax.php'));
ob_start();
?>
'ai-builder-language-switcher-block',
'editor_style' => 'ai-builder-language-switcher-style',
'style' => 'ai-builder-language-switcher-style',
'render_callback' => array($translation_switcher, 'render_block'),
'attributes' => [
'backgroundColor' => ['type' => 'string', 'default' => '#5686c9'],
'textColor' => ['type' => 'string', 'default' => '#ffffff'],
'minWidth' => ['type' => 'number', 'default' => 90],
'minHeight' => ['type' => 'number', 'default' => 30],
'borderRadius' => ['type' => 'number', 'default' => 22],
],
'supports' => [
'align' => ['left', 'center', 'right', 'wide', 'full'],
],
]);
});
add_action('after_setup_theme', function () {
add_theme_support('align-wide');
});
function enqueue_ai_builder_scripts() {
// Charger config.js en premier (dépendance pour les autres scripts)
wp_enqueue_script(
'ai-builder-config',
plugins_url('config.js', __FILE__),
array(),
AIBUI_VERSION,
false // Charger dans le pour être disponible partout
);
// Autres scripts qui utilisent config.js
wp_enqueue_script(
'ai-builder-image-ai-controls',
plugins_url('assets/js/src/editor-blocks/image-ai-blocks/image-ai-controls.js', __FILE__),
array('ai-builder-config'),
AIBUI_VERSION,
true
);
// Autres scripts qui utilisent config.js
wp_enqueue_script(
'ai-builder-text-ai-controls',
plugins_url('assets/js/src/editor-blocks/text-ai-blocks/text-ai-controls.js', __FILE__),
array('ai-builder-config'),
AIBUI_VERSION,
true
);
// Autres scripts qui utilisent config.js
wp_enqueue_script(
'ai-builder-text-ai-controls',
plugins_url('assets/js/src/editor-blocks/text-ai-blocks/text-ai-controls.js', __FILE__),
array('ai-builder-config'),
AIBUI_VERSION,
true
);
// Autres scripts qui utilisent config.js
wp_enqueue_script(
'ai-builder-ai-block',
plugins_url('assets/js/src/editor-blocks/ai-block/ai-block.js', __FILE__),
array('ai-builder-config'),
AIBUI_VERSION,
true
);
}
add_action('enqueue_block_editor_assets', 'enqueue_ai_builder_scripts');
add_action('wp_enqueue_scripts', function () {
// Combined CSS already enqueued above; only enqueue any extra block scss-generated styles if needed
// Table, snackbar, cards editor styles are not required on frontend separately when bundled
// Load snackbar frontend JavaScript
wp_enqueue_script(
'ai-builder-snackbar-frontend',
plugin_dir_url(__FILE__) . 'assets/js/snackbar-frontend.js',
[],
AIBUI_VERSION,
true
);
});
add_action('enqueue_block_editor_assets', function () {
// Combined CSS already enqueued above; keep editor-specific assets below
// Load fixed background group block CSS specifically (already inside combined, but keep safe fallback if combined failed)
$fixed_bg_css_url = plugin_dir_url(__FILE__) . 'assets/js/src/editor-blocks/fixed-bg-group/style.css';
wp_enqueue_style('ai-builder-fixed-bg-group-editor', $fixed_bg_css_url, [], AIBUI_VERSION);
// Load WordPress media scripts for image selection
wp_enqueue_media();
});
// -------------------------------
// Meta description per page/post
// -------------------------------
add_action('add_meta_boxes', function () {
add_meta_box(
'aibui_meta_description',
__('Meta description', 'ai-builder'),
function ($post) {
$value = get_post_meta($post->ID, 'aibui_meta_description', true);
wp_nonce_field('aibui_meta_description_save', 'aibui_meta_description_nonce');
echo '' . esc_html__('Add a meta description for this page/post.', 'ai-builder') . '
';
echo '';
echo '' . esc_html__('Tip: 140–160 characters for best SEO results.', 'ai-builder') . '
';
},
array('post', 'page'),
'normal',
'default'
);
});
add_action('save_post', function ($post_id) {
if (!isset($_POST['aibui_meta_description_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['aibui_meta_description_nonce'])), 'aibui_meta_description_save')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) return;
if (!current_user_can('edit_post', $post_id)) return;
$raw = isset($_POST['aibui_meta_description']) ? wp_unslash($_POST['aibui_meta_description']) : '';
$san = trim(wp_strip_all_tags($raw));
if (strlen($san) > 320) {
$san = mb_substr($san, 0, 320);
}
if ($san === '') {
delete_post_meta($post_id, 'aibui_meta_description');
} else {
update_post_meta($post_id, 'aibui_meta_description', $san);
}
});
add_action('wp_head', function () {
if (is_admin() || !is_singular()) {
return;
}
$post_id = get_queried_object_id();
if (!$post_id) {
return;
}
$possible_keys = array(
'aibui_meta_description',
'_ai_builder_seo_desc',
'_yoast_wpseo_metadesc',
'_ai_translation_meta_desc'
);
$desc = '';
foreach ($possible_keys as $meta_key) {
$value = get_post_meta($post_id, $meta_key, true);
if (!empty($value)) {
$desc = $value;
break;
}
}
if (!$desc) {
$excerpt = get_post_field('post_excerpt', $post_id);
if (!empty($excerpt)) {
$desc = $excerpt;
}
}
$desc = trim(wp_strip_all_tags((string) $desc));
if ($desc !== '') {
echo "\n\n";
}
}, 1);
// Initialiser le gestionnaire AJAX
new AIBUI_Ajax_Handler();