is_divi_available() ) { return; } // Hook AFTER Divi 4's priority 100 to override its block editor filter. // Divi 4 uses priority 100, so we need priority > 100 to run after it. add_filter( 'use_block_editor_for_post_type', [ $this, 'divi4_force_classic_editor' ], 999, 2 ); // Modify settings UI to reflect Divi 4 incompatibility. add_filter( 'pum_settings_fields', [ $this, 'modify_classic_editor_setting' ], 10, 1 ); // Make popups queryable when Divi builder is loading. add_filter( 'popup_maker/popup_post_type_args', [ $this, 'make_popup_queryable_for_divi' ] ); // Add popup to Divi's supported post types. add_filter( 'et_builder_post_types', [ $this, 'add_popup_support' ] ); // Enable Visual Builder for popup post type. add_filter( 'et_fb_is_enabled', [ $this, 'enable_fb_for_popups' ], 10, 2 ); } /** * Check if Divi is available (theme or plugin). * * Uses the same detection logic as Divi itself to detect both theme and plugin. * * @return bool */ private function is_divi_available() { static $is_divi_available = null; if ( null !== $is_divi_available ) { return $is_divi_available; } // Divi Theme detection: ET_BUILDER_THEME constant or et_divi_fonts_url function. $theme_available = ( defined( 'ET_BUILDER_THEME' ) && ET_BUILDER_THEME ) || function_exists( 'et_divi_fonts_url' ); // Divi Plugin detection: Plugin version constant or main plugin class. $plugin_available = defined( 'ET_BUILDER_PLUGIN_VERSION' ) || class_exists( 'ET_Builder_Plugin' ); // Also check for general ET_BUILDER_VERSION which both use. $general_available = defined( 'ET_BUILDER_VERSION' ) || function_exists( 'et_setup_builder' ); $is_divi_available = $theme_available || $plugin_available || $general_available; return $is_divi_available; } /** * Detect if Divi 4 is active (not 5+). * * Divi 4 has a bug where it conflicts with WordPress block editor filter, * preventing popup editor from loading when block editor is enabled. * * @return bool True if Divi 4.x is active. */ private function is_divi4_active() { static $is_divi4 = null; if ( null !== $is_divi4 ) { return $is_divi4; } $is_divi4 = false; // Check ET_BUILDER_VERSION constant (used by both theme and plugin). if ( defined( 'ET_BUILDER_VERSION' ) ) { $version = ET_BUILDER_VERSION; // Divi 4 versions are 4.0.0 - 4.99.99. $is_divi4 = version_compare( $version, '4.0.0', '>=' ) && version_compare( $version, '5.0.0', '<' ); } return $is_divi4; } /** * Force classic editor for popups when Divi 4 is active. * * This runs at priority 5 (before PostTypes filter at priority 10) * to ensure Divi 4's conflicting filters can't override our setting. * * @param bool $use_block_editor Whether to use the block editor. * @param string $post_type The post type. * @return bool Whether to use the block editor. */ public function divi4_force_classic_editor( $use_block_editor, $post_type ) { // Only handle our post types. if ( ! in_array( $post_type, [ 'popup', 'popup_theme' ], true ) ) { return $use_block_editor; } // Only force classic editor if Divi 4 is active. if ( ! $this->is_divi4_active() ) { return $use_block_editor; } // Force classic editor to prevent Divi 4 block editor conflict. // Return false to DISABLE block editor (use classic editor instead). return false; } /** * Modify the classic editor setting for Divi 4 compatibility display. * * Forces the option to be enabled, disables the UI, and adds an explanation. * * @param array $fields Settings fields array. * @return array Modified settings fields. */ public function modify_classic_editor_setting( $fields ) { // Only modify if Divi 4 is active. if ( ! $this->is_divi4_active() ) { return $fields; } // Navigate to the classic editor field in the general settings. if ( isset( $fields['general']['main']['enable_classic_editor'] ) ) { $field = &$fields['general']['main']['enable_classic_editor']; // Disable the field in UI and set to checked. $field['disabled'] = true; // Append Divi 4 note to existing description. $field['desc'] .= '
' . esc_html__( 'Divi 4 requires the classic editor for popup editing. This setting is automatically enforced for compatibility.', 'popup-maker' ) . ''; } return $fields; } /** * Add popup post type to Divi's builder post types. * * @param array $post_types Existing post types. * * @return array Modified post types. */ public function add_popup_support( $post_types ) { if ( ! $this->is_divi_available() ) { return $post_types; } if ( ! in_array( 'popup', $post_types, true ) ) { $post_types[] = 'popup'; } return $post_types; } /** * Make popups queryable when Divi builder is active. * * @param array $popup_args Popup post type arguments. * @return array Modified popup post type arguments. */ public function make_popup_queryable_for_divi( $popup_args ) { if ( ! $this->is_divi_available() ) { return $popup_args; } // Check for Divi builder parameters. if ( ! $this->is_divi_builder_request() ) { return $popup_args; } // Verify user has permission. if ( ! is_user_logged_in() || ! current_user_can( $this->container->get_permission( 'edit_popups' ) ) ) { return $popup_args; } // Get post ID from various possible query string parameters. $post_id = $this->get_popup_id_from_request(); if ( ! $post_id ) { return $popup_args; } // Verify it's a popup (this might be redundant but good for safety). if ( $post_id && 'popup' !== get_post_type( $post_id ) ) { return $popup_args; } // Verify user can edit this specific popup. if ( $post_id && ! current_user_can( 'edit_post', $post_id ) ) { return $popup_args; } // Make popups publicly queryable for this request. $popup_args['publicly_queryable'] = true; return $popup_args; } /** * Enable Visual Builder for popup posts. * * @param bool|null $enabled Current enabled status. * @param int $post_id Post ID being checked. * * @return bool|null Whether Visual Builder is enabled. */ public function enable_fb_for_popups( $enabled, $post_id ) { if ( ! $this->is_divi_available() ) { return $enabled; } if ( 'popup' === get_post_type( $post_id ) ) { return current_user_can( 'edit_post', $post_id ); } return $enabled; } /** * Check if current request is for Divi builder. * * @return bool */ private function is_divi_builder_request() { if ( ! $this->is_divi_available() ) { return false; } // Check for Visual Builder parameters. // phpcs:ignore WordPress.Security.NonceVerification.Recommended return isset( $_GET['et_fb'] ) || isset( $_GET['et_bfb'] ); } /** * Get popup ID from request parameters. * * @return int Post ID or 0 if not found. */ private function get_popup_id_from_request() { // Try different parameter names that Divi might use. $possible_params = [ 'p', 'post', 'post_id', 'et_post_id' ]; foreach ( $possible_params as $param ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET[ $param ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $post_id = absint( $_GET[ $param ] ); if ( $post_id > 0 ) { return $post_id; } } } // Try to get from current page if we're on a singular popup. if ( is_singular( 'popup' ) ) { return get_the_ID(); } return 0; } }