PluginProbe
Elementor Website Builder – more than just a page builder / 3.25.5
Elementor Website Builder – more than just a page builder v3.25.5
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / includes / widgets / testimonial.php

testimonial.php in Elementor Website Builder – more than just a page builder 3.25.5, at includes/widgets/testimonial.php

654 lines 17.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 protected function is_dynamic_content(): bool {
77 return false;
78 }
79
80 /**
81 * Get style dependencies.
82 *
83 * Retrieve the list of style dependencies the widget requires.
84 *
85 * @since 3.24.0
86 * @access public
87 *
88 * @return array Widget style dependencies.
89 */
90 public function get_style_depends(): array {
91 return [ 'widget-testimonial' ];
92 }
93
94 /**
95 * Get widget upsale data.
96 *
97 * Retrieve the widget promotion data.
98 *
99 * @since 3.18.0
100 * @access protected
101 *
102 * @return array Widget promotion data.
103 */
104 protected function get_upsale_data() {
105 return [
106 'condition' => ! Utils::has_pro(),
107 'image' => esc_url( ELEMENTOR_ASSETS_URL . 'images/go-pro.svg' ),
108 'image_alt' => esc_attr__( 'Upgrade', 'elementor' ),
109 'description' => esc_html__( 'Use interesting masonry layouts and other overlay features with Elementor\'s Pro Gallery widget.', 'elementor' ),
110 'upgrade_url' => esc_url( 'https://go.elementor.com/go-pro-testimonial-widget/' ),
111 'upgrade_text' => esc_html__( 'Upgrade Now', 'elementor' ),
112 ];
113 }
114
115 /**
116 * Register testimonial widget controls.
117 *
118 * Adds different input fields to allow the user to change and customize the widget settings.
119 *
120 * @since 3.1.0
121 * @access protected
122 */
123 protected function register_controls() {
124 $this->start_controls_section(
125 'section_testimonial',
126 [
127 'label' => esc_html__( 'Testimonial', 'elementor' ),
128 ]
129 );
130
131 $this->add_control(
132 'testimonial_content',
133 [
134 'label' => esc_html__( 'Content', 'elementor' ),
135 'type' => Controls_Manager::TEXTAREA,
136 'dynamic' => [
137 'active' => true,
138 ],
139 'rows' => '10',
140 'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
141 ]
142 );
143
144 $this->add_control(
145 'testimonial_image',
146 [
147 'label' => esc_html__( 'Choose Image', 'elementor' ),
148 'type' => Controls_Manager::MEDIA,
149 'dynamic' => [
150 'active' => true,
151 ],
152 'default' => [
153 'url' => Utils::get_placeholder_image_src(),
154 ],
155 ]
156 );
157
158 $this->add_group_control(
159 Group_Control_Image_Size::get_type(),
160 [
161 'name' => 'testimonial_image', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `testimonial_image_size` and `testimonial_image_custom_dimension`.
162 'default' => 'full',
163 ]
164 );
165
166 $this->add_control(
167 'testimonial_name',
168 [
169 'label' => esc_html__( 'Name', 'elementor' ),
170 'type' => Controls_Manager::TEXT,
171 'dynamic' => [
172 'active' => true,
173 ],
174 'ai' => [
175 'active' => false,
176 ],
177 'default' => esc_html__( 'John Doe', 'elementor' ),
178 ]
179 );
180
181 $this->add_control(
182 'testimonial_job',
183 [
184 'label' => esc_html__( 'Title', 'elementor' ),
185 'type' => Controls_Manager::TEXT,
186 'dynamic' => [
187 'active' => true,
188 ],
189 'ai' => [
190 'active' => false,
191 ],
192 'default' => esc_html__( 'Designer', 'elementor' ),
193 ]
194 );
195
196 $this->add_control(
197 'link',
198 [
199 'label' => esc_html__( 'Link', 'elementor' ),
200 'type' => Controls_Manager::URL,
201 'dynamic' => [
202 'active' => true,
203 ],
204 ]
205 );
206
207 $aside = is_rtl() ? 'right' : 'left';
208
209 $this->add_control(
210 'testimonial_image_position',
211 [
212 'label' => esc_html__( 'Image Position', 'elementor' ),
213 'type' => Controls_Manager::CHOOSE,
214 'default' => 'aside',
215 'options' => [
216 'aside' => [
217 'title' => esc_html__( 'Aside', 'elementor' ),
218 'icon' => 'eicon-h-align-' . $aside,
219 ],
220 'top' => [
221 'title' => esc_html__( 'Top', 'elementor' ),
222 'icon' => 'eicon-v-align-top',
223 ],
224 ],
225 'toggle' => false,
226 'condition' => [
227 'testimonial_image[url]!' => '',
228 ],
229 'separator' => 'before',
230 'style_transfer' => true,
231 ]
232 );
233
234 $this->add_responsive_control(
235 'testimonial_alignment',
236 [
237 'label' => esc_html__( 'Alignment', 'elementor' ),
238 'type' => Controls_Manager::CHOOSE,
239 'default' => 'center',
240 'options' => [
241 'left' => [
242 'title' => esc_html__( 'Left', 'elementor' ),
243 'icon' => 'eicon-text-align-left',
244 ],
245 'center' => [
246 'title' => esc_html__( 'Center', 'elementor' ),
247 'icon' => 'eicon-text-align-center',
248 ],
249 'right' => [
250 'title' => esc_html__( 'Right', 'elementor' ),
251 'icon' => 'eicon-text-align-right',
252 ],
253 ],
254 'selectors' => [
255 '{{WRAPPER}} .elementor-testimonial-wrapper' => 'text-align: {{VALUE}}',
256 ],
257 'style_transfer' => true,
258 ]
259 );
260
261 $this->end_controls_section();
262
263 // Content.
264 $this->start_controls_section(
265 'section_style_testimonial_content',
266 [
267 'label' => esc_html__( 'Content', 'elementor' ),
268 'tab' => Controls_Manager::TAB_STYLE,
269 ]
270 );
271
272 $this->add_control(
273 'content_content_color',
274 [
275 'label' => esc_html__( 'Text Color', 'elementor' ),
276 'type' => Controls_Manager::COLOR,
277 'global' => [
278 'default' => Global_Colors::COLOR_TEXT,
279 ],
280 'default' => '',
281 'selectors' => [
282 '{{WRAPPER}} .elementor-testimonial-content' => 'color: {{VALUE}};',
283 ],
284 ]
285 );
286
287 $this->add_group_control(
288 Group_Control_Typography::get_type(),
289 [
290 'name' => 'content_typography',
291 'global' => [
292 'default' => Global_Typography::TYPOGRAPHY_TEXT,
293 ],
294 'selector' => '{{WRAPPER}} .elementor-testimonial-content',
295 ]
296 );
297
298 $this->add_group_control(
299 Group_Control_Text_Shadow::get_type(),
300 [
301 'name' => 'content_shadow',
302 'selector' => '{{WRAPPER}} .elementor-testimonial-content',
303 ]
304 );
305
306 $this->end_controls_section();
307
308 // Image.
309 $this->start_controls_section(
310 'section_style_testimonial_image',
311 [
312 'label' => esc_html__( 'Image', 'elementor' ),
313 'tab' => Controls_Manager::TAB_STYLE,
314 'condition' => [
315 'testimonial_image[url]!' => '',
316 ],
317 ]
318 );
319
320 $this->add_responsive_control(
321 'image_size',
322 [
323 'label' => esc_html__( 'Image Resolution', 'elementor' ),
324 'type' => Controls_Manager::SLIDER,
325 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
326 'range' => [
327 'px' => [
328 'min' => 20,
329 'max' => 200,
330 ],
331 ],
332 'selectors' => [
333 '{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img' => 'width: {{SIZE}}{{UNIT}};height: {{SIZE}}{{UNIT}};',
334 ],
335 ]
336 );
337
338 $this->add_group_control(
339 Group_Control_Border::get_type(),
340 [
341 'name' => 'image_border',
342 'selector' => '{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img',
343 'separator' => 'before',
344 ]
345 );
346
347 $this->add_responsive_control(
348 'image_border_radius',
349 [
350 'label' => esc_html__( 'Border Radius', 'elementor' ),
351 'type' => Controls_Manager::DIMENSIONS,
352 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
353 'selectors' => [
354 '{{WRAPPER}} .elementor-testimonial-wrapper .elementor-testimonial-image img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
355 ],
356 ]
357 );
358
359 $this->end_controls_section();
360
361 // Name.
362 $this->start_controls_section(
363 'section_style_testimonial_name',
364 [
365 'label' => esc_html__( 'Name', 'elementor' ),
366 'tab' => Controls_Manager::TAB_STYLE,
367 ]
368 );
369
370 $this->add_control(
371 'name_text_color',
372 [
373 'label' => esc_html__( 'Text Color', 'elementor' ),
374 'type' => Controls_Manager::COLOR,
375 'global' => [
376 'default' => Global_Colors::COLOR_PRIMARY,
377 ],
378 'default' => '',
379 'selectors' => [
380 '{{WRAPPER}} .elementor-testimonial-name' => 'color: {{VALUE}};',
381 ],
382 ]
383 );
384
385 $this->add_group_control(
386 Group_Control_Typography::get_type(),
387 [
388 'name' => 'name_typography',
389 'global' => [
390 'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
391 ],
392 'selector' => '{{WRAPPER}} .elementor-testimonial-name',
393 ]
394 );
395
396 $this->add_group_control(
397 Group_Control_Text_Shadow::get_type(),
398 [
399 'name' => 'name_shadow',
400 'selector' => '{{WRAPPER}} .elementor-testimonial-name',
401 ]
402 );
403
404 $this->end_controls_section();
405
406 // Job.
407 $this->start_controls_section(
408 'section_style_testimonial_job',
409 [
410 'label' => esc_html__( 'Title', 'elementor' ),
411 'tab' => Controls_Manager::TAB_STYLE,
412 ]
413 );
414
415 $this->add_control(
416 'job_text_color',
417 [
418 'label' => esc_html__( 'Text Color', 'elementor' ),
419 'type' => Controls_Manager::COLOR,
420 'global' => [
421 'default' => Global_Colors::COLOR_SECONDARY,
422 ],
423 'default' => '',
424 'selectors' => [
425 '{{WRAPPER}} .elementor-testimonial-job' => 'color: {{VALUE}};',
426 ],
427 ]
428 );
429
430 $this->add_group_control(
431 Group_Control_Typography::get_type(),
432 [
433 'name' => 'job_typography',
434 'global' => [
435 'default' => Global_Typography::TYPOGRAPHY_SECONDARY,
436 ],
437 'selector' => '{{WRAPPER}} .elementor-testimonial-job',
438 ]
439 );
440
441 $this->add_group_control(
442 Group_Control_Text_Shadow::get_type(),
443 [
444 'name' => 'job_shadow',
445 'selector' => '{{WRAPPER}} .elementor-testimonial-job',
446 ]
447 );
448
449 $this->end_controls_section();
450 }
451
452 /**
453 * Render testimonial widget output on the frontend.
454 *
455 * Written in PHP and used to generate the final HTML.
456 *
457 * @since 1.0.0
458 * @access protected
459 */
460 protected function render() {
461 $settings = $this->get_settings_for_display();
462
463 $has_content = ! empty( $settings['testimonial_content'] );
464 $has_image = ! empty( $settings['testimonial_image']['url'] );
465 $has_name = ! empty( $settings['testimonial_name'] );
466 $has_job = ! empty( $settings['testimonial_job'] );
467
468 if ( ! $has_content && ! $has_image && ! $has_name && ! $has_job ) {
469 return;
470 }
471
472 $this->add_render_attribute( 'wrapper', 'class', 'elementor-testimonial-wrapper' );
473
474 $this->add_render_attribute( 'meta', 'class', 'elementor-testimonial-meta' );
475
476 if ( $settings['testimonial_image']['url'] ) {
477 $this->add_render_attribute( 'meta', 'class', 'elementor-has-image' );
478 }
479
480 if ( $settings['testimonial_image_position'] ) {
481 $this->add_render_attribute( 'meta', 'class', 'elementor-testimonial-image-position-' . $settings['testimonial_image_position'] );
482 }
483
484 if ( ! empty( $settings['link']['url'] ) ) {
485 $this->add_link_attributes( 'link', $settings['link'] );
486 }
487 ?>
488 <div <?php $this->print_render_attribute_string( 'wrapper' ); ?>>
489 <?php
490 if ( $has_content ) :
491 $this->add_render_attribute( 'testimonial_content', 'class', 'elementor-testimonial-content' );
492 $this->add_inline_editing_attributes( 'testimonial_content' );
493 ?>
494 <div <?php $this->print_render_attribute_string( 'testimonial_content' ); ?>><?php $this->print_unescaped_setting( 'testimonial_content' ); ?></div>
495 <?php endif; ?>
496
497 <?php if ( $has_image || $has_name || $has_job ) : ?>
498 <div <?php $this->print_render_attribute_string( 'meta' ); ?>>
499 <div class="elementor-testimonial-meta-inner">
500 <?php if ( $has_image ) : ?>
501 <div class="elementor-testimonial-image">
502 <?php
503 $image_html = Group_Control_Image_Size::get_attachment_image_html( $settings, 'testimonial_image' );
504 if ( ! empty( $settings['link']['url'] ) ) :
505 $image_html = '<a ' . $this->get_render_attribute_string( 'link' ) . '>' . $image_html . '</a>';
506 endif;
507 echo wp_kses_post( $image_html );
508 ?>
509 </div>
510 <?php endif; ?>
511
512 <?php if ( $has_name || $has_job ) : ?>
513 <div class="elementor-testimonial-details">
514 <?php
515 if ( $has_name ) :
516 $this->add_render_attribute( 'testimonial_name', 'class', 'elementor-testimonial-name' );
517 $this->add_inline_editing_attributes( 'testimonial_name', 'none' );
518
519 if ( ! empty( $settings['link']['url'] ) ) :
520 ?>
521 <a <?php $this->print_render_attribute_string( 'testimonial_name' ); ?> <?php $this->print_render_attribute_string( 'link' ); ?>><?php $this->print_unescaped_setting( 'testimonial_name' ); ?></a>
522 <?php
523 else :
524 ?>
525 <div <?php $this->print_render_attribute_string( 'testimonial_name' ); ?>><?php $this->print_unescaped_setting( 'testimonial_name' ); ?></div>
526 <?php
527 endif;
528 endif; ?>
529 <?php
530 if ( $has_job ) :
531 $this->add_render_attribute( 'testimonial_job', 'class', 'elementor-testimonial-job' );
532
533 $this->add_inline_editing_attributes( 'testimonial_job', 'none' );
534
535 if ( ! empty( $settings['link']['url'] ) ) :
536 ?>
537 <a <?php $this->print_render_attribute_string( 'testimonial_job' ); ?> <?php $this->print_render_attribute_string( 'link' ); ?>><?php $this->print_unescaped_setting( 'testimonial_job' ); ?></a>
538 <?php
539 else :
540 ?>
541 <div <?php $this->print_render_attribute_string( 'testimonial_job' ); ?>><?php $this->print_unescaped_setting( 'testimonial_job' ); ?></div>
542 <?php
543 endif;
544 endif; ?>
545 </div>
546 <?php endif; ?>
547 </div>
548 </div>
549 <?php endif; ?>
550 </div>
551 <?php
552 }
553
554 /**
555 * Render testimonial widget output in the editor.
556 *
557 * Written as a Backbone JavaScript template and used to generate the live preview.
558 *
559 * @since 2.9.0
560 * @access protected
561 */
562 protected function content_template() {
563 ?>
564 <#
565 if ( '' === settings.testimonial_content && '' === settings.testimonial_image.url && '' === settings.testimonial_name && '' === settings.testimonial_job ) {
566 return;
567 }
568
569 var image = {
570 id: settings.testimonial_image.id,
571 url: settings.testimonial_image.url,
572 size: settings.testimonial_image_size,
573 dimension: settings.testimonial_image_custom_dimension,
574 model: view.getEditModel()
575 };
576 var imageUrl = false, hasImage = '';
577
578 if ( '' !== settings.testimonial_image.url ) {
579 imageUrl = elementor.imagesManager.getImageUrl( image );
580 hasImage = ' elementor-has-image';
581
582 var imageHtml = '<img src="' + _.escape( imageUrl ) + '" alt="testimonial" />';
583 if ( settings.link.url ) {
584 imageHtml = '<a href="' + elementor.helpers.sanitizeUrl( settings.link.url ) + '">' + imageHtml + '</a>';
585 }
586 }
587
588 var testimonial_image_position = settings.testimonial_image_position ? ' elementor-testimonial-image-position-' + settings.testimonial_image_position : '';
589 #>
590 <div class="elementor-testimonial-wrapper">
591 <# if ( '' !== settings.testimonial_content ) {
592 view.addRenderAttribute( 'testimonial_content', {
593 'data-binding-type': 'content',
594 'data-binding-setting': 'testimonial_content',
595 } );
596 view.addRenderAttribute( 'testimonial_content', 'class', 'elementor-testimonial-content' );
597
598 view.addInlineEditingAttributes( 'testimonial_content' );
599 #>
600 <div {{{ view.getRenderAttributeString( 'testimonial_content' ) }}}>{{{ settings.testimonial_content }}}</div>
601 <# } #>
602 <div class="elementor-testimonial-meta{{ hasImage }}{{ testimonial_image_position }}">
603 <div class="elementor-testimonial-meta-inner">
604 <# if ( imageUrl ) { #>
605 <div class="elementor-testimonial-image">{{{ imageHtml }}}</div>
606 <# } #>
607 <div class="elementor-testimonial-details">
608 <?php $this->render_testimonial_description(); ?>
609 </div>
610 </div>
611 </div>
612 </div>
613 <?php
614 }
615
616 protected function render_testimonial_description() {
617 ?>
618 <#
619 if ( '' !== settings.testimonial_name ) {
620 view.addRenderAttribute( 'testimonial_name', 'class', 'elementor-testimonial-name' );
621
622 view.addInlineEditingAttributes( 'testimonial_name', 'none' );
623
624 if ( settings.link.url ) {
625 #>
626 <a href="{{ elementor.helpers.sanitizeUrl( settings.link.url ) }}" {{{ view.getRenderAttributeString( 'testimonial_name' ) }}}>{{{ settings.testimonial_name }}}</a>
627 <#
628 } else {
629 #>
630 <div {{{ view.getRenderAttributeString( 'testimonial_name' ) }}}>{{{ settings.testimonial_name }}}</div>
631 <#
632 }
633 }
634
635 if ( '' !== settings.testimonial_job ) {
636 view.addRenderAttribute( 'testimonial_job', 'class', 'elementor-testimonial-job' );
637
638 view.addInlineEditingAttributes( 'testimonial_job', 'none' );
639
640 if ( settings.link.url ) {
641 #>
642 <a href="{{ elementor.helpers.sanitizeUrl( settings.link.url ) }}" {{{ view.getRenderAttributeString( 'testimonial_job' ) }}}>{{{ settings.testimonial_job }}}</a>
643 <#
644 } else {
645 #>
646 <div {{{ view.getRenderAttributeString( 'testimonial_job' ) }}}>{{{ settings.testimonial_job }}}</div>
647 <#
648 }
649 }
650 #>
651 <?php
652 }
653 }
654