Completed
Branch fix/relocate-cssinliner (cac68f)
by
unknown
08:36 queued 06:17
created
core/libraries/messages/messenger/EE_Email_messenger.class.php 2 patches
Indentation   +644 added lines, -644 removed lines patch added patch discarded remove patch
@@ -5,648 +5,648 @@
 block discarded – undo
5 5
  */
6 6
 class EE_Email_messenger extends EE_messenger
7 7
 {
8
-    /**
9
-     * To field for email
10
-     * @var string
11
-     */
12
-    protected $_to = '';
13
-
14
-
15
-    /**
16
-     * CC field for email.
17
-     * @var string
18
-     */
19
-    protected $_cc = '';
20
-
21
-    /**
22
-     * From field for email
23
-     * @var string
24
-     */
25
-    protected $_from = '';
26
-
27
-
28
-    /**
29
-     * Subject field for email
30
-     * @var string
31
-     */
32
-    protected $_subject = '';
33
-
34
-
35
-    /**
36
-     * Content field for email
37
-     * @var string
38
-     */
39
-    protected $_content = '';
40
-
41
-
42
-    /**
43
-     * constructor
44
-     *
45
-     * @access public
46
-     */
47
-    public function __construct()
48
-    {
49
-        // set name and description properties
50
-        $this->name                = 'email';
51
-        $this->description         = sprintf(
52
-            esc_html__(
53
-                'This messenger delivers messages via email using the built-in %s function included with WordPress',
54
-                'event_espresso'
55
-            ),
56
-            '<code>wp_mail</code>'
57
-        );
58
-        $this->label               = array(
59
-            'singular' => esc_html__('email', 'event_espresso'),
60
-            'plural'   => esc_html__('emails', 'event_espresso'),
61
-        );
62
-        $this->activate_on_install = true;
63
-
64
-        // we're using defaults so let's call parent constructor that will take care of setting up all the other
65
-        // properties
66
-        parent::__construct();
67
-    }
68
-
69
-
70
-    /**
71
-     * see abstract declaration in parent class for details.
72
-     */
73
-    protected function _set_admin_pages()
74
-    {
75
-        $this->admin_registered_pages = array(
76
-            'events_edit' => true,
77
-        );
78
-    }
79
-
80
-
81
-    /**
82
-     * see abstract declaration in parent class for details
83
-     */
84
-    protected function _set_valid_shortcodes()
85
-    {
86
-        // remember by leaving the other fields not set, those fields will inherit the valid shortcodes from the
87
-        // message type.
88
-        $this->_valid_shortcodes = array(
89
-            'to'   => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
90
-            'cc' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
91
-            'from' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
92
-        );
93
-    }
94
-
95
-
96
-    /**
97
-     * see abstract declaration in parent class for details
98
-     *
99
-     * @access protected
100
-     * @return void
101
-     */
102
-    protected function _set_validator_config()
103
-    {
104
-        $valid_shortcodes = $this->get_valid_shortcodes();
105
-
106
-        $this->_validator_config = array(
107
-            'to'            => array(
108
-                'shortcodes' => $valid_shortcodes['to'],
109
-                'type'       => 'email',
110
-            ),
111
-            'cc' => array(
112
-                'shortcodes' => $valid_shortcodes['to'],
113
-                'type' => 'email',
114
-            ),
115
-            'from'          => array(
116
-                'shortcodes' => $valid_shortcodes['from'],
117
-                'type'       => 'email',
118
-            ),
119
-            'subject'       => array(
120
-                'shortcodes' => array(
121
-                    'organization',
122
-                    'primary_registration_details',
123
-                    'event_author',
124
-                    'primary_registration_details',
125
-                    'recipient_details',
126
-                ),
127
-            ),
128
-            'content'       => array(
129
-                'shortcodes' => array(
130
-                    'event_list',
131
-                    'attendee_list',
132
-                    'ticket_list',
133
-                    'organization',
134
-                    'primary_registration_details',
135
-                    'primary_registration_list',
136
-                    'event_author',
137
-                    'recipient_details',
138
-                    'recipient_list',
139
-                    'transaction',
140
-                    'messenger',
141
-                ),
142
-            ),
143
-            'attendee_list' => array(
144
-                'shortcodes' => array('attendee', 'event_list', 'ticket_list'),
145
-                'required'   => array('[ATTENDEE_LIST]'),
146
-            ),
147
-            'event_list'    => array(
148
-                'shortcodes' => array(
149
-                    'event',
150
-                    'attendee_list',
151
-                    'ticket_list',
152
-                    'venue',
153
-                    'datetime_list',
154
-                    'attendee',
155
-                    'primary_registration_details',
156
-                    'primary_registration_list',
157
-                    'event_author',
158
-                    'recipient_details',
159
-                    'recipient_list',
160
-                ),
161
-                'required'   => array('[EVENT_LIST]'),
162
-            ),
163
-            'ticket_list'   => array(
164
-                'shortcodes' => array(
165
-                    'event_list',
166
-                    'attendee_list',
167
-                    'ticket',
168
-                    'datetime_list',
169
-                    'primary_registration_details',
170
-                    'recipient_details',
171
-                ),
172
-                'required'   => array('[TICKET_LIST]'),
173
-            ),
174
-            'datetime_list' => array(
175
-                'shortcodes' => array('datetime'),
176
-                'required'   => array('[DATETIME_LIST]'),
177
-            ),
178
-        );
179
-    }
180
-
181
-
182
-    /**
183
-     * @see   parent EE_messenger class for docs
184
-     * @since 4.5.0
185
-     */
186
-    public function do_secondary_messenger_hooks($sending_messenger_name)
187
-    {
188
-        if ($sending_messenger_name === 'html') {
189
-            add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
190
-        }
191
-    }
192
-
193
-
194
-    public function add_email_css(
195
-        $variation_path,
196
-        $messenger,
197
-        $message_type,
198
-        $type,
199
-        $variation,
200
-        $file_extension,
201
-        $url,
202
-        EE_Messages_Template_Pack $template_pack
203
-    ) {
204
-        // prevent recursion on this callback.
205
-        remove_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10);
206
-        $variation = $this->get_variation($template_pack, $message_type, $url, 'main', $variation, false);
207
-
208
-        add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
209
-        return $variation;
210
-    }
211
-
212
-
213
-    /**
214
-     * See parent for details
215
-     *
216
-     * @access protected
217
-     * @return void
218
-     */
219
-    protected function _set_test_settings_fields()
220
-    {
221
-        $this->_test_settings_fields = array(
222
-            'to'      => array(
223
-                'input'      => 'text',
224
-                'label'      => esc_html__('Send a test email to', 'event_espresso'),
225
-                'type'       => 'email',
226
-                'required'   => false,
227
-                'validation' => true,
228
-                'css_class'  => 'large-text',
229
-                'format'     => '%s',
230
-                'default'    => get_bloginfo('admin_email'),
231
-            ),
232
-            'subject' => array(
233
-                'input'      => 'hidden',
234
-                'label'      => '',
235
-                'type'       => 'string',
236
-                'required'   => false,
237
-                'validation' => false,
238
-                'format'     => '%s',
239
-                'value'      => sprintf(esc_html__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')),
240
-                'default'    => '',
241
-                'css_class'  => '',
242
-            ),
243
-        );
244
-    }
245
-
246
-
247
-    /**
248
-     * _set_template_fields
249
-     * This sets up the fields that a messenger requires for the message to go out.
250
-     *
251
-     * @access  protected
252
-     * @return void
253
-     */
254
-    protected function _set_template_fields()
255
-    {
256
-        // any extra template fields that are NOT used by the messenger but will get used by a messenger field for
257
-        // shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field
258
-        // they relate to.  This is important for the Messages_admin to know what fields to display to the user.
259
-        //  Also, notice that the "values" are equal to the field type that messages admin will use to know what
260
-        // kind of field to display. The values ALSO have one index labeled "shortcode".  the values in that array
261
-        // indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be
262
-        // displayed.  If the required shortcode isn't part of the shortcodes array then the field is not needed and
263
-        // will not be displayed/parsed.
264
-        $this->_template_fields = array(
265
-            'to'      => array(
266
-                'input'      => 'text',
267
-                'label'      => esc_html_x(
268
-                    'To',
269
-                    'Label for the "To" field for email addresses',
270
-                    'event_espresso'
271
-                ),
272
-                'type'       => 'string',
273
-                'required'   => true,
274
-                'validation' => true,
275
-                'css_class'  => 'large-text',
276
-                'format'     => '%s',
277
-            ),
278
-            'cc'      => array(
279
-                'input'      => 'text',
280
-                'label'      => esc_html_x(
281
-                    'CC',
282
-                    'Label for the "Carbon Copy" field used for additional email addresses',
283
-                    'event_espresso'
284
-                ),
285
-                'type'       => 'string',
286
-                'required'   => false,
287
-                'validation' => true,
288
-                'css_class'  => 'large-text',
289
-                'format'     => '%s',
290
-            ),
291
-            'from'    => array(
292
-                'input'      => 'text',
293
-                'label'      => esc_html_x(
294
-                    'From',
295
-                    'Label for the "From" field for email addresses.',
296
-                    'event_espresso'
297
-                ),
298
-                'type'       => 'string',
299
-                'required'   => true,
300
-                'validation' => true,
301
-                'css_class'  => 'large-text',
302
-                'format'     => '%s',
303
-            ),
304
-            'subject' => array(
305
-                'input'      => 'text',
306
-                'label'      => esc_html_x(
307
-                    'Subject',
308
-                    'Label for the "Subject" field (short description of contents) for emails.',
309
-                    'event_espresso'
310
-                ),
311
-                'type'       => 'string',
312
-                'required'   => true,
313
-                'validation' => true,
314
-                'css_class'  => 'large-text',
315
-                'format'     => '%s',
316
-            ),
317
-            'content' => '',
318
-            // left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
319
-            'extra'   => array(
320
-                'content' => array(
321
-                    'main'          => array(
322
-                        'input'      => 'wp_editor',
323
-                        'label'      => esc_html__('Main Content', 'event_espresso'),
324
-                        'type'       => 'string',
325
-                        'required'   => true,
326
-                        'validation' => true,
327
-                        'format'     => '%s',
328
-                        'rows'       => '15',
329
-                    ),
330
-                    'event_list'    => array(
331
-                        'input'               => 'wp_editor',
332
-                        'label'               => '[EVENT_LIST]',
333
-                        'type'                => 'string',
334
-                        'required'            => true,
335
-                        'validation'          => true,
336
-                        'format'              => '%s',
337
-                        'rows'                => '15',
338
-                        'shortcodes_required' => array('[EVENT_LIST]'),
339
-                    ),
340
-                    'attendee_list' => array(
341
-                        'input'               => 'textarea',
342
-                        'label'               => '[ATTENDEE_LIST]',
343
-                        'type'                => 'string',
344
-                        'required'            => true,
345
-                        'validation'          => true,
346
-                        'format'              => '%s',
347
-                        'css_class'           => 'large-text',
348
-                        'rows'                => '5',
349
-                        'shortcodes_required' => array('[ATTENDEE_LIST]'),
350
-                    ),
351
-                    'ticket_list'   => array(
352
-                        'input'               => 'textarea',
353
-                        'label'               => '[TICKET_LIST]',
354
-                        'type'                => 'string',
355
-                        'required'            => true,
356
-                        'validation'          => true,
357
-                        'format'              => '%s',
358
-                        'css_class'           => 'large-text',
359
-                        'rows'                => '10',
360
-                        'shortcodes_required' => array('[TICKET_LIST]'),
361
-                    ),
362
-                    'datetime_list' => array(
363
-                        'input'               => 'textarea',
364
-                        'label'               => '[DATETIME_LIST]',
365
-                        'type'                => 'string',
366
-                        'required'            => true,
367
-                        'validation'          => true,
368
-                        'format'              => '%s',
369
-                        'css_class'           => 'large-text',
370
-                        'rows'                => '10',
371
-                        'shortcodes_required' => array('[DATETIME_LIST]'),
372
-                    ),
373
-                ),
374
-            ),
375
-        );
376
-    }
377
-
378
-
379
-    /**
380
-     * See definition of this class in parent
381
-     */
382
-    protected function _set_default_message_types()
383
-    {
384
-        $this->_default_message_types = array(
385
-            'payment',
386
-            'payment_refund',
387
-            'registration',
388
-            'not_approved_registration',
389
-            'pending_approval',
390
-        );
391
-    }
392
-
393
-
394
-    /**
395
-     * @see   definition of this class in parent
396
-     * @since 4.5.0
397
-     */
398
-    protected function _set_valid_message_types()
399
-    {
400
-        $this->_valid_message_types = array(
401
-            'payment',
402
-            'registration',
403
-            'not_approved_registration',
404
-            'declined_registration',
405
-            'cancelled_registration',
406
-            'pending_approval',
407
-            'registration_summary',
408
-            'payment_reminder',
409
-            'payment_declined',
410
-            'payment_refund',
411
-        );
412
-    }
413
-
414
-
415
-    /**
416
-     * setting up admin_settings_fields for messenger.
417
-     */
418
-    protected function _set_admin_settings_fields()
419
-    {
420
-    }
421
-
422
-    /**
423
-     * We just deliver the messages don't kill us!!
424
-     *
425
-     * @return bool|WP_Error true if message delivered, false if it didn't deliver OR bubble up any error object if
426
-     *              present.
427
-     * @throws EE_Error
428
-     * @throws \TijsVerkoyen\CssToInlineStyles\Exception
429
-     */
430
-    protected function _send_message()
431
-    {
432
-        $success = wp_mail(
433
-            $this->_to,
434
-            // some old values for subject may be expecting HTML entities to be decoded in the subject
435
-            // and subjects aren't interpreted as HTML, so there should be no HTML in them
436
-            wp_strip_all_tags(wp_specialchars_decode($this->_subject, ENT_QUOTES)),
437
-            $this->_body(),
438
-            $this->_headers()
439
-        );
440
-        if (! $success) {
441
-            EE_Error::add_error(
442
-                sprintf(
443
-                    esc_html__(
444
-                        'The email did not send successfully.%3$sThe WordPress wp_mail function is used for sending mails but does not give any useful information when an email fails to send.%3$sIt is possible the "to" address (%1$s) or "from" address (%2$s) is invalid.%3$s',
445
-                        'event_espresso'
446
-                    ),
447
-                    $this->_to,
448
-                    $this->_from,
449
-                    '<br />'
450
-                ),
451
-                __FILE__,
452
-                __FUNCTION__,
453
-                __LINE__
454
-            );
455
-        }
456
-        return $success;
457
-    }
458
-
459
-
460
-    /**
461
-     * see parent for definition
462
-     *
463
-     * @return string html body of the message content and the related css.
464
-     * @throws EE_Error
465
-     * @throws \TijsVerkoyen\CssToInlineStyles\Exception
466
-     */
467
-    protected function _preview()
468
-    {
469
-        return $this->_body(true);
470
-    }
471
-
472
-
473
-    /**
474
-     * Setup headers for email
475
-     *
476
-     * @access protected
477
-     * @return string formatted header for email
478
-     */
479
-    protected function _headers()
480
-    {
481
-        $this->_ensure_has_from_email_address();
482
-        $from    = $this->_from;
483
-        $headers = array(
484
-            'From:' . $from,
485
-            'Reply-To:' . $from,
486
-            'Content-Type:text/html; charset=utf-8',
487
-        );
488
-
489
-        /**
490
-         * Second condition added as a result of https://events.codebasehq.com/projects/event-espresso/tickets/11416 to
491
-         * cover back compat where there may be users who have saved cc values in their db for the newsletter message
492
-         * type which they are no longer able to change.
493
-         */
494
-        if (! empty($this->_cc) && ! $this->_incoming_message_type instanceof EE_Newsletter_message_type) {
495
-            $headers[] = 'cc: ' . $this->_cc;
496
-        }
497
-
498
-        // but wait!  Header's for the from is NOT reliable because some plugins don't respect From: as set in the
499
-        // header.
500
-        add_filter('wp_mail_from', array($this, 'set_from_address'), 100);
501
-        add_filter('wp_mail_from_name', array($this, 'set_from_name'), 100);
502
-        return apply_filters('FHEE__EE_Email_messenger___headers', $headers, $this->_incoming_message_type, $this);
503
-    }
504
-
505
-
506
-    /**
507
-     * This simply ensures that the from address is not empty.  If it is, then we use whatever is set as the site email
508
-     * address for the from address to avoid problems with sending emails.
509
-     */
510
-    protected function _ensure_has_from_email_address()
511
-    {
512
-        if (empty($this->_from)) {
513
-            $this->_from = get_bloginfo('admin_email');
514
-        }
515
-    }
516
-
517
-
518
-    /**
519
-     * This simply parses whatever is set as the $_from address and determines if it is in the format {name} <{email}>
520
-     * or just {email} and returns an array with the "from_name" and "from_email" as the values. Note from_name *MAY*
521
-     * be empty
522
-     *
523
-     * @since 4.3.1
524
-     * @return array
525
-     */
526
-    private function _parse_from()
527
-    {
528
-        if (strpos($this->_from, '<') !== false) {
529
-            $from_name = substr($this->_from, 0, strpos($this->_from, '<') - 1);
530
-            $from_name = str_replace('"', '', $from_name);
531
-            $from_name = trim($from_name);
532
-
533
-            $from_email = substr($this->_from, strpos($this->_from, '<') + 1);
534
-            $from_email = str_replace('>', '', $from_email);
535
-            $from_email = trim($from_email);
536
-        } elseif (trim($this->_from) !== '') {
537
-            $from_name  = '';
538
-            $from_email = trim($this->_from);
539
-        } else {
540
-            $from_name = $from_email = '';
541
-        }
542
-        return array($from_name, $from_email);
543
-    }
544
-
545
-
546
-    /**
547
-     * Callback for the wp_mail_from filter.
548
-     *
549
-     * @since 4.3.1
550
-     * @param string $from_email What the original from_email is.
551
-     * @return string
552
-     */
553
-    public function set_from_address($from_email)
554
-    {
555
-        $parsed_from = $this->_parse_from();
556
-        // includes fallback if the parsing failed.
557
-        $from_email = is_array($parsed_from) && ! empty($parsed_from[1])
558
-            ? $parsed_from[1]
559
-            : get_bloginfo('admin_email');
560
-        return $from_email;
561
-    }
562
-
563
-
564
-    /**
565
-     * Callback fro the wp_mail_from_name filter.
566
-     *
567
-     * @since 4.3.1
568
-     * @param string $from_name The original from_name.
569
-     * @return string
570
-     */
571
-    public function set_from_name($from_name)
572
-    {
573
-        $parsed_from = $this->_parse_from();
574
-        if (is_array($parsed_from) && ! empty($parsed_from[0])) {
575
-            $from_name = $parsed_from[0];
576
-        }
577
-
578
-        // if from name is "WordPress" let's sub in the site name instead (more friendly!)
579
-        // but realize the default name is HTML entity-encoded
580
-        $from_name = $from_name == 'WordPress' ? wp_specialchars_decode(get_bloginfo(), ENT_QUOTES) : $from_name;
581
-
582
-        return $from_name;
583
-    }
584
-
585
-
586
-    /**
587
-     * setup body for email
588
-     *
589
-     * @param bool $preview will determine whether this is preview template or not.
590
-     * @return string formatted body for email.
591
-     * @throws EE_Error
592
-     * @throws \TijsVerkoyen\CssToInlineStyles\Exception
593
-     */
594
-    protected function _body($preview = false)
595
-    {
596
-        // setup template args!
597
-        $this->_template_args = array(
598
-            'subject'   => $this->_subject,
599
-            'from'      => $this->_from,
600
-            'main_body' => wpautop($this->_content),
601
-        );
602
-        $body                 = $this->_get_main_template($preview);
603
-
604
-        /**
605
-         * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched.
606
-         *
607
-         * @type    bool $preview Indicates whether a preview is being generated or not.
608
-         * @return  bool    true  indicates to use the inliner, false bypasses it.
609
-         */
610
-        if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) {
611
-            // require CssToInlineStyles library and its dependencies via composer autoloader
612
-            require_once EE_LIBRARIES . 'messages/cssinliner/vendor/autoload.php';
613
-
614
-            // now if this isn't a preview, let's setup the body so it has inline styles
615
-            if (! $preview || ($preview && defined('DOING_AJAX'))) {
616
-                $style = file_get_contents(
617
-                    $this->get_variation(
618
-                        $this->_tmp_pack,
619
-                        $this->_incoming_message_type->name,
620
-                        false,
621
-                        'main',
622
-                        $this->_variation
623
-                    ),
624
-                    true
625
-                );
626
-                $CSS   = new TijsVerkoyen\CssToInlineStyles\CssToInlineStyles($body, $style);
627
-                // for some reason the library has a bracket and new line at the beginning.  This takes care of that.
628
-                $body  = ltrim($CSS->convert(true), ">\n");
629
-                // see https://events.codebasehq.com/projects/event-espresso/tickets/8609
630
-                $body  = ltrim($body, "<?");
631
-            }
632
-        }
633
-        return $body;
634
-    }
635
-
636
-
637
-    /**
638
-     * This just returns any existing test settings that might be saved in the database
639
-     *
640
-     * @access public
641
-     * @return array
642
-     */
643
-    public function get_existing_test_settings()
644
-    {
645
-        $settings = parent::get_existing_test_settings();
646
-        // override subject if present because we always want it to be fresh.
647
-        if (is_array($settings) && ! empty($settings['subject'])) {
648
-            $settings['subject'] = sprintf(esc_html__('Test email sent from %s', 'event_espresso'), get_bloginfo('name'));
649
-        }
650
-        return $settings;
651
-    }
8
+	/**
9
+	 * To field for email
10
+	 * @var string
11
+	 */
12
+	protected $_to = '';
13
+
14
+
15
+	/**
16
+	 * CC field for email.
17
+	 * @var string
18
+	 */
19
+	protected $_cc = '';
20
+
21
+	/**
22
+	 * From field for email
23
+	 * @var string
24
+	 */
25
+	protected $_from = '';
26
+
27
+
28
+	/**
29
+	 * Subject field for email
30
+	 * @var string
31
+	 */
32
+	protected $_subject = '';
33
+
34
+
35
+	/**
36
+	 * Content field for email
37
+	 * @var string
38
+	 */
39
+	protected $_content = '';
40
+
41
+
42
+	/**
43
+	 * constructor
44
+	 *
45
+	 * @access public
46
+	 */
47
+	public function __construct()
48
+	{
49
+		// set name and description properties
50
+		$this->name                = 'email';
51
+		$this->description         = sprintf(
52
+			esc_html__(
53
+				'This messenger delivers messages via email using the built-in %s function included with WordPress',
54
+				'event_espresso'
55
+			),
56
+			'<code>wp_mail</code>'
57
+		);
58
+		$this->label               = array(
59
+			'singular' => esc_html__('email', 'event_espresso'),
60
+			'plural'   => esc_html__('emails', 'event_espresso'),
61
+		);
62
+		$this->activate_on_install = true;
63
+
64
+		// we're using defaults so let's call parent constructor that will take care of setting up all the other
65
+		// properties
66
+		parent::__construct();
67
+	}
68
+
69
+
70
+	/**
71
+	 * see abstract declaration in parent class for details.
72
+	 */
73
+	protected function _set_admin_pages()
74
+	{
75
+		$this->admin_registered_pages = array(
76
+			'events_edit' => true,
77
+		);
78
+	}
79
+
80
+
81
+	/**
82
+	 * see abstract declaration in parent class for details
83
+	 */
84
+	protected function _set_valid_shortcodes()
85
+	{
86
+		// remember by leaving the other fields not set, those fields will inherit the valid shortcodes from the
87
+		// message type.
88
+		$this->_valid_shortcodes = array(
89
+			'to'   => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
90
+			'cc' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
91
+			'from' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
92
+		);
93
+	}
94
+
95
+
96
+	/**
97
+	 * see abstract declaration in parent class for details
98
+	 *
99
+	 * @access protected
100
+	 * @return void
101
+	 */
102
+	protected function _set_validator_config()
103
+	{
104
+		$valid_shortcodes = $this->get_valid_shortcodes();
105
+
106
+		$this->_validator_config = array(
107
+			'to'            => array(
108
+				'shortcodes' => $valid_shortcodes['to'],
109
+				'type'       => 'email',
110
+			),
111
+			'cc' => array(
112
+				'shortcodes' => $valid_shortcodes['to'],
113
+				'type' => 'email',
114
+			),
115
+			'from'          => array(
116
+				'shortcodes' => $valid_shortcodes['from'],
117
+				'type'       => 'email',
118
+			),
119
+			'subject'       => array(
120
+				'shortcodes' => array(
121
+					'organization',
122
+					'primary_registration_details',
123
+					'event_author',
124
+					'primary_registration_details',
125
+					'recipient_details',
126
+				),
127
+			),
128
+			'content'       => array(
129
+				'shortcodes' => array(
130
+					'event_list',
131
+					'attendee_list',
132
+					'ticket_list',
133
+					'organization',
134
+					'primary_registration_details',
135
+					'primary_registration_list',
136
+					'event_author',
137
+					'recipient_details',
138
+					'recipient_list',
139
+					'transaction',
140
+					'messenger',
141
+				),
142
+			),
143
+			'attendee_list' => array(
144
+				'shortcodes' => array('attendee', 'event_list', 'ticket_list'),
145
+				'required'   => array('[ATTENDEE_LIST]'),
146
+			),
147
+			'event_list'    => array(
148
+				'shortcodes' => array(
149
+					'event',
150
+					'attendee_list',
151
+					'ticket_list',
152
+					'venue',
153
+					'datetime_list',
154
+					'attendee',
155
+					'primary_registration_details',
156
+					'primary_registration_list',
157
+					'event_author',
158
+					'recipient_details',
159
+					'recipient_list',
160
+				),
161
+				'required'   => array('[EVENT_LIST]'),
162
+			),
163
+			'ticket_list'   => array(
164
+				'shortcodes' => array(
165
+					'event_list',
166
+					'attendee_list',
167
+					'ticket',
168
+					'datetime_list',
169
+					'primary_registration_details',
170
+					'recipient_details',
171
+				),
172
+				'required'   => array('[TICKET_LIST]'),
173
+			),
174
+			'datetime_list' => array(
175
+				'shortcodes' => array('datetime'),
176
+				'required'   => array('[DATETIME_LIST]'),
177
+			),
178
+		);
179
+	}
180
+
181
+
182
+	/**
183
+	 * @see   parent EE_messenger class for docs
184
+	 * @since 4.5.0
185
+	 */
186
+	public function do_secondary_messenger_hooks($sending_messenger_name)
187
+	{
188
+		if ($sending_messenger_name === 'html') {
189
+			add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
190
+		}
191
+	}
192
+
193
+
194
+	public function add_email_css(
195
+		$variation_path,
196
+		$messenger,
197
+		$message_type,
198
+		$type,
199
+		$variation,
200
+		$file_extension,
201
+		$url,
202
+		EE_Messages_Template_Pack $template_pack
203
+	) {
204
+		// prevent recursion on this callback.
205
+		remove_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10);
206
+		$variation = $this->get_variation($template_pack, $message_type, $url, 'main', $variation, false);
207
+
208
+		add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
209
+		return $variation;
210
+	}
211
+
212
+
213
+	/**
214
+	 * See parent for details
215
+	 *
216
+	 * @access protected
217
+	 * @return void
218
+	 */
219
+	protected function _set_test_settings_fields()
220
+	{
221
+		$this->_test_settings_fields = array(
222
+			'to'      => array(
223
+				'input'      => 'text',
224
+				'label'      => esc_html__('Send a test email to', 'event_espresso'),
225
+				'type'       => 'email',
226
+				'required'   => false,
227
+				'validation' => true,
228
+				'css_class'  => 'large-text',
229
+				'format'     => '%s',
230
+				'default'    => get_bloginfo('admin_email'),
231
+			),
232
+			'subject' => array(
233
+				'input'      => 'hidden',
234
+				'label'      => '',
235
+				'type'       => 'string',
236
+				'required'   => false,
237
+				'validation' => false,
238
+				'format'     => '%s',
239
+				'value'      => sprintf(esc_html__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')),
240
+				'default'    => '',
241
+				'css_class'  => '',
242
+			),
243
+		);
244
+	}
245
+
246
+
247
+	/**
248
+	 * _set_template_fields
249
+	 * This sets up the fields that a messenger requires for the message to go out.
250
+	 *
251
+	 * @access  protected
252
+	 * @return void
253
+	 */
254
+	protected function _set_template_fields()
255
+	{
256
+		// any extra template fields that are NOT used by the messenger but will get used by a messenger field for
257
+		// shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field
258
+		// they relate to.  This is important for the Messages_admin to know what fields to display to the user.
259
+		//  Also, notice that the "values" are equal to the field type that messages admin will use to know what
260
+		// kind of field to display. The values ALSO have one index labeled "shortcode".  the values in that array
261
+		// indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be
262
+		// displayed.  If the required shortcode isn't part of the shortcodes array then the field is not needed and
263
+		// will not be displayed/parsed.
264
+		$this->_template_fields = array(
265
+			'to'      => array(
266
+				'input'      => 'text',
267
+				'label'      => esc_html_x(
268
+					'To',
269
+					'Label for the "To" field for email addresses',
270
+					'event_espresso'
271
+				),
272
+				'type'       => 'string',
273
+				'required'   => true,
274
+				'validation' => true,
275
+				'css_class'  => 'large-text',
276
+				'format'     => '%s',
277
+			),
278
+			'cc'      => array(
279
+				'input'      => 'text',
280
+				'label'      => esc_html_x(
281
+					'CC',
282
+					'Label for the "Carbon Copy" field used for additional email addresses',
283
+					'event_espresso'
284
+				),
285
+				'type'       => 'string',
286
+				'required'   => false,
287
+				'validation' => true,
288
+				'css_class'  => 'large-text',
289
+				'format'     => '%s',
290
+			),
291
+			'from'    => array(
292
+				'input'      => 'text',
293
+				'label'      => esc_html_x(
294
+					'From',
295
+					'Label for the "From" field for email addresses.',
296
+					'event_espresso'
297
+				),
298
+				'type'       => 'string',
299
+				'required'   => true,
300
+				'validation' => true,
301
+				'css_class'  => 'large-text',
302
+				'format'     => '%s',
303
+			),
304
+			'subject' => array(
305
+				'input'      => 'text',
306
+				'label'      => esc_html_x(
307
+					'Subject',
308
+					'Label for the "Subject" field (short description of contents) for emails.',
309
+					'event_espresso'
310
+				),
311
+				'type'       => 'string',
312
+				'required'   => true,
313
+				'validation' => true,
314
+				'css_class'  => 'large-text',
315
+				'format'     => '%s',
316
+			),
317
+			'content' => '',
318
+			// left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
319
+			'extra'   => array(
320
+				'content' => array(
321
+					'main'          => array(
322
+						'input'      => 'wp_editor',
323
+						'label'      => esc_html__('Main Content', 'event_espresso'),
324
+						'type'       => 'string',
325
+						'required'   => true,
326
+						'validation' => true,
327
+						'format'     => '%s',
328
+						'rows'       => '15',
329
+					),
330
+					'event_list'    => array(
331
+						'input'               => 'wp_editor',
332
+						'label'               => '[EVENT_LIST]',
333
+						'type'                => 'string',
334
+						'required'            => true,
335
+						'validation'          => true,
336
+						'format'              => '%s',
337
+						'rows'                => '15',
338
+						'shortcodes_required' => array('[EVENT_LIST]'),
339
+					),
340
+					'attendee_list' => array(
341
+						'input'               => 'textarea',
342
+						'label'               => '[ATTENDEE_LIST]',
343
+						'type'                => 'string',
344
+						'required'            => true,
345
+						'validation'          => true,
346
+						'format'              => '%s',
347
+						'css_class'           => 'large-text',
348
+						'rows'                => '5',
349
+						'shortcodes_required' => array('[ATTENDEE_LIST]'),
350
+					),
351
+					'ticket_list'   => array(
352
+						'input'               => 'textarea',
353
+						'label'               => '[TICKET_LIST]',
354
+						'type'                => 'string',
355
+						'required'            => true,
356
+						'validation'          => true,
357
+						'format'              => '%s',
358
+						'css_class'           => 'large-text',
359
+						'rows'                => '10',
360
+						'shortcodes_required' => array('[TICKET_LIST]'),
361
+					),
362
+					'datetime_list' => array(
363
+						'input'               => 'textarea',
364
+						'label'               => '[DATETIME_LIST]',
365
+						'type'                => 'string',
366
+						'required'            => true,
367
+						'validation'          => true,
368
+						'format'              => '%s',
369
+						'css_class'           => 'large-text',
370
+						'rows'                => '10',
371
+						'shortcodes_required' => array('[DATETIME_LIST]'),
372
+					),
373
+				),
374
+			),
375
+		);
376
+	}
377
+
378
+
379
+	/**
380
+	 * See definition of this class in parent
381
+	 */
382
+	protected function _set_default_message_types()
383
+	{
384
+		$this->_default_message_types = array(
385
+			'payment',
386
+			'payment_refund',
387
+			'registration',
388
+			'not_approved_registration',
389
+			'pending_approval',
390
+		);
391
+	}
392
+
393
+
394
+	/**
395
+	 * @see   definition of this class in parent
396
+	 * @since 4.5.0
397
+	 */
398
+	protected function _set_valid_message_types()
399
+	{
400
+		$this->_valid_message_types = array(
401
+			'payment',
402
+			'registration',
403
+			'not_approved_registration',
404
+			'declined_registration',
405
+			'cancelled_registration',
406
+			'pending_approval',
407
+			'registration_summary',
408
+			'payment_reminder',
409
+			'payment_declined',
410
+			'payment_refund',
411
+		);
412
+	}
413
+
414
+
415
+	/**
416
+	 * setting up admin_settings_fields for messenger.
417
+	 */
418
+	protected function _set_admin_settings_fields()
419
+	{
420
+	}
421
+
422
+	/**
423
+	 * We just deliver the messages don't kill us!!
424
+	 *
425
+	 * @return bool|WP_Error true if message delivered, false if it didn't deliver OR bubble up any error object if
426
+	 *              present.
427
+	 * @throws EE_Error
428
+	 * @throws \TijsVerkoyen\CssToInlineStyles\Exception
429
+	 */
430
+	protected function _send_message()
431
+	{
432
+		$success = wp_mail(
433
+			$this->_to,
434
+			// some old values for subject may be expecting HTML entities to be decoded in the subject
435
+			// and subjects aren't interpreted as HTML, so there should be no HTML in them
436
+			wp_strip_all_tags(wp_specialchars_decode($this->_subject, ENT_QUOTES)),
437
+			$this->_body(),
438
+			$this->_headers()
439
+		);
440
+		if (! $success) {
441
+			EE_Error::add_error(
442
+				sprintf(
443
+					esc_html__(
444
+						'The email did not send successfully.%3$sThe WordPress wp_mail function is used for sending mails but does not give any useful information when an email fails to send.%3$sIt is possible the "to" address (%1$s) or "from" address (%2$s) is invalid.%3$s',
445
+						'event_espresso'
446
+					),
447
+					$this->_to,
448
+					$this->_from,
449
+					'<br />'
450
+				),
451
+				__FILE__,
452
+				__FUNCTION__,
453
+				__LINE__
454
+			);
455
+		}
456
+		return $success;
457
+	}
458
+
459
+
460
+	/**
461
+	 * see parent for definition
462
+	 *
463
+	 * @return string html body of the message content and the related css.
464
+	 * @throws EE_Error
465
+	 * @throws \TijsVerkoyen\CssToInlineStyles\Exception
466
+	 */
467
+	protected function _preview()
468
+	{
469
+		return $this->_body(true);
470
+	}
471
+
472
+
473
+	/**
474
+	 * Setup headers for email
475
+	 *
476
+	 * @access protected
477
+	 * @return string formatted header for email
478
+	 */
479
+	protected function _headers()
480
+	{
481
+		$this->_ensure_has_from_email_address();
482
+		$from    = $this->_from;
483
+		$headers = array(
484
+			'From:' . $from,
485
+			'Reply-To:' . $from,
486
+			'Content-Type:text/html; charset=utf-8',
487
+		);
488
+
489
+		/**
490
+		 * Second condition added as a result of https://events.codebasehq.com/projects/event-espresso/tickets/11416 to
491
+		 * cover back compat where there may be users who have saved cc values in their db for the newsletter message
492
+		 * type which they are no longer able to change.
493
+		 */
494
+		if (! empty($this->_cc) && ! $this->_incoming_message_type instanceof EE_Newsletter_message_type) {
495
+			$headers[] = 'cc: ' . $this->_cc;
496
+		}
497
+
498
+		// but wait!  Header's for the from is NOT reliable because some plugins don't respect From: as set in the
499
+		// header.
500
+		add_filter('wp_mail_from', array($this, 'set_from_address'), 100);
501
+		add_filter('wp_mail_from_name', array($this, 'set_from_name'), 100);
502
+		return apply_filters('FHEE__EE_Email_messenger___headers', $headers, $this->_incoming_message_type, $this);
503
+	}
504
+
505
+
506
+	/**
507
+	 * This simply ensures that the from address is not empty.  If it is, then we use whatever is set as the site email
508
+	 * address for the from address to avoid problems with sending emails.
509
+	 */
510
+	protected function _ensure_has_from_email_address()
511
+	{
512
+		if (empty($this->_from)) {
513
+			$this->_from = get_bloginfo('admin_email');
514
+		}
515
+	}
516
+
517
+
518
+	/**
519
+	 * This simply parses whatever is set as the $_from address and determines if it is in the format {name} <{email}>
520
+	 * or just {email} and returns an array with the "from_name" and "from_email" as the values. Note from_name *MAY*
521
+	 * be empty
522
+	 *
523
+	 * @since 4.3.1
524
+	 * @return array
525
+	 */
526
+	private function _parse_from()
527
+	{
528
+		if (strpos($this->_from, '<') !== false) {
529
+			$from_name = substr($this->_from, 0, strpos($this->_from, '<') - 1);
530
+			$from_name = str_replace('"', '', $from_name);
531
+			$from_name = trim($from_name);
532
+
533
+			$from_email = substr($this->_from, strpos($this->_from, '<') + 1);
534
+			$from_email = str_replace('>', '', $from_email);
535
+			$from_email = trim($from_email);
536
+		} elseif (trim($this->_from) !== '') {
537
+			$from_name  = '';
538
+			$from_email = trim($this->_from);
539
+		} else {
540
+			$from_name = $from_email = '';
541
+		}
542
+		return array($from_name, $from_email);
543
+	}
544
+
545
+
546
+	/**
547
+	 * Callback for the wp_mail_from filter.
548
+	 *
549
+	 * @since 4.3.1
550
+	 * @param string $from_email What the original from_email is.
551
+	 * @return string
552
+	 */
553
+	public function set_from_address($from_email)
554
+	{
555
+		$parsed_from = $this->_parse_from();
556
+		// includes fallback if the parsing failed.
557
+		$from_email = is_array($parsed_from) && ! empty($parsed_from[1])
558
+			? $parsed_from[1]
559
+			: get_bloginfo('admin_email');
560
+		return $from_email;
561
+	}
562
+
563
+
564
+	/**
565
+	 * Callback fro the wp_mail_from_name filter.
566
+	 *
567
+	 * @since 4.3.1
568
+	 * @param string $from_name The original from_name.
569
+	 * @return string
570
+	 */
571
+	public function set_from_name($from_name)
572
+	{
573
+		$parsed_from = $this->_parse_from();
574
+		if (is_array($parsed_from) && ! empty($parsed_from[0])) {
575
+			$from_name = $parsed_from[0];
576
+		}
577
+
578
+		// if from name is "WordPress" let's sub in the site name instead (more friendly!)
579
+		// but realize the default name is HTML entity-encoded
580
+		$from_name = $from_name == 'WordPress' ? wp_specialchars_decode(get_bloginfo(), ENT_QUOTES) : $from_name;
581
+
582
+		return $from_name;
583
+	}
584
+
585
+
586
+	/**
587
+	 * setup body for email
588
+	 *
589
+	 * @param bool $preview will determine whether this is preview template or not.
590
+	 * @return string formatted body for email.
591
+	 * @throws EE_Error
592
+	 * @throws \TijsVerkoyen\CssToInlineStyles\Exception
593
+	 */
594
+	protected function _body($preview = false)
595
+	{
596
+		// setup template args!
597
+		$this->_template_args = array(
598
+			'subject'   => $this->_subject,
599
+			'from'      => $this->_from,
600
+			'main_body' => wpautop($this->_content),
601
+		);
602
+		$body                 = $this->_get_main_template($preview);
603
+
604
+		/**
605
+		 * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched.
606
+		 *
607
+		 * @type    bool $preview Indicates whether a preview is being generated or not.
608
+		 * @return  bool    true  indicates to use the inliner, false bypasses it.
609
+		 */
610
+		if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) {
611
+			// require CssToInlineStyles library and its dependencies via composer autoloader
612
+			require_once EE_LIBRARIES . 'messages/cssinliner/vendor/autoload.php';
613
+
614
+			// now if this isn't a preview, let's setup the body so it has inline styles
615
+			if (! $preview || ($preview && defined('DOING_AJAX'))) {
616
+				$style = file_get_contents(
617
+					$this->get_variation(
618
+						$this->_tmp_pack,
619
+						$this->_incoming_message_type->name,
620
+						false,
621
+						'main',
622
+						$this->_variation
623
+					),
624
+					true
625
+				);
626
+				$CSS   = new TijsVerkoyen\CssToInlineStyles\CssToInlineStyles($body, $style);
627
+				// for some reason the library has a bracket and new line at the beginning.  This takes care of that.
628
+				$body  = ltrim($CSS->convert(true), ">\n");
629
+				// see https://events.codebasehq.com/projects/event-espresso/tickets/8609
630
+				$body  = ltrim($body, "<?");
631
+			}
632
+		}
633
+		return $body;
634
+	}
635
+
636
+
637
+	/**
638
+	 * This just returns any existing test settings that might be saved in the database
639
+	 *
640
+	 * @access public
641
+	 * @return array
642
+	 */
643
+	public function get_existing_test_settings()
644
+	{
645
+		$settings = parent::get_existing_test_settings();
646
+		// override subject if present because we always want it to be fresh.
647
+		if (is_array($settings) && ! empty($settings['subject'])) {
648
+			$settings['subject'] = sprintf(esc_html__('Test email sent from %s', 'event_espresso'), get_bloginfo('name'));
649
+		}
650
+		return $settings;
651
+	}
652 652
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
             ),
