PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.2.2
UiCore Elements – Free widgets and templates for Elementor v1.2.2
1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 All 41 releases
uicore-elements / includes / widgets / newsletter.php

newsletter.php in UiCore Elements – Free widgets and templates for Elementor 1.2.2, at includes/widgets/newsletter.php

720 lines 26.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace UiCoreElements;
3
4
5 use UiCoreElements\Utils\Contact_Form_Service;
6 use UiCoreElements\Utils\Form_Component;
7 use Elementor\Controls_Manager;
8 use Elementor\Icons_Manager;
9 use Elementor\Utils;
10
11
12 defined('ABSPATH') || exit();
13
14 /**
15 * Newsletter
16 *
17 * @author Lucas Marini Falbo <lucas@uicore.co>
18 * @since 1.0.7
19 */
20
21 class Newsletter extends UiCoreWidget {
22
23 use Form_Component;
24
25 public function get_name() {
26 return 'uicore-newsletter';
27 }
28
29 public function get_title() {
30 return __( 'Newsletter', 'uicore-elements' );
31 }
32
33 public function get_icon() {
34 return 'eicon-form-horizontal ui-e-widget';
35 }
36 public function get_categories()
37 {
38 return ['uicore'];
39 }
40 public function get_keywords() {
41 return [ 'form', 'forms', 'newsletter', 'news', 'subscribe', 'subscription', 'mailchimp' ];
42 }
43 public function get_styles()
44 {
45 return ['newsletter'];
46 }
47 public function get_scripts()
48 {
49 return [
50 'contact-form',
51 'recaptcha' => [
52 'custom_condition' => $this->check_recaptcha_version('v2')
53 ],
54 'recaptcha-v3' => [
55 'custom_condition' => $this->check_recaptcha_version('v3')
56 ]
57 ];
58 }
59 public function has_widget_inner_wrapper(): bool {
60 // TODO: remove after 3.30, when the full deprecation of widget innet wrapper is ready
61 return ! \Elementor\Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
62 }
63 function check_recaptcha_version($version)
64 {
65
66 if( $this->is_edit_mode() ){
67 return true;
68 }
69
70 return $version === $this->get_settings_for_display('recaptcha_version') ? true : false;
71 }
72
73 function form_fields_render_attributes( $i, $instance, $item ) {
74 $this->add_render_attribute(
75 [
76 'field-group' . $i => [
77 'class' => [
78 'ui-e-field-type-text',
79 'ui-e-field-group',
80 'elementor-column',
81 ],
82 ],
83 'honeypot' => [
84 'class' => [
85 'ui-e-field-type-address',
86 'ui-e-field-group',
87 'elementor-column',
88 ],
89 ],
90 'recaptcha' => [
91 'class' => [
92 'ui-e-field-type-recaptcha',
93 'ui-e-field-group',
94 'elementor-column',
95 'elementor-col-100'
96 ],
97 ],
98 'recaptcha_v3' => [
99 'class' => [
100 'ui-e-field-type-recaptcha_v3',
101 'ui-e-field-group',
102 'elementor-column',
103 'elementor-col-100'
104 ],
105 ],
106 'input' . $i => [
107 'type' => 'text',
108 'size' => '1',
109 'name' => 'form_fields[' . $item . ']',
110 'id' => 'form-fields-' . $item,
111 'class' => [
112 'ui-e-field',
113 empty( $instance[$item.'_css'] ) ? '' : esc_attr( $instance[$item.'_css'] ),
114 ],
115 ],
116 'label' . $i => [
117 'for' => 'form-field-' . $item,
118 'class' => 'ui-e-label',
119 ],
120 ]
121 );
122
123 if ( empty( $instance[$item . '_width'] ) ) {
124 $item['width'] = '100';
125 }
126
127 $this->add_render_attribute( 'field-group' . $i, 'class', 'elementor-col-' . $instance[$item . '_width'] );
128
129 if ( ! empty( $instance[$item . '_width_tablet'] ) ) {
130 $this->add_render_attribute( 'field-group' . $i, 'class', 'elementor-md-' . $instance[$item . '_width_tablet'] );
131 }
132
133 if ( ! empty( $instance[$item . '_width_mobile'] ) ) {
134 $this->add_render_attribute( 'field-group' . $i, 'class', 'elementor-sm-' . $instance[$item . '_width_mobile'] );
135 }
136
137 // Allow zero as placeholder.
138 if ( ! Utils::is_empty( $instance[$item . '_placeholder'] ) ) {
139 $this->add_render_attribute( 'input' . $i, 'placeholder', $instance[$item . '_placeholder'] );
140 }
141
142 if ( ! $instance['show_labels'] ) {
143 $this->add_render_attribute( 'label' . $i, 'class', 'elementor-screen-only' );
144 }
145
146 if ( ! empty( $instance[$item . '_required'] ) ) {
147 if ( ! empty( $instance['mark_required'] ) ) {
148 $this->add_render_attribute( 'field-group' . $i,
149 [
150 'class' => 'ui-e-required',
151 'required' => 'required',
152 ]
153 );
154 }
155 }
156 }
157
158 protected function register_controls() {
159
160 $this->start_controls_section(
161 'section_form_settings',
162 [
163 'label' => esc_html__( 'Form Settings', 'uicore-elements' ),
164 ]
165 );
166
167 $this->add_control(
168 'form_name',
169 [
170 'label' => esc_html__( 'Form Name', 'uicore-elements' ),
171 'type' => Controls_Manager::TEXT,
172 'default' => esc_html__( 'New Form', 'uicore-elements' ),
173 'placeholder' => esc_html__( 'Form Name', 'uicore-elements' ),
174 ]
175 );
176 $this->add_control(
177 'show_labels',
178 [
179 'label' => esc_html__( 'Label', 'uicore-elements' ),
180 'type' => Controls_Manager::SWITCHER,
181 'label_on' => esc_html__( 'Show', 'uicore-elements' ),
182 'label_off' => esc_html__( 'Hide', 'uicore-elements' ),
183 'return_value' => 'true',
184 'default' => 'true',
185 ]
186 );
187 $this->add_control(
188 'mark_required',
189 [
190 'label' => esc_html__( 'Required Mark', 'uicore-elements' ),
191 'type' => Controls_Manager::SWITCHER,
192 'label_on' => esc_html__( 'Show', 'uicore-elements' ),
193 'label_off' => esc_html__( 'Hide', 'uicore-elements' ),
194 'default' => '',
195 'render_type' => 'template',
196 'condition' => [
197 'show_labels!' => '',
198 ],
199 ]
200 );
201 $this->end_controls_section();
202
203 $this->start_controls_section(
204 'section_form_fields',
205 [
206 'label' => esc_html__( 'Fields', 'uicore-elements' ),
207 ]
208 );
209
210 $this->add_control(
211 'add_name',
212 [
213 'label' => esc_html__( 'Name', 'uicore-elements' ),
214 'type' => Controls_Manager::SWITCHER,
215 'return_value' => 'true',
216 'default' => 'true',
217 ]
218 );
219 $this->add_control(
220 'add_recaptcha',
221 [
222 'label' => esc_html__( 'Recaptcha', 'uicore-elements' ),
223 'type' => Controls_Manager::SWITCHER,
224 'return_value' => 'true',
225 ]
226 );
227 $this->add_control(
228 'add_honeypot',
229 [
230 'label' => esc_html__( 'Honeypot', 'uicore-elements' ),
231 'type' => Controls_Manager::SWITCHER,
232 'description' => esc_html__('Adds a hidden field to trap and identify bots by capturing automated form submissions.', 'uicore-elements'),
233 'return_value' => 'true',
234 'default' => 'true',
235 ]
236 );
237
238 $this->start_controls_tabs( 'form_fields_tabs' );
239
240 $this->start_controls_tab(
241 'email_tab',
242 [
243 'label' => esc_html__( 'E-mail', 'uicore-elements' ),
244 ]
245 );
246
247 $this->add_control(
248 'email_label',
249 [
250 'label' => esc_html__( 'Label', 'uicore-elements' ),
251 'type' => Controls_Manager::TEXT,
252 'default' => '',
253 'dynamic' => [
254 'active' => true,
255 ],
256 ]
257 );
258 $this->add_control(
259 'email_placeholder',
260 [
261 'label' => esc_html__( 'Placeholder', 'uicore-elements' ),
262 'type' => Controls_Manager::TEXT,
263 'default' => esc_html__('Your e-mail', 'uicore-elements'),
264 'dynamic' => [
265 'active' => true,
266 ],
267 ]
268 );
269 $this->add_control(
270 'email_required',
271 [
272 'label' => esc_html__( 'Required', 'uicore-elements' ),
273 'type' => Controls_Manager::SWITCHER,
274 'return_value' => 'true',
275 'default' => '',
276 ]
277 );
278 $this->add_responsive_control(
279 'email_width',
280 [
281 'label' => esc_html__( 'Column Width', 'uicore-elements' ),
282 'type' => Controls_Manager::SELECT,
283 'options' => $this->TRAIT_get_width_values(),
284 'default' => '40',
285 ]
286 );
287 $this->add_control(
288 'email_css',
289 [
290 'label' => esc_html__( 'Custom Class', 'uicore-elements' ),
291 'type' => Controls_Manager::TEXT,
292 'default' => '',
293 'ai' => [
294 'active' => false,
295 ],
296 'separator' => 'before',
297 'placeholder' => esc_html__( 'e.g: my-class', 'uicore-elements' ),
298 ]
299 );
300 $this->add_control(
301 'email_shortcode',
302 [
303 'label' => esc_html__( 'Shortcode', 'uicore-elements' ),
304 'type' => Controls_Manager::RAW_HTML,
305 'classes' => 'forms-field-shortcode',
306 'raw' => '<input class="elementor-form-field-shortcode" value=\'[field id="email"]\' readonly />',
307 ]
308 );
309
310 $this->end_controls_tab();
311
312 $this->start_controls_tab(
313 'name_tab',
314 [
315 'label' => esc_html__( 'Name', 'uicore-elements' ),
316 'condition' => [
317 'add_name' => 'true',
318 ],
319 ]
320 );
321
322 $this->add_control(
323 'name_label',
324 [
325 'label' => esc_html__( 'Label', 'uicore-elements' ),
326 'type' => Controls_Manager::TEXT,
327 'default' => '',
328 'dynamic' => [
329 'active' => true,
330 ],
331 ]
332 );
333 $this->add_control(
334 'name_placeholder',
335 [
336 'label' => esc_html__( 'Placeholder', 'uicore-elements' ),
337 'type' => Controls_Manager::TEXT,
338 'default' => esc_html__('Your name', 'uicore-elements'),
339 'dynamic' => [
340 'active' => true,
341 ],
342 ]
343 );
344 $this->add_control(
345 'name_required',
346 [
347 'label' => esc_html__( 'Required', 'uicore-elements' ),
348 'type' => Controls_Manager::SWITCHER,
349 'return_value' => 'true',
350 'default' => '',
351 ]
352 );
353 $this->add_responsive_control(
354 'name_width',
355 [
356 'label' => esc_html__( 'Column Width', 'uicore-elements' ),
357 'type' => Controls_Manager::SELECT,
358 'options' => $this->TRAIT_get_width_values(),
359 'default' => '40',
360 ]
361 );
362 $this->add_control(
363 'name_css',
364 [
365 'label' => esc_html__( 'Custom Class', 'uicore-elements' ),
366 'type' => Controls_Manager::TEXT,
367 'default' => '',
368 'ai' => [
369 'active' => false,
370 ],
371 'separator' => 'before',
372 'placeholder' => esc_html__( 'e.g: my-class', 'uicore-elements' ),
373 ]
374 );
375 $this->add_control(
376 'name_shortcode',
377 [
378 'label' => esc_html__( 'Shortcode', 'uicore-elements' ),
379 'type' => Controls_Manager::RAW_HTML,
380 'classes' => 'forms-field-shortcode',
381 'raw' => '<input class="elementor-form-field-shortcode" value=\'[field id="name"]\' readonly />',
382 ]
383 );
384
385 $this->end_controls_tab();
386
387 $this->start_controls_tab(
388 'recaptcha_tab',
389 [
390 'label' => esc_html__( 'Recaptcha', 'uicore-elements' ),
391 'condition' => [
392 'add_recaptcha' => 'true',
393 ],
394 ]
395 );
396
397 $this->add_control(
398 'recaptcha_version',
399 [
400 'label' => esc_html__( 'Recaptcha Version', 'uicore-elements' ),
401 'type' => Controls_Manager::SELECT,
402 'options' => [
403 'v2' => 'V2',
404 'v3' => 'V3',
405 ],
406 'default' => 'v2',
407 ]
408 );
409 $this->add_control(
410 'recaptcha_hide',
411 [
412 'label' => esc_html__( 'Badge', 'uicore-elements' ),
413 'type' => Controls_Manager::SELECT,
414 'default' => 'hidden',
415 'options' => [
416 'hidden' => esc_html__( 'Hidden', 'uicore-elements' ),
417 'visible' => esc_html__( 'Visible', 'uicore-elements' )
418 ],
419 'condition' => [
420 'recaptcha_version' => 'v3',
421 ],
422 'selectors' => [
423 '.grecaptcha-badge' => 'visibility: {{VALUE}};',
424 ],
425 ]
426 );
427 $recaptcha_keys = (!get_option('uicore_elements_recaptcha_secret_key') && !get_option('uicore_elements_recaptcha_site_key')) ? true : false; // Check if recaptcha API keys were set
428 $this->add_control(
429 'recaptcha_warning',
430 [
431 'type' => Controls_Manager::ALERT,
432 'alert_type' => 'warning',
433 'dismissible' => false,
434 'heading' => esc_html__("You haven't set your reCAPTCHA API keys yet.", 'uicore-elements'),
435 'content' => Helper::get_admin_settings_url( esc_html__("Click here to configure your API keys.", 'uicore-elements' ) ),
436 'condition' => [
437 'add_recaptcha' => $recaptcha_keys ? 'true' : [],
438 ]
439 ]
440 );
441
442 $this->end_controls_tab();
443
444 $this->end_controls_tabs();
445
446 $this->end_controls_section();
447
448 $this->start_controls_section(
449 'section_buttons',
450 [
451 'label' => esc_html__( 'Button', 'uicore-elements' ),
452 ]
453 );
454
455 $this->TRAIT_register_button_controls('Subscribe');
456
457 $this->end_controls_section();
458
459 $this->start_controls_section(
460 'section_actions',
461 [
462 'label' => esc_html__( 'Actions After Submit', 'uicore-elements' ),
463 ]
464 );
465
466 $this->add_control(
467 'submit_actions',
468 [
469 'label' => esc_html__( 'Submit Actions', 'uicore-elements' ),
470 'type' => Controls_Manager::SELECT2,
471 'label_block' => true,
472 'multiple' => true,
473 'options' => [
474 'email' => esc_html__( 'Email', 'uicore-elements' ),
475 'email_2' => esc_html__( 'Email 2', 'uicore-elements' ),
476 'redirect' => esc_html__( 'Redirect', 'uicore-elements' ),
477 'mailchimp' => esc_html__( 'MailChimp', 'uicore-elements' ),
478 ],
479 'default' => [ 'email' ],
480 ]
481 );
482
483 $this->end_controls_section();
484
485 // Submit sections
486 $this->start_controls_section(
487 'section_email',
488 [
489 'label' => esc_html__( 'Email', 'uicore-elements' ),
490 'condition' => [
491 'submit_actions' => 'email',
492 ],
493 ]
494 );
495
496 $this->TRAIT_register_submit_email_controls($this);
497
498 $this->end_controls_section();
499
500 $this->start_controls_section(
501 'section_email_2',
502 [
503 'label' => esc_html__( 'Email 2', 'uicore-elements' ),
504 'condition' => [
505 'submit_actions' => 'email_2',
506 ],
507 ]
508 );
509
510 $this->TRAIT_register_submit_email_controls($this, '_2');
511
512 $this->end_controls_section();
513
514 $this->start_controls_section(
515 'section_redirect',
516 [
517 'label' => esc_html__( 'Redirect', 'uicore-elements' ),
518 'condition' => [
519 'submit_actions' => 'redirect',
520 ],
521 ]
522 );
523
524 $this->TRAIT_register_submit_redirect_controls();
525
526 $this->end_controls_section();
527
528 $this->start_controls_section(
529 'mailchimp_redirect',
530 [
531 'label' => esc_html__( 'Mailchimp', 'uicore-elements' ),
532 'condition' => [
533 'submit_actions' => 'mailchimp',
534 ],
535 ]
536 );
537
538 $this->TRAIT_register_submit_mailchimp_controls();
539
540 $this->end_controls_section();
541
542 $this->start_controls_section(
543 'section_form_options',
544 [
545 'label' => esc_html__( 'Additional Options', 'uicore-elements' ),
546 'tab' => Controls_Manager::TAB_CONTENT,
547 ]
548 );
549
550 $this->TRAIT_register_additional_controls( Contact_Form_Service::get_default_messages() );
551
552 $this->end_controls_section();
553
554 $this->TRAIT_register_all_form_style_controls();
555 }
556
557 protected function render() {
558
559 $instance = $this->get_settings_for_display();
560 $is_recaptcha_required = false;
561
562 // Save widget settings so form API can retrieve them
563 set_transient('ui_e_form_widget_settings_' . $this->get_id(), $instance, DAY_IN_SECONDS);
564
565 // Render Form and Fields Atts
566 $this->add_render_attribute(
567 [
568 'wrapper' => [
569 'class' => [
570 'ui-e-fields-wrp',
571 ],
572 ],
573 'submit-group' => [
574 'class' => [
575 'ui-e-field-group',
576 'elementor-column',
577 'ui-e-field-type-submit',
578 ],
579 ],
580 'button' => [
581 'class' => 'elementor-button',
582 ],
583 'icon-align' => [
584 'class' => [
585 empty( $instance['button_icon_align'] ) ? '' : 'ui-e-icon ui-e-align-' . $instance['button_icon_align'],
586 ],
587 ],
588 ]
589 );
590 if($instance['add_name'] == 'true') {
591 $this->form_fields_render_attributes( '_name', $instance, 'name' );
592 }
593 $this->form_fields_render_attributes( '_email', $instance, 'email' );
594
595 // Fallback for empty control values
596 if ( empty( $instance['button_width'] ) ) {
597 $instance['button_width'] = '100';
598 }
599
600 // Button atts
601 $this->add_render_attribute( 'submit-group', 'class', 'elementor-col-' . $instance['button_width'] . ' e-form__buttons' );
602
603 if ( ! empty( $instance['button_width_tablet'] ) ) {
604 $this->add_render_attribute( 'submit-group', 'class', 'elementor-md-' . $instance['button_width_tablet'] );
605 }
606 if ( ! empty( $instance['button_width_mobile'] ) ) {
607 $this->add_render_attribute( 'submit-group', 'class', 'elementor-sm-' . $instance['button_width_mobile'] );
608 }
609 if ( $instance['button_hover_animation'] ) {
610 $this->add_render_attribute( 'button', 'class', 'elementor-animation-' . $instance['button_hover_animation'] );
611 }
612
613 // Form atts
614 if ( ! empty( $instance['form_id'] ) ) {
615 $this->add_render_attribute( 'form', 'id', $instance['form_id'] );
616 }
617 if ( ! empty( $instance['form_name'] ) ) {
618 $this->add_render_attribute( 'form', 'name', $instance['form_name'] );
619 }
620 if ( 'no' === $instance['form_validation'] ) {
621 $this->add_render_attribute( 'form', 'novalidate' );
622 }
623 if ( ! empty( $instance['button_css_id'] ) ) {
624 $this->add_render_attribute( 'button', 'id', $instance['button_css_id'] );
625 }
626
627 // Basic settings
628 $print_label = $instance['show_labels'] == 'true';
629 ?>
630
631 <form class="ui-e-form" method="post" <?php $this->print_render_attribute_string( 'form' ); ?>>
632
633 <input type="hidden" name="widget_id" value="<?php echo esc_attr( $this->get_id() ); ?>"/>
634 <input type="hidden" name="widget_type" value="newsletter">
635
636 <div <?php $this->print_render_attribute_string( 'wrapper' ); ?>>
637
638 <?php if($instance['add_name'] == 'true') : ?>
639 <div <?php $this->print_render_attribute_string( 'field-group_name'); ?>>
640 <?php if ( $print_label && $instance['name_label'] ) : ?>
641 <label <?php $this->print_render_attribute_string( 'label_name' ); ?>>
642 <?php echo esc_html($instance['name_label']);?>
643 </label>
644 <?php endif; ?>
645 <input <?php $this->print_render_attribute_string( 'input_name'); ?>>
646 </div>
647 <?php endif; ?>
648
649 <div <?php $this->print_render_attribute_string( 'field-group_email'); ?>>
650 <?php if ( $print_label && $instance['email_label'] ) : ?>
651 <label <?php $this->print_render_attribute_string( 'label_email' ); ?>>
652 <?php echo esc_html($instance['email_label']);?>
653 </label>
654 <?php endif; ?>
655 <input <?php $this->print_render_attribute_string( 'input_email'); ?>>
656 </div>
657
658 <?php if($instance['add_honeypot'] == 'true') : ?>
659 <div <?php $this->print_render_attribute_string( 'honeypot'); ?>>
660 <label for="form-field-address" class="ui-e-label">
661 <?php echo esc_html__( 'Address', 'uicore-elements' ); ?>
662 </label>
663 <input class="ui-e-field ui-e-h-p" name="ui-e-h-p" id="ui-e-h-p" tabindex="-1" autocomplete="off">
664 </div>
665 <?php endif; ?>
666
667 <div <?php $this->print_render_attribute_string( 'submit-group' ); ?>>
668 <button type="submit" <?php $this->print_render_attribute_string( 'button' ); ?>>
669 <span <?php $this->print_render_attribute_string( 'content-wrapper' ); ?>>
670 <?php if ( ! empty( $instance['button_icon'] ) || ! empty( $instance['selected_button_icon'] ) ) : ?>
671 <span <?php $this->print_render_attribute_string( 'icon-align' ); ?>>
672 <?php Icons_Manager::render_icon( $instance['selected_button_icon'], [ 'aria-hidden' => 'true' ] ); ?>
673 <?php if ( empty( $instance['button_text'] ) ) : ?>
674 <span class="elementor-screen-only"><?php echo esc_html__( 'Submit', 'uicore-elements' ); ?></span>
675 <?php endif; ?>
676 </span>
677 <?php endif; ?>
678 <?php if ( ! empty( $instance['button_text'] ) ) : ?>
679 <span class="ui-e-text"><?php $this->print_unescaped_setting( 'button_text' ); ?></span>
680 <?php endif; ?>
681 </span>
682 </button>
683 </div>
684
685 <?php
686 if($instance['add_recaptcha'] == 'true') :
687 $recaptcha_type = $instance['recaptcha_version'] === 'v2' ? 'recaptcha' : 'recaptcha_v3';
688 $is_recaptcha_required = true;
689 ?>
690 <div <?php $this->print_render_attribute_string($recaptcha_type); ?>>
691 <input type="hidden" name="<?php echo esc_attr($recaptcha_type);?>">
692 <?php if($instance['recaptcha_version'] == 'v2') : ?>
693 <div id="ui-e-recaptcha-<?php echo esc_attr( $this->get_ID() ); ?>"></div>
694 <?php endif; ?>
695 </div>
696 <?php endif; ?>
697
698 </div>
699
700 <div class="ui-e-message <?php echo $this->is_edit_mode() ? 'elementor-hidden' : ''; ?>">
701 <?php if($this->is_edit_mode()) :
702 // Get custom messages if set, else use default
703 $messages = Contact_Form_Service::get_default_messages();
704 $success = isset($instance['success_message']) ? $instance['success_message'] : $messages['success'];
705 $error = isset($instance['error_message']) ? $instance['error_message'] : $messages['error'];
706 ?>
707 <span class="success"> <?php echo esc_html($success);?> </span> <br>
708 <span class="error"> <?php echo esc_html($error);?> </span>
709 <?php endif; ?>
710 </div>
711 </form>
712 <?php
713
714 //add js to footer if recaptcha is enabled
715 if($is_recaptcha_required){
716 add_action('wp_footer', [$this, 'TRAIT_recaptcha_key_js'], 999);
717 }
718 }
719 }
720 \Elementor\Plugin::instance()->widgets_manager->register(new Newsletter());