Changeset 3383555
- Timestamp:
- 10/23/2025 03:54:15 PM (4 months ago)
- Location:
- popup-for-elementor
- Files:
-
- 8 edited
- 1 copied
-
tags/1.6 (copied) (copied from popup-for-elementor/trunk)
-
tags/1.6/includes/editor-options.php (modified) (1 diff)
-
tags/1.6/includes/popup-handler.php (modified) (2 diffs)
-
tags/1.6/popup-for-elementor.php (modified) (1 diff)
-
tags/1.6/readme.txt (modified) (2 diffs)
-
trunk/includes/editor-options.php (modified) (1 diff)
-
trunk/includes/popup-handler.php (modified) (2 diffs)
-
trunk/popup-for-elementor.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
popup-for-elementor/tags/1.6/includes/editor-options.php
r3380762 r3383555 1 1 <?php 2 // File: popup-handler.php 3 // Dynamically passes configuration from Elementor controls to the JavaScript. 4 5 if (!defined('ABSPATH')) { 6 exit; 2 // Adds options to Elementor editor for configuring the popup 3 if ( ! defined( 'ABSPATH' ) ) { 4 exit; // Exit if accessed directly 7 5 } 8 function popup_for_elementor_register_assets() 6 class Popupfe_Popup_Widget extends \Elementor\Widget_Base 9 7 { 10 if (!is_admin()) { 11 wp_register_script( 8 public function get_name() 9 { 10 return "popup_widget"; 11 } 12 public function get_title() 13 { 14 return esc_html__("Popup Widget", "popup-for-elementor"); 15 } 16 17 public function get_categories() 18 { 19 return ["basic"]; 20 } 21 public function get_icon() { 22 return 'eicon-table-of-contents'; 23 } 24 25 protected function _register_controls() 26 { 27 // Content controls 28 $this->start_controls_section("content_section", [ 29 "label" => esc_html__("Content", "popup-for-elementor"), 30 "tab" => \Elementor\Controls_Manager::TAB_CONTENT, 31 ]); 32 33 $templates = []; 34 if (class_exists("\Elementor\Plugin")) { 35 $template_manager = \Elementor\Plugin::instance()->templates_manager->get_source( 36 "local" 37 ); 38 $templates_raw = $template_manager 39 ? $template_manager->get_items() 40 : []; 41 foreach ($templates_raw as $template) { 42 $templates[$template["template_id"]] = $template["title"]; 43 } 44 } 45 46 $this->add_control("template_id", [ 47 "label" => esc_html__("Select Template", "popup-for-elementor"), 48 "type" => \Elementor\Controls_Manager::SELECT2, // Cambiado a SELECT2 49 "options" => $templates, // Asegúrate de que $templates tiene las opciones disponibles 50 "default" => "", 51 "description" => esc_html__( 52 "Choose a template from your Elementor library.", 53 "popup-for-elementor" 54 ), 55 ]); 56 57 $this->add_control("template_create_link", [ 58 "type" => \Elementor\Controls_Manager::RAW_HTML, 59 "raw" => sprintf( 60 '<a href="%s" target="_blank" class="elementor-button elementor-button-success" style="margin-top: 10px;">%s</a>', 61 admin_url("edit.php?post_type=elementor_library"), 62 esc_html__("Create New Template", "popup-for-elementor") 63 ), 64 "content_classes" => "elementor-control-field", 65 ]); 66 67 $this->add_control("upgrade_to_pro_notice1", [ 68 "type" => \Elementor\Controls_Manager::RAW_HTML, 69 "raw" => sprintf( 70 '<div style="margin-top: 20px; padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 71 <strong style="display: block; color: #ffffff; font-size: 14px; font-weight: 300; margin-bottom: 12px;">%s</strong> 72 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 73 %s 74 </a> 75 </div>', 76 esc_html__("Need more triggers like Scroll, OnClick, or AdBlock detection?", "popup-for-elementor"), 77 "https://popupforelementor.com/en/home/#buy", 78 esc_html__("Get Popup for Elementor Pro", "popup-for-elementor") 79 ), 80 "content_classes" => "elementor-control-field", 81 ]); 82 83 $this->end_controls_section(); 84 85 // Style controls 86 $this->start_controls_section("style_section", [ 87 "label" => esc_html__("Popup window", "popup-for-elementor"), 88 "tab" => \Elementor\Controls_Manager::TAB_STYLE, 89 ]); 90 $this->add_responsive_control( 91 'popup_background', 92 [ 93 'label' => esc_html__('Background Color', 'popup-for-elementor'), 94 'type' => \Elementor\Controls_Manager::COLOR, 95 'selectors' => [ 96 '{{WRAPPER}} .popup-content' => 'background-color: {{VALUE}};', 97 ], 98 ] 99 ); 100 101 $this->add_control("overlay_color", [ 102 "label" => esc_html__("Overlay Color", "popup-for-elementor"), 103 "type" => \Elementor\Controls_Manager::COLOR, 104 "default" => "rgba(0, 0, 0, 0.5)", 105 "selectors" => [ 106 "{{WRAPPER}} .popup-overlay" => "background-color: {{VALUE}};", 107 ], 108 ]); 109 110 $this->add_control("border_radius", [ 111 "label" => esc_html__("Border Radius", "popup-for-elementor"), 112 "type" => \Elementor\Controls_Manager::SLIDER, 113 "default" => [ 114 "size" => 10, 115 ], 116 "selectors" => [ 117 "{{WRAPPER}} .popup-content" => 118 "border-radius: {{SIZE}}{{UNIT}};", 119 ], 120 ]); 121 122 $this->add_group_control( 123 \Elementor\Group_Control_Box_Shadow::get_type(), 124 [ 125 "name" => "popup_box_shadow", 126 "label" => esc_html__("Box Shadow", "popup-for-elementor"), 127 "selector" => "{{WRAPPER}} .popup-content", 128 "description" => esc_html__( 129 "Configure the shadow settings directly.", 130 "popup-for-elementor" 131 ), 132 ] 133 ); 134 135 $this->add_responsive_control("popup_width", [ 136 "label" => esc_html__("Popup Width", "popup-for-elementor"), 137 "type" => \Elementor\Controls_Manager::SELECT, 138 "default" => "400px", 139 "options" => [ 140 "auto" => esc_html__("Auto (Fit Content)", "popup-for-elementor"), 141 "custom" => esc_html__("Custom", "popup-for-elementor"), 142 ], 143 "selectors" => [ 144 "{{WRAPPER}} .popup-content" => "width: {{VALUE}};", 145 ], 146 ]); 147 148 $this->add_responsive_control("custom_popup_width", [ 149 "label" => esc_html__("Custom Width", "popup-for-elementor"), 150 "type" => \Elementor\Controls_Manager::SLIDER, 151 "default" => [ 152 "size" => 400, 153 "unit" => "px", 154 ], 155 "size_units" => ["px", "%", "vw"], 156 "range" => [ 157 "px" => [ 158 "min" => 100, 159 "max" => 2000, 160 "step" => 10, 161 ], 162 "%" => [ 163 "min" => 1, 164 "max" => 100, 165 ], 166 "vw" => [ 167 "min" => 1, 168 "max" => 100, 169 ], 170 ], 171 "condition" => [ 172 "popup_width" => "custom", 173 ], 174 "selectors" => [ 175 "{{WRAPPER}} .popup-content" => "width: {{SIZE}}{{UNIT}};", 176 ], 177 ]); 178 179 180 $this->add_responsive_control("popup_height", [ 181 "label" => esc_html__("Popup Height", "popup-for-elementor"), 182 "type" => \Elementor\Controls_Manager::SELECT, 183 "default" => "auto", 184 "options" => [ 185 "auto" => esc_html__("Auto (Fit Content)", "popup-for-elementor"), 186 "custom" => esc_html__("Custom", "popup-for-elementor"), 187 ], 188 "selectors" => [ 189 "{{WRAPPER}} .popup-content" => "height: {{VALUE}};", 190 ], 191 ]); 192 193 $this->add_responsive_control("custom_popup_height", [ 194 "label" => esc_html__("Custom Height", "popup-for-elementor"), 195 "type" => \Elementor\Controls_Manager::SLIDER, 196 "default" => [ 197 "size" => 400, 198 "unit" => "px", 199 ], 200 "size_units" => ["px", "%", "vh"], 201 "range" => [ 202 "px" => [ 203 "min" => 100, 204 "max" => 2000, 205 "step" => 10, 206 ], 207 "%" => [ 208 "min" => 1, 209 "max" => 100, 210 ], 211 "vh" => [ 212 "min" => 1, 213 "max" => 100, 214 ], 215 ], 216 "condition" => [ 217 "popup_height" => "custom", 218 ], 219 "selectors" => [ 220 "{{WRAPPER}} .popup-content" => "height: {{SIZE}}{{UNIT}};", 221 ], 222 ]); 223 224 225 226 $this->add_responsive_control("horizontal_position", [ 227 "label" => esc_html__("Horizontal Position", "popup-for-elementor"), 228 "type" => \Elementor\Controls_Manager::CHOOSE, 229 "options" => [ 230 "flex-start" => [ 231 "title" => esc_html__("Left", "popup-for-elementor"), 232 "icon" => "eicon-h-align-left", 233 ], 234 "center" => [ 235 "title" => esc_html__("Center", "popup-for-elementor"), 236 "icon" => "eicon-h-align-center", 237 ], 238 "flex-end" => [ 239 "title" => esc_html__("Right", "popup-for-elementor"), 240 "icon" => "eicon-h-align-right", 241 ], 242 ], 243 "default" => "center", 244 "selectors" => [ 245 "{{WRAPPER}} .popup-overlay" => "justify-content: {{VALUE}};", 246 ], 247 ]); 248 249 $this->add_responsive_control("vertical_position", [ 250 "label" => esc_html__("Vertical Position", "popup-for-elementor"), 251 "type" => \Elementor\Controls_Manager::CHOOSE, 252 "options" => [ 253 "flex-start" => [ 254 "title" => esc_html__("Top", "popup-for-elementor"), 255 "icon" => "eicon-v-align-top", 256 ], 257 "center" => [ 258 "title" => esc_html__("Center", "popup-for-elementor"), 259 "icon" => "eicon-v-align-middle", 260 ], 261 "flex-end" => [ 262 "title" => esc_html__("Bottom", "popup-for-elementor"), 263 "icon" => "eicon-v-align-bottom", 264 ], 265 ], 266 "default" => "center", 267 "selectors" => [ 268 "{{WRAPPER}} .popup-overlay" => "align-items: {{VALUE}};", 269 ], 270 ]); 271 272 // Control para el margen (Responsive) 273 $this->add_responsive_control( 274 'popup_margin', 275 [ 276 'label' => esc_html__('Margin', 'popup-for-elementor'), 277 'type' => \Elementor\Controls_Manager::DIMENSIONS, 278 'size_units' => ['px', '%', 'em'], 279 'selectors' => [ 280 '{{WRAPPER}} .popup-content' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 281 ], 282 ] 283 ); 284 285 // Control para el padding (Responsive) 286 $this->add_responsive_control( 287 'popup_padding', 288 [ 289 'label' => esc_html__('Padding', 'popup-for-elementor'), 290 'type' => \Elementor\Controls_Manager::DIMENSIONS, 291 'size_units' => ['px', '%', 'em'], 292 'selectors' => [ 293 '{{WRAPPER}} .popup-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 294 ], 295 ] 296 ); 297 298 299 $this->end_controls_section(); 300 301 // Animation 302 303 $this->start_controls_section("animation_section_custom", [ 304 "label" => esc_html__("Animation", "popup-for-elementor"), 305 "tab" => \Elementor\Controls_Manager::TAB_STYLE, // Colocamos esta sección en la pestaña de estilo 306 ]); 307 308 $this->add_control("popup_animation_in", [ 309 "label" => esc_html__("Entrance Animation", "popup-for-elementor"), 310 "type" => \Elementor\Controls_Manager::SELECT, 311 "options" => [ 312 "none" => esc_html__("None", "popup-for-elementor"), 313 "animate__fadeIn" => esc_html__("Fade In", "popup-for-elementor"), 314 "animate__fadeInUp" => esc_html__("Fade In Up", "popup-for-elementor"), 315 "anixmate__fadeInDown" => esc_html__("Fade In Down", "popup-for-elementor"), 316 "animate__fadeInLeft" => esc_html__("Fade In Left", "popup-for-elementor"), 317 "animate__fadeInRight" => esc_html__("Fade In Right", "popup-for-elementor"), 318 "animate__zoomIn" => esc_html__("Zoom In", "popup-for-elementor"), 319 "animate__slideInUp" => esc_html__("Slide In Up", "popup-for-elementor"), 320 "animate__slideInDown" => esc_html__("Slide In Down", "popup-for-elementor"), 321 "animate__slideInLeft" => esc_html__("Slide In Left", "popup-for-elementor"), 322 "animate__slideInRight" => esc_html__("Slide In Right", "popup-for-elementor"), 323 ], 324 "default" => "animate__fadeIn", 325 "description" => esc_html__( 326 "Choose an animation for the popup to appear.", 327 "popup-for-elementor" 328 ), 329 ]); 330 331 $this->add_control("popup_animation_out", [ 332 "label" => esc_html__("Exit Animation", "popup-for-elementor"), 333 "type" => \Elementor\Controls_Manager::SELECT, 334 "options" => [ 335 "none" => esc_html__("None", "popup-for-elementor"), 336 "animate__fadeOut" => esc_html__("Fade Out", "popup-for-elementor"), 337 "animate__fadeOutUp" => esc_html__("Fade Out Up", "popup-for-elementor"), 338 "animate__fadeOutDown" => esc_html__("Fade Out Down", "popup-for-elementor"), 339 "animate__fadeOutLeft" => esc_html__("Fade Out Left", "popup-for-elementor"), 340 "animate__fadeOutRight" => esc_html__("Fade Out Right", "popup-for-elementor"), 341 "animate__zoomOut" => esc_html__("Zoom Out", "popup-for-elementor"), 342 "animate__slideOutUp" => esc_html__("Slide Out Up", "popup-for-elementor"), 343 "animate__slideOutDown" => esc_html__("Slide Out Down", "popup-for-elementor"), 344 "animate__slideOutLeft" => esc_html__("Slide Out Left", "popup-for-elementor"), 345 "animate__slideOutRight" => esc_html__( 346 "Slide Out Right", 347 "popup-for-elementor" 348 ), 349 ], 350 "default" => "animate__fadeOut", 351 "description" => esc_html__( 352 "Choose an animation for the popup to disappear.", 353 "popup-for-elementor" 354 ), 355 ]); 356 357 $this->add_control("animation_duration_custom", [ 358 "label" => esc_html__("Animation Duration (ms)", "popup-for-elementor"), 359 "type" => \Elementor\Controls_Manager::SLIDER, 360 "size_units" => ["ms"], 361 "range" => [ 362 "ms" => [ 363 "min" => 100, 364 "max" => 3000, 365 "step" => 100, 366 ], 367 ], 368 "default" => [ 369 "size" => 500, 370 "unit" => "ms", 371 ], 372 "selectors" => [ 373 "{{WRAPPER}} .popup-content" => 374 "animation-duration: {{SIZE}}{{UNIT}};", 375 ], 376 ]); 377 378 $this->end_controls_section(); 379 //Close Button 380 381 $this->start_controls_section("close_button_section", [ 382 "label" => esc_html__("Close Button", "popup-for-elementor"), 383 "tab" => \Elementor\Controls_Manager::TAB_STYLE, 384 ]); 385 $this->add_control("hide_close_button", [ 386 "label" => esc_html__("Hide Close Button", "popup-for-elementor"), 387 "type" => \Elementor\Controls_Manager::SWITCHER, 388 "label_on" => esc_html__("Yes", "popup-for-elementor"), 389 "label_off" => esc_html__("No", "popup-for-elementor"), 390 "return_value" => "yes", 391 "default" => "no", 392 "selectors" => [ 393 "{{WRAPPER}} .popup-close" => "display: none;", 394 ], 395 ]); 396 397 $this->add_control("close_button_background_color", [ 398 "label" => esc_html__("Close Button Background", "popup-for-elementor"), 399 "type" => \Elementor\Controls_Manager::COLOR, 400 "selectors" => [ 401 "{{WRAPPER}} .popup-close" => "background-color: {{VALUE}};", 402 ], 403 ]); 404 405 $this->add_control("close_button_hover_background_color", [ 406 "label" => esc_html__("Close Button Hover Background", "popup-for-elementor"), 407 "type" => \Elementor\Controls_Manager::COLOR, 408 "selectors" => [ 409 "{{WRAPPER}} .popup-close:hover" => 410 "background-color: {{VALUE}};", 411 ], 412 ]); 413 414 $this->add_control("close_button_color", [ 415 "label" => esc_html__("Close Button Color", "popup-for-elementor"), 416 "type" => \Elementor\Controls_Manager::COLOR, 417 "selectors" => [ 418 "{{WRAPPER}} .popup-close" => "color: {{VALUE}};", 419 ], 420 ]); 421 422 $this->add_control("close_button_hover_color", [ 423 "label" => esc_html__("Close Button Hover Color", "popup-for-elementor"), 424 "type" => \Elementor\Controls_Manager::COLOR, 425 "selectors" => [ 426 "{{WRAPPER}} .popup-close:hover" => "color: {{VALUE}};", 427 ], 428 ]); 429 430 $this->add_control("close_button_size", [ 431 "label" => esc_html__("Close Button Size", "popup-for-elementor"), 432 "type" => \Elementor\Controls_Manager::SLIDER, 433 "size_units" => ["px"], // Solo permite px 434 "range" => [ 435 "px" => [ 436 "min" => 10, 437 "max" => 100, 438 ], 439 ], 440 "default" => [ 441 "unit" => "px", 442 "size" => 40, // Tamaño por defecto del botón de cerrar 443 ], 444 "selectors" => [ 445 "{{WRAPPER}} .popup-close" => 446 "width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}}; font-size: calc({{SIZE}}{{UNIT}} / 2);", 447 ], 448 "description" => esc_html__( 449 "Adjust the size of the close button.", 450 "popup-for-elementor" 451 ), 452 ]); 453 $this->add_control("close_button_alignment", [ 454 "label" => esc_html__("Close Button Alignment", "popup-for-elementor"), 455 "type" => \Elementor\Controls_Manager::CHOOSE, 456 "options" => [ 457 "left" => [ 458 "title" => esc_html__("Left", "popup-for-elementor"), 459 "icon" => "eicon-h-align-left", 460 ], 461 "right" => [ 462 "title" => esc_html__("Right", "popup-for-elementor"), 463 "icon" => "eicon-h-align-right", 464 ], 465 ], 466 "default" => "right", 467 "selectors" => [ 468 "{{WRAPPER}} .popup-close" => "{{VALUE}}: 10px;", 469 ], 470 "description" => esc_html__( 471 "Align the close button to the left or right.", 472 "popup-for-elementor" 473 ), 474 ]); 475 476 $this->add_control("close_button_border_radius", [ 477 "label" => esc_html__("Close Button Border Radius", "popup-for-elementor"), 478 "type" => \Elementor\Controls_Manager::SLIDER, 479 "size_units" => ["px"], // Solo permite px 480 "range" => [ 481 "px" => [ 482 "min" => 0, 483 "max" => 50, 484 ], 485 ], 486 "selectors" => [ 487 "{{WRAPPER}} .popup-close" => 488 "border-radius: {{SIZE}}{{UNIT}};", 489 ], 490 "description" => esc_html__( 491 "Controls the border radius of the close button.", 492 "popup-for-elementor" 493 ), 494 ]); 495 496 $this->end_controls_section(); 497 498 // Visibility controls 499 $this->start_controls_section("visibility_section", [ 500 "label" => esc_html__("Visibility", "popup-for-elementor"), 501 "tab" => \Elementor\Controls_Manager::TAB_CONTENT, 502 ]); 503 504 $this->add_control("show_on_load", [ 505 "label" => esc_html__("Show on Page Load", "popup-for-elementor"), 506 "type" => \Elementor\Controls_Manager::SWITCHER, 507 "default" => "", 508 "description" => esc_html__("Activate to show popup when the page loads. Will disable other visibility options.", "popup-for-elementor"), 509 "condition" => [ 510 "show_after_delay_enabled!" => "yes", 511 "show_on_exit_intent!" => "yes", 512 "show_once!" => "yes", 513 "trigger_selector_enabled!" => "yes", 514 515 ], 516 ]); 517 518 $this->add_control("show_after_delay_enabled", [ 519 "label" => esc_html__("Enable Show After Delay", "popup-for-elementor"), 520 "type" => \Elementor\Controls_Manager::SWITCHER, 521 "default" => "", 522 "description" => esc_html__("Activate to show popup after a delay. Will disable other visibility options.", "popup-for-elementor"), 523 "condition" => [ 524 "show_on_load!" => "yes", 525 "show_on_exit_intent!" => "yes", 526 "show_once!" => "yes", 527 "trigger_selector_enabled!" => "yes", 528 529 ], 530 ]); 531 532 $this->add_control("show_after_delay", [ 533 "label" => esc_html__("Delay (seconds)", "popup-for-elementor"), 534 "type" => \Elementor\Controls_Manager::NUMBER, 535 "default" => 3, 536 "condition" => [ 537 "show_after_delay_enabled" => "yes", 538 539 ], 540 ]); 541 542 $this->add_control("show_on_exit_intent", [ 543 "label" => esc_html__("Show on Exit Intent", "popup-for-elementor"), 544 "type" => \Elementor\Controls_Manager::SWITCHER, 545 "default" => "", 546 "description" => esc_html__("Activate to show popup when the user intends to exit. Will disable other visibility options.", "popup-for-elementor"), 547 "condition" => [ 548 "show_on_load!" => "yes", 549 "show_after_delay_enabled!" => "yes", 550 "show_once!" => "yes", 551 "trigger_selector_enabled!" => "yes", 552 553 ], 554 ]); 555 556 // NUEVO: control interno del Exit Intent (no es switch) 557 $this->add_control("exit_intent_display_mode", [ 558 "label" => esc_html__("Exit Intent — Display", "popup-for-elementor"), 559 "type" => \Elementor\Controls_Manager::SELECT, 560 "default" => "always", 561 "options" => [ 562 "always" => esc_html__("Always", "popup-for-elementor"), 563 "once" => esc_html__("Only once", "popup-for-elementor"), 564 ], 565 "description" => esc_html__("Show the Exit Intent popup always or only once per visitor (cookie).", "popup-for-elementor"), 566 "condition" => [ 567 "show_on_exit_intent" => "yes", // ← aparece solo si el trigger está activo 568 ], 569 ]); 570 571 $this->add_control("show_once", [ 572 "label" => esc_html__("Show Only Once", "popup-for-elementor"), 573 "type" => \Elementor\Controls_Manager::SWITCHER, 574 "default" => "", 575 "description" => esc_html__("Show the popup only once per session.", "popup-for-elementor"), 576 "condition" => [ 577 "show_on_load!" => "yes", 578 "show_after_delay_enabled!" => "yes", 579 "show_on_exit_intent!" => "yes", 580 "trigger_selector_enabled!" => "yes", 581 582 ], 583 ]); 584 585 $this->add_control('trigger_selector_enabled', [ 586 'label' => esc_html__('Trigger by selector (class or ID)', 'popup-for-elementor'), 587 'type' => \Elementor\Controls_Manager::SWITCHER, 588 'label_on' => esc_html__('Yes', 'popup-for-elementor'), 589 'label_off' => esc_html__('No', 'popup-for-elementor'), 590 'return_value' => 'yes', 591 'default' => '', 592 'description' => esc_html__('Enter the class or ID name (without “.” or “#”). Example: my-button or popup-trigger. The popup will open when any element with that class or ID is clicked.', 'popup-for-elementor'), 593 'condition' => [ 594 'show_on_load!' => 'yes', 595 'show_after_delay_enabled!' => 'yes', 596 'show_on_exit_intent!' => 'yes', 597 'show_once!' => 'yes', 598 ], 599 ]); 600 601 602 603 $this->add_control('trigger_selector', [ 604 'label' => esc_html__('Element name (class or ID)', 'popup-for-elementor'), 605 'type' => \Elementor\Controls_Manager::TEXT, 606 'placeholder' => esc_html__('e.g. my-button or popup-trigger', 'popup-for-elementor'), 607 'description' => esc_html__('Enter the class or ID name (without “.” or “#”). Example: my-button or popup-trigger.', 'popup-for-elementor'), 608 'condition' => [ 609 'trigger_selector_enabled' => 'yes', // ← solo dependemos del switch 610 ], 611 ]); 612 613 614 $this->add_control("upgrade_to_pro_notice2", [ 615 "type" => \Elementor\Controls_Manager::RAW_HTML, 616 "raw" => sprintf( 617 '<div style="margin-top: 20px; padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 618 <strong style="display: block; color: #ffffff; font-size: 14px; font-weight: 300; margin-bottom: 12px;">%s</strong> 619 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 620 %s 621 </a> 622 </div>', 623 esc_html__("Need more triggers like Scroll, OnClick, or AdBlock detection?", "popup-for-elementor"), 624 "https://popupforelementor.com/en/home/#buy", 625 esc_html__("Get Popup for Elementor Pro", "popup-for-elementor") 626 ), 627 "content_classes" => "elementor-control-field", 628 ]); 629 $this->end_controls_section(); 630 $this->start_controls_section("refresh_section", [ 631 "label" => esc_html__("Refresh", "popup-for-elementor"), 632 "tab" => \Elementor\Controls_Manager::TAB_CONTENT, 633 ]); 634 635 $this->add_control( 636 'refresh_popup', 637 [ 638 'label' => esc_html__('Refresh Popup', 'popup-for-elementor'), 639 'type' => \Elementor\Controls_Manager::BUTTON, 640 'button_type' => 'success', 641 'text' => esc_html__('Refresh', 'popup-for-elementor'), 642 'description' => esc_html__('Click to refresh the popup content.', 'popup-for-elementor'), 643 'frontend_available' => true, 644 ] 645 ); 646 $this->add_control("upgrade_to_pro_notice3", [ 647 "type" => \Elementor\Controls_Manager::RAW_HTML, 648 "raw" => sprintf( 649 '<div style="margin-top: 20px; padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 650 <strong style="display: block; color: #ffffff; font-size: 14px; font-weight: 300; margin-bottom: 12px;">%s</strong> 651 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 652 %s 653 </a> 654 </div>', 655 esc_html__("Need more triggers like Scroll, OnClick, or AdBlock detection?", "popup-for-elementor"), 656 "https://popupforelementor.com/en/home/#buy", 657 esc_html__("Get Popup for Elementor Pro", "popup-for-elementor") 658 ), 659 "content_classes" => "elementor-control-field", 660 ]); 661 $this->end_controls_section(); 662 $this->start_controls_section("upgrade_section", [ 663 "label" => esc_html__("Popup for Elementor (PRO)", "popup-for-elementor"), 664 "tab" => null, 665 ]); 666 667 $this->add_control("pro_upgrade_box", [ 668 "type" => \Elementor\Controls_Manager::RAW_HTML, 669 "raw" => sprintf( 670 '<div style="padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 671 <h3 style="color: #ffffff; font-size: 16px; margin-bottom: 12px; font-weight: 600;">%s</h3> 672 <p style="color: #bbbbbb; font-size: 13px; margin-bottom: 20px;">%s</p> 673 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 674 %s 675 </a> 676 </div>', 677 esc_html__("Unlock More Power", "popup-for-elementor"), 678 esc_html__("Upgrade to Pro and access all premium triggers and features.", "popup-for-elementor"), 679 "https://popupforelementor.com/en/home/#buy", 680 esc_html__("Upgrade to Pro", "popup-for-elementor") 681 ), 682 ]); 683 684 $this->end_controls_section(); 685 686 687 688 } 689 690 protected function render() 691 { 692 $settings = $this->get_settings_for_display(); 693 694 // Configuraciones dinámicas para pasar al script 695 $config = [ 696 'showOnLoad' => isset($settings['show_on_load']) && $settings['show_on_load'] === 'yes' ? 'yes' : 'no', 697 'delay' => isset($settings['show_after_delay']) ? (int) $settings['show_after_delay'] * 1000 : 0, 698 'exitIntent' => isset($settings['show_on_exit_intent']) && $settings['show_on_exit_intent'] === 'yes' ? 'yes' : 'no', 699 'exitIntentDisplayMode' => !empty($settings['exit_intent_display_mode']) ? $settings['exit_intent_display_mode'] : 'always', 700 'showOnce' => isset($settings['show_once']) && $settings['show_once'] === 'yes' ? 'yes' : 'no', 701 'cookieName' => 'popup_seen', 702 'cookieExpiry'=> 7, 703 'triggerBySelector' => (!empty($settings['trigger_selector_enabled']) && $settings['trigger_selector_enabled'] === 'yes') ? 'yes' : 'no', 704 'triggerSelector' => !empty($settings['trigger_selector']) ? $settings['trigger_selector'] : '', 705 ]; 706 707 708 709 // Pasar configuraciones dinámicas al script 710 wp_localize_script( 12 711 'popup-widget-js', 13 plugin_dir_url(__FILE__) . '../assets/popup-widget.js', 14 array('jquery'), 15 '1.0.0', 16 true 712 'PopupForElementorConfig', 713 $config 17 714 ); 18 $post_id = get_the_ID(); 19 20 if ($post_id) { 21 $dynamic_config = array( 22 'showOnLoad' => get_post_meta($post_id, '_elementor_popup_show_on_load', true) ?: 'no', 23 'delay' => (int) get_post_meta($post_id, '_elementor_popup_delay', true) ?: 0, 24 'showOnScroll' => get_post_meta($post_id, '_elementor_popup_show_on_scroll', true) === 'yes', 25 'scrollPercentage' => (int) (get_post_meta($post_id, '_elementor_popup_scroll_percentage', true) ?: 50), 26 'exitIntent' => get_post_meta($post_id, '_elementor_popup_exit_intent', true) === 'yes', 27 'exitIntentDisplayMode'=> get_post_meta($post_id, '_elementor_exit_intent_display_mode', true) ?: 'always', 28 'cookieName' => 'popup_seen', 29 'cookieExpiry' => 7, 30 'triggerBySelector' => get_post_meta($post_id, '_elementor_trigger_selector_enabled', true) === 'yes', 31 'triggerSelector' => get_post_meta($post_id, '_elementor_trigger_selector', true) ?: '', 32 33 ); 34 35 wp_localize_script( 36 'popup-widget-js', 37 'PopupForElementorConfig', 38 $dynamic_config 39 ); 40 } 41 wp_enqueue_script('popup-widget-js'); 715 716 717 // Obtener animaciones seleccionadas y duración 718 $animation_in = $settings['popup_animation_in'] ?? 'animate__fadeIn'; 719 $animation_out = $settings['popup_animation_out'] ?? 'animate__fadeOut'; 720 $animation_duration = isset($settings['animation_duration_custom']['size']) 721 ? (int) $settings['animation_duration_custom']['size'] 722 : 500; 723 724 // Renderizar plantilla de Elementor si está configurada 725 if (!empty($settings['template_id']) && class_exists('\Elementor\Plugin')) { 726 $popup_content = \Elementor\Plugin::instance()->frontend->get_builder_content_for_display($settings['template_id']); 727 728 if (\Elementor\Plugin::$instance->editor->is_edit_mode()) { 729 // Recuperar la URL del editor de Elementor 730 $edit_url = admin_url('post.php?post=' . absint($settings['template_id']) . '&action=elementor'); 731 732 // Solo eliminar etiquetas que no afecten la funcionalidad 733 $filtered_content = preg_replace('/<meta\b[^>]*>(.*?)<\/meta>/is', '', $popup_content); 734 $filtered_content = preg_replace('/<link\b[^>]*>(.*?)<\/link>/is', '', $filtered_content); 735 736 // Crear contenido para el modal 737 $popup_content = ' 738 <div class="elementor-template-button-wrapper" style="text-align: center; margin-top: 15px;"> 739 <a href="javascript:void(0);" 740 class="popup-edit-button elementor-button elementor-button-success elementor-size-sm button-edit-custom" 741 data-popup-id="' . esc_attr( 'popup_' . get_the_ID() . '_' . $settings['template_id'] ) . '" 742 data-edit-url="' . esc_url($edit_url) . '" 743 id="open-modal"> 744 <i class="eicon-edit" style="margin-right: 8px;"></i>' . esc_html__('Edit Template', 'popup-for-elementor') . ' 745 </a> 746 </div> 747 <div class="popup-editor-content"> 748 ' . $filtered_content . ' 749 </div>'; 42 750 } 43 751 } 44 add_action('wp_enqueue_scripts', 'popup_for_elementor_register_assets'); 45 46 add_action('admin_enqueue_scripts', function () { 47 wp_dequeue_script('popup-widget-js'); 48 wp_deregister_script('popup-widget-js'); 49 }, PHP_INT_MAX); 50 752 753 754 // Generar un identificador único para el popup 755 $current_page_id = get_the_ID(); 756 $popup_id = get_post_meta($settings['template_id'], '_popup_id_' . $current_page_id, true); 757 758 if (empty($popup_id)) { 759 $popup_id = 'popup_' . $current_page_id . '_' . uniqid(); 760 update_post_meta($settings['template_id'], '_popup_id_' . $current_page_id, $popup_id); 761 } 762 763 // Renderizar el HTML del popup con ID único 764 $styles = ''; 765 if (!defined('ELEMENTOR_VERSION') || !\Elementor\Plugin::$instance->editor->is_edit_mode()) { 766 // Aplicar estilos para ocultar el popup fuera del editor 767 $styles = 'display: none; visibility: hidden; opacity: 1;'; 768 } 769 770 function filter_popup_content($content) 771 { 772 // Lista de etiquetas peligrosas a eliminar (pero manteniendo SVGs y estilos de Elementor) 773 $dangerous_tags = ['iframe', 'embed', 'object', 'applet', 'meta', 'link']; 774 775 foreach ($dangerous_tags as $tag) { 776 $content = preg_replace('/<' . $tag . '.*?>.*?<\/' . $tag . '>/is', '', $content); 777 $content = preg_replace('/<' . $tag . '.*?>/is', '', $content); 778 } 779 780 return $content; 781 } 782 783 /* Escaping is not applied here because the content has already been filtered 784 by `filter_popup_content()`, which removes dangerous tags. 785 Using `esc_html()` would break Elementor's functionality. 786 This code has been reviewed and is safe. */ 787 788 $popup_content_filtered = filter_popup_content($popup_content); 789 790 echo '<div id="' . esc_attr($popup_id) . '" class="popup-overlay popup-widget" style="' . esc_attr($styles) . '"> 791 <div class="popup-content animate__animated ' . esc_attr($animation_in) . '" 792 style="position: relative; animation-duration: ' . esc_attr($animation_duration) . 'ms;"> 793 <button class="popup-close">×</button>'; 794 795 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 796 echo $popup_content_filtered; 797 798 echo '</div></div>'; 799 800 // This script controls the popup behavior (open/close, animations, hover effects). 801 // It must be injected directly here because Elementor dynamically refreshes widget content. 802 // Using wp_enqueue_script or wp_add_inline_script would not persist across reloads. 803 804 echo '<script> 805 (function($) { 806 $(document).ready(function() { 807 const popup = $("#' . 808 esc_attr($popup_id) . 809 '"); 810 const popupContent = popup.find(".popup-content"); 811 812 if (popup.length) { 813 // Abrir popup con animación de entrada 814 popup.closest(".elementor-widget-popup_widget").off("click").on("click", function(e) { 815 e.preventDefault(); 816 popup.css({ 817 display: "flex", 818 visibility: "visible" 819 }); 820 popupContent.removeClass("' . 821 esc_attr($animation_out) . 822 '").addClass("' . 823 esc_attr($animation_in) . 824 '"); 825 }); 826 827 // Cerrar popup con animación de salida 828 popup.find(".popup-close").off("click").on("click", function(e) { 829 e.stopPropagation(); 830 popupContent 831 .removeClass("' . 832 esc_attr($animation_in) . 833 '") 834 .addClass("' . 835 esc_attr($animation_out) . 836 '"); 837 838 // Esperar la duración de la animación antes de ocultar el popup 839 const duration = ' . 840 esc_attr($animation_duration) . 841 '; 842 setTimeout(function() { 843 popup.css({ 844 display: "none", 845 visibility: "hidden" 846 }); 847 popupContent.removeClass("' . 848 esc_attr($animation_out) . 849 '"); 850 }, duration); 851 }); 852 853 // Hover en el botón para cambiar el fondo del popup 854 popup.find(".popup-edit-button").on("mouseenter", function() { 855 popupContent.css("background-color", "#ffebf2"); 856 }).on("mouseleave", function() { 857 popupContent.css("background-color", ""); 858 }); 859 } else { 860 console.error("Popup element not found in the DOM."); 861 } 862 }); 863 elementor.hooks.addAction("panel/open_editor/widget", function (panel, model) { 864 panel.$el.on("click", ".elementor-control-refresh_popup .elementor-button", function () { 865 console.log("¡Botón clicado! Refrescando el widget..."); 866 867 // Simular un cambio en el modelo 868 model.set("refresh_trigger", Date.now()); // Valor ficticio para forzar el cambio 869 model.trigger("change"); // Notificar el cambio a Elementor 870 871 // Verificar si Elementor actualiza la vista 872 setTimeout(function () { 873 console.log("Intentando recargar la vista previa..."); 874 elementor.reloadPreview(); // Forzar la recarga si no responde 875 elementor.once("preview:loaded", function () { 876 console.log("Vista previa recargada correctamente."); 877 878 // Reabrir el popup después de recargar la vista previa 879 const $popupOverlay = jQuery(".popup-overlay"); 880 if ($popupOverlay.length) { 881 console.log("Reabriendo el popup..."); 882 $popupOverlay.css({ 883 display: "", 884 visibility: "", 885 opacity: 1, 886 }); 887 console.log("Popup reabierto correctamente."); 888 } else { 889 console.error("No se encontró el popup en el DOM."); 890 } 891 }); 892 }, 500); // Fallback por si el trigger no es suficiente 893 }); 894 }); 895 })(jQuery); 896 </script>'; 897 898 // This script controls the custom modal editor outside the iframe (open, close, panel resize). 899 // Since the modal is rendered outside the iframe (via editor/after_footer), 900 // this script needs to access it using parent.jQuery. 901 // It must be echoed directly to stay bound to the button rendered in the iframe. 902 903 echo '<div id="custom-modal"> 904 <div class="modal-container"> 905 <div class="modal-header"> 906 <div class="modal-title" style="display: flex; align-items: center;"> 907 <div style="width: 40px; height: 40px; background-color: white; border-radius: 50%; display: flex; justify-content: center; align-items: center; margin-right: 10px;"> 908 <span class="eicon-table-of-contents" style="font-size: 20px; color: #333;"></span> <!-- Icono de Elementor --> 909 </div> 910 ' . esc_html__("Popup for Elementor", "popup-for-elementor") . ' 911 </div> 912 <button id="close-modal">×</button> 913 </div> 914 <iframe id="modal-iframe" src=""></iframe> 915 </div> 916 </div>'; 917 918 echo '<script> 919 (function($) { 920 $(document).ready(function() { 921 const $modal = $("#custom-modal"); 922 const $iframe = $("#modal-iframe"); 923 const $closeButton = $("#close-modal"); 924 925 let originalPanelStyles = {}; // Guardamos los estilos originales 926 927 function refreshWidget() { 928 console.log("Ejecutando refresh del widget..."); 929 if (typeof parent.elementor !== "undefined" && parent.elementor.reloadPreview) { 930 parent.elementor.reloadPreview(); 931 parent.elementor.once("preview:loaded", function() { 932 console.log("Vista previa recargada correctamente."); 933 }); 934 } 935 } 936 937 function toggleElementorPanel(reduce) { 938 if (typeof parent.jQuery !== "undefined") { 939 const $panel = parent.jQuery("#elementor-panel"); 940 const $preview = parent.jQuery("#elementor-preview"); 941 942 if (reduce) { 943 console.log("Guardando estado del panel y reduciéndolo..."); 944 originalPanelStyles = { 945 width: $panel.css("width"), 946 minWidth: $panel.css("min-width"), 947 maxWidth: $panel.css("max-width"), 948 overflow: $panel.css("overflow"), 949 visibility: $panel.css("visibility"), 950 opacity: $panel.css("opacity"), 951 }; 952 953 $panel.css({ 954 "width": "60px", 955 "min-width": "60px", 956 "max-width": "60px", 957 "overflow": "hidden", 958 "visibility": "hidden", 959 "opacity": "0", 960 "transition": "width 0.3s ease-in-out" 961 }); 962 963 $preview.css({ 964 "width": "calc(100% - 60px)", 965 "transition": "width 0.3s ease-in-out" 966 }); 967 } else { 968 console.log("Restaurando el panel de Elementor..."); 969 $panel.css(originalPanelStyles); 970 971 $preview.css({ 972 "width": "calc(100% - " + originalPanelStyles.width + ")" 973 }); 974 } 975 } 976 } 977 978 $("#open-modal").on("click", function() { 979 console.log("Modal abierto, reduciendo panel en la ventana principal..."); 980 const editUrl = $(this).data("edit-url"); 981 $iframe.attr("src", editUrl); 982 $modal.removeClass("hide").addClass("show"); 983 984 toggleElementorPanel(true); 985 }); 986 987 $closeButton.on("click", function() { 988 console.log("Cerrando modal, restaurando panel en la ventana principal..."); 989 $modal.removeClass("show").addClass("hide"); 990 991 setTimeout(() => { 992 $iframe.attr("src", ""); // Limpiar el iframe 993 toggleElementorPanel(false); 994 refreshWidget(); 995 }, 300); 996 }); 997 998 console.log("Script de reducción de panel cargado."); 999 }); 1000 })(jQuery); 1001 </script>'; 1002 } 1003 } -
popup-for-elementor/tags/1.6/includes/popup-handler.php
r3382610 r3383555 3 3 // Dynamically passes configuration from Elementor controls to the JavaScript. 4 4 5 if (!defined('ABSPATH')) exit; 5 if (!defined('ABSPATH')) { 6 exit; 7 } 8 function popup_for_elementor_register_assets() 9 { 10 if (!is_admin()) { 11 wp_register_script( 12 'popup-widget-js', 13 plugin_dir_url(__FILE__) . '../assets/popup-widget.js', 14 array('jquery'), 15 '1.0.0', 16 true 17 ); 18 $post_id = get_the_ID(); 6 19 7 if ( ! function_exists( 'popup_for_elementor_register_assets' ) ) { 8 function popup_for_elementor_register_assets() { 9 if (!is_admin()) { 10 wp_register_script( 20 if ($post_id) { 21 $dynamic_config = array( 22 'showOnLoad' => get_post_meta($post_id, '_elementor_popup_show_on_load', true) ?: 'no', 23 'delay' => (int) get_post_meta($post_id, '_elementor_popup_delay', true) ?: 0, 24 'showOnScroll' => get_post_meta($post_id, '_elementor_popup_show_on_scroll', true) === 'yes', 25 'scrollPercentage' => (int) (get_post_meta($post_id, '_elementor_popup_scroll_percentage', true) ?: 50), 26 'exitIntent' => get_post_meta($post_id, '_elementor_popup_exit_intent', true) === 'yes', 27 'exitIntentDisplayMode'=> get_post_meta($post_id, '_elementor_exit_intent_display_mode', true) ?: 'always', 28 'cookieName' => 'popup_seen', 29 'cookieExpiry' => 7, 30 'triggerBySelector' => get_post_meta($post_id, '_elementor_trigger_selector_enabled', true) === 'yes', 31 'triggerSelector' => get_post_meta($post_id, '_elementor_trigger_selector', true) ?: '', 32 33 ); 34 35 wp_localize_script( 11 36 'popup-widget-js', 12 plugin_dir_url(__FILE__) . '../assets/popup-widget.js', 13 array('jquery'), 14 '1.0.0', 15 true 37 'PopupForElementorConfig', 38 $dynamic_config 16 39 ); 17 18 $post_id = get_the_ID();19 20 if ($post_id) {21 $dynamic_config = array(22 'showOnLoad' => get_post_meta($post_id, '_elementor_popup_show_on_load', true) ?: 'no',23 'delay' => (int) get_post_meta($post_id, '_elementor_popup_delay', true) ?: 0,24 'showOnScroll' => get_post_meta($post_id, '_elementor_popup_show_on_scroll', true) === 'yes',25 'scrollPercentage' => (int) (get_post_meta($post_id, '_elementor_popup_scroll_percentage', true) ?: 50),26 'exitIntent' => get_post_meta($post_id, '_elementor_popup_exit_intent', true) === 'yes',27 'exitIntentDisplayMode' => get_post_meta($post_id, '_elementor_exit_intent_display_mode', true) ?: 'always',28 'cookieName' => 'popup_seen',29 'cookieExpiry' => 7,30 'triggerBySelector' => get_post_meta($post_id, '_elementor_trigger_selector_enabled', true) === 'yes',31 'triggerSelector' => get_post_meta($post_id, '_elementor_trigger_selector', true) ?: '',32 );33 34 wp_localize_script('popup-widget-js','PopupForElementorConfig',$dynamic_config);35 }36 37 wp_enqueue_script('popup-widget-js');38 40 } 41 wp_enqueue_script('popup-widget-js'); 39 42 } 40 43 } 41 42 44 add_action('wp_enqueue_scripts', 'popup_for_elementor_register_assets'); 43 45 … … 46 48 wp_deregister_script('popup-widget-js'); 47 49 }, PHP_INT_MAX); 50 -
popup-for-elementor/tags/1.6/popup-for-elementor.php
r3382610 r3383555 4 4 * Plugin URI: https://www.popupforelementor.com 5 5 * Description: Create powerful, fully customizable popups directly in Elementor Free — includes click, delay, load, and exit-intent triggers, animations, and smart visibility controls to boost user engagement. 6 * Version: 1.5.9 6 * Version: 1.5.9.1 7 7 * Author: Veelo 8 8 * Author URI: https://www.veelo.es -
popup-for-elementor/tags/1.6/readme.txt
r3382610 r3383555 97 97 == Changelog == 98 98 99 = 1.6 = 100 * **Fix:** File correction. 101 99 102 = 1.5.9 = 100 103 * **Fix:** Prevented rare fatal error caused by multiple declarations of `popup_for_elementor_register_assets()` on some setups. … … 133 136 == Upgrade Notice == 134 137 135 = 1. 5.9=138 = 1.6 = 136 139 🛠️ Fixes a rare **fatal error** that could occur when scripts were loaded twice. 137 140 Highly recommended update for all users to ensure full compatibility and stability. -
popup-for-elementor/trunk/includes/editor-options.php
r3380762 r3383555 1 1 <?php 2 // File: popup-handler.php 3 // Dynamically passes configuration from Elementor controls to the JavaScript. 4 5 if (!defined('ABSPATH')) { 6 exit; 2 // Adds options to Elementor editor for configuring the popup 3 if ( ! defined( 'ABSPATH' ) ) { 4 exit; // Exit if accessed directly 7 5 } 8 function popup_for_elementor_register_assets() 6 class Popupfe_Popup_Widget extends \Elementor\Widget_Base 9 7 { 10 if (!is_admin()) { 11 wp_register_script( 8 public function get_name() 9 { 10 return "popup_widget"; 11 } 12 public function get_title() 13 { 14 return esc_html__("Popup Widget", "popup-for-elementor"); 15 } 16 17 public function get_categories() 18 { 19 return ["basic"]; 20 } 21 public function get_icon() { 22 return 'eicon-table-of-contents'; 23 } 24 25 protected function _register_controls() 26 { 27 // Content controls 28 $this->start_controls_section("content_section", [ 29 "label" => esc_html__("Content", "popup-for-elementor"), 30 "tab" => \Elementor\Controls_Manager::TAB_CONTENT, 31 ]); 32 33 $templates = []; 34 if (class_exists("\Elementor\Plugin")) { 35 $template_manager = \Elementor\Plugin::instance()->templates_manager->get_source( 36 "local" 37 ); 38 $templates_raw = $template_manager 39 ? $template_manager->get_items() 40 : []; 41 foreach ($templates_raw as $template) { 42 $templates[$template["template_id"]] = $template["title"]; 43 } 44 } 45 46 $this->add_control("template_id", [ 47 "label" => esc_html__("Select Template", "popup-for-elementor"), 48 "type" => \Elementor\Controls_Manager::SELECT2, // Cambiado a SELECT2 49 "options" => $templates, // Asegúrate de que $templates tiene las opciones disponibles 50 "default" => "", 51 "description" => esc_html__( 52 "Choose a template from your Elementor library.", 53 "popup-for-elementor" 54 ), 55 ]); 56 57 $this->add_control("template_create_link", [ 58 "type" => \Elementor\Controls_Manager::RAW_HTML, 59 "raw" => sprintf( 60 '<a href="%s" target="_blank" class="elementor-button elementor-button-success" style="margin-top: 10px;">%s</a>', 61 admin_url("edit.php?post_type=elementor_library"), 62 esc_html__("Create New Template", "popup-for-elementor") 63 ), 64 "content_classes" => "elementor-control-field", 65 ]); 66 67 $this->add_control("upgrade_to_pro_notice1", [ 68 "type" => \Elementor\Controls_Manager::RAW_HTML, 69 "raw" => sprintf( 70 '<div style="margin-top: 20px; padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 71 <strong style="display: block; color: #ffffff; font-size: 14px; font-weight: 300; margin-bottom: 12px;">%s</strong> 72 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 73 %s 74 </a> 75 </div>', 76 esc_html__("Need more triggers like Scroll, OnClick, or AdBlock detection?", "popup-for-elementor"), 77 "https://popupforelementor.com/en/home/#buy", 78 esc_html__("Get Popup for Elementor Pro", "popup-for-elementor") 79 ), 80 "content_classes" => "elementor-control-field", 81 ]); 82 83 $this->end_controls_section(); 84 85 // Style controls 86 $this->start_controls_section("style_section", [ 87 "label" => esc_html__("Popup window", "popup-for-elementor"), 88 "tab" => \Elementor\Controls_Manager::TAB_STYLE, 89 ]); 90 $this->add_responsive_control( 91 'popup_background', 92 [ 93 'label' => esc_html__('Background Color', 'popup-for-elementor'), 94 'type' => \Elementor\Controls_Manager::COLOR, 95 'selectors' => [ 96 '{{WRAPPER}} .popup-content' => 'background-color: {{VALUE}};', 97 ], 98 ] 99 ); 100 101 $this->add_control("overlay_color", [ 102 "label" => esc_html__("Overlay Color", "popup-for-elementor"), 103 "type" => \Elementor\Controls_Manager::COLOR, 104 "default" => "rgba(0, 0, 0, 0.5)", 105 "selectors" => [ 106 "{{WRAPPER}} .popup-overlay" => "background-color: {{VALUE}};", 107 ], 108 ]); 109 110 $this->add_control("border_radius", [ 111 "label" => esc_html__("Border Radius", "popup-for-elementor"), 112 "type" => \Elementor\Controls_Manager::SLIDER, 113 "default" => [ 114 "size" => 10, 115 ], 116 "selectors" => [ 117 "{{WRAPPER}} .popup-content" => 118 "border-radius: {{SIZE}}{{UNIT}};", 119 ], 120 ]); 121 122 $this->add_group_control( 123 \Elementor\Group_Control_Box_Shadow::get_type(), 124 [ 125 "name" => "popup_box_shadow", 126 "label" => esc_html__("Box Shadow", "popup-for-elementor"), 127 "selector" => "{{WRAPPER}} .popup-content", 128 "description" => esc_html__( 129 "Configure the shadow settings directly.", 130 "popup-for-elementor" 131 ), 132 ] 133 ); 134 135 $this->add_responsive_control("popup_width", [ 136 "label" => esc_html__("Popup Width", "popup-for-elementor"), 137 "type" => \Elementor\Controls_Manager::SELECT, 138 "default" => "400px", 139 "options" => [ 140 "auto" => esc_html__("Auto (Fit Content)", "popup-for-elementor"), 141 "custom" => esc_html__("Custom", "popup-for-elementor"), 142 ], 143 "selectors" => [ 144 "{{WRAPPER}} .popup-content" => "width: {{VALUE}};", 145 ], 146 ]); 147 148 $this->add_responsive_control("custom_popup_width", [ 149 "label" => esc_html__("Custom Width", "popup-for-elementor"), 150 "type" => \Elementor\Controls_Manager::SLIDER, 151 "default" => [ 152 "size" => 400, 153 "unit" => "px", 154 ], 155 "size_units" => ["px", "%", "vw"], 156 "range" => [ 157 "px" => [ 158 "min" => 100, 159 "max" => 2000, 160 "step" => 10, 161 ], 162 "%" => [ 163 "min" => 1, 164 "max" => 100, 165 ], 166 "vw" => [ 167 "min" => 1, 168 "max" => 100, 169 ], 170 ], 171 "condition" => [ 172 "popup_width" => "custom", 173 ], 174 "selectors" => [ 175 "{{WRAPPER}} .popup-content" => "width: {{SIZE}}{{UNIT}};", 176 ], 177 ]); 178 179 180 $this->add_responsive_control("popup_height", [ 181 "label" => esc_html__("Popup Height", "popup-for-elementor"), 182 "type" => \Elementor\Controls_Manager::SELECT, 183 "default" => "auto", 184 "options" => [ 185 "auto" => esc_html__("Auto (Fit Content)", "popup-for-elementor"), 186 "custom" => esc_html__("Custom", "popup-for-elementor"), 187 ], 188 "selectors" => [ 189 "{{WRAPPER}} .popup-content" => "height: {{VALUE}};", 190 ], 191 ]); 192 193 $this->add_responsive_control("custom_popup_height", [ 194 "label" => esc_html__("Custom Height", "popup-for-elementor"), 195 "type" => \Elementor\Controls_Manager::SLIDER, 196 "default" => [ 197 "size" => 400, 198 "unit" => "px", 199 ], 200 "size_units" => ["px", "%", "vh"], 201 "range" => [ 202 "px" => [ 203 "min" => 100, 204 "max" => 2000, 205 "step" => 10, 206 ], 207 "%" => [ 208 "min" => 1, 209 "max" => 100, 210 ], 211 "vh" => [ 212 "min" => 1, 213 "max" => 100, 214 ], 215 ], 216 "condition" => [ 217 "popup_height" => "custom", 218 ], 219 "selectors" => [ 220 "{{WRAPPER}} .popup-content" => "height: {{SIZE}}{{UNIT}};", 221 ], 222 ]); 223 224 225 226 $this->add_responsive_control("horizontal_position", [ 227 "label" => esc_html__("Horizontal Position", "popup-for-elementor"), 228 "type" => \Elementor\Controls_Manager::CHOOSE, 229 "options" => [ 230 "flex-start" => [ 231 "title" => esc_html__("Left", "popup-for-elementor"), 232 "icon" => "eicon-h-align-left", 233 ], 234 "center" => [ 235 "title" => esc_html__("Center", "popup-for-elementor"), 236 "icon" => "eicon-h-align-center", 237 ], 238 "flex-end" => [ 239 "title" => esc_html__("Right", "popup-for-elementor"), 240 "icon" => "eicon-h-align-right", 241 ], 242 ], 243 "default" => "center", 244 "selectors" => [ 245 "{{WRAPPER}} .popup-overlay" => "justify-content: {{VALUE}};", 246 ], 247 ]); 248 249 $this->add_responsive_control("vertical_position", [ 250 "label" => esc_html__("Vertical Position", "popup-for-elementor"), 251 "type" => \Elementor\Controls_Manager::CHOOSE, 252 "options" => [ 253 "flex-start" => [ 254 "title" => esc_html__("Top", "popup-for-elementor"), 255 "icon" => "eicon-v-align-top", 256 ], 257 "center" => [ 258 "title" => esc_html__("Center", "popup-for-elementor"), 259 "icon" => "eicon-v-align-middle", 260 ], 261 "flex-end" => [ 262 "title" => esc_html__("Bottom", "popup-for-elementor"), 263 "icon" => "eicon-v-align-bottom", 264 ], 265 ], 266 "default" => "center", 267 "selectors" => [ 268 "{{WRAPPER}} .popup-overlay" => "align-items: {{VALUE}};", 269 ], 270 ]); 271 272 // Control para el margen (Responsive) 273 $this->add_responsive_control( 274 'popup_margin', 275 [ 276 'label' => esc_html__('Margin', 'popup-for-elementor'), 277 'type' => \Elementor\Controls_Manager::DIMENSIONS, 278 'size_units' => ['px', '%', 'em'], 279 'selectors' => [ 280 '{{WRAPPER}} .popup-content' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 281 ], 282 ] 283 ); 284 285 // Control para el padding (Responsive) 286 $this->add_responsive_control( 287 'popup_padding', 288 [ 289 'label' => esc_html__('Padding', 'popup-for-elementor'), 290 'type' => \Elementor\Controls_Manager::DIMENSIONS, 291 'size_units' => ['px', '%', 'em'], 292 'selectors' => [ 293 '{{WRAPPER}} .popup-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 294 ], 295 ] 296 ); 297 298 299 $this->end_controls_section(); 300 301 // Animation 302 303 $this->start_controls_section("animation_section_custom", [ 304 "label" => esc_html__("Animation", "popup-for-elementor"), 305 "tab" => \Elementor\Controls_Manager::TAB_STYLE, // Colocamos esta sección en la pestaña de estilo 306 ]); 307 308 $this->add_control("popup_animation_in", [ 309 "label" => esc_html__("Entrance Animation", "popup-for-elementor"), 310 "type" => \Elementor\Controls_Manager::SELECT, 311 "options" => [ 312 "none" => esc_html__("None", "popup-for-elementor"), 313 "animate__fadeIn" => esc_html__("Fade In", "popup-for-elementor"), 314 "animate__fadeInUp" => esc_html__("Fade In Up", "popup-for-elementor"), 315 "anixmate__fadeInDown" => esc_html__("Fade In Down", "popup-for-elementor"), 316 "animate__fadeInLeft" => esc_html__("Fade In Left", "popup-for-elementor"), 317 "animate__fadeInRight" => esc_html__("Fade In Right", "popup-for-elementor"), 318 "animate__zoomIn" => esc_html__("Zoom In", "popup-for-elementor"), 319 "animate__slideInUp" => esc_html__("Slide In Up", "popup-for-elementor"), 320 "animate__slideInDown" => esc_html__("Slide In Down", "popup-for-elementor"), 321 "animate__slideInLeft" => esc_html__("Slide In Left", "popup-for-elementor"), 322 "animate__slideInRight" => esc_html__("Slide In Right", "popup-for-elementor"), 323 ], 324 "default" => "animate__fadeIn", 325 "description" => esc_html__( 326 "Choose an animation for the popup to appear.", 327 "popup-for-elementor" 328 ), 329 ]); 330 331 $this->add_control("popup_animation_out", [ 332 "label" => esc_html__("Exit Animation", "popup-for-elementor"), 333 "type" => \Elementor\Controls_Manager::SELECT, 334 "options" => [ 335 "none" => esc_html__("None", "popup-for-elementor"), 336 "animate__fadeOut" => esc_html__("Fade Out", "popup-for-elementor"), 337 "animate__fadeOutUp" => esc_html__("Fade Out Up", "popup-for-elementor"), 338 "animate__fadeOutDown" => esc_html__("Fade Out Down", "popup-for-elementor"), 339 "animate__fadeOutLeft" => esc_html__("Fade Out Left", "popup-for-elementor"), 340 "animate__fadeOutRight" => esc_html__("Fade Out Right", "popup-for-elementor"), 341 "animate__zoomOut" => esc_html__("Zoom Out", "popup-for-elementor"), 342 "animate__slideOutUp" => esc_html__("Slide Out Up", "popup-for-elementor"), 343 "animate__slideOutDown" => esc_html__("Slide Out Down", "popup-for-elementor"), 344 "animate__slideOutLeft" => esc_html__("Slide Out Left", "popup-for-elementor"), 345 "animate__slideOutRight" => esc_html__( 346 "Slide Out Right", 347 "popup-for-elementor" 348 ), 349 ], 350 "default" => "animate__fadeOut", 351 "description" => esc_html__( 352 "Choose an animation for the popup to disappear.", 353 "popup-for-elementor" 354 ), 355 ]); 356 357 $this->add_control("animation_duration_custom", [ 358 "label" => esc_html__("Animation Duration (ms)", "popup-for-elementor"), 359 "type" => \Elementor\Controls_Manager::SLIDER, 360 "size_units" => ["ms"], 361 "range" => [ 362 "ms" => [ 363 "min" => 100, 364 "max" => 3000, 365 "step" => 100, 366 ], 367 ], 368 "default" => [ 369 "size" => 500, 370 "unit" => "ms", 371 ], 372 "selectors" => [ 373 "{{WRAPPER}} .popup-content" => 374 "animation-duration: {{SIZE}}{{UNIT}};", 375 ], 376 ]); 377 378 $this->end_controls_section(); 379 //Close Button 380 381 $this->start_controls_section("close_button_section", [ 382 "label" => esc_html__("Close Button", "popup-for-elementor"), 383 "tab" => \Elementor\Controls_Manager::TAB_STYLE, 384 ]); 385 $this->add_control("hide_close_button", [ 386 "label" => esc_html__("Hide Close Button", "popup-for-elementor"), 387 "type" => \Elementor\Controls_Manager::SWITCHER, 388 "label_on" => esc_html__("Yes", "popup-for-elementor"), 389 "label_off" => esc_html__("No", "popup-for-elementor"), 390 "return_value" => "yes", 391 "default" => "no", 392 "selectors" => [ 393 "{{WRAPPER}} .popup-close" => "display: none;", 394 ], 395 ]); 396 397 $this->add_control("close_button_background_color", [ 398 "label" => esc_html__("Close Button Background", "popup-for-elementor"), 399 "type" => \Elementor\Controls_Manager::COLOR, 400 "selectors" => [ 401 "{{WRAPPER}} .popup-close" => "background-color: {{VALUE}};", 402 ], 403 ]); 404 405 $this->add_control("close_button_hover_background_color", [ 406 "label" => esc_html__("Close Button Hover Background", "popup-for-elementor"), 407 "type" => \Elementor\Controls_Manager::COLOR, 408 "selectors" => [ 409 "{{WRAPPER}} .popup-close:hover" => 410 "background-color: {{VALUE}};", 411 ], 412 ]); 413 414 $this->add_control("close_button_color", [ 415 "label" => esc_html__("Close Button Color", "popup-for-elementor"), 416 "type" => \Elementor\Controls_Manager::COLOR, 417 "selectors" => [ 418 "{{WRAPPER}} .popup-close" => "color: {{VALUE}};", 419 ], 420 ]); 421 422 $this->add_control("close_button_hover_color", [ 423 "label" => esc_html__("Close Button Hover Color", "popup-for-elementor"), 424 "type" => \Elementor\Controls_Manager::COLOR, 425 "selectors" => [ 426 "{{WRAPPER}} .popup-close:hover" => "color: {{VALUE}};", 427 ], 428 ]); 429 430 $this->add_control("close_button_size", [ 431 "label" => esc_html__("Close Button Size", "popup-for-elementor"), 432 "type" => \Elementor\Controls_Manager::SLIDER, 433 "size_units" => ["px"], // Solo permite px 434 "range" => [ 435 "px" => [ 436 "min" => 10, 437 "max" => 100, 438 ], 439 ], 440 "default" => [ 441 "unit" => "px", 442 "size" => 40, // Tamaño por defecto del botón de cerrar 443 ], 444 "selectors" => [ 445 "{{WRAPPER}} .popup-close" => 446 "width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}}; font-size: calc({{SIZE}}{{UNIT}} / 2);", 447 ], 448 "description" => esc_html__( 449 "Adjust the size of the close button.", 450 "popup-for-elementor" 451 ), 452 ]); 453 $this->add_control("close_button_alignment", [ 454 "label" => esc_html__("Close Button Alignment", "popup-for-elementor"), 455 "type" => \Elementor\Controls_Manager::CHOOSE, 456 "options" => [ 457 "left" => [ 458 "title" => esc_html__("Left", "popup-for-elementor"), 459 "icon" => "eicon-h-align-left", 460 ], 461 "right" => [ 462 "title" => esc_html__("Right", "popup-for-elementor"), 463 "icon" => "eicon-h-align-right", 464 ], 465 ], 466 "default" => "right", 467 "selectors" => [ 468 "{{WRAPPER}} .popup-close" => "{{VALUE}}: 10px;", 469 ], 470 "description" => esc_html__( 471 "Align the close button to the left or right.", 472 "popup-for-elementor" 473 ), 474 ]); 475 476 $this->add_control("close_button_border_radius", [ 477 "label" => esc_html__("Close Button Border Radius", "popup-for-elementor"), 478 "type" => \Elementor\Controls_Manager::SLIDER, 479 "size_units" => ["px"], // Solo permite px 480 "range" => [ 481 "px" => [ 482 "min" => 0, 483 "max" => 50, 484 ], 485 ], 486 "selectors" => [ 487 "{{WRAPPER}} .popup-close" => 488 "border-radius: {{SIZE}}{{UNIT}};", 489 ], 490 "description" => esc_html__( 491 "Controls the border radius of the close button.", 492 "popup-for-elementor" 493 ), 494 ]); 495 496 $this->end_controls_section(); 497 498 // Visibility controls 499 $this->start_controls_section("visibility_section", [ 500 "label" => esc_html__("Visibility", "popup-for-elementor"), 501 "tab" => \Elementor\Controls_Manager::TAB_CONTENT, 502 ]); 503 504 $this->add_control("show_on_load", [ 505 "label" => esc_html__("Show on Page Load", "popup-for-elementor"), 506 "type" => \Elementor\Controls_Manager::SWITCHER, 507 "default" => "", 508 "description" => esc_html__("Activate to show popup when the page loads. Will disable other visibility options.", "popup-for-elementor"), 509 "condition" => [ 510 "show_after_delay_enabled!" => "yes", 511 "show_on_exit_intent!" => "yes", 512 "show_once!" => "yes", 513 "trigger_selector_enabled!" => "yes", 514 515 ], 516 ]); 517 518 $this->add_control("show_after_delay_enabled", [ 519 "label" => esc_html__("Enable Show After Delay", "popup-for-elementor"), 520 "type" => \Elementor\Controls_Manager::SWITCHER, 521 "default" => "", 522 "description" => esc_html__("Activate to show popup after a delay. Will disable other visibility options.", "popup-for-elementor"), 523 "condition" => [ 524 "show_on_load!" => "yes", 525 "show_on_exit_intent!" => "yes", 526 "show_once!" => "yes", 527 "trigger_selector_enabled!" => "yes", 528 529 ], 530 ]); 531 532 $this->add_control("show_after_delay", [ 533 "label" => esc_html__("Delay (seconds)", "popup-for-elementor"), 534 "type" => \Elementor\Controls_Manager::NUMBER, 535 "default" => 3, 536 "condition" => [ 537 "show_after_delay_enabled" => "yes", 538 539 ], 540 ]); 541 542 $this->add_control("show_on_exit_intent", [ 543 "label" => esc_html__("Show on Exit Intent", "popup-for-elementor"), 544 "type" => \Elementor\Controls_Manager::SWITCHER, 545 "default" => "", 546 "description" => esc_html__("Activate to show popup when the user intends to exit. Will disable other visibility options.", "popup-for-elementor"), 547 "condition" => [ 548 "show_on_load!" => "yes", 549 "show_after_delay_enabled!" => "yes", 550 "show_once!" => "yes", 551 "trigger_selector_enabled!" => "yes", 552 553 ], 554 ]); 555 556 // NUEVO: control interno del Exit Intent (no es switch) 557 $this->add_control("exit_intent_display_mode", [ 558 "label" => esc_html__("Exit Intent — Display", "popup-for-elementor"), 559 "type" => \Elementor\Controls_Manager::SELECT, 560 "default" => "always", 561 "options" => [ 562 "always" => esc_html__("Always", "popup-for-elementor"), 563 "once" => esc_html__("Only once", "popup-for-elementor"), 564 ], 565 "description" => esc_html__("Show the Exit Intent popup always or only once per visitor (cookie).", "popup-for-elementor"), 566 "condition" => [ 567 "show_on_exit_intent" => "yes", // ← aparece solo si el trigger está activo 568 ], 569 ]); 570 571 $this->add_control("show_once", [ 572 "label" => esc_html__("Show Only Once", "popup-for-elementor"), 573 "type" => \Elementor\Controls_Manager::SWITCHER, 574 "default" => "", 575 "description" => esc_html__("Show the popup only once per session.", "popup-for-elementor"), 576 "condition" => [ 577 "show_on_load!" => "yes", 578 "show_after_delay_enabled!" => "yes", 579 "show_on_exit_intent!" => "yes", 580 "trigger_selector_enabled!" => "yes", 581 582 ], 583 ]); 584 585 $this->add_control('trigger_selector_enabled', [ 586 'label' => esc_html__('Trigger by selector (class or ID)', 'popup-for-elementor'), 587 'type' => \Elementor\Controls_Manager::SWITCHER, 588 'label_on' => esc_html__('Yes', 'popup-for-elementor'), 589 'label_off' => esc_html__('No', 'popup-for-elementor'), 590 'return_value' => 'yes', 591 'default' => '', 592 'description' => esc_html__('Enter the class or ID name (without “.” or “#”). Example: my-button or popup-trigger. The popup will open when any element with that class or ID is clicked.', 'popup-for-elementor'), 593 'condition' => [ 594 'show_on_load!' => 'yes', 595 'show_after_delay_enabled!' => 'yes', 596 'show_on_exit_intent!' => 'yes', 597 'show_once!' => 'yes', 598 ], 599 ]); 600 601 602 603 $this->add_control('trigger_selector', [ 604 'label' => esc_html__('Element name (class or ID)', 'popup-for-elementor'), 605 'type' => \Elementor\Controls_Manager::TEXT, 606 'placeholder' => esc_html__('e.g. my-button or popup-trigger', 'popup-for-elementor'), 607 'description' => esc_html__('Enter the class or ID name (without “.” or “#”). Example: my-button or popup-trigger.', 'popup-for-elementor'), 608 'condition' => [ 609 'trigger_selector_enabled' => 'yes', // ← solo dependemos del switch 610 ], 611 ]); 612 613 614 $this->add_control("upgrade_to_pro_notice2", [ 615 "type" => \Elementor\Controls_Manager::RAW_HTML, 616 "raw" => sprintf( 617 '<div style="margin-top: 20px; padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 618 <strong style="display: block; color: #ffffff; font-size: 14px; font-weight: 300; margin-bottom: 12px;">%s</strong> 619 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 620 %s 621 </a> 622 </div>', 623 esc_html__("Need more triggers like Scroll, OnClick, or AdBlock detection?", "popup-for-elementor"), 624 "https://popupforelementor.com/en/home/#buy", 625 esc_html__("Get Popup for Elementor Pro", "popup-for-elementor") 626 ), 627 "content_classes" => "elementor-control-field", 628 ]); 629 $this->end_controls_section(); 630 $this->start_controls_section("refresh_section", [ 631 "label" => esc_html__("Refresh", "popup-for-elementor"), 632 "tab" => \Elementor\Controls_Manager::TAB_CONTENT, 633 ]); 634 635 $this->add_control( 636 'refresh_popup', 637 [ 638 'label' => esc_html__('Refresh Popup', 'popup-for-elementor'), 639 'type' => \Elementor\Controls_Manager::BUTTON, 640 'button_type' => 'success', 641 'text' => esc_html__('Refresh', 'popup-for-elementor'), 642 'description' => esc_html__('Click to refresh the popup content.', 'popup-for-elementor'), 643 'frontend_available' => true, 644 ] 645 ); 646 $this->add_control("upgrade_to_pro_notice3", [ 647 "type" => \Elementor\Controls_Manager::RAW_HTML, 648 "raw" => sprintf( 649 '<div style="margin-top: 20px; padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 650 <strong style="display: block; color: #ffffff; font-size: 14px; font-weight: 300; margin-bottom: 12px;">%s</strong> 651 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 652 %s 653 </a> 654 </div>', 655 esc_html__("Need more triggers like Scroll, OnClick, or AdBlock detection?", "popup-for-elementor"), 656 "https://popupforelementor.com/en/home/#buy", 657 esc_html__("Get Popup for Elementor Pro", "popup-for-elementor") 658 ), 659 "content_classes" => "elementor-control-field", 660 ]); 661 $this->end_controls_section(); 662 $this->start_controls_section("upgrade_section", [ 663 "label" => esc_html__("Popup for Elementor (PRO)", "popup-for-elementor"), 664 "tab" => null, 665 ]); 666 667 $this->add_control("pro_upgrade_box", [ 668 "type" => \Elementor\Controls_Manager::RAW_HTML, 669 "raw" => sprintf( 670 '<div style="padding: 24px; background: linear-gradient(135deg, #1e1e1e, #2b2b2b); border: 1px solid #3c3c3c; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"> 671 <h3 style="color: #ffffff; font-size: 16px; margin-bottom: 12px; font-weight: 600;">%s</h3> 672 <p style="color: #bbbbbb; font-size: 13px; margin-bottom: 20px;">%s</p> 673 <a href="%s" target="_blank" style="display: inline-block; padding: 10px 20px; background-color: #d33a92; color: #fff; border-radius: 4px; text-decoration: none; font-weight: 600; transition: background-color 0.3s;"> 674 %s 675 </a> 676 </div>', 677 esc_html__("Unlock More Power", "popup-for-elementor"), 678 esc_html__("Upgrade to Pro and access all premium triggers and features.", "popup-for-elementor"), 679 "https://popupforelementor.com/en/home/#buy", 680 esc_html__("Upgrade to Pro", "popup-for-elementor") 681 ), 682 ]); 683 684 $this->end_controls_section(); 685 686 687 688 } 689 690 protected function render() 691 { 692 $settings = $this->get_settings_for_display(); 693 694 // Configuraciones dinámicas para pasar al script 695 $config = [ 696 'showOnLoad' => isset($settings['show_on_load']) && $settings['show_on_load'] === 'yes' ? 'yes' : 'no', 697 'delay' => isset($settings['show_after_delay']) ? (int) $settings['show_after_delay'] * 1000 : 0, 698 'exitIntent' => isset($settings['show_on_exit_intent']) && $settings['show_on_exit_intent'] === 'yes' ? 'yes' : 'no', 699 'exitIntentDisplayMode' => !empty($settings['exit_intent_display_mode']) ? $settings['exit_intent_display_mode'] : 'always', 700 'showOnce' => isset($settings['show_once']) && $settings['show_once'] === 'yes' ? 'yes' : 'no', 701 'cookieName' => 'popup_seen', 702 'cookieExpiry'=> 7, 703 'triggerBySelector' => (!empty($settings['trigger_selector_enabled']) && $settings['trigger_selector_enabled'] === 'yes') ? 'yes' : 'no', 704 'triggerSelector' => !empty($settings['trigger_selector']) ? $settings['trigger_selector'] : '', 705 ]; 706 707 708 709 // Pasar configuraciones dinámicas al script 710 wp_localize_script( 12 711 'popup-widget-js', 13 plugin_dir_url(__FILE__) . '../assets/popup-widget.js', 14 array('jquery'), 15 '1.0.0', 16 true 712 'PopupForElementorConfig', 713 $config 17 714 ); 18 $post_id = get_the_ID(); 19 20 if ($post_id) { 21 $dynamic_config = array( 22 'showOnLoad' => get_post_meta($post_id, '_elementor_popup_show_on_load', true) ?: 'no', 23 'delay' => (int) get_post_meta($post_id, '_elementor_popup_delay', true) ?: 0, 24 'showOnScroll' => get_post_meta($post_id, '_elementor_popup_show_on_scroll', true) === 'yes', 25 'scrollPercentage' => (int) (get_post_meta($post_id, '_elementor_popup_scroll_percentage', true) ?: 50), 26 'exitIntent' => get_post_meta($post_id, '_elementor_popup_exit_intent', true) === 'yes', 27 'exitIntentDisplayMode'=> get_post_meta($post_id, '_elementor_exit_intent_display_mode', true) ?: 'always', 28 'cookieName' => 'popup_seen', 29 'cookieExpiry' => 7, 30 'triggerBySelector' => get_post_meta($post_id, '_elementor_trigger_selector_enabled', true) === 'yes', 31 'triggerSelector' => get_post_meta($post_id, '_elementor_trigger_selector', true) ?: '', 32 33 ); 34 35 wp_localize_script( 36 'popup-widget-js', 37 'PopupForElementorConfig', 38 $dynamic_config 39 ); 40 } 41 wp_enqueue_script('popup-widget-js'); 715 716 717 // Obtener animaciones seleccionadas y duración 718 $animation_in = $settings['popup_animation_in'] ?? 'animate__fadeIn'; 719 $animation_out = $settings['popup_animation_out'] ?? 'animate__fadeOut'; 720 $animation_duration = isset($settings['animation_duration_custom']['size']) 721 ? (int) $settings['animation_duration_custom']['size'] 722 : 500; 723 724 // Renderizar plantilla de Elementor si está configurada 725 if (!empty($settings['template_id']) && class_exists('\Elementor\Plugin')) { 726 $popup_content = \Elementor\Plugin::instance()->frontend->get_builder_content_for_display($settings['template_id']); 727 728 if (\Elementor\Plugin::$instance->editor->is_edit_mode()) { 729 // Recuperar la URL del editor de Elementor 730 $edit_url = admin_url('post.php?post=' . absint($settings['template_id']) . '&action=elementor'); 731 732 // Solo eliminar etiquetas que no afecten la funcionalidad 733 $filtered_content = preg_replace('/<meta\b[^>]*>(.*?)<\/meta>/is', '', $popup_content); 734 $filtered_content = preg_replace('/<link\b[^>]*>(.*?)<\/link>/is', '', $filtered_content); 735 736 // Crear contenido para el modal 737 $popup_content = ' 738 <div class="elementor-template-button-wrapper" style="text-align: center; margin-top: 15px;"> 739 <a href="javascript:void(0);" 740 class="popup-edit-button elementor-button elementor-button-success elementor-size-sm button-edit-custom" 741 data-popup-id="' . esc_attr( 'popup_' . get_the_ID() . '_' . $settings['template_id'] ) . '" 742 data-edit-url="' . esc_url($edit_url) . '" 743 id="open-modal"> 744 <i class="eicon-edit" style="margin-right: 8px;"></i>' . esc_html__('Edit Template', 'popup-for-elementor') . ' 745 </a> 746 </div> 747 <div class="popup-editor-content"> 748 ' . $filtered_content . ' 749 </div>'; 42 750 } 43 751 } 44 add_action('wp_enqueue_scripts', 'popup_for_elementor_register_assets'); 45 46 add_action('admin_enqueue_scripts', function () { 47 wp_dequeue_script('popup-widget-js'); 48 wp_deregister_script('popup-widget-js'); 49 }, PHP_INT_MAX); 50 752 753 754 // Generar un identificador único para el popup 755 $current_page_id = get_the_ID(); 756 $popup_id = get_post_meta($settings['template_id'], '_popup_id_' . $current_page_id, true); 757 758 if (empty($popup_id)) { 759 $popup_id = 'popup_' . $current_page_id . '_' . uniqid(); 760 update_post_meta($settings['template_id'], '_popup_id_' . $current_page_id, $popup_id); 761 } 762 763 // Renderizar el HTML del popup con ID único 764 $styles = ''; 765 if (!defined('ELEMENTOR_VERSION') || !\Elementor\Plugin::$instance->editor->is_edit_mode()) { 766 // Aplicar estilos para ocultar el popup fuera del editor 767 $styles = 'display: none; visibility: hidden; opacity: 1;'; 768 } 769 770 function filter_popup_content($content) 771 { 772 // Lista de etiquetas peligrosas a eliminar (pero manteniendo SVGs y estilos de Elementor) 773 $dangerous_tags = ['iframe', 'embed', 'object', 'applet', 'meta', 'link']; 774 775 foreach ($dangerous_tags as $tag) { 776 $content = preg_replace('/<' . $tag . '.*?>.*?<\/' . $tag . '>/is', '', $content); 777 $content = preg_replace('/<' . $tag . '.*?>/is', '', $content); 778 } 779 780 return $content; 781 } 782 783 /* Escaping is not applied here because the content has already been filtered 784 by `filter_popup_content()`, which removes dangerous tags. 785 Using `esc_html()` would break Elementor's functionality. 786 This code has been reviewed and is safe. */ 787 788 $popup_content_filtered = filter_popup_content($popup_content); 789 790 echo '<div id="' . esc_attr($popup_id) . '" class="popup-overlay popup-widget" style="' . esc_attr($styles) . '"> 791 <div class="popup-content animate__animated ' . esc_attr($animation_in) . '" 792 style="position: relative; animation-duration: ' . esc_attr($animation_duration) . 'ms;"> 793 <button class="popup-close">×</button>'; 794 795 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 796 echo $popup_content_filtered; 797 798 echo '</div></div>'; 799 800 // This script controls the popup behavior (open/close, animations, hover effects). 801 // It must be injected directly here because Elementor dynamically refreshes widget content. 802 // Using wp_enqueue_script or wp_add_inline_script would not persist across reloads. 803 804 echo '<script> 805 (function($) { 806 $(document).ready(function() { 807 const popup = $("#' . 808 esc_attr($popup_id) . 809 '"); 810 const popupContent = popup.find(".popup-content"); 811 812 if (popup.length) { 813 // Abrir popup con animación de entrada 814 popup.closest(".elementor-widget-popup_widget").off("click").on("click", function(e) { 815 e.preventDefault(); 816 popup.css({ 817 display: "flex", 818 visibility: "visible" 819 }); 820 popupContent.removeClass("' . 821 esc_attr($animation_out) . 822 '").addClass("' . 823 esc_attr($animation_in) . 824 '"); 825 }); 826 827 // Cerrar popup con animación de salida 828 popup.find(".popup-close").off("click").on("click", function(e) { 829 e.stopPropagation(); 830 popupContent 831 .removeClass("' . 832 esc_attr($animation_in) . 833 '") 834 .addClass("' . 835 esc_attr($animation_out) . 836 '"); 837 838 // Esperar la duración de la animación antes de ocultar el popup 839 const duration = ' . 840 esc_attr($animation_duration) . 841 '; 842 setTimeout(function() { 843 popup.css({ 844 display: "none", 845 visibility: "hidden" 846 }); 847 popupContent.removeClass("' . 848 esc_attr($animation_out) . 849 '"); 850 }, duration); 851 }); 852 853 // Hover en el botón para cambiar el fondo del popup 854 popup.find(".popup-edit-button").on("mouseenter", function() { 855 popupContent.css("background-color", "#ffebf2"); 856 }).on("mouseleave", function() { 857 popupContent.css("background-color", ""); 858 }); 859 } else { 860 console.error("Popup element not found in the DOM."); 861 } 862 }); 863 elementor.hooks.addAction("panel/open_editor/widget", function (panel, model) { 864 panel.$el.on("click", ".elementor-control-refresh_popup .elementor-button", function () { 865 console.log("¡Botón clicado! Refrescando el widget..."); 866 867 // Simular un cambio en el modelo 868 model.set("refresh_trigger", Date.now()); // Valor ficticio para forzar el cambio 869 model.trigger("change"); // Notificar el cambio a Elementor 870 871 // Verificar si Elementor actualiza la vista 872 setTimeout(function () { 873 console.log("Intentando recargar la vista previa..."); 874 elementor.reloadPreview(); // Forzar la recarga si no responde 875 elementor.once("preview:loaded", function () { 876 console.log("Vista previa recargada correctamente."); 877 878 // Reabrir el popup después de recargar la vista previa 879 const $popupOverlay = jQuery(".popup-overlay"); 880 if ($popupOverlay.length) { 881 console.log("Reabriendo el popup..."); 882 $popupOverlay.css({ 883 display: "", 884 visibility: "", 885 opacity: 1, 886 }); 887 console.log("Popup reabierto correctamente."); 888 } else { 889 console.error("No se encontró el popup en el DOM."); 890 } 891 }); 892 }, 500); // Fallback por si el trigger no es suficiente 893 }); 894 }); 895 })(jQuery); 896 </script>'; 897 898 // This script controls the custom modal editor outside the iframe (open, close, panel resize). 899 // Since the modal is rendered outside the iframe (via editor/after_footer), 900 // this script needs to access it using parent.jQuery. 901 // It must be echoed directly to stay bound to the button rendered in the iframe. 902 903 echo '<div id="custom-modal"> 904 <div class="modal-container"> 905 <div class="modal-header"> 906 <div class="modal-title" style="display: flex; align-items: center;"> 907 <div style="width: 40px; height: 40px; background-color: white; border-radius: 50%; display: flex; justify-content: center; align-items: center; margin-right: 10px;"> 908 <span class="eicon-table-of-contents" style="font-size: 20px; color: #333;"></span> <!-- Icono de Elementor --> 909 </div> 910 ' . esc_html__("Popup for Elementor", "popup-for-elementor") . ' 911 </div> 912 <button id="close-modal">×</button> 913 </div> 914 <iframe id="modal-iframe" src=""></iframe> 915 </div> 916 </div>'; 917 918 echo '<script> 919 (function($) { 920 $(document).ready(function() { 921 const $modal = $("#custom-modal"); 922 const $iframe = $("#modal-iframe"); 923 const $closeButton = $("#close-modal"); 924 925 let originalPanelStyles = {}; // Guardamos los estilos originales 926 927 function refreshWidget() { 928 console.log("Ejecutando refresh del widget..."); 929 if (typeof parent.elementor !== "undefined" && parent.elementor.reloadPreview) { 930 parent.elementor.reloadPreview(); 931 parent.elementor.once("preview:loaded", function() { 932 console.log("Vista previa recargada correctamente."); 933 }); 934 } 935 } 936 937 function toggleElementorPanel(reduce) { 938 if (typeof parent.jQuery !== "undefined") { 939 const $panel = parent.jQuery("#elementor-panel"); 940 const $preview = parent.jQuery("#elementor-preview"); 941 942 if (reduce) { 943 console.log("Guardando estado del panel y reduciéndolo..."); 944 originalPanelStyles = { 945 width: $panel.css("width"), 946 minWidth: $panel.css("min-width"), 947 maxWidth: $panel.css("max-width"), 948 overflow: $panel.css("overflow"), 949 visibility: $panel.css("visibility"), 950 opacity: $panel.css("opacity"), 951 }; 952 953 $panel.css({ 954 "width": "60px", 955 "min-width": "60px", 956 "max-width": "60px", 957 "overflow": "hidden", 958 "visibility": "hidden", 959 "opacity": "0", 960 "transition": "width 0.3s ease-in-out" 961 }); 962 963 $preview.css({ 964 "width": "calc(100% - 60px)", 965 "transition": "width 0.3s ease-in-out" 966 }); 967 } else { 968 console.log("Restaurando el panel de Elementor..."); 969 $panel.css(originalPanelStyles); 970 971 $preview.css({ 972 "width": "calc(100% - " + originalPanelStyles.width + ")" 973 }); 974 } 975 } 976 } 977 978 $("#open-modal").on("click", function() { 979 console.log("Modal abierto, reduciendo panel en la ventana principal..."); 980 const editUrl = $(this).data("edit-url"); 981 $iframe.attr("src", editUrl); 982 $modal.removeClass("hide").addClass("show"); 983 984 toggleElementorPanel(true); 985 }); 986 987 $closeButton.on("click", function() { 988 console.log("Cerrando modal, restaurando panel en la ventana principal..."); 989 $modal.removeClass("show").addClass("hide"); 990 991 setTimeout(() => { 992 $iframe.attr("src", ""); // Limpiar el iframe 993 toggleElementorPanel(false); 994 refreshWidget(); 995 }, 300); 996 }); 997 998 console.log("Script de reducción de panel cargado."); 999 }); 1000 })(jQuery); 1001 </script>'; 1002 } 1003 } -
popup-for-elementor/trunk/includes/popup-handler.php
r3382610 r3383555 3 3 // Dynamically passes configuration from Elementor controls to the JavaScript. 4 4 5 if (!defined('ABSPATH')) exit; 5 if (!defined('ABSPATH')) { 6 exit; 7 } 8 function popup_for_elementor_register_assets() 9 { 10 if (!is_admin()) { 11 wp_register_script( 12 'popup-widget-js', 13 plugin_dir_url(__FILE__) . '../assets/popup-widget.js', 14 array('jquery'), 15 '1.0.0', 16 true 17 ); 18 $post_id = get_the_ID(); 6 19 7 if ( ! function_exists( 'popup_for_elementor_register_assets' ) ) { 8 function popup_for_elementor_register_assets() { 9 if (!is_admin()) { 10 wp_register_script( 20 if ($post_id) { 21 $dynamic_config = array( 22 'showOnLoad' => get_post_meta($post_id, '_elementor_popup_show_on_load', true) ?: 'no', 23 'delay' => (int) get_post_meta($post_id, '_elementor_popup_delay', true) ?: 0, 24 'showOnScroll' => get_post_meta($post_id, '_elementor_popup_show_on_scroll', true) === 'yes', 25 'scrollPercentage' => (int) (get_post_meta($post_id, '_elementor_popup_scroll_percentage', true) ?: 50), 26 'exitIntent' => get_post_meta($post_id, '_elementor_popup_exit_intent', true) === 'yes', 27 'exitIntentDisplayMode'=> get_post_meta($post_id, '_elementor_exit_intent_display_mode', true) ?: 'always', 28 'cookieName' => 'popup_seen', 29 'cookieExpiry' => 7, 30 'triggerBySelector' => get_post_meta($post_id, '_elementor_trigger_selector_enabled', true) === 'yes', 31 'triggerSelector' => get_post_meta($post_id, '_elementor_trigger_selector', true) ?: '', 32 33 ); 34 35 wp_localize_script( 11 36 'popup-widget-js', 12 plugin_dir_url(__FILE__) . '../assets/popup-widget.js', 13 array('jquery'), 14 '1.0.0', 15 true 37 'PopupForElementorConfig', 38 $dynamic_config 16 39 ); 17 18 $post_id = get_the_ID();19 20 if ($post_id) {21 $dynamic_config = array(22 'showOnLoad' => get_post_meta($post_id, '_elementor_popup_show_on_load', true) ?: 'no',23 'delay' => (int) get_post_meta($post_id, '_elementor_popup_delay', true) ?: 0,24 'showOnScroll' => get_post_meta($post_id, '_elementor_popup_show_on_scroll', true) === 'yes',25 'scrollPercentage' => (int) (get_post_meta($post_id, '_elementor_popup_scroll_percentage', true) ?: 50),26 'exitIntent' => get_post_meta($post_id, '_elementor_popup_exit_intent', true) === 'yes',27 'exitIntentDisplayMode' => get_post_meta($post_id, '_elementor_exit_intent_display_mode', true) ?: 'always',28 'cookieName' => 'popup_seen',29 'cookieExpiry' => 7,30 'triggerBySelector' => get_post_meta($post_id, '_elementor_trigger_selector_enabled', true) === 'yes',31 'triggerSelector' => get_post_meta($post_id, '_elementor_trigger_selector', true) ?: '',32 );33 34 wp_localize_script('popup-widget-js','PopupForElementorConfig',$dynamic_config);35 }36 37 wp_enqueue_script('popup-widget-js');38 40 } 41 wp_enqueue_script('popup-widget-js'); 39 42 } 40 43 } 41 42 44 add_action('wp_enqueue_scripts', 'popup_for_elementor_register_assets'); 43 45 … … 46 48 wp_deregister_script('popup-widget-js'); 47 49 }, PHP_INT_MAX); 50 -
popup-for-elementor/trunk/popup-for-elementor.php
r3382610 r3383555 4 4 * Plugin URI: https://www.popupforelementor.com 5 5 * Description: Create powerful, fully customizable popups directly in Elementor Free — includes click, delay, load, and exit-intent triggers, animations, and smart visibility controls to boost user engagement. 6 * Version: 1.5.9 6 * Version: 1.5.9.1 7 7 * Author: Veelo 8 8 * Author URI: https://www.veelo.es -
popup-for-elementor/trunk/readme.txt
r3382610 r3383555 97 97 == Changelog == 98 98 99 = 1.6 = 100 * **Fix:** File correction. 101 99 102 = 1.5.9 = 100 103 * **Fix:** Prevented rare fatal error caused by multiple declarations of `popup_for_elementor_register_assets()` on some setups. … … 133 136 == Upgrade Notice == 134 137 135 = 1. 5.9=138 = 1.6 = 136 139 🛠️ Fixes a rare **fatal error** that could occur when scripts were loaded twice. 137 140 Highly recommended update for all users to ensure full compatibility and stability.
Note: See TracChangeset
for help on using the changeset viewer.