Changeset 3448969
- Timestamp:
- 01/28/2026 07:15:00 PM (6 weeks ago)
- Location:
- vectoron/trunk
- Files:
-
- 1 added
- 6 edited
-
includes/settings-page.php (modified) (10 diffs)
-
integrations/beaver-builder.php (modified) (2 diffs)
-
integrations/divi.php (modified) (2 diffs)
-
integrations/elementor.php (modified) (1 diff)
-
integrations/wp-bakery.php (added)
-
readme.txt (modified) (4 diffs)
-
vectoron.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
vectoron/trunk/includes/settings-page.php
r3448227 r3448969 74 74 'type' => 'string', 75 75 'sanitize_callback' => 'vectoron_sanitize_divi_sync_mode', 76 'default' => 'always', 77 ) 78 ); 79 80 // WP Bakery sync mode setting. 81 register_setting( 82 'vectoron_settings', 83 'vectoron_wp_bakery_sync_mode', 84 array( 85 'type' => 'string', 86 'sanitize_callback' => 'vectoron_sanitize_wp_bakery_sync_mode', 76 87 'default' => 'always', 77 88 ) … … 470 481 } 471 482 483 // Check if this is a WP Bakery post - with detailed diagnostics. 484 vectoron_debug( '--- WP Bakery Post Detection ---' ); 485 $wp_bakery_installed = vectoron_is_wp_bakery_active(); 486 $wp_bakery_sync_mode = get_option( 'vectoron_wp_bakery_sync_mode', 'always' ); 487 $wp_bakery_js_status = get_post_meta( $test_post_id, '_wpb_vc_js_status', true ); 488 $wp_bakery_shortcodes_css = get_post_meta( $test_post_id, '_wpb_shortcodes_custom_css', true ); 489 $is_wp_bakery_post = vectoron_is_wp_bakery_post( $test_post_id ); 490 $has_wp_bakery_shortcodes = vectoron_content_has_wp_bakery_shortcodes( $test_post->post_content ); 491 492 vectoron_debug( 'WP Bakery Installed: ' . ( $wp_bakery_installed ? 'YES (v' . vectoron_get_wp_bakery_version() . ')' : 'NO' ) ); 493 vectoron_debug( 'Sync Mode: ' . $wp_bakery_sync_mode ); 494 vectoron_debug( '_wpb_vc_js_status: ' . ( $wp_bakery_js_status ? $wp_bakery_js_status : '(not set)' ) ); 495 vectoron_debug( '_wpb_shortcodes_custom_css: ' . ( $wp_bakery_shortcodes_css ? 'Yes (' . strlen( $wp_bakery_shortcodes_css ) . ' chars)' : '(not set)' ) ); 496 vectoron_debug( 'Detected as WP Bakery Post: ' . ( $is_wp_bakery_post ? 'YES' : 'NO' ) ); 497 vectoron_debug( 'Content has WP Bakery shortcodes: ' . ( $has_wp_bakery_shortcodes ? 'YES' : 'NO' ) ); 498 499 if ( ! $is_wp_bakery_post && $wp_bakery_installed ) { 500 vectoron_debug( ' -> Post will NOT sync in "auto" mode (not built with WP Bakery)' ); 501 vectoron_debug( ' -> To sync anyway, set WP Bakery Sync Mode to "always"' ); 502 } 503 472 504 // Check if we have any sync target configured (page builders OR SEO plugins). 473 505 $can_sync_acf = ! empty( $acf_meta_key ) && function_exists( 'acf_get_field_groups' ); … … 475 507 $can_sync_beaver_builder = $beaver_builder_installed && 'disabled' !== $beaver_builder_sync_mode; 476 508 $can_sync_divi = $divi_installed && 'disabled' !== $divi_sync_mode; 509 $can_sync_wp_bakery = $wp_bakery_installed && 'disabled' !== $wp_bakery_sync_mode; 477 510 $can_sync_yoast = defined( 'WPSEO_VERSION' ); 478 511 $can_sync_seopress = defined( 'SEOPRESS_VERSION' ); 479 512 $can_sync_rankmath = defined( 'RANK_MATH_VERSION' ); 480 513 481 $has_page_builder_target = $can_sync_acf || $can_sync_elementor || $can_sync_beaver_builder || $can_sync_divi ;514 $has_page_builder_target = $can_sync_acf || $can_sync_elementor || $can_sync_beaver_builder || $can_sync_divi || $can_sync_wp_bakery; 482 515 $has_seo_target = $can_sync_yoast || $can_sync_seopress || $can_sync_rankmath; 483 516 … … 490 523 vectoron_debug( ' - Beaver Builder: ' . ( $can_sync_beaver_builder ? 'Available' : 'Disabled or not installed' ) ); 491 524 vectoron_debug( ' - DIVI: ' . ( $can_sync_divi ? 'Available' : 'Disabled or not installed' ) ); 525 vectoron_debug( ' - WP Bakery: ' . ( $can_sync_wp_bakery ? 'Available' : 'Disabled or not installed' ) ); 492 526 vectoron_debug( ' SEO Plugins:' ); 493 527 vectoron_debug( ' - Yoast SEO: ' . ( $can_sync_yoast ? 'Available' : 'Not installed' ) ); … … 762 796 } 763 797 798 // Run WP Bakery sync if applicable. 799 vectoron_debug( '--- WP Bakery Sync ---' ); 800 if ( ! $wp_bakery_installed ) { 801 vectoron_debug( 'SKIPPED: WP Bakery not installed.' ); 802 } elseif ( 'disabled' === $wp_bakery_sync_mode ) { 803 vectoron_debug( 'SKIPPED: WP Bakery sync is disabled in settings.' ); 804 vectoron_debug( ' -> Change setting to "auto" or "always" to enable.' ); 805 } elseif ( 'auto' === $wp_bakery_sync_mode && ! $is_wp_bakery_post ) { 806 vectoron_debug( 'SKIPPED: Auto mode and post is not a WP Bakery post.' ); 807 vectoron_debug( ' -> This post was not created with WP Bakery editor.' ); 808 vectoron_debug( ' -> Option 1: Edit this post in WP Bakery first, then try again.' ); 809 vectoron_debug( ' -> Option 2: Change sync mode to "always" to force sync.' ); 810 } elseif ( $has_wp_bakery_shortcodes ) { 811 vectoron_debug( 'SKIPPED: Content already contains WP Bakery shortcodes.' ); 812 vectoron_debug( ' -> Updating _wpb_vc_js_status meta only to avoid double-wrapping.' ); 813 update_post_meta( $test_post_id, '_wpb_vc_js_status', 'true' ); 814 vectoron_clear_wp_bakery_cache( $test_post_id ); 815 } else { 816 // Perform WP Bakery sync. 817 $sync_reason = ( 'always' === $wp_bakery_sync_mode ) ? 'Mode is "always"' : 'Post is a WP Bakery post'; 818 vectoron_debug( "PROCEEDING: {$sync_reason}" ); 819 820 // Convert HTML to WP Bakery shortcode structure. 821 vectoron_debug( 'Converting HTML to WP Bakery shortcode structure...' ); 822 $wpb_content = vectoron_html_to_wp_bakery_shortcodes( $test_post->post_content ); 823 824 if ( empty( $wpb_content ) ) { 825 vectoron_debug( 'ERROR: Failed to convert content to WP Bakery shortcodes.' ); 826 } else { 827 // Show the structure we're creating. 828 vectoron_debug( 'Created structure: 1 row -> 1 column -> 1 column_text' ); 829 vectoron_debug( 'WP Bakery shortcode Length: ' . strlen( $wpb_content ) . ' characters' ); 830 vectoron_debug( 'Original content Length: ' . strlen( $test_post->post_content ) . ' characters' ); 831 832 // Update post_content with WP Bakery shortcodes. 833 vectoron_debug( 'Writing WP Bakery shortcodes to post_content...' ); 834 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 835 $result_content = $wpdb->update( 836 $wpdb->posts, 837 array( 'post_content' => $wpb_content ), 838 array( 'ID' => $test_post_id ), 839 array( '%s' ), 840 array( '%d' ) 841 ); 842 843 vectoron_debug( 'update post_content: ' . ( false !== $result_content ? 'SUCCESS' : 'FAILED' ) ); 844 845 // Update WP Bakery postmeta (IMPORTANT: 'true' as STRING). 846 $result_status = update_post_meta( $test_post_id, '_wpb_vc_js_status', 'true' ); 847 vectoron_debug( 'update_post_meta(_wpb_vc_js_status): ' . vectoron_debug_export( $result_status ) ); 848 849 // Clear WP Bakery cache. 850 vectoron_debug( 'Clearing WP Bakery cache...' ); 851 vectoron_clear_wp_bakery_cache( $test_post_id ); 852 853 // Clean WordPress cache. 854 clean_post_cache( $test_post_id ); 855 856 // Verify the update by re-reading from database. 857 vectoron_debug( '--- Verification ---' ); 858 $verify_status = get_post_meta( $test_post_id, '_wpb_vc_js_status', true ); 859 $verify_post = get_post( $test_post_id ); 860 $verify_has_wpb = vectoron_content_has_wp_bakery_shortcodes( $verify_post->post_content ); 861 862 vectoron_debug( '_wpb_vc_js_status = ' . ( $verify_status ? $verify_status : '(empty)' ) ); 863 vectoron_debug( 'post_content has WP Bakery shortcodes: ' . ( $verify_has_wpb ? 'YES - SUCCESS' : 'NO - FAILED' ) ); 864 865 vectoron_debug( '' ); 866 vectoron_debug( 'WP Bakery sync completed. View post: ' . get_permalink( $test_post_id ) ); 867 } 868 } 869 764 870 vectoron_debug( '=== MANUAL SYNC TEST COMPLETED ===' ); 765 871 … … 773 879 "SELECT meta_key, LEFT(meta_value, 200) as meta_value 774 880 FROM {$wpdb->postmeta} 775 WHERE post_id = %d AND (meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s )881 WHERE post_id = %d AND (meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s OR meta_key LIKE %s) 776 882 ORDER BY meta_key", 777 883 $test_post_id, … … 780 886 '_fl_builder%', 781 887 '_et_pb%', 888 '_wpb_%', 782 889 '_yoast_wpseo%', 783 890 '_seopress%', … … 1212 1319 </div> 1213 1320 1321 <!-- WP Bakery Integration Card --> 1322 <?php 1323 $wp_bakery_installed = vectoron_is_wp_bakery_active(); 1324 $wp_bakery_version = $wp_bakery_installed ? vectoron_get_wp_bakery_version() : null; 1325 $wp_bakery_sync_mode = get_option( 'vectoron_wp_bakery_sync_mode', 'always' ); 1326 ?> 1327 <div class="vectoron-card"> 1328 <div class="vectoron-card-header"> 1329 <h2 class="vectoron-card-title"> 1330 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 1331 <rect x="3" y="3" width="18" height="18" rx="2"/> 1332 <path d="M3 9h18"/> 1333 <path d="M9 21V9"/> 1334 </svg> 1335 WP Bakery Integration 1336 </h2> 1337 <p class="vectoron-card-description"> 1338 <?php if ( $wp_bakery_installed ) : ?> 1339 WP Bakery <?php echo esc_html( $wp_bakery_version ); ?> detected. Configure content sync for WP Bakery-powered pages. 1340 <?php else : ?> 1341 WP Bakery Page Builder is not installed. Standard post_content will be used for page rendering. 1342 <?php endif; ?> 1343 </p> 1344 </div> 1345 <div class="vectoron-card-content"> 1346 <form action="options.php" method="post"> 1347 <?php settings_fields( 'vectoron_settings' ); ?> 1348 1349 <div class="vectoron-settings-row"> 1350 <label class="vectoron-settings-label">Sync Mode</label> 1351 <div class="vectoron-settings-field"> 1352 <?php if ( $wp_bakery_installed ) : ?> 1353 <select name="vectoron_wp_bakery_sync_mode" class="vectoron-select"> 1354 <option value="auto" <?php selected( $wp_bakery_sync_mode, 'auto' ); ?>>Auto (sync only WP Bakery posts)</option> 1355 <option value="always" <?php selected( $wp_bakery_sync_mode, 'always' ); ?>>Always (convert all posts to WP Bakery format)</option> 1356 <option value="disabled" <?php selected( $wp_bakery_sync_mode, 'disabled' ); ?>>Disabled (never sync to WP Bakery)</option> 1357 </select> 1358 <?php else : ?> 1359 <select class="vectoron-select" disabled> 1360 <option>WP Bakery not installed</option> 1361 </select> 1362 <?php endif; ?> 1363 <p class="vectoron-description">Auto mode syncs content only for posts that were originally created with WP Bakery.</p> 1364 </div> 1365 </div> 1366 1367 <?php if ( $wp_bakery_installed ) : ?> 1368 <div style="margin-top: 16px;"> 1369 <button type="submit" class="vectoron-btn vectoron-btn-primary"> 1370 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 1371 <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/> 1372 <polyline points="17 21 17 13 7 13 7 21"/> 1373 <polyline points="7 3 7 8 15 8"/> 1374 </svg> 1375 Save Settings 1376 </button> 1377 </div> 1378 <?php endif; ?> 1379 </form> 1380 </div> 1381 <div class="vectoron-card-footer"> 1382 <div class="vectoron-grid vectoron-grid-3"> 1383 <div class="vectoron-stat"> 1384 <span class="vectoron-stat-label">Status</span> 1385 <span class="vectoron-stat-value"> 1386 <?php if ( $wp_bakery_installed ) : ?> 1387 <span class="vectoron-badge vectoron-badge-success"> 1388 <span class="vectoron-status-dot vectoron-status-dot-success"></span> 1389 Active 1390 </span> 1391 <?php else : ?> 1392 <span class="vectoron-badge vectoron-badge-muted">Not Installed</span> 1393 <?php endif; ?> 1394 </span> 1395 </div> 1396 <div class="vectoron-stat"> 1397 <span class="vectoron-stat-label">Version</span> 1398 <span class="vectoron-stat-value"> 1399 <?php if ( $wp_bakery_version ) : ?> 1400 <span class="vectoron-code"><?php echo esc_html( $wp_bakery_version ); ?></span> 1401 <?php else : ?> 1402 <span style="color: var(--vectoron-tertiary);">-</span> 1403 <?php endif; ?> 1404 </span> 1405 </div> 1406 <div class="vectoron-stat"> 1407 <span class="vectoron-stat-label">Sync Mode</span> 1408 <span class="vectoron-stat-value"> 1409 <span class="vectoron-code"><?php echo esc_html( $wp_bakery_sync_mode ); ?></span> 1410 </span> 1411 </div> 1412 </div> 1413 </div> 1414 </div> 1415 1214 1416 <!-- Yoast SEO Integration Card --> 1215 1417 <?php … … 1495 1697 $acf_installed_test = function_exists( 'acf_get_field_groups' ); 1496 1698 $elementor_installed_test = defined( 'ELEMENTOR_VERSION' ); 1699 $divi_installed_test = vectoron_is_divi_active(); 1700 $wp_bakery_installed_test = vectoron_is_wp_bakery_active(); 1497 1701 $yoast_installed_test = defined( 'WPSEO_VERSION' ); 1498 1702 $seopress_installed_test = defined( 'SEOPRESS_VERSION' ); … … 1500 1704 $acf_field_test = get_option( 'vectoron_acf_content_field', '' ); 1501 1705 $elementor_mode_test = get_option( 'vectoron_elementor_sync_mode', 'always' ); 1706 $divi_mode_test = get_option( 'vectoron_divi_sync_mode', 'always' ); 1707 $wp_bakery_mode_test = get_option( 'vectoron_wp_bakery_sync_mode', 'always' ); 1502 1708 ?> 1503 1709 ACF: <?php echo $acf_installed_test ? ( $acf_field_test ? '✅ Active (field: ' . esc_html( $acf_field_test ) . ')' : '⚠️ Installed but no field configured' ) : '❌ Not installed'; ?> 1504 1710 1505 1711 Elementor: <?php echo $elementor_installed_test ? ( 'disabled' !== $elementor_mode_test ? '✅ Active (mode: ' . esc_html( $elementor_mode_test ) . ')' : '⚠️ Installed but disabled' ) : '❌ Not installed'; ?> 1712 1713 DIVI: <?php echo $divi_installed_test ? ( 'disabled' !== $divi_mode_test ? '✅ Active (mode: ' . esc_html( $divi_mode_test ) . ')' : '⚠️ Installed but disabled' ) : '❌ Not installed'; ?> 1714 1715 WP Bakery: <?php echo $wp_bakery_installed_test ? ( 'disabled' !== $wp_bakery_mode_test ? '✅ Active (mode: ' . esc_html( $wp_bakery_mode_test ) . ')' : '⚠️ Installed but disabled' ) : '❌ Not installed'; ?> 1506 1716 1507 1717 Yoast SEO: <?php echo $yoast_installed_test ? '✅ Active (v' . esc_html( WPSEO_VERSION ) . ')' : '❌ Not installed'; ?> -
vectoron/trunk/integrations/beaver-builder.php
r3448212 r3448969 107 107 108 108 // Rich-text module node with the HTML content. 109 // Wrap content in .vectoron-content div so CSS styles (FAQ accordions, headings, etc.) work. 109 110 $module_node = array( 110 111 'node' => $module_id, … … 114 115 'settings' => (object) array( 115 116 'type' => 'rich-text', 116 'text' => $html_content,117 'text' => '<div class="vectoron-content">' . $html_content . '</div>', 117 118 ), 118 119 ); -
vectoron/trunk/integrations/divi.php
r3448212 r3448969 127 127 // Using a single-column (4_4 = full width) layout. 128 128 // Sanitize HTML content to prevent XSS while allowing safe HTML tags. 129 // Wrap content in .vectoron-content div so CSS styles (FAQ accordions, headings, etc.) work. 129 130 $shortcode_content = sprintf( 130 131 '[et_pb_section fb_built="1" _builder_version="%1$s" global_colors_info="{}"]' . … … 132 133 '[et_pb_column type="4_4" _builder_version="%1$s" custom_padding="|||" global_colors_info="" custom_padding__hover="|||"]' . 133 134 '[et_pb_text _builder_version="%1$s" background_size="initial" background_position="top_left" background_repeat="repeat" global_colors_info="{}"]' . 134 ' %2$s' .135 '<div class="vectoron-content">%2$s</div>' . 135 136 '[/et_pb_text]' . 136 137 '[/et_pb_column]' . -
vectoron/trunk/integrations/elementor.php
r3448212 r3448969 93 93 'isInner' => false, 94 94 'settings' => array( 95 'editor' => $html_content, 95 // Wrap content in .vectoron-content div so CSS styles (FAQ accordions, headings, etc.) work. 96 'editor' => '<div class="vectoron-content">' . $html_content . '</div>', 96 97 ), 97 98 'elements' => array(), -
vectoron/trunk/readme.txt
r3448224 r3448969 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 2.9. 77 Stable tag: 2.9.9 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 49 49 * **Beaver Builder**: Auto-sync content to Beaver Builder's rich-text modules 50 50 * **DIVI**: Auto-sync content to DIVI's shortcode format (sections, rows, columns, text modules) 51 * **WP Bakery**: Auto-sync content to WP Bakery's shortcode format (rows, columns, column_text) 51 52 * Configurable sync modes: Auto (detect existing builder posts), Always (convert all posts), or Disabled 52 53 * Cache clearing for immediate visual updates … … 134 135 135 136 == Changelog == 137 138 = 2.9.9 = 139 * Fixed: Page builder integrations now wrap content in `.vectoron-content` container 140 * This ensures all Vectoron CSS styles (FAQ accordions, headings, tables, etc.) work correctly 141 * Affects: Elementor, Beaver Builder, DIVI, and WP Bakery integrations 142 * Existing posts will be styled correctly on next publish/update via Vectoron API 143 144 = 2.9.8 = 145 * Added WP Bakery (Visual Composer) Page Builder integration for automatic content sync 146 * New settings card for WP Bakery sync mode configuration (Auto/Always/Disabled) 147 * WP Bakery status added to /status API endpoint (installed, version, sync_mode) 148 * Content converted to WP Bakery shortcode structure: row -> column -> column_text 149 * Smart detection prevents double-wrapping of existing WP Bakery shortcode content 150 * Full cache clearing support for WP Bakery CSS transients and custom CSS files 151 * Manual sync test diagnostics now include WP Bakery detection and testing 152 * Page builder integrations section updated in documentation 136 153 137 154 = 2.9.7 = … … 265 282 == Upgrade Notice == 266 283 284 = 2.9.9 = 285 CSS styling fix for page builders: Elementor, Beaver Builder, DIVI, and WP Bakery now properly wrap content so FAQ accordions, headings, and other Vectoron styles work correctly. 286 287 = 2.9.8 = 288 New feature: WP Bakery (Visual Composer) Page Builder integration for automatic content sync. Content is converted to WP Bakery shortcodes with row/column/column_text structure. Configure sync mode under Settings > Vectoron. 289 267 290 = 2.9.0 = 268 291 New feature: DIVI Theme and Builder integration for automatic content sync. Content is converted to DIVI shortcodes with section/row/column/text module structure. Configure sync mode under Settings > Vectoron. -
vectoron/trunk/vectoron.php
r3448212 r3448969 3 3 * Plugin Name: Vectoron 4 4 * Description: Provides the [vectoron_article] shortcode to disable wpautop and load assets for custom content like the FAQ accordion and GA4 tracking. Includes REST API endpoints for external content management and ACF integration. 5 * Version: 2.9. 75 * Version: 2.9.9 6 6 * Author: Vectoron 7 7 * Author URI: https://vectoron.ai … … 25 25 require_once __DIR__ . '/integrations/beaver-builder.php'; 26 26 require_once __DIR__ . '/integrations/divi.php'; 27 require_once __DIR__ . '/integrations/wp-bakery.php'; 27 28 require_once __DIR__ . '/integrations/yoast.php'; 28 29 require_once __DIR__ . '/integrations/seopress.php'; … … 74 75 || defined( 'ET_BUILDER_VERSION' ); 75 76 update_option( 'vectoron_divi_sync_mode', $divi_installed ? 'always' : 'disabled' ); 77 } 78 79 // WP Bakery: disabled if not installed, always if installed. 80 // Added in v2.9.8 - Vectoron creates content, so there's no existing layout to protect. 81 if ( false === get_option( 'vectoron_wp_bakery_sync_mode' ) ) { 82 $wp_bakery_installed = defined( 'WPB_VC_VERSION' ) 83 || class_exists( 'Vc_Manager' ); 84 update_option( 'vectoron_wp_bakery_sync_mode', $wp_bakery_installed ? 'always' : 'disabled' ); 76 85 } 77 86 … … 135 144 136 145 // ============================================================================= 146 // WP BAKERY INTEGRATION - CONTENT SYNC 147 // ============================================================================= 148 // WP Bakery integration functions have been moved to integrations/wp-bakery.php 149 // Functions: vectoron_is_wp_bakery_post(), vectoron_is_wp_bakery_active(), 150 // vectoron_get_wp_bakery_version(), vectoron_html_to_wp_bakery_shortcodes(), 151 // vectoron_clear_wp_bakery_cache(), vectoron_sync_content_to_wp_bakery(), 152 // vectoron_add_wp_bakery_to_status() 153 154 // ============================================================================= 137 155 // YOAST SEO INTEGRATION 138 156 // =============================================================================
Note: See TracChangeset
for help on using the changeset viewer.