PluginProbe
Elementor Website Builder – more than just a page builder / 3.22.2
Elementor Website Builder – more than just a page builder v3.22.2
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.22.2, at includes/widgets/testimonial.php

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