testimonial.php (15970B)
1 <?php 2 namespace Elementor; 3 4 if ( ! defined( 'ABSPATH' ) ) { 5 exit; // Exit if accessed directly. 6 } 7 8 use Elementor\Core\Kits\Documents\Tabs\Global_Colors; 9 use Elementor\Core\Kits\Documents\Tabs\Global_Typography; 10 11 /** 12 * Elementor testimonial widget. 13 * 14 * Elementor widget that displays customer testimonials that show social proof. 15 * 16 * @since 1.0.0 17 */ 18 class Widget_Testimonial extends Widget_Base { 19 20 /** 21 * Get widget name. 22 * 23 * Retrieve testimonial widget name. 24 * 25 * @since 1.0.0 26 * @access public 27 * 28 * @return string Widget name. 29 */ 30 public function get_name() { 31 return 'testimonial'; 32 } 33 34 /** 35 * Get widget title. 36 * 37 * Retrieve testimonial widget title. 38 * 39 * @since 1.0.0 40 * @access public 41 * 42 * @return string Widget title. 43 */ 44 public function get_title() { 45 return esc_html__( 'Testimonial', 'elementor' ); 46 } 47 48 /** 49 * Get widget icon. 50 * 51 * Retrieve testimonial widget icon. 52 * 53 * @since 1.0.0 54 * @access public 55 * 56 * @return string Widget icon. 57 */ 58 public function get_icon() { 59 return 'eicon-testimonial'; 60 } 61 62 /** 63 * Get widget keywords. 64 * 65 * Retrieve the list of keywords the widget belongs to. 66 * 67 * @since 2.1.0 68 * @access public 69 * 70 * @return array Widget keywords. 71 */ 72 public function get_keywords() { 73 return [ 'testimonial', 'blockquote' ]; 74 } 75 76 /** 77 * Register testimonial widget controls. 78 * 79 * Adds different input fields to allow the user to change and customize the widget settings. 80 * 81 * @since 3.1.0 82 * @access protected 83 */ 84 protected function register_controls() { 85 $this->start_controls_section( 86 'section_testimonial', 87 [ 88 'label' => esc_html__( 'Testimonial', 'elementor' ), 89 ] 90 ); 91 92 $this->add_control( 93 'testimonial_content', 94 [ 95 'label' => esc_html__( 'Content', 'elementor' ), 96 'type' => Controls_Manager::TEXTAREA, 97 'dynamic' => [ 98 'active' => true, 99 ], 100 'rows' => '10', 101 'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ), 102 ] 103 ); 104 105 $this->add_control( 106 'testimonial_image', 107 [ 108 'label' => esc_html__( 'Choose Image', 'elementor' ), 109 'type' => Controls_Manager::MEDIA, 110 'dynamic' => [ 111 'active' => true, 112 ], 113 'default' => [ 114 'url' => Utils::get_placeholder_image_src(), 115 ], 116 ] 117 ); 118 119 $this->add_group_control( 120 Group_Control_Image_Size::get_type(), 121 [ 122 'name' => 'testimonial_image', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `testimonial_image_size` and `testimonial_image_custom_dimension`. 123 'default' => 'full', 124 'separator' => 'none', 125 ] 126 ); 127 128 $this->add_control( 129 'testimonial_name', 130 [ 131 'label' => esc_html__( 'Name', 'elementor' ), 132 'type' => Controls_Manager::TEXT, 133 'dynamic' => [ 134 'active' => true, 135 ], 136 'default' => 'John Doe', 137 ] 138 ); 139 140 $this->add_control( 141 'testimonial_job', 142 [ 143 'label' => esc_html__( 'Title', 'elementor' ), 144 'type' => Controls_Manager::TEXT, 145 'dynamic' => [ 146 'active' => true, 147 ], 148 'default' => 'Designer', 149 ] 150 ); 151 152 $this->add_control( 153 'link', 154 [ 155 'label' => esc_html__( 'Link', 'elementor' ), 156 'type' => Controls_Manager::URL, 157 'dynamic' => [ 158 'active' => true, 159 ], 160 'placeholder' => esc_html__( 'https://your-link.com', 'elementor' ), 161 ] 162 ); 163 164 $this->add_control( 165 'testimonial_image_position', 166 [ 167 'label' => esc_html__( 'Image Position', 'elementor' ), 168 'type' => Controls_Manager::SELECT, 169 'default' => 'aside', 170 'options' => [ 171 'aside' => esc_html__( 'Aside', 'elementor' ), 172 'top' => esc_html__( 'Top', 'elementor' ), 173 ], 174 'condition' => [ 175 'testimonial_image[url]!' => '', 176 ], 177 'separator' => 'before', 178 'style_transfer' => true, 179 ] 180 ); 181 182 $this->add_responsive_control( 183 'testimonial_alignment', 184 [ 185 'label' => esc_html__( 'Alignment', 'elementor' ), 186 'type' => Controls_Manager::CHOOSE, 187 'default' => 'center', 188 'options' => [ 189 'left' => [ 190 'title' => esc_html__( 'Left', 'elementor' ), 191 'icon' => 'eicon-text-align-left', 192 ], 193 'center' => [ 194 'title' => esc_html__( 'Center', 'elementor' ), 195 'icon' => 'eicon-text-align-center', 196 ], 197 'right' => [ 198 'title' => esc_html__( 'Right', 'elementor' ), 199 'icon' => 'eicon-text-align-right', 200 ], 201 ], 202 'selectors' => [ 203 '{{WRAPPER}} .elementor-testimonial-wrapper' => 'text-align: {{VALUE}}', 204 ], 205 'style_transfer' => true, 206 ] 207 ); 208 209 $this->add_control( 210 'view', 211 [ 212 'label' => esc_html__( 'View', 'elementor' ), 213 'type' => Controls_Manager::HIDDEN, 214 'default' => 'traditional', 215 ] 216 ); 217 218 $this->end_controls_section(); 219 220 // Content. 221 $this->start_controls_section( 222 'section_style_testimonial_content', 223 [ 224 'label' => esc_html__( 'Content', 'elementor' ), 225 'tab' => Controls_Manager::TAB_STYLE, 226 ] 227 ); 228 229 $this->add_control( 230 'content_content_color', 231 [ 232 'label' => esc_html__( 'Text Color', 'elementor' ), 233 'type' => Controls_Manager::COLOR, 234 'global' => [ 235 'default' => Global_Colors::COLOR_TEXT, 236 ], 237 'default' => '', 238 'selectors' => [ 239 '{{WRAPPER}} .elementor-testimonial-content' => 'color: {{VALUE}};', 240 ], 241 ] 242 ); 243 244 $this->add_group_control( 245 Group_Control_Typography::get_type(), 246 [ 247 'name' => 'content_typography', 248 'global' => [ 249 'default' => Global_Typography::TYPOGRAPHY_TEXT, 250 ], 251 'selector' => '{{WRAPPER}} .elementor-testimonial-content', 252 ] 253 ); 254 255 $this->add_group_control( 256 Group_Control_Text_Shadow::get_type(), 257 [ 258 'name' => 'content_shadow', 259 'selector' => '{{WRAPPER}} .elementor-testimonial-content', 260 ] 261 ); 262 263 $this->end_controls_section(); 264 265 // Image. 266 $this->start_controls_section( 267 'section_style_testimonial_image', 268 [ 269 'label' => esc_html__( 'Image', 'elementor' ), 270 'tab' => Controls_Manager::TAB_STYLE, 271 'condition' => [ 272 'testimonial_image[url]!' => '', 273 ], 274 ] 275 ); 276 277 $this->add_control( 278 'image_size', 279 [ 280 'label' => esc_html__( 'Image Size', 'elementor' ), 281 'type' => Controls_Manager::SLIDER, 282 'size_units' => [ 'px' ], 283 'range' => [ 284 'px' => [ 285 'min' => 20, 286 'max' => 200, 287 ], 288 ], 289 'selectors' => [ 290 '{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img' => 'width: {{SIZE}}{{UNIT}};height: {{SIZE}}{{UNIT}};', 291 ], 292 ] 293 ); 294 295 $this->add_group_control( 296 Group_Control_Border::get_type(), 297 [ 298 'name' => 'image_border', 299 'selector' => '{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img', 300 'separator' => 'before', 301 ] 302 ); 303 304 $this->add_control( 305 'image_border_radius', 306 [ 307 'label' => esc_html__( 'Border Radius', 'elementor' ), 308 'type' => Controls_Manager::DIMENSIONS, 309 'size_units' => [ 'px', '%' ], 310 'selectors' => [ 311 '{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 312 ], 313 ] 314 ); 315 316 $this->end_controls_section(); 317 318 // Name. 319 $this->start_controls_section( 320 'section_style_testimonial_name', 321 [ 322 'label' => esc_html__( 'Name', 'elementor' ), 323 'tab' => Controls_Manager::TAB_STYLE, 324 ] 325 ); 326 327 $this->add_control( 328 'name_text_color', 329 [ 330 'label' => esc_html__( 'Text Color', 'elementor' ), 331 'type' => Controls_Manager::COLOR, 332 'global' => [ 333 'default' => Global_Colors::COLOR_PRIMARY, 334 ], 335 'default' => '', 336 'selectors' => [ 337 '{{WRAPPER}} .elementor-testimonial-name' => 'color: {{VALUE}};', 338 ], 339 ] 340 ); 341 342 $this->add_group_control( 343 Group_Control_Typography::get_type(), 344 [ 345 'name' => 'name_typography', 346 'global' => [ 347 'default' => Global_Typography::TYPOGRAPHY_PRIMARY, 348 ], 349 'selector' => '{{WRAPPER}} .elementor-testimonial-name', 350 ] 351 ); 352 353 $this->add_group_control( 354 Group_Control_Text_Shadow::get_type(), 355 [ 356 'name' => 'name_shadow', 357 'selector' => '{{WRAPPER}} .elementor-testimonial-name', 358 ] 359 ); 360 361 $this->end_controls_section(); 362 363 // Job. 364 $this->start_controls_section( 365 'section_style_testimonial_job', 366 [ 367 'label' => esc_html__( 'Title', 'elementor' ), 368 'tab' => Controls_Manager::TAB_STYLE, 369 ] 370 ); 371 372 $this->add_control( 373 'job_text_color', 374 [ 375 'label' => esc_html__( 'Text Color', 'elementor' ), 376 'type' => Controls_Manager::COLOR, 377 'global' => [ 378 'default' => Global_Colors::COLOR_SECONDARY, 379 ], 380 'default' => '', 381 'selectors' => [ 382 '{{WRAPPER}} .elementor-testimonial-job' => 'color: {{VALUE}};', 383 ], 384 ] 385 ); 386 387 $this->add_group_control( 388 Group_Control_Typography::get_type(), 389 [ 390 'name' => 'job_typography', 391 'global' => [ 392 'default' => Global_Typography::TYPOGRAPHY_SECONDARY, 393 ], 394 'selector' => '{{WRAPPER}} .elementor-testimonial-job', 395 ] 396 ); 397 398 $this->add_group_control( 399 Group_Control_Text_Shadow::get_type(), 400 [ 401 'name' => 'job_shadow', 402 'selector' => '{{WRAPPER}} .elementor-testimonial-job', 403 ] 404 ); 405 406 $this->end_controls_section(); 407 } 408 409 /** 410 * Render testimonial widget output on the frontend. 411 * 412 * Written in PHP and used to generate the final HTML. 413 * 414 * @since 1.0.0 415 * @access protected 416 */ 417 protected function render() { 418 $settings = $this->get_settings_for_display(); 419 420 $this->add_render_attribute( 'wrapper', 'class', 'elementor-testimonial-wrapper' ); 421 422 $this->add_render_attribute( 'meta', 'class', 'elementor-testimonial-meta' ); 423 424 if ( $settings['testimonial_image']['url'] ) { 425 $this->add_render_attribute( 'meta', 'class', 'elementor-has-image' ); 426 } 427 428 if ( $settings['testimonial_image_position'] ) { 429 $this->add_render_attribute( 'meta', 'class', 'elementor-testimonial-image-position-' . $settings['testimonial_image_position'] ); 430 } 431 432 $has_content = ! ! $settings['testimonial_content']; 433 $has_image = ! ! $settings['testimonial_image']['url']; 434 $has_name = ! ! $settings['testimonial_name']; 435 $has_job = ! ! $settings['testimonial_job']; 436 437 if ( ! $has_content && ! $has_image && ! $has_name && ! $has_job ) { 438 return; 439 } 440 441 if ( ! empty( $settings['link']['url'] ) ) { 442 $this->add_link_attributes( 'link', $settings['link'] ); 443 } 444 ?> 445 <div <?php $this->print_render_attribute_string( 'wrapper' ); ?>> 446 <?php 447 if ( $has_content ) : 448 $this->add_render_attribute( 'testimonial_content', 'class', 'elementor-testimonial-content' ); 449 $this->add_inline_editing_attributes( 'testimonial_content' ); 450 ?> 451 <div <?php $this->print_render_attribute_string( 'testimonial_content' ); ?>><?php $this->print_unescaped_setting( 'testimonial_content' ); ?></div> 452 <?php endif; ?> 453 454 <?php if ( $has_image || $has_name || $has_job ) : ?> 455 <div <?php $this->print_render_attribute_string( 'meta' ); ?>> 456 <div class="elementor-testimonial-meta-inner"> 457 <?php if ( $has_image ) : ?> 458 <div class="elementor-testimonial-image"> 459 <?php 460 $image_html = Group_Control_Image_Size::get_attachment_image_html( $settings, 'testimonial_image' ); 461 if ( ! empty( $settings['link']['url'] ) ) : 462 $image_html = '<a ' . $this->get_render_attribute_string( 'link' ) . '>' . $image_html . '</a>'; 463 endif; 464 echo wp_kses_post( $image_html ); 465 ?> 466 </div> 467 <?php endif; ?> 468 469 <?php if ( $has_name || $has_job ) : ?> 470 <div class="elementor-testimonial-details"> 471 <?php 472 if ( $has_name ) : 473 $this->add_render_attribute( 'testimonial_name', 'class', 'elementor-testimonial-name' ); 474 $this->add_inline_editing_attributes( 'testimonial_name', 'none' ); 475 476 if ( ! empty( $settings['link']['url'] ) ) : 477 ?> 478 <a <?php $this->print_render_attribute_string( 'testimonial_name' ); ?> <?php $this->print_render_attribute_string( 'link' ); ?>><?php $this->print_unescaped_setting( 'testimonial_name' ); ?></a> 479 <?php 480 else : 481 ?> 482 <div <?php $this->print_render_attribute_string( 'testimonial_name' ); ?>><?php $this->print_unescaped_setting( 'testimonial_name' ); ?></div> 483 <?php 484 endif; 485 endif; ?> 486 <?php 487 if ( $has_job ) : 488 $this->add_render_attribute( 'testimonial_job', 'class', 'elementor-testimonial-job' ); 489 490 $this->add_inline_editing_attributes( 'testimonial_job', 'none' ); 491 492 if ( ! empty( $settings['link']['url'] ) ) : 493 ?> 494 <a <?php $this->print_render_attribute_string( 'testimonial_job' ); ?> <?php $this->print_render_attribute_string( 'link' ); ?>><?php $this->print_unescaped_setting( 'testimonial_job' ); ?></a> 495 <?php 496 else : 497 ?> 498 <div <?php $this->print_render_attribute_string( 'testimonial_job' ); ?>><?php $this->print_unescaped_setting( 'testimonial_job' ); ?></div> 499 <?php 500 endif; 501 endif; ?> 502 </div> 503 <?php endif; ?> 504 </div> 505 </div> 506 <?php endif; ?> 507 </div> 508 <?php 509 } 510 511 /** 512 * Render testimonial widget output in the editor. 513 * 514 * Written as a Backbone JavaScript template and used to generate the live preview. 515 * 516 * @since 2.9.0 517 * @access protected 518 */ 519 protected function content_template() { 520 ?> 521 <# 522 var image = { 523 id: settings.testimonial_image.id, 524 url: settings.testimonial_image.url, 525 size: settings.testimonial_image_size, 526 dimension: settings.testimonial_image_custom_dimension, 527 model: view.getEditModel() 528 }; 529 var imageUrl = false, hasImage = ''; 530 531 if ( '' !== settings.testimonial_image.url ) { 532 imageUrl = elementor.imagesManager.getImageUrl( image ); 533 hasImage = ' elementor-has-image'; 534 535 var imageHtml = '<img src="' + imageUrl + '" alt="testimonial" />'; 536 if ( settings.link.url ) { 537 imageHtml = '<a href="' + settings.link.url + '">' + imageHtml + '</a>'; 538 } 539 } 540 541 var testimonial_image_position = settings.testimonial_image_position ? ' elementor-testimonial-image-position-' + settings.testimonial_image_position : ''; 542 #> 543 <div class="elementor-testimonial-wrapper"> 544 <# if ( '' !== settings.testimonial_content ) { 545 view.addRenderAttribute( 'testimonial_content', 'class', 'elementor-testimonial-content' ); 546 547 view.addInlineEditingAttributes( 'testimonial_content' ); 548 #> 549 <div {{{ view.getRenderAttributeString( 'testimonial_content' ) }}}>{{{ settings.testimonial_content }}}</div> 550 <# } #> 551 <div class="elementor-testimonial-meta{{ hasImage }}{{ testimonial_image_position }}"> 552 <div class="elementor-testimonial-meta-inner"> 553 <# if ( imageUrl ) { #> 554 <div class="elementor-testimonial-image">{{{ imageHtml }}}</div> 555 <# } #> 556 <div class="elementor-testimonial-details"> 557 <?php $this->render_testimonial_description(); ?> 558 </div> 559 </div> 560 </div> 561 </div> 562 <?php 563 } 564 565 protected function render_testimonial_description() { 566 ?> 567 <# 568 if ( '' !== settings.testimonial_name ) { 569 view.addRenderAttribute( 'testimonial_name', 'class', 'elementor-testimonial-name' ); 570 571 view.addInlineEditingAttributes( 'testimonial_name', 'none' ); 572 573 if ( settings.link.url ) { 574 #> 575 <a href="{{{ settings.link.url }}}" {{{ view.getRenderAttributeString( 'testimonial_name' ) }}}>{{{ settings.testimonial_name }}}</a> 576 <# 577 } else { 578 #> 579 <div {{{ view.getRenderAttributeString( 'testimonial_name' ) }}}>{{{ settings.testimonial_name }}}</div> 580 <# 581 } 582 } 583 584 if ( '' !== settings.testimonial_job ) { 585 view.addRenderAttribute( 'testimonial_job', 'class', 'elementor-testimonial-job' ); 586 587 view.addInlineEditingAttributes( 'testimonial_job', 'none' ); 588 589 if ( settings.link.url ) { 590 #> 591 <a href="{{{ settings.link.url }}}" {{{ view.getRenderAttributeString( 'testimonial_job' ) }}}>{{{ settings.testimonial_job }}}</a> 592 <# 593 } else { 594 #> 595 <div {{{ view.getRenderAttributeString( 'testimonial_job' ) }}}>{{{ settings.testimonial_job }}}</div> 596 <# 597 } 598 } 599 #> 600 <?php 601 } 602 }