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

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