PluginProbe
Elementor Website Builder – more than just a page builder / 3.6.1
Elementor Website Builder – more than just a page builder v3.6.1
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 / toggle.php

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

694 lines 18.7 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 toggle widget.
13 *
14 * Elementor widget that displays a collapsible display of content in an toggle
15 * style, allowing the user to open multiple items.
16 *
17 * @since 1.0.0
18 */
19 class Widget_Toggle extends Widget_Base {
20
21 /**
22 * Get widget name.
23 *
24 * Retrieve toggle 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 'toggle';
33 }
34
35 /**
36 * Get widget title.
37 *
38 * Retrieve toggle 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__( 'Toggle', 'elementor' );
47 }
48
49 /**
50 * Get widget icon.
51 *
52 * Retrieve toggle 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-toggle';
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 [ 'tabs', 'accordion', 'toggle' ];
75 }
76
77 /**
78 * Register toggle widget controls.
79 *
80 * Adds different input fields to allow the user to change and customize the widget settings.
81 *
82 * @since 3.1.0
83 * @access protected
84 */
85 protected function register_controls() {
86 $this->start_controls_section(
87 'section_toggle',
88 [
89 'label' => esc_html__( 'Toggle', 'elementor' ),
90 ]
91 );
92
93 $repeater = new Repeater();
94
95 $repeater->add_control(
96 'tab_title',
97 [
98 'label' => esc_html__( 'Title & Description', 'elementor' ),
99 'type' => Controls_Manager::TEXT,
100 'default' => esc_html__( 'Toggle Title', 'elementor' ),
101 'label_block' => true,
102 'dynamic' => [
103 'active' => true,
104 ],
105 ]
106 );
107
108 $repeater->add_control(
109 'tab_content',
110 [
111 'label' => esc_html__( 'Content', 'elementor' ),
112 'type' => Controls_Manager::WYSIWYG,
113 'default' => esc_html__( 'Toggle Content', 'elementor' ),
114 'show_label' => false,
115 'dynamic' => [
116 'active' => true,
117 ],
118 ]
119 );
120
121 $this->add_control(
122 'tabs',
123 [
124 'label' => esc_html__( 'Toggle Items', 'elementor' ),
125 'type' => Controls_Manager::REPEATER,
126 'fields' => $repeater->get_controls(),
127 'default' => [
128 [
129 'tab_title' => esc_html__( 'Toggle #1', 'elementor' ),
130 'tab_content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
131 ],
132 [
133 'tab_title' => esc_html__( 'Toggle #2', 'elementor' ),
134 'tab_content' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor' ),
135 ],
136 ],
137 'title_field' => '{{{ tab_title }}}',
138 ]
139 );
140
141 $this->add_control(
142 'view',
143 [
144 'label' => esc_html__( 'View', 'elementor' ),
145 'type' => Controls_Manager::HIDDEN,
146 'default' => 'traditional',
147 ]
148 );
149
150 $this->add_control(
151 'selected_icon',
152 [
153 'label' => esc_html__( 'Icon', 'elementor' ),
154 'type' => Controls_Manager::ICONS,
155 'separator' => 'before',
156 'fa4compatibility' => 'icon',
157 'default' => [
158 'value' => 'fas fa-caret' . ( is_rtl() ? '-left' : '-right' ),
159 'library' => 'fa-solid',
160 ],
161 'recommended' => [
162 'fa-solid' => [
163 'chevron-down',
164 'angle-down',
165 'angle-double-down',
166 'caret-down',
167 'caret-square-down',
168 ],
169 'fa-regular' => [
170 'caret-square-down',
171 ],
172 ],
173 'label_block' => false,
174 'skin' => 'inline',
175 ]
176 );
177
178 $this->add_control(
179 'selected_active_icon',
180 [
181 'label' => esc_html__( 'Active Icon', 'elementor' ),
182 'type' => Controls_Manager::ICONS,
183 'fa4compatibility' => 'icon_active',
184 'default' => [
185 'value' => 'fas fa-caret-up',
186 'library' => 'fa-solid',
187 ],
188 'recommended' => [
189 'fa-solid' => [
190 'chevron-up',
191 'angle-up',
192 'angle-double-up',
193 'caret-up',
194 'caret-square-up',
195 ],
196 'fa-regular' => [
197 'caret-square-up',
198 ],
199 ],
200 'skin' => 'inline',
201 'label_block' => false,
202 'condition' => [
203 'selected_icon[value]!' => '',
204 ],
205 ]
206 );
207
208 $this->add_control(
209 'title_html_tag',
210 [
211 'label' => esc_html__( 'Title HTML Tag', 'elementor' ),
212 'type' => Controls_Manager::SELECT,
213 'options' => [
214 'h1' => 'H1',
215 'h2' => 'H2',
216 'h3' => 'H3',
217 'h4' => 'H4',
218 'h5' => 'H5',
219 'h6' => 'H6',
220 'div' => 'div',
221 ],
222 'default' => 'div',
223 'separator' => 'before',
224 ]
225 );
226
227 $this->add_control(
228 'faq_schema',
229 [
230 'label' => esc_html__( 'FAQ Schema', 'elementor' ),
231 'type' => Controls_Manager::SWITCHER,
232 'separator' => 'before',
233 ]
234 );
235
236 $this->end_controls_section();
237
238 $this->start_controls_section(
239 'section_toggle_style',
240 [
241 'label' => esc_html__( 'Toggle', 'elementor' ),
242 'tab' => Controls_Manager::TAB_STYLE,
243 ]
244 );
245
246 $this->add_control(
247 'border_width',
248 [
249 'label' => esc_html__( 'Border Width', 'elementor' ),
250 'type' => Controls_Manager::SLIDER,
251 'range' => [
252 'px' => [
253 'min' => 0,
254 'max' => 10,
255 ],
256 ],
257 'selectors' => [
258 '{{WRAPPER}} .elementor-tab-title' => 'border-width: {{SIZE}}{{UNIT}};',
259 '{{WRAPPER}} .elementor-tab-content' => 'border-width: {{SIZE}}{{UNIT}};',
260 ],
261 ]
262 );
263
264 $this->add_control(
265 'border_color',
266 [
267 'label' => esc_html__( 'Border Color', 'elementor' ),
268 'type' => Controls_Manager::COLOR,
269 'selectors' => [
270 '{{WRAPPER}} .elementor-tab-content' => 'border-bottom-color: {{VALUE}};',
271 '{{WRAPPER}} .elementor-tab-title' => 'border-color: {{VALUE}};',
272 ],
273 ]
274 );
275
276 $this->add_responsive_control(
277 'space_between',
278 [
279 'label' => esc_html__( 'Space Between', 'elementor' ),
280 'type' => Controls_Manager::SLIDER,
281 'range' => [
282 'px' => [
283 'min' => 0,
284 'max' => 100,
285 ],
286 ],
287 'selectors' => [
288 '{{WRAPPER}} .elementor-toggle-item:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}',
289 ],
290 ]
291 );
292
293 $this->add_group_control(
294 Group_Control_Box_Shadow::get_type(),
295 [
296 'name' => 'box_shadow',
297 'selector' => '{{WRAPPER}} .elementor-toggle-item',
298 ]
299 );
300
301 $this->end_controls_section();
302
303 $this->start_controls_section(
304 'section_toggle_style_title',
305 [
306 'label' => esc_html__( 'Title', 'elementor' ),
307 'tab' => Controls_Manager::TAB_STYLE,
308 ]
309 );
310
311 $this->add_control(
312 'title_background',
313 [
314 'label' => esc_html__( 'Background', 'elementor' ),
315 'type' => Controls_Manager::COLOR,
316 'selectors' => [
317 '{{WRAPPER}} .elementor-tab-title' => 'background-color: {{VALUE}};',
318 ],
319 ]
320 );
321
322 // The title selector specificity is to override Theme Style
323 $this->add_control(
324 'title_color',
325 [
326 'label' => esc_html__( 'Color', 'elementor' ),
327 'type' => Controls_Manager::COLOR,
328 'selectors' => [
329 '{{WRAPPER}} .elementor-toggle-title, {{WRAPPER}} .elementor-toggle-icon' => 'color: {{VALUE}};',
330 '{{WRAPPER}} .elementor-toggle-icon svg' => 'fill: {{VALUE}};',
331 ],
332 'global' => [
333 'default' => Global_Colors::COLOR_PRIMARY,
334 ],
335 ]
336 );
337
338 $this->add_control(
339 'tab_active_color',
340 [
341 'label' => esc_html__( 'Active Color', 'elementor' ),
342 'type' => Controls_Manager::COLOR,
343 'selectors' => [
344 '{{WRAPPER}} .elementor-tab-title.elementor-active a, {{WRAPPER}} .elementor-tab-title.elementor-active .elementor-toggle-icon' => 'color: {{VALUE}};',
345 ],
346 'global' => [
347 'default' => Global_Colors::COLOR_ACCENT,
348 ],
349 ]
350 );
351
352 $this->add_group_control(
353 Group_Control_Typography::get_type(),
354 [
355 'name' => 'title_typography',
356 'selector' => '{{WRAPPER}} .elementor-toggle-title',
357 'global' => [
358 'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
359 ],
360 ]
361 );
362
363 $this->add_group_control(
364 Group_Control_Text_Shadow::get_type(),
365 [
366 'name' => 'title_shadow',
367 'selector' => '{{WRAPPER}} .elementor-toggle-title',
368 ]
369 );
370
371 $this->add_responsive_control(
372 'title_padding',
373 [
374 'label' => esc_html__( 'Padding', 'elementor' ),
375 'type' => Controls_Manager::DIMENSIONS,
376 'size_units' => [ 'px', 'em', '%' ],
377 'selectors' => [
378 '{{WRAPPER}} .elementor-tab-title' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
379 ],
380 ]
381 );
382
383 $this->end_controls_section();
384
385 $this->start_controls_section(
386 'section_toggle_style_icon',
387 [
388 'label' => esc_html__( 'Icon', 'elementor' ),
389 'tab' => Controls_Manager::TAB_STYLE,
390 'condition' => [
391 'selected_icon[value]!' => '',
392 ],
393 ]
394 );
395
396 $this->add_control(
397 'icon_align',
398 [
399 'label' => esc_html__( 'Alignment', 'elementor' ),
400 'type' => Controls_Manager::CHOOSE,
401 'options' => [
402 'left' => [
403 'title' => esc_html__( 'Start', 'elementor' ),
404 'icon' => 'eicon-h-align-left',
405 ],
406 'right' => [
407 'title' => esc_html__( 'End', 'elementor' ),
408 'icon' => 'eicon-h-align-right',
409 ],
410 ],
411 'default' => is_rtl() ? 'right' : 'left',
412 'toggle' => false,
413 ]
414 );
415
416 $this->add_control(
417 'icon_color',
418 [
419 'label' => esc_html__( 'Color', 'elementor' ),
420 'type' => Controls_Manager::COLOR,
421 'selectors' => [
422 '{{WRAPPER}} .elementor-tab-title .elementor-toggle-icon i:before' => 'color: {{VALUE}};',
423 '{{WRAPPER}} .elementor-tab-title .elementor-toggle-icon svg' => 'fill: {{VALUE}};',
424 ],
425 ]
426 );
427
428 $this->add_control(
429 'icon_active_color',
430 [
431 'label' => esc_html__( 'Active Color', 'elementor' ),
432 'type' => Controls_Manager::COLOR,
433 'selectors' => [
434 '{{WRAPPER}} .elementor-tab-title.elementor-active .elementor-toggle-icon i:before' => 'color: {{VALUE}};',
435 '{{WRAPPER}} .elementor-tab-title.elementor-active .elementor-toggle-icon svg' => 'fill: {{VALUE}};',
436 ],
437 ]
438 );
439
440 $this->add_responsive_control(
441 'icon_space',
442 [
443 'label' => esc_html__( 'Spacing', 'elementor' ),
444 'type' => Controls_Manager::SLIDER,
445 'range' => [
446 'px' => [
447 'min' => 0,
448 'max' => 100,
449 ],
450 ],
451 'selectors' => [
452 '{{WRAPPER}} .elementor-toggle-icon.elementor-toggle-icon-left' => 'margin-right: {{SIZE}}{{UNIT}};',
453 '{{WRAPPER}} .elementor-toggle-icon.elementor-toggle-icon-right' => 'margin-left: {{SIZE}}{{UNIT}};',
454 ],
455 ]
456 );
457
458 $this->end_controls_section();
459
460 $this->start_controls_section(
461 'section_toggle_style_content',
462 [
463 'label' => esc_html__( 'Content', 'elementor' ),
464 'tab' => Controls_Manager::TAB_STYLE,
465 ]
466 );
467
468 $this->add_control(
469 'content_background_color',
470 [
471 'label' => esc_html__( 'Background', 'elementor' ),
472 'type' => Controls_Manager::COLOR,
473 'selectors' => [
474 '{{WRAPPER}} .elementor-tab-content' => 'background-color: {{VALUE}};',
475 ],
476 ]
477 );
478
479 $this->add_control(
480 'content_color',
481 [
482 'label' => esc_html__( 'Color', 'elementor' ),
483 'type' => Controls_Manager::COLOR,
484 'selectors' => [
485 '{{WRAPPER}} .elementor-tab-content' => 'color: {{VALUE}};',
486 ],
487 'global' => [
488 'default' => Global_Colors::COLOR_TEXT,
489 ],
490 ]
491 );
492
493 $this->add_group_control(
494 Group_Control_Typography::get_type(),
495 [
496 'name' => 'content_typography',
497 'selector' => '{{WRAPPER}} .elementor-tab-content',
498 'global' => [
499 'default' => Global_Typography::TYPOGRAPHY_TEXT,
500 ],
501 ]
502 );
503
504 $this->add_group_control(
505 Group_Control_Text_Shadow::get_type(),
506 [
507 'name' => 'content_shadow',
508 'selector' => '{{WRAPPER}} .elementor-tab-content',
509 ]
510 );
511
512 $this->add_responsive_control(
513 'content_padding',
514 [
515 'label' => esc_html__( 'Padding', 'elementor' ),
516 'type' => Controls_Manager::DIMENSIONS,
517 'size_units' => [ 'px', 'em', '%' ],
518 'selectors' => [
519 '{{WRAPPER}} .elementor-tab-content' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
520 ],
521 ]
522 );
523
524 $this->end_controls_section();
525 }
526
527 /**
528 * Render toggle widget output on the frontend.
529 *
530 * Written in PHP and used to generate the final HTML.
531 *
532 * @since 1.0.0
533 * @access protected
534 */
535 protected function render() {
536 $settings = $this->get_settings_for_display();
537
538 $id_int = substr( $this->get_id_int(), 0, 3 );
539 $migrated = isset( $settings['__fa4_migrated']['selected_icon'] );
540
541 if ( ! isset( $settings['icon'] ) && ! Icons_Manager::is_migration_allowed() ) {
542 // @todo: remove when deprecated
543 // added as bc in 2.6
544 // add old default
545 $settings['icon'] = 'fa fa-caret' . ( is_rtl() ? '-left' : '-right' );
546 $settings['icon_active'] = 'fa fa-caret-up';
547 $settings['icon_align'] = $this->get_settings( 'icon_align' );
548 }
549
550 $is_new = empty( $settings['icon'] ) && Icons_Manager::is_migration_allowed();
551 $has_icon = ( ! $is_new || ! empty( $settings['selected_icon']['value'] ) );
552
553 ?>
554 <div class="elementor-toggle" role="tablist">
555 <?php
556 foreach ( $settings['tabs'] as $index => $item ) :
557 $tab_count = $index + 1;
558
559 $tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
560
561 $tab_content_setting_key = $this->get_repeater_setting_key( 'tab_content', 'tabs', $index );
562
563 $this->add_render_attribute( $tab_title_setting_key, [
564 'id' => 'elementor-tab-title-' . $id_int . $tab_count,
565 'class' => [ 'elementor-tab-title' ],
566 'data-tab' => $tab_count,
567 'role' => 'tab',
568 'aria-controls' => 'elementor-tab-content-' . $id_int . $tab_count,
569 'aria-expanded' => 'false',
570 ] );
571
572 $this->add_render_attribute( $tab_content_setting_key, [
573 'id' => 'elementor-tab-content-' . $id_int . $tab_count,
574 'class' => [ 'elementor-tab-content', 'elementor-clearfix' ],
575 'data-tab' => $tab_count,
576 'role' => 'tabpanel',
577 'aria-labelledby' => 'elementor-tab-title-' . $id_int . $tab_count,
578 ] );
579
580 $this->add_inline_editing_attributes( $tab_content_setting_key, 'advanced' );
581 ?>
582 <div class="elementor-toggle-item">
583 <<?php Utils::print_validated_html_tag( $settings['title_html_tag'] ); ?> <?php $this->print_render_attribute_string( $tab_title_setting_key ); ?>>
584 <?php if ( $has_icon ) : ?>
585 <span class="elementor-toggle-icon elementor-toggle-icon-<?php echo esc_attr( $settings['icon_align'] ); ?>" aria-hidden="true">
586 <?php
587 if ( $is_new || $migrated ) { ?>
588 <span class="elementor-toggle-icon-closed"><?php Icons_Manager::render_icon( $settings['selected_icon'] ); ?></span>
589 <span class="elementor-toggle-icon-opened"><?php Icons_Manager::render_icon( $settings['selected_active_icon'], [ 'class' => 'elementor-toggle-icon-opened' ] ); ?></span>
590 <?php } else { ?>
591 <i class="elementor-toggle-icon-closed <?php echo esc_attr( $settings['icon'] ); ?>"></i>
592 <i class="elementor-toggle-icon-opened <?php echo esc_attr( $settings['icon_active'] ); ?>"></i>
593 <?php } ?>
594 </span>
595 <?php endif; ?>
596 <a href="" class="elementor-toggle-title"><?php $this->print_unescaped_setting( 'tab_title', 'tabs', $index ); ?></a>
597 </<?php Utils::print_validated_html_tag( $settings['title_html_tag'] ); ?>>
598
599 <div <?php $this->print_render_attribute_string( $tab_content_setting_key ); ?>><?php Utils::print_unescaped_internal_string( $this->parse_text_editor( $item['tab_content'] ) ); ?></div>
600 </div>
601 <?php endforeach; ?>
602 <?php
603 if ( isset( $settings['faq_schema'] ) && 'yes' === $settings['faq_schema'] ) {
604 $json = [
605 '@context' => 'https://schema.org',
606 '@type' => 'FAQPage',
607 'mainEntity' => [],
608 ];
609
610 foreach ( $settings['tabs'] as $index => $item ) {
611 $json['mainEntity'][] = [
612 '@type' => 'Question',
613 'name' => wp_strip_all_tags( $item['tab_title'] ),
614 'acceptedAnswer' => [
615 '@type' => 'Answer',
616 'text' => $this->parse_text_editor( $item['tab_content'] ),
617 ],
618 ];
619 }
620 ?>
621 <script type="application/ld+json"><?php echo wp_json_encode( $json ); ?></script>
622 <?php } ?>
623 </div>
624 <?php
625 }
626
627 /**
628 * Render toggle widget output in the editor.
629 *
630 * Written as a Backbone JavaScript template and used to generate the live preview.
631 *
632 * @since 2.9.0
633 * @access protected
634 */
635 protected function content_template() {
636 ?>
637 <div class="elementor-toggle" role="tablist">
638 <#
639 if ( settings.tabs ) {
640 var tabindex = view.getIDInt().toString().substr( 0, 3 ),
641 iconHTML = elementor.helpers.renderIcon( view, settings.selected_icon, {}, 'i' , 'object' ),
642 iconActiveHTML = elementor.helpers.renderIcon( view, settings.selected_active_icon, {}, 'i' , 'object' ),
643 migrated = elementor.helpers.isIconMigrated( settings, 'selected_icon' ),
644 titleHTMLTag = elementor.helpers.validateHTMLTag( settings.title_html_tag );
645
646 _.each( settings.tabs, function( item, index ) {
647 var tabCount = index + 1,
648 tabTitleKey = view.getRepeaterSettingKey( 'tab_title', 'tabs', index ),
649 tabContentKey = view.getRepeaterSettingKey( 'tab_content', 'tabs', index );
650
651 view.addRenderAttribute( tabTitleKey, {
652 'id': 'elementor-tab-title-' + tabindex + tabCount,
653 'class': [ 'elementor-tab-title' ],
654 'data-tab': tabCount,
655 'role': 'tab',
656 'aria-controls': 'elementor-tab-content-' + tabindex + tabCount,
657 'aria-expanded': 'false',
658 } );
659
660 view.addRenderAttribute( tabContentKey, {
661 'id': 'elementor-tab-content-' + tabindex + tabCount,
662 'class': [ 'elementor-tab-content', 'elementor-clearfix' ],
663 'data-tab': tabCount,
664 'role': 'tabpanel',
665 'aria-labelledby': 'elementor-tab-title-' + tabindex + tabCount
666 } );
667
668 view.addInlineEditingAttributes( tabContentKey, 'advanced' );
669 #>
670 <div class="elementor-toggle-item">
671 <{{{ titleHTMLTag }}} {{{ view.getRenderAttributeString( tabTitleKey ) }}}>
672 <# if ( settings.icon || settings.selected_icon ) { #>
673 <span class="elementor-toggle-icon elementor-toggle-icon-{{ settings.icon_align }}" aria-hidden="true">
674 <# if ( iconHTML && iconHTML.rendered && ( ! settings.icon || migrated ) ) { #>
675 <span class="elementor-toggle-icon-closed">{{{ iconHTML.value }}}</span>
676 <span class="elementor-toggle-icon-opened">{{{ iconActiveHTML.value }}}</span>
677 <# } else { #>
678 <i class="elementor-toggle-icon-closed {{ settings.icon }}"></i>
679 <i class="elementor-toggle-icon-opened {{ settings.icon_active }}"></i>
680 <# } #>
681 </span>
682 <# } #>
683 <a href="" class="elementor-toggle-title">{{{ item.tab_title }}}</a>
684 </{{{ titleHTMLTag }}}>
685 <div {{{ view.getRenderAttributeString( tabContentKey ) }}}>{{{ item.tab_content }}}</div>
686 </div>
687 <#
688 } );
689 } #>
690 </div>
691 <?php
692 }
693 }
694