PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.63
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.63
51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 All 40 releases
king-addons / includes / widgets / Pull_Quotes_Callouts_Builder / Pull_Quotes_Callouts_Builder.php

Pull_Quotes_Callouts_Builder.php in King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder 51.1.63, at includes/widgets/Pull_Quotes_Callouts_Builder/Pull_Quotes_Callouts_Builder.php

1,455 lines 47.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Pull Quotes & Callouts Builder Widget (Free).
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons;
9
10 use Elementor\Controls_Manager;
11 use Elementor\Group_Control_Background;
12 use Elementor\Group_Control_Border;
13 use Elementor\Group_Control_Box_Shadow;
14 use Elementor\Group_Control_Typography;
15 use Elementor\Icons_Manager;
16 use Elementor\Widget_Base;
17
18 if (!defined('ABSPATH')) {
19 exit;
20 }
21
22 /**
23 * Pull Quotes & Callouts Builder widget.
24 */
25 class Pull_Quotes_Callouts_Builder extends Widget_Base
26 {
27 /**
28 * Widget slug.
29 *
30 * @return string
31 */
32 public function get_name(): string
33 {
34 return 'king-addons-pull-quotes-callouts-builder';
35 }
36
37 /**
38 * Widget title.
39 *
40 * @return string
41 */
42 public function get_title(): string
43 {
44 return esc_html__('Pull Quotes & Callouts Builder', 'king-addons');
45 }
46
47 /**
48 * Widget icon.
49 *
50 * @return string
51 */
52 public function get_icon(): string
53 {
54 return 'king-addons-icon king-addons-pull-quotes-callouts-builder';
55 }
56
57 /**
58 * Style dependencies.
59 *
60 * @return array<int, string>
61 */
62 public function get_style_depends(): array
63 {
64 return [
65 KING_ADDONS_ASSETS_UNIQUE_KEY . '-pull-quotes-callouts-builder-style',
66 ];
67 }
68
69 /**
70 * Script dependencies.
71 *
72 * @return array<int, string>
73 */
74 public function get_script_depends(): array
75 {
76 return [];
77 }
78
79 /**
80 * Categories.
81 *
82 * @return array<int, string>
83 */
84 public function get_categories(): array
85 {
86 return ['king-addons'];
87 }
88
89 /**
90 * Keywords.
91 *
92 * @return array<int, string>
93 */
94 public function get_keywords(): array
95 {
96 return ['quote', 'pull quote', 'callout', 'editorial', 'highlight', 'testimonial', 'tip'];
97 }
98
99 public function get_custom_help_url()
100 {
101 return 'mailto:[email protected]?subject=Bug Report - King Addons&body=Please describe the issue';
102 }
103
104 /**
105 * Register controls.
106 *
107 * @return void
108 */
109 public function register_controls(): void
110 {
111 $this->register_content_controls();
112 $this->register_layout_controls();
113 $this->register_style_controls();
114 $this->register_pro_notice_controls();
115 }
116
117 /**
118 * Render widget output.
119 *
120 * @return void
121 */
122 public function render(): void
123 {
124 $settings = $this->get_settings_for_display();
125
126 $block_type = $this->sanitize_block_type($settings['kng_block_type'] ?? 'pull-quote');
127 $preset = $this->sanitize_preset($settings['kng_preset'] ?? 'classic-accent');
128 $mark_style = $this->sanitize_mark_style($settings['kng_quote_mark_style'] ?? 'classic');
129 $mark_mode = $this->sanitize_mark_mode($settings['kng_quote_mark_mode'] ?? 'corner');
130 $icon_position = $this->sanitize_icon_position($settings['kng_icon_position'] ?? 'left');
131 $accent_side = $this->sanitize_accent_side($settings['kng_accent_side'] ?? 'left');
132
133 $show_mark = $block_type === 'pull-quote' && ($settings['kng_quote_mark_show'] ?? 'yes') === 'yes';
134 $show_icon = $block_type === 'callout' && ($settings['kng_icon_enable'] ?? 'yes') === 'yes';
135 $show_label = $block_type === 'callout' && ($settings['kng_label_show'] ?? '') === 'yes';
136
137 $wrapper_classes = [
138 'king-addons-pull-quotes-callouts',
139 'king-addons-pull-quotes-callouts--type-' . $block_type,
140 'king-addons-pull-quotes-callouts--preset-' . $preset,
141 'king-addons-pull-quotes-callouts--accent-' . $accent_side,
142 'king-addons-pull-quotes-callouts--mark-' . $mark_style,
143 'king-addons-pull-quotes-callouts--mark-mode-' . $mark_mode,
144 ];
145
146 if ($show_icon) {
147 $wrapper_classes[] = 'king-addons-pull-quotes-callouts--icon-' . $icon_position;
148 } else {
149 $wrapper_classes[] = 'king-addons-pull-quotes-callouts--icon-none';
150 }
151
152 if (!$show_mark) {
153 $wrapper_classes[] = 'king-addons-pull-quotes-callouts--mark-hidden';
154 }
155
156 if ($show_label) {
157 $wrapper_classes[] = 'king-addons-pull-quotes-callouts--label-enabled';
158 }
159
160 $this->add_render_attribute('wrapper', [
161 'class' => $wrapper_classes,
162 ]);
163
164 $text = $settings['kng_text'] ?? '';
165 $author = $settings['kng_author_name'] ?? '';
166 $source = $settings['kng_author_source'] ?? '';
167 $label = $settings['kng_label_text'] ?? '';
168
169 $link = $settings['kng_link'] ?? [];
170 $href = is_array($link) ? ($link['url'] ?? '') : '';
171 $is_external = is_array($link) && !empty($link['is_external']);
172 $nofollow = is_array($link) && !empty($link['nofollow']);
173 $rels = [];
174 if ($is_external) {
175 $rels[] = 'noopener';
176 $rels[] = 'noreferrer';
177 }
178 if ($nofollow) {
179 $rels[] = 'nofollow';
180 }
181 $rel_attr = !empty($rels) ? ' rel="' . esc_attr(implode(' ', array_unique($rels))) . '"' : '';
182 $target_attr = $is_external ? ' target="_blank"' : '';
183 $link_text = $settings['kng_link_text'] ?? '';
184
185 $wrapper_tag = $block_type === 'pull-quote' ? 'figure' : 'aside';
186 $role_attr = $block_type === 'callout' ? ' role="note"' : '';
187
188 echo '<' . esc_html($wrapper_tag) . ' ' . $this->get_render_attribute_string('wrapper') . $role_attr . '>';
189 echo '<div class="king-addons-pull-quotes-callouts__inner">';
190
191 if ($show_icon && !empty($settings['kng_icon']['value'])) {
192 echo '<span class="king-addons-pull-quotes-callouts__icon" aria-hidden="true">';
193 Icons_Manager::render_icon($settings['kng_icon'], ['aria-hidden' => 'true']);
194 echo '</span>';
195 }
196
197 echo '<div class="king-addons-pull-quotes-callouts__body">';
198
199 if ($show_label && !empty($label)) {
200 echo '<span class="king-addons-pull-quotes-callouts__label">' . esc_html($label) . '</span>';
201 }
202
203 if ($show_mark) {
204 echo '<span class="king-addons-pull-quotes-callouts__mark" aria-hidden="true">&#8220;</span>';
205 }
206
207 if (!empty($text)) {
208 if ($block_type === 'pull-quote') {
209 echo '<blockquote class="king-addons-pull-quotes-callouts__text">' . wp_kses_post($text) . '</blockquote>';
210 } else {
211 echo '<div class="king-addons-pull-quotes-callouts__text">' . wp_kses_post($text) . '</div>';
212 }
213 }
214
215 if (!empty($href) && !empty($link_text)) {
216 echo '<a class="king-addons-pull-quotes-callouts__link" href="' . esc_url($href) . '"' . $target_attr . $rel_attr . '>' . esc_html($link_text) . '</a>';
217 }
218
219 echo '</div>';
220 echo '</div>';
221
222 if (!empty($author) || !empty($source)) {
223 $footer_tag = $block_type === 'pull-quote' ? 'figcaption' : 'div';
224 $separator = $settings['kng_author_source_separator'] ?? '';
225 echo '<' . esc_html($footer_tag) . ' class="king-addons-pull-quotes-callouts__footer">';
226 if (!empty($author)) {
227 echo '<span class="king-addons-pull-quotes-callouts__author">' . esc_html($author) . '</span>';
228 }
229 if (!empty($separator) && !empty($author) && !empty($source)) {
230 echo '<span class="king-addons-pull-quotes-callouts__separator" aria-hidden="true">' . esc_html($separator) . '</span>';
231 }
232 if (!empty($source)) {
233 echo '<span class="king-addons-pull-quotes-callouts__source">' . esc_html($source) . '</span>';
234 }
235 echo '</' . esc_html($footer_tag) . '>';
236 }
237
238 echo '</' . esc_html($wrapper_tag) . '>';
239 }
240
241 /**
242 * Content controls.
243 *
244 * @return void
245 */
246 protected function register_content_controls(): void
247 {
248 $can_pro = king_addons_can_use_pro();
249
250 $this->start_controls_section(
251 'kng_content_section',
252 [
253 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
254 'tab' => Controls_Manager::TAB_CONTENT,
255 ]
256 );
257
258 $this->add_control(
259 'kng_block_type',
260 [
261 'label' => esc_html__('Block Type', 'king-addons'),
262 'type' => Controls_Manager::SELECT,
263 'default' => 'pull-quote',
264 'options' => [
265 'pull-quote' => esc_html__('Pull Quote', 'king-addons'),
266 'callout' => esc_html__('Callout', 'king-addons'),
267 ],
268 ]
269 );
270
271 $this->add_control(
272 'kng_preset',
273 [
274 'label' => esc_html__('Preset', 'king-addons'),
275 'type' => Controls_Manager::VISUAL_CHOICE,
276 'label_block' => true,
277 'columns' => 4,
278 'default' => 'classic-accent',
279 'options' => $this->get_preset_options(),
280 'render_type' => 'template',
281 ]
282 );
283
284 $this->add_control(
285 'kng_text',
286 [
287 'label' => esc_html__('Main Text', 'king-addons'),
288 'type' => Controls_Manager::WYSIWYG,
289 'default' => '<p>' . esc_html__('Add your quote or callout text here.', 'king-addons') . '</p>',
290 'dynamic' => [
291 'active' => $can_pro,
292 ],
293 ]
294 );
295
296 $this->add_control(
297 'kng_author_name',
298 [
299 'label' => esc_html__('Author', 'king-addons'),
300 'type' => Controls_Manager::TEXT,
301 'dynamic' => [
302 'active' => $can_pro,
303 ],
304 ]
305 );
306
307 $this->add_control(
308 'kng_author_source',
309 [
310 'label' => esc_html__('Source / Role', 'king-addons'),
311 'type' => Controls_Manager::TEXT,
312 'dynamic' => [
313 'active' => $can_pro,
314 ],
315 ]
316 );
317
318 $this->add_control(
319 'kng_label_show',
320 [
321 'label' => esc_html__('Show Label', 'king-addons'),
322 'type' => Controls_Manager::SWITCHER,
323 'return_value' => 'yes',
324 'default' => 'yes',
325 'condition' => [
326 'kng_block_type' => 'callout',
327 ],
328 ]
329 );
330
331 $this->add_control(
332 'kng_label_text',
333 [
334 'label' => esc_html__('Label Text', 'king-addons'),
335 'type' => Controls_Manager::TEXT,
336 'default' => esc_html__('Callout', 'king-addons'),
337 'dynamic' => [
338 'active' => $can_pro,
339 ],
340 'condition' => [
341 'kng_block_type' => 'callout',
342 'kng_label_show' => 'yes',
343 ],
344 ]
345 );
346
347 $this->add_control(
348 'kng_quote_mark_show',
349 [
350 'label' => esc_html__('Show Quote Mark', 'king-addons'),
351 'type' => Controls_Manager::SWITCHER,
352 'return_value' => 'yes',
353 'default' => 'yes',
354 'condition' => [
355 'kng_block_type' => 'pull-quote',
356 ],
357 ]
358 );
359
360 $this->add_control(
361 'kng_quote_mark_style',
362 [
363 'label' => esc_html__('Quote Mark Style', 'king-addons'),
364 'type' => Controls_Manager::SELECT,
365 'default' => 'classic',
366 'options' => [
367 'classic' => esc_html__('Classic', 'king-addons'),
368 'modern' => esc_html__('Modern', 'king-addons'),
369 'minimal' => esc_html__('Minimal', 'king-addons'),
370 ],
371 'condition' => [
372 'kng_block_type' => 'pull-quote',
373 'kng_quote_mark_show' => 'yes',
374 ],
375 ]
376 );
377
378 $this->add_control(
379 'kng_quote_mark_mode',
380 [
381 'label' => esc_html__('Quote Mark Mode', 'king-addons'),
382 'type' => Controls_Manager::SELECT,
383 'default' => 'corner',
384 'options' => [
385 'corner' => esc_html__('Corner', 'king-addons'),
386 'inline' => esc_html__('Inline', 'king-addons'),
387 'watermark' => esc_html__('Watermark', 'king-addons'),
388 ],
389 'condition' => [
390 'kng_block_type' => 'pull-quote',
391 'kng_quote_mark_show' => 'yes',
392 ],
393 ]
394 );
395
396 $this->add_control(
397 'kng_icon_enable',
398 [
399 'label' => esc_html__('Show Icon', 'king-addons'),
400 'type' => Controls_Manager::SWITCHER,
401 'return_value' => 'yes',
402 'default' => 'yes',
403 'condition' => [
404 'kng_block_type' => 'callout',
405 ],
406 ]
407 );
408
409 $this->add_control(
410 'kng_icon',
411 [
412 'label' => esc_html__('Icon', 'king-addons'),
413 'type' => Controls_Manager::ICONS,
414 'default' => [
415 'value' => 'fas fa-quote-left',
416 'library' => 'fa-solid',
417 ],
418 'condition' => [
419 'kng_block_type' => 'callout',
420 'kng_icon_enable' => 'yes',
421 ],
422 ]
423 );
424
425 $this->add_control(
426 'kng_icon_position',
427 [
428 'label' => esc_html__('Icon Position', 'king-addons'),
429 'type' => Controls_Manager::SELECT,
430 'default' => 'left',
431 'options' => [
432 'left' => esc_html__('Left', 'king-addons'),
433 'top' => esc_html__('Top', 'king-addons'),
434 ],
435 'condition' => [
436 'kng_block_type' => 'callout',
437 'kng_icon_enable' => 'yes',
438 ],
439 ]
440 );
441
442 $this->add_control(
443 'kng_link',
444 [
445 'label' => esc_html__('Link', 'king-addons'),
446 'type' => Controls_Manager::URL,
447 'dynamic' => [
448 'active' => $can_pro,
449 ],
450 'show_external' => true,
451 ]
452 );
453
454 $this->add_control(
455 'kng_link_text',
456 [
457 'label' => esc_html__('Link Text', 'king-addons'),
458 'type' => Controls_Manager::TEXT,
459 'default' => esc_html__('Read more', 'king-addons'),
460 'condition' => [
461 'kng_link[url]!' => '',
462 ],
463 ]
464 );
465
466 $this->end_controls_section();
467 }
468
469 /**
470 * Layout controls.
471 *
472 * @return void
473 */
474 protected function register_layout_controls(): void
475 {
476 $this->start_controls_section(
477 'kng_layout_section',
478 [
479 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Layout', 'king-addons'),
480 'tab' => Controls_Manager::TAB_STYLE,
481 ]
482 );
483
484 $this->add_responsive_control(
485 'kng_alignment',
486 [
487 'label' => esc_html__('Alignment', 'king-addons'),
488 'type' => Controls_Manager::CHOOSE,
489 'toggle' => true,
490 'default' => 'left',
491 'options' => [
492 'left' => [
493 'title' => esc_html__('Left', 'king-addons'),
494 'icon' => 'eicon-text-align-left',
495 ],
496 'center' => [
497 'title' => esc_html__('Center', 'king-addons'),
498 'icon' => 'eicon-text-align-center',
499 ],
500 'right' => [
501 'title' => esc_html__('Right', 'king-addons'),
502 'icon' => 'eicon-text-align-right',
503 ],
504 ],
505 'prefix_class' => 'king-addons-pqcb-align%s-',
506 'selectors' => [
507 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => 'text-align: {{VALUE}};',
508 ],
509 ]
510 );
511
512 $this->add_responsive_control(
513 'kng_gap',
514 [
515 'label' => esc_html__('Gap', 'king-addons'),
516 'type' => Controls_Manager::SLIDER,
517 'size_units' => ['px'],
518 'range' => [
519 'px' => [
520 'min' => 0,
521 'max' => 60,
522 ],
523 ],
524 'default' => [
525 'size' => 14,
526 'unit' => 'px',
527 ],
528 'selectors' => [
529 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-gap: {{SIZE}}{{UNIT}};',
530 ],
531 ]
532 );
533
534 $this->add_responsive_control(
535 'kng_padding',
536 [
537 'label' => esc_html__('Padding', 'king-addons'),
538 'type' => Controls_Manager::DIMENSIONS,
539 'size_units' => ['px', '%', 'em', 'rem'],
540 'selectors' => [
541 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
542 ],
543 ]
544 );
545
546 $this->add_responsive_control(
547 'kng_margin',
548 [
549 'label' => esc_html__('Margin', 'king-addons'),
550 'type' => Controls_Manager::DIMENSIONS,
551 'size_units' => ['px', '%', 'em', 'rem'],
552 'selectors' => [
553 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
554 ],
555 ]
556 );
557
558 $this->end_controls_section();
559 }
560
561 /**
562 * Style controls.
563 *
564 * @return void
565 */
566 protected function register_style_controls(): void
567 {
568 $this->start_controls_section(
569 'kng_style_box_section',
570 [
571 'label' => esc_html__('Box', 'king-addons'),
572 'tab' => Controls_Manager::TAB_STYLE,
573 ]
574 );
575
576 $this->add_group_control(
577 Group_Control_Background::get_type(),
578 [
579 'name' => 'kng_background',
580 'types' => ['classic', 'gradient'],
581 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts',
582 ]
583 );
584
585 $this->add_group_control(
586 Group_Control_Border::get_type(),
587 [
588 'name' => 'kng_border',
589 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts',
590 ]
591 );
592
593 $this->add_control(
594 'kng_border_radius',
595 [
596 'label' => esc_html__('Border Radius', 'king-addons'),
597 'type' => Controls_Manager::SLIDER,
598 'size_units' => ['px', '%'],
599 'range' => [
600 'px' => [
601 'min' => 0,
602 'max' => 80,
603 ],
604 '%' => [
605 'min' => 0,
606 'max' => 50,
607 ],
608 ],
609 'selectors' => [
610 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => 'border-radius: {{SIZE}}{{UNIT}};',
611 ],
612 ]
613 );
614
615 $this->add_group_control(
616 Group_Control_Box_Shadow::get_type(),
617 [
618 'name' => 'kng_shadow',
619 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts',
620 ]
621 );
622
623 $this->add_control(
624 'kng_accent_heading',
625 [
626 'label' => esc_html__('Accent Line', 'king-addons'),
627 'type' => Controls_Manager::HEADING,
628 'separator' => 'before',
629 ]
630 );
631
632 $this->add_control(
633 'kng_accent_side',
634 [
635 'label' => esc_html__('Accent Side', 'king-addons'),
636 'type' => Controls_Manager::SELECT,
637 'default' => 'left',
638 'options' => [
639 'left' => esc_html__('Left', 'king-addons'),
640 'right' => esc_html__('Right', 'king-addons'),
641 'top' => esc_html__('Top', 'king-addons'),
642 'bottom' => esc_html__('Bottom', 'king-addons'),
643 ],
644 'render_type' => 'template',
645 ]
646 );
647
648 $this->add_control(
649 'kng_accent_size',
650 [
651 'label' => esc_html__('Accent Size', 'king-addons'),
652 'type' => Controls_Manager::SLIDER,
653 'size_units' => ['px'],
654 'range' => [
655 'px' => [
656 'min' => 0,
657 'max' => 20,
658 ],
659 ],
660 'default' => [
661 'size' => 0,
662 'unit' => 'px',
663 ],
664 'selectors' => [
665 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-accent-size: {{SIZE}}{{UNIT}};',
666 ],
667 ]
668 );
669
670 $this->add_control(
671 'kng_accent_color',
672 [
673 'label' => esc_html__('Accent Color', 'king-addons'),
674 'type' => Controls_Manager::COLOR,
675 'selectors' => [
676 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-accent-color: {{VALUE}};',
677 ],
678 ]
679 );
680
681 $this->end_controls_section();
682
683 $this->start_controls_section(
684 'kng_style_typography_section',
685 [
686 'label' => esc_html__('Typography', 'king-addons'),
687 'tab' => Controls_Manager::TAB_STYLE,
688 ]
689 );
690
691 $this->add_control(
692 'kng_text_color',
693 [
694 'label' => esc_html__('Text Color', 'king-addons'),
695 'type' => Controls_Manager::COLOR,
696 'selectors' => [
697 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-text-color: {{VALUE}};',
698 ],
699 ]
700 );
701
702 $this->add_group_control(
703 Group_Control_Typography::get_type(),
704 [
705 'name' => 'kng_text_typography',
706 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts__text',
707 ]
708 );
709
710 $this->add_control(
711 'kng_author_color',
712 [
713 'label' => esc_html__('Author Color', 'king-addons'),
714 'type' => Controls_Manager::COLOR,
715 'selectors' => [
716 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-author-color: {{VALUE}};',
717 ],
718 'separator' => 'before',
719 ]
720 );
721
722 $this->add_group_control(
723 Group_Control_Typography::get_type(),
724 [
725 'name' => 'kng_author_typography',
726 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts__author',
727 ]
728 );
729
730 $this->add_control(
731 'kng_source_color',
732 [
733 'label' => esc_html__('Source Color', 'king-addons'),
734 'type' => Controls_Manager::COLOR,
735 'selectors' => [
736 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-source-color: {{VALUE}};',
737 ],
738 'separator' => 'before',
739 ]
740 );
741
742 $this->add_group_control(
743 Group_Control_Typography::get_type(),
744 [
745 'name' => 'kng_source_typography',
746 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts__source',
747 ]
748 );
749
750 $this->add_control(
751 'kng_label_color',
752 [
753 'label' => esc_html__('Label Color', 'king-addons'),
754 'type' => Controls_Manager::COLOR,
755 'selectors' => [
756 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-label-color: {{VALUE}};',
757 ],
758 'separator' => 'before',
759 ]
760 );
761
762 $this->add_control(
763 'kng_label_background',
764 [
765 'label' => esc_html__('Label Background', 'king-addons'),
766 'type' => Controls_Manager::COLOR,
767 'selectors' => [
768 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-label-bg: {{VALUE}};',
769 ],
770 ]
771 );
772
773 $this->add_group_control(
774 Group_Control_Typography::get_type(),
775 [
776 'name' => 'kng_label_typography',
777 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts__label',
778 ]
779 );
780
781 $this->add_responsive_control(
782 'kng_label_padding',
783 [
784 'label' => esc_html__('Label Padding', 'king-addons'),
785 'type' => Controls_Manager::DIMENSIONS,
786 'size_units' => ['px', 'em', 'rem'],
787 'selectors' => [
788 '{{WRAPPER}} .king-addons-pull-quotes-callouts__label' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
789 ],
790 'condition' => [
791 'kng_block_type' => 'callout',
792 'kng_label_show' => 'yes',
793 ],
794 ]
795 );
796
797 $this->add_control(
798 'kng_label_radius',
799 [
800 'label' => esc_html__('Label Radius', 'king-addons'),
801 'type' => Controls_Manager::SLIDER,
802 'size_units' => ['px', '%'],
803 'range' => [
804 'px' => [
805 'min' => 0,
806 'max' => 50,
807 ],
808 '%' => [
809 'min' => 0,
810 'max' => 50,
811 ],
812 ],
813 'selectors' => [
814 '{{WRAPPER}} .king-addons-pull-quotes-callouts__label' => 'border-radius: {{SIZE}}{{UNIT}};',
815 ],
816 'condition' => [
817 'kng_block_type' => 'callout',
818 'kng_label_show' => 'yes',
819 ],
820 ]
821 );
822
823 $this->add_control(
824 'kng_label_transform',
825 [
826 'label' => esc_html__('Label Transform', 'king-addons'),
827 'type' => Controls_Manager::SELECT,
828 'default' => 'uppercase',
829 'options' => [
830 'uppercase' => esc_html__('Uppercase', 'king-addons'),
831 'capitalize' => esc_html__('Capitalize', 'king-addons'),
832 'lowercase' => esc_html__('Lowercase', 'king-addons'),
833 'none' => esc_html__('None', 'king-addons'),
834 ],
835 'selectors' => [
836 '{{WRAPPER}} .king-addons-pull-quotes-callouts__label' => 'text-transform: {{VALUE}};',
837 ],
838 'condition' => [
839 'kng_block_type' => 'callout',
840 'kng_label_show' => 'yes',
841 ],
842 ]
843 );
844
845 $this->add_control(
846 'kng_label_letter_spacing',
847 [
848 'label' => esc_html__('Label Letter Spacing', 'king-addons'),
849 'type' => Controls_Manager::SLIDER,
850 'size_units' => ['px', 'em'],
851 'range' => [
852 'px' => [
853 'min' => 0,
854 'max' => 6,
855 ],
856 'em' => [
857 'min' => 0,
858 'max' => 0.4,
859 ],
860 ],
861 'selectors' => [
862 '{{WRAPPER}} .king-addons-pull-quotes-callouts__label' => 'letter-spacing: {{SIZE}}{{UNIT}};',
863 ],
864 'condition' => [
865 'kng_block_type' => 'callout',
866 'kng_label_show' => 'yes',
867 ],
868 ]
869 );
870
871 $this->add_control(
872 'kng_link_color',
873 [
874 'label' => esc_html__('Link Color', 'king-addons'),
875 'type' => Controls_Manager::COLOR,
876 'selectors' => [
877 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-link-color: {{VALUE}};',
878 ],
879 'separator' => 'before',
880 ]
881 );
882
883 $this->add_group_control(
884 Group_Control_Typography::get_type(),
885 [
886 'name' => 'kng_link_typography',
887 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts__link',
888 ]
889 );
890
891 $this->add_control(
892 'kng_link_hover_color',
893 [
894 'label' => esc_html__('Link Hover Color', 'king-addons'),
895 'type' => Controls_Manager::COLOR,
896 'selectors' => [
897 '{{WRAPPER}} .king-addons-pull-quotes-callouts__link:hover' => 'color: {{VALUE}};',
898 ],
899 ]
900 );
901
902 $this->end_controls_section();
903
904 $this->start_controls_section(
905 'kng_style_footer_section',
906 [
907 'label' => esc_html__('Footer', 'king-addons'),
908 'tab' => Controls_Manager::TAB_STYLE,
909 ]
910 );
911
912 $this->add_responsive_control(
913 'kng_footer_spacing',
914 [
915 'label' => esc_html__('Top Spacing', 'king-addons'),
916 'type' => Controls_Manager::SLIDER,
917 'size_units' => ['px'],
918 'range' => [
919 'px' => [
920 'min' => 0,
921 'max' => 60,
922 ],
923 ],
924 'selectors' => [
925 '{{WRAPPER}} .king-addons-pull-quotes-callouts__footer' => 'margin-top: {{SIZE}}{{UNIT}};',
926 ],
927 ]
928 );
929
930 $this->add_responsive_control(
931 'kng_footer_gap',
932 [
933 'label' => esc_html__('Gap', 'king-addons'),
934 'type' => Controls_Manager::SLIDER,
935 'size_units' => ['px'],
936 'range' => [
937 'px' => [
938 'min' => 0,
939 'max' => 40,
940 ],
941 ],
942 'selectors' => [
943 '{{WRAPPER}} .king-addons-pull-quotes-callouts__footer' => 'gap: {{SIZE}}{{UNIT}};',
944 ],
945 ]
946 );
947
948 $this->add_responsive_control(
949 'kng_footer_alignment',
950 [
951 'label' => esc_html__('Alignment', 'king-addons'),
952 'type' => Controls_Manager::CHOOSE,
953 'toggle' => true,
954 'options' => [
955 'flex-start' => [
956 'title' => esc_html__('Left', 'king-addons'),
957 'icon' => 'eicon-h-align-left',
958 ],
959 'center' => [
960 'title' => esc_html__('Center', 'king-addons'),
961 'icon' => 'eicon-h-align-center',
962 ],
963 'flex-end' => [
964 'title' => esc_html__('Right', 'king-addons'),
965 'icon' => 'eicon-h-align-right',
966 ],
967 ],
968 'selectors' => [
969 '{{WRAPPER}} .king-addons-pull-quotes-callouts__footer' => 'justify-content: {{VALUE}};',
970 ],
971 ]
972 );
973
974 $this->add_control(
975 'kng_footer_direction',
976 [
977 'label' => esc_html__('Direction', 'king-addons'),
978 'type' => Controls_Manager::SELECT,
979 'default' => 'row',
980 'options' => [
981 'row' => esc_html__('Horizontal', 'king-addons'),
982 'column' => esc_html__('Vertical', 'king-addons'),
983 ],
984 'selectors' => [
985 '{{WRAPPER}} .king-addons-pull-quotes-callouts__footer' => 'flex-direction: {{VALUE}};',
986 ],
987 ]
988 );
989
990 $this->add_control(
991 'kng_author_source_separator',
992 [
993 'label' => esc_html__('Separator', 'king-addons'),
994 'type' => Controls_Manager::TEXT,
995 'default' => '',
996 'placeholder' => '—',
997 'description' => esc_html__('Character between author and source (e.g. — or |)', 'king-addons'),
998 'render_type' => 'template',
999 ]
1000 );
1001
1002 $this->end_controls_section();
1003
1004 $this->start_controls_section(
1005 'kng_style_hover_section',
1006 [
1007 'label' => esc_html__('Hover', 'king-addons'),
1008 'tab' => Controls_Manager::TAB_STYLE,
1009 ]
1010 );
1011
1012 $this->add_group_control(
1013 Group_Control_Box_Shadow::get_type(),
1014 [
1015 'name' => 'kng_hover_shadow',
1016 'label' => esc_html__('Box Shadow', 'king-addons'),
1017 'selector' => '{{WRAPPER}} .king-addons-pull-quotes-callouts:hover',
1018 ]
1019 );
1020
1021 $this->add_control(
1022 'kng_hover_border_color',
1023 [
1024 'label' => esc_html__('Border Color', 'king-addons'),
1025 'type' => Controls_Manager::COLOR,
1026 'selectors' => [
1027 '{{WRAPPER}} .king-addons-pull-quotes-callouts:hover' => 'border-color: {{VALUE}};',
1028 ],
1029 ]
1030 );
1031
1032 $this->add_control(
1033 'kng_hover_transform',
1034 [
1035 'label' => esc_html__('Transform', 'king-addons'),
1036 'type' => Controls_Manager::SELECT,
1037 'default' => 'none',
1038 'options' => [
1039 'none' => esc_html__('None', 'king-addons'),
1040 'translateY(-4px)' => esc_html__('Lift Up', 'king-addons'),
1041 'scale(1.02)' => esc_html__('Scale Up', 'king-addons'),
1042 'translateY(-4px) scale(1.02)' => esc_html__('Lift + Scale', 'king-addons'),
1043 ],
1044 'selectors' => [
1045 '{{WRAPPER}} .king-addons-pull-quotes-callouts:hover' => 'transform: {{VALUE}};',
1046 ],
1047 ]
1048 );
1049
1050 $this->add_control(
1051 'kng_hover_transition',
1052 [
1053 'label' => esc_html__('Transition Duration (ms)', 'king-addons'),
1054 'type' => Controls_Manager::NUMBER,
1055 'min' => 0,
1056 'max' => 1000,
1057 'step' => 50,
1058 'default' => 300,
1059 'selectors' => [
1060 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => 'transition: transform {{VALUE}}ms ease, box-shadow {{VALUE}}ms ease, border-color {{VALUE}}ms ease;',
1061 ],
1062 ]
1063 );
1064
1065 $this->end_controls_section();
1066
1067 $this->start_controls_section(
1068 'kng_style_mark_section',
1069 [
1070 'label' => esc_html__('Quote Mark', 'king-addons'),
1071 'tab' => Controls_Manager::TAB_STYLE,
1072 'condition' => [
1073 'kng_block_type' => 'pull-quote',
1074 ],
1075 ]
1076 );
1077
1078 $this->add_control(
1079 'kng_mark_size',
1080 [
1081 'label' => esc_html__('Size', 'king-addons'),
1082 'type' => Controls_Manager::SLIDER,
1083 'size_units' => ['px'],
1084 'range' => [
1085 'px' => [
1086 'min' => 12,
1087 'max' => 200,
1088 ],
1089 ],
1090 'selectors' => [
1091 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-mark-size: {{SIZE}}{{UNIT}};',
1092 ],
1093 ]
1094 );
1095
1096 $this->add_control(
1097 'kng_mark_color',
1098 [
1099 'label' => esc_html__('Color', 'king-addons'),
1100 'type' => Controls_Manager::COLOR,
1101 'selectors' => [
1102 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-mark-color: {{VALUE}};',
1103 ],
1104 ]
1105 );
1106
1107 $this->add_control(
1108 'kng_mark_opacity',
1109 [
1110 'label' => esc_html__('Opacity', 'king-addons'),
1111 'type' => Controls_Manager::NUMBER,
1112 'min' => 0,
1113 'max' => 1,
1114 'step' => 0.05,
1115 'default' => 0.2,
1116 'selectors' => [
1117 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-mark-opacity: {{VALUE}};',
1118 ],
1119 ]
1120 );
1121
1122 $this->add_control(
1123 'kng_mark_scale',
1124 [
1125 'label' => esc_html__('Scale', 'king-addons'),
1126 'type' => Controls_Manager::NUMBER,
1127 'min' => 0.5,
1128 'max' => 2,
1129 'step' => 0.05,
1130 'default' => 1,
1131 'selectors' => [
1132 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-mark-scale: {{VALUE}};',
1133 ],
1134 ]
1135 );
1136
1137 $this->add_control(
1138 'kng_mark_offset_x',
1139 [
1140 'label' => esc_html__('Offset X', 'king-addons'),
1141 'type' => Controls_Manager::SLIDER,
1142 'size_units' => ['px'],
1143 'range' => [
1144 'px' => [
1145 'min' => -80,
1146 'max' => 80,
1147 ],
1148 ],
1149 'selectors' => [
1150 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-mark-offset-x: {{SIZE}}{{UNIT}};',
1151 ],
1152 ]
1153 );
1154
1155 $this->add_control(
1156 'kng_mark_offset_y',
1157 [
1158 'label' => esc_html__('Offset Y', 'king-addons'),
1159 'type' => Controls_Manager::SLIDER,
1160 'size_units' => ['px'],
1161 'range' => [
1162 'px' => [
1163 'min' => -80,
1164 'max' => 80,
1165 ],
1166 ],
1167 'selectors' => [
1168 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-mark-offset-y: {{SIZE}}{{UNIT}};',
1169 ],
1170 ]
1171 );
1172
1173 $this->end_controls_section();
1174
1175 $this->start_controls_section(
1176 'kng_style_icon_section',
1177 [
1178 'label' => esc_html__('Icon', 'king-addons'),
1179 'tab' => Controls_Manager::TAB_STYLE,
1180 'condition' => [
1181 'kng_block_type' => 'callout',
1182 ],
1183 ]
1184 );
1185
1186 $this->add_control(
1187 'kng_icon_size',
1188 [
1189 'label' => esc_html__('Size', 'king-addons'),
1190 'type' => Controls_Manager::SLIDER,
1191 'size_units' => ['px'],
1192 'range' => [
1193 'px' => [
1194 'min' => 12,
1195 'max' => 120,
1196 ],
1197 ],
1198 'selectors' => [
1199 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-icon-size: {{SIZE}}{{UNIT}};',
1200 ],
1201 ]
1202 );
1203
1204 $this->add_control(
1205 'kng_icon_color',
1206 [
1207 'label' => esc_html__('Color', 'king-addons'),
1208 'type' => Controls_Manager::COLOR,
1209 'selectors' => [
1210 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-icon-color: {{VALUE}};',
1211 ],
1212 ]
1213 );
1214
1215 $this->add_control(
1216 'kng_icon_offset_x',
1217 [
1218 'label' => esc_html__('Offset X', 'king-addons'),
1219 'type' => Controls_Manager::SLIDER,
1220 'size_units' => ['px'],
1221 'range' => [
1222 'px' => [
1223 'min' => -60,
1224 'max' => 60,
1225 ],
1226 ],
1227 'selectors' => [
1228 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-icon-offset-x: {{SIZE}}{{UNIT}};',
1229 ],
1230 ]
1231 );
1232
1233 $this->add_control(
1234 'kng_icon_offset_y',
1235 [
1236 'label' => esc_html__('Offset Y', 'king-addons'),
1237 'type' => Controls_Manager::SLIDER,
1238 'size_units' => ['px'],
1239 'range' => [
1240 'px' => [
1241 'min' => -60,
1242 'max' => 60,
1243 ],
1244 ],
1245 'selectors' => [
1246 '{{WRAPPER}} .king-addons-pull-quotes-callouts' => '--ka-pqcb-icon-offset-y: {{SIZE}}{{UNIT}};',
1247 ],
1248 ]
1249 );
1250
1251 $this->add_control(
1252 'kng_icon_bg_heading',
1253 [
1254 'label' => esc_html__('Icon Box', 'king-addons'),
1255 'type' => Controls_Manager::HEADING,
1256 'separator' => 'before',
1257 ]
1258 );
1259
1260 $this->add_control(
1261 'kng_icon_background',
1262 [
1263 'label' => esc_html__('Background', 'king-addons'),
1264 'type' => Controls_Manager::COLOR,
1265 'selectors' => [
1266 '{{WRAPPER}} .king-addons-pull-quotes-callouts__icon' => 'background: {{VALUE}};',
1267 ],
1268 ]
1269 );
1270
1271 $this->add_responsive_control(
1272 'kng_icon_padding',
1273 [
1274 'label' => esc_html__('Padding', 'king-addons'),
1275 'type' => Controls_Manager::SLIDER,
1276 'size_units' => ['px'],
1277 'range' => [
1278 'px' => [
1279 'min' => 0,
1280 'max' => 40,
1281 ],
1282 ],
1283 'selectors' => [
1284 '{{WRAPPER}} .king-addons-pull-quotes-callouts__icon' => 'padding: {{SIZE}}{{UNIT}};',
1285 ],
1286 ]
1287 );
1288
1289 $this->add_control(
1290 'kng_icon_border_radius',
1291 [
1292 'label' => esc_html__('Border Radius', 'king-addons'),
1293 'type' => Controls_Manager::SLIDER,
1294 'size_units' => ['px', '%'],
1295 'range' => [
1296 'px' => [
1297 'min' => 0,
1298 'max' => 50,
1299 ],
1300 '%' => [
1301 'min' => 0,
1302 'max' => 50,
1303 ],
1304 ],
1305 'selectors' => [
1306 '{{WRAPPER}} .king-addons-pull-quotes-callouts__icon' => 'border-radius: {{SIZE}}{{UNIT}};',
1307 ],
1308 ]
1309 );
1310
1311 $this->end_controls_section();
1312 }
1313
1314 /**
1315 * Register Pro notice controls.
1316 *
1317 * @return void
1318 */
1319 public function register_pro_notice_controls(): void
1320 {
1321 if (!king_addons_can_use_pro()) {
1322 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'pull-quotes-callouts-builder', [
1323 'Editorial float layout with gutters and wide pull quotes',
1324 'Copy, share, and deep-link actions with button styles',
1325 'Decorative effects: gradient accents, noise, blur, and watermark controls',
1326 'Reveal-on-scroll animations with staggered elements',
1327 'Expanded dynamic tags for quote, author, label, and link',
1328 ]);
1329 }
1330 }
1331
1332 /**
1333 * Preset options list.
1334 *
1335 * @return array<string, array<string, string>>
1336 */
1337 protected function get_preset_options(): array
1338 {
1339 $base_url = KING_ADDONS_URL . 'includes/widgets/Pull_Quotes_Callouts_Builder/assets/';
1340
1341 return [
1342 'classic-accent' => [
1343 'title' => esc_html__('Classic Left Accent', 'king-addons'),
1344 'image' => $base_url . 'preset-classic-accent.svg',
1345 ],
1346 'centered-mark' => [
1347 'title' => esc_html__('Centered Quote Mark', 'king-addons'),
1348 'image' => $base_url . 'preset-centered-mark.svg',
1349 ],
1350 'modern-card' => [
1351 'title' => esc_html__('Modern Card', 'king-addons'),
1352 'image' => $base_url . 'preset-modern-card.svg',
1353 ],
1354 'minimal-inline' => [
1355 'title' => esc_html__('Minimal Inline', 'king-addons'),
1356 'image' => $base_url . 'preset-minimal-inline.svg',
1357 ],
1358 'highlight-strip' => [
1359 'title' => esc_html__('Highlight Strip', 'king-addons'),
1360 'image' => $base_url . 'preset-highlight-strip.svg',
1361 ],
1362 'side-callout' => [
1363 'title' => esc_html__('Side Callout', 'king-addons'),
1364 'image' => $base_url . 'preset-side-callout.svg',
1365 ],
1366 'badge-callout' => [
1367 'title' => esc_html__('Badge Callout', 'king-addons'),
1368 'image' => $base_url . 'preset-badge-callout.svg',
1369 ],
1370 'editorial-watermark' => [
1371 'title' => esc_html__('Editorial Watermark', 'king-addons'),
1372 'image' => $base_url . 'preset-editorial-watermark.svg',
1373 ],
1374 ];
1375 }
1376
1377 /**
1378 * Sanitize block type.
1379 *
1380 * @param string $value Block type.
1381 *
1382 * @return string
1383 */
1384 protected function sanitize_block_type(string $value): string
1385 {
1386 $allowed = ['pull-quote', 'callout'];
1387 return in_array($value, $allowed, true) ? $value : 'pull-quote';
1388 }
1389
1390 /**
1391 * Sanitize preset value.
1392 *
1393 * @param string $value Preset value.
1394 *
1395 * @return string
1396 */
1397 protected function sanitize_preset(string $value): string
1398 {
1399 $allowed = array_keys($this->get_preset_options());
1400 return in_array($value, $allowed, true) ? $value : 'classic-accent';
1401 }
1402
1403 /**
1404 * Sanitize mark style.
1405 *
1406 * @param string $value Mark style.
1407 *
1408 * @return string
1409 */
1410 protected function sanitize_mark_style(string $value): string
1411 {
1412 $allowed = ['classic', 'modern', 'minimal'];
1413 return in_array($value, $allowed, true) ? $value : 'classic';
1414 }
1415
1416 /**
1417 * Sanitize mark mode.
1418 *
1419 * @param string $value Mark mode.
1420 *
1421 * @return string
1422 */
1423 protected function sanitize_mark_mode(string $value): string
1424 {
1425 $allowed = ['corner', 'inline', 'watermark'];
1426 return in_array($value, $allowed, true) ? $value : 'corner';
1427 }
1428
1429 /**
1430 * Sanitize icon position.
1431 *
1432 * @param string $value Icon position.
1433 *
1434 * @return string
1435 */
1436 protected function sanitize_icon_position(string $value): string
1437 {
1438 $allowed = ['left', 'top'];
1439 return in_array($value, $allowed, true) ? $value : 'left';
1440 }
1441
1442 /**
1443 * Sanitize accent side.
1444 *
1445 * @param string $value Accent side.
1446 *
1447 * @return string
1448 */
1449 protected function sanitize_accent_side(string $value): string
1450 {
1451 $allowed = ['left', 'right', 'top', 'bottom'];
1452 return in_array($value, $allowed, true) ? $value : 'left';
1453 }
1454 }
1455