56 56
             '<code>wp_mail</code>'
57 57
         );
58
-        $this->label               = array(
58
+        $this->label = array(
59 59
             'singular' => esc_html__('email', 'event_espresso'),
60 60
             'plural'   => esc_html__('emails', 'event_espresso'),
61 61
         );
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
             $this->_body(),
438 438
             $this->_headers()
439 439
         );
440
-        if (! $success) {
440
+        if ( ! $success) {
441 441
             EE_Error::add_error(
442 442
                 sprintf(
443 443
                     esc_html__(
@@ -481,8 +481,8 @@  discard block
 block discarded – undo
481 481
         $this->_ensure_has_from_email_address();
482 482
         $from    = $this->_from;
483 483
         $headers = array(
484
-            'From:' . $from,
485
-            'Reply-To:' . $from,
484
+            'From:'.$from,
485
+            'Reply-To:'.$from,
486 486
             'Content-Type:text/html; charset=utf-8',
487 487
         );
488 488
 
@@ -491,8 +491,8 @@  discard block
 block discarded – undo
491 491
          * cover back compat where there may be users who have saved cc values in their db for the newsletter message
492 492
          * type which they are no longer able to change.
493 493
          */
494
-        if (! empty($this->_cc) && ! $this->_incoming_message_type instanceof EE_Newsletter_message_type) {
495
-            $headers[] = 'cc: ' . $this->_cc;
494
+        if ( ! empty($this->_cc) && ! $this->_incoming_message_type instanceof EE_Newsletter_message_type) {
495
+            $headers[] = 'cc: '.$this->_cc;
496 496
         }
497 497
 
498 498
         // but wait!  Header's for the from is NOT reliable because some plugins don't respect From: as set in the
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
             'from'      => $this->_from,
600 600
             'main_body' => wpautop($this->_content),
601 601
         );
602
-        $body                 = $this->_get_main_template($preview);
602
+        $body = $this->_get_main_template($preview);
603 603
 
604 604
         /**
605 605
          * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched.
@@ -609,10 +609,10 @@  discard block
 block discarded – undo
609 609
          */
610 610
         if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) {
611 611
             // require CssToInlineStyles library and its dependencies via composer autoloader
612
-            require_once EE_LIBRARIES . 'messages/cssinliner/vendor/autoload.php';
612
+            require_once EE_LIBRARIES.'messages/cssinliner/vendor/autoload.php';
613 613
 
614 614
             // now if this isn't a preview, let's setup the body so it has inline styles
615
-            if (! $preview || ($preview && defined('DOING_AJAX'))) {
615
+            if ( ! $preview || ($preview && defined('DOING_AJAX'))) {
616 616
                 $style = file_get_contents(
617 617
                     $this->get_variation(
618 618
                         $this->_tmp_pack,
Please login to merge, or discard this patch.