: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
namespace WPForms\Integrations\Elementor;
use Elementor\Plugin as ElementorPlugin;
use WPForms\Frontend\CSSVars;
use WPForms\Integrations\IntegrationInterface;
* Improve Elementor Compatibility.
class Elementor implements IntegrationInterface {
* Indicates if current integration is allowed to load.
public function allow_load() {
return (bool) did_action( 'elementor/loaded' );
protected function hooks() {
// Skip if Elementor is not available.
if ( ! class_exists( '\Elementor\Plugin' ) ) {
add_action( 'elementor/preview/init', [ $this, 'init' ] );
add_action( 'elementor/frontend/after_enqueue_scripts', [ $this, 'preview_assets' ] );
add_action( 'elementor/frontend/after_enqueue_scripts', [ $this, 'frontend_assets' ] );
add_action( 'elementor/editor/after_enqueue_styles', [ $this, 'editor_assets' ] );
version_compare( ELEMENTOR_VERSION, '3.5.0', '>=' ) ?
add_action( 'elementor/widgets/register', [ $this, 'register_widget' ] ) :
add_action( 'elementor/widgets/widgets_registered', [ $this, 'register_widget' ] );
add_action( 'wp_ajax_wpforms_admin_get_form_selector_options', [ $this, 'ajax_get_form_selector_options' ] );
add_filter( 'wpforms_integrations_gutenberg_form_selector_allow_render', [ $this, 'disable_gutenberg_block_render' ] );
public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
* Allow developers to determine whether the compatibility layer should be applied.
* We do this check here because we want this filter to be available for theme developers too.
* @param bool $use_compat Use compatibility.
$use_compat = (bool) apply_filters( 'wpforms_apply_elementor_preview_compat', true ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
if ( $use_compat !== true ) {
// Load WPForms assets globally on Elementor Preview panel only.
add_filter( 'wpforms_global_assets', '__return_true' );
// Hide CAPTCHA badge on Elementor Preview panel.
add_filter( 'wpforms_frontend_recaptcha_disable', '__return_true' );
* Load assets in the preview panel.
public function preview_assets() {
if ( ! ElementorPlugin::$instance->preview->is_preview_mode() ) {
$min = wpforms_get_min_suffix();
WPFORMS_PLUGIN_URL . "assets/css/admin-integrations{$min}.css",
WPFORMS_PLUGIN_URL . "assets/js/integrations/elementor/editor{$min}.js",
[ 'elementor-frontend', 'jquery', 'wp-util' ],
if ( $this->is_modern_widget() ) {
'wpforms-elementor-modern',
WPFORMS_PLUGIN_URL . "assets/js/integrations/elementor/editor-modern{$min}.js",
// Define strings for JS.
'heads_up' => esc_html__( 'Heads up!', 'wpforms-lite' ),
'cancel' => esc_html__( 'Cancel', 'wpforms-lite' ),
'confirm' => esc_html__( 'Confirm', 'wpforms-lite' ),
'reset_style_settings' => esc_html__( 'Reset Style Settings', 'wpforms-lite' ),
'reset_settings_confirm_text' => esc_html__( 'Are you sure you want to reset the style settings for this form? All your current styling will be removed and canʼt be recovered.', 'wpforms-lite' ),
'copy_paste_error' => esc_html__( 'There was an error parsing your JSON code. Please check your code and try again.', 'wpforms-lite' ),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'wpforms-elementor-integration' ),
'edit_form_url' => admin_url( 'admin.php?page=wpforms-builder&view=fields&form_id=' ),
'add_form_url' => admin_url( 'admin.php?page=wpforms-builder&view=setup' ),
'css_url' => WPFORMS_PLUGIN_URL . "assets/css/admin-integrations{$min}.css",
'debug' => wpforms_debug(),
'field-size' => CSSVars::FIELD_SIZE,
'label-size' => CSSVars::LABEL_SIZE,
'button-size' => CSSVars::BUTTON_SIZE,
* Load an integration assets on the frontend.
public function frontend_assets() {
if ( ElementorPlugin::$instance->preview->is_preview_mode() ) {
$min = wpforms_get_min_suffix();
WPFORMS_PLUGIN_URL . "assets/js/integrations/elementor/frontend{$min}.js",
[ 'elementor-frontend', 'jquery', 'wp-util' ],
'captcha_provider' => wpforms_setting( 'captcha-provider', 'recaptcha' ),
'recaptcha_type' => wpforms_setting( 'recaptcha-type', 'v2' ),
* Load assets in the elementor document.
public function editor_assets() {
if ( empty( $_GET['action'] ) || $_GET['action'] !== 'elementor' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$min = wpforms_get_min_suffix();
WPFORMS_PLUGIN_URL . "assets/css/admin-integrations{$min}.css",
* Register WPForms Widget.
* @since 1.7.6 Added support for new registration method since 3.5.0.
* @since 1.8.3 Added a condition for selecting the required widget instance.
public function register_widget() {
$widget_instance = $this->is_modern_widget() ? new WidgetModern() : new Widget();
version_compare( ELEMENTOR_VERSION, '3.5.0', '>=' ) ?
ElementorPlugin::instance()->widgets_manager->register( $widget_instance ) :
ElementorPlugin::instance()->widgets_manager->register_widget_type( $widget_instance );
* Get form selector options.
public function ajax_get_form_selector_options() {
check_ajax_referer( 'wpforms-elementor-integration', 'nonce' );
wp_send_json_success( ( new Widget() )->get_form_selector_options() );
protected function is_modern_widget() {
return wpforms_get_render_engine() === 'modern' && (int) wpforms_setting( 'disable-css', '1' ) === 1;
* Disable the block render for pages built in Elementor.
* @param bool $allow_render Whether to allow the block render.
* @return bool Whether to disable the block render.
public function disable_gutenberg_block_render( $allow_render ): bool {
$document = ElementorPlugin::$instance->documents->get( get_the_ID() );
if ( $document && $document->is_built_with_elementor() ) {