Completed
Branch BUG-11108-ticket-reserved-coun... (144d27)
by
unknown
14:21 queued 17s
created
core/libraries/messages/messenger/EE_Html_messenger.class.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if (!defined('EVENT_ESPRESSO_VERSION')) {
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3 3
     exit('NO direct script access allowed');
4 4
 }
5 5
 
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
                     ),
319 319
                     'ticket_line_item_no_pms' => array(
320 320
                         'input' => 'textarea',
321
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
321
+                        'label' => '[TICKET_LINE_ITEM_LIST] <br>'.__(
322 322
                                 'Ticket Line Item List with no Price Modifiers',
323 323
                                 'event_espresso'
324 324
                             ),
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
                     ),
333 333
                     'ticket_line_item_pms' => array(
334 334
                         'input' => 'textarea',
335
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
335
+                        'label' => '[TICKET_LINE_ITEM_LIST] <br>'.__(
336 336
                                 'Ticket Line Item List with Price Modifiers',
337 337
                                 'event_espresso'
338 338
                             ),
Please login to merge, or discard this patch.
Indentation   +548 added lines, -548 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (!defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 
@@ -16,552 +16,552 @@  discard block
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * The following are the properties that this messenger requires for displaying the html
21
-     */
22
-    /**
23
-     * This is the html body generated by the template via the message type.
24
-     *
25
-     * @var string
26
-     */
27
-    protected $_content;
28
-
29
-
30
-    /**
31
-     * This is for the page title that gets displayed.  (Why use "subject"?  Because the "title" tag in html is
32
-     * equivalent to the "subject" of the page.
33
-     *
34
-     * @var string
35
-     */
36
-    protected $_subject;
37
-
38
-
39
-    /**
40
-     * EE_Html_messenger constructor.
41
-     */
42
-    public function __construct()
43
-    {
44
-        //set properties
45
-        $this->name = 'html';
46
-        $this->description = __('This messenger outputs a message to a browser for display.', 'event_espresso');
47
-        $this->label = array(
48
-            'singular' => __('html', 'event_espresso'),
49
-            'plural' => __('html', 'event_espresso'),
50
-        );
51
-        $this->activate_on_install = true;
52
-        // add the "powered by EE" credit link to the HTML receipt and invoice
53
-        add_filter(
54
-            'FHEE__EE_Html_messenger___send_message__main_body',
55
-            array($this, 'add_powered_by_credit_link_to_receipt_and_invoice'),
56
-            10,
57
-            3
58
-        );
59
-        parent::__construct();
60
-    }
61
-
62
-
63
-    /**
64
-     * HTML Messenger desires execution immediately.
65
-     *
66
-     * @see    parent::send_now() for documentation.
67
-     * @since  4.9.0
68
-     * @return bool
69
-     */
70
-    public function send_now()
71
-    {
72
-        return true;
73
-    }
74
-
75
-
76
-    /**
77
-     * HTML Messenger allows an empty to field.
78
-     *
79
-     * @see    parent::allow_empty_to_field() for documentation
80
-     * @since  4.9.0
81
-     * @return bool
82
-     */
83
-    public function allow_empty_to_field()
84
-    {
85
-        return true;
86
-    }
87
-
88
-
89
-    /**
90
-     * @see abstract declaration in EE_messenger for details.
91
-     */
92
-    protected function _set_admin_pages()
93
-    {
94
-        $this->admin_registered_pages = array('events_edit' => true);
95
-    }
96
-
97
-
98
-    /**
99
-     * @see abstract declaration in EE_messenger for details.
100
-     */
101
-    protected function _set_valid_shortcodes()
102
-    {
103
-        $this->_valid_shortcodes = array();
104
-    }
105
-
106
-
107
-    /**
108
-     * @see abstract declaration in EE_messenger for details.
109
-     */
110
-    protected function _set_validator_config()
111
-    {
112
-        $this->_validator_config = array(
113
-            'subject' => array(
114
-                'shortcodes' => array('organization', 'primary_registration_details', 'email', 'transaction'),
115
-            ),
116
-            'content' => array(
117
-                'shortcodes' => array(
118
-                    'organization',
119
-                    'primary_registration_list',
120
-                    'primary_registration_details',
121
-                    'email',
122
-                    'transaction',
123
-                    'event_list',
124
-                    'payment_list',
125
-                    'venue',
126
-                    'line_item_list',
127
-                    'messenger',
128
-                    'ticket_list',
129
-                ),
130
-            ),
131
-            'event_list' => array(
132
-                'shortcodes' => array(
133
-                    'event',
134
-                    'ticket_list',
135
-                    'venue',
136
-                    'primary_registration_details',
137
-                    'primary_registration_list',
138
-                    'event_author',
139
-                ),
140
-                'required' => array('[EVENT_LIST]'),
141
-            ),
142
-            'ticket_list' => array(
143
-                'shortcodes' => array(
144
-                    'attendee_list',
145
-                    'ticket',
146
-                    'datetime_list',
147
-                    'primary_registration_details',
148
-                    'line_item_list',
149
-                    'venue',
150
-                ),
151
-                'required' => array('[TICKET_LIST]'),
152
-            ),
153
-            'ticket_line_item_no_pms' => array(
154
-                'shortcodes' => array('line_item', 'ticket'),
155
-                'required' => array('[TICKET_LINE_ITEM_LIST]'),
156
-            ),
157
-            'ticket_line_item_pms' => array(
158
-                'shortcodes' => array('line_item', 'ticket', 'line_item_list'),
159
-                'required' => array('[TICKET_LINE_ITEM_LIST]'),
160
-            ),
161
-            'price_modifier_line_item_list' => array(
162
-                'shortcodes' => array('line_item'),
163
-                'required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
164
-            ),
165
-            'datetime_list' => array(
166
-                'shortcodes' => array('datetime'),
167
-                'required' => array('[DATETIME_LIST]'),
168
-            ),
169
-            'attendee_list' => array(
170
-                'shortcodes' => array('attendee'),
171
-                'required' => array('[ATTENDEE_LIST]'),
172
-            ),
173
-            'tax_line_item_list' => array(
174
-                'shortcodes' => array('line_item'),
175
-                'required' => array('[TAX_LINE_ITEM_LIST]'),
176
-            ),
177
-            'additional_line_item_list' => array(
178
-                'shortcodes' => array('line_item'),
179
-                'required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
180
-            ),
181
-            'payment_list' => array(
182
-                'shortcodes' => array('payment'),
183
-                'required' => array('[PAYMENT_LIST_*]'),
184
-            ),
185
-        );
186
-    }
187
-
188
-
189
-    /**
190
-     * This is a method called from EE_messages when this messenger is a generating messenger and the sending messenger
191
-     * is a different messenger.  Child messengers can set hooks for the sending messenger to callback on if necessary
192
-     * (i.e. swap out css files or something else).
193
-     *
194
-     * @since 4.5.0
195
-     * @param string $sending_messenger_name the name of the sending messenger so we only set the hooks needed.
196
-     * @return void
197
-     */
198
-    public function do_secondary_messenger_hooks($sending_messenger_name)
199
-    {
200
-        if ($sending_messenger_name = 'pdf') {
201
-            add_filter('EE_messenger__get_variation__variation', array($this, 'add_html_css'), 10, 8);
202
-        }
203
-    }
204
-
205
-
206
-    /**
207
-     * @param                            $variation_path
208
-     * @param \EE_Messages_Template_Pack $template_pack
209
-     * @param                            $messenger_name
210
-     * @param                            $message_type_name
211
-     * @param                            $url
212
-     * @param                            $type
213
-     * @param                            $variation
214
-     * @param                            $skip_filters
215
-     * @return string
216
-     */
217
-    public function add_html_css(
218
-        $variation_path,
219
-        EE_Messages_Template_Pack $template_pack,
220
-        $messenger_name,
221
-        $message_type_name,
222
-        $url,
223
-        $type,
224
-        $variation,
225
-        $skip_filters
226
-    )
227
-    {
228
-        $variation = $template_pack->get_variation(
229
-            $this->name,
230
-            $message_type_name,
231
-            $type,
232
-            $variation,
233
-            $url,
234
-            '.css',
235
-            $skip_filters
236
-        );
237
-        return $variation;
238
-    }
239
-
240
-
241
-    /**
242
-     * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this
243
-     * messenger can add their own js.
244
-     *
245
-     * @return void.
246
-     */
247
-    public function enqueue_scripts_styles()
248
-    {
249
-        parent::enqueue_scripts_styles();
250
-        do_action('AHEE__EE_Html_messenger__enqueue_scripts_styles');
251
-    }
252
-
253
-
254
-    /**
255
-     * _set_template_fields
256
-     * This sets up the fields that a messenger requires for the message to go out.
257
-     *
258
-     * @access  protected
259
-     * @return void
260
-     */
261
-    protected function _set_template_fields()
262
-    {
263
-        // any extra template fields that are NOT used by the messenger
264
-        // but will get used by a messenger field for shortcode replacement
265
-        // get added to the 'extra' key in an associated array
266
-        // indexed by the messenger field they relate to.
267
-        // This is important for the Messages_admin to know what fields to display to the user.
268
-        // Also, notice that the "values" are equal to the field type
269
-        // that messages admin will use to know what kind of field to display.
270
-        // The values ALSO have one index labeled "shortcode".
271
-        // The values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE])
272
-        // is required in order for this extra field to be displayed.
273
-        //  If the required shortcode isn't part of the shortcodes array
274
-        // then the field is not needed and will not be displayed/parsed.
275
-        $this->_template_fields = array(
276
-            'subject' => array(
277
-                'input' => 'text',
278
-                'label' => __('Page Title', 'event_espresso'),
279
-                'type' => 'string',
280
-                'required' => true,
281
-                'validation' => true,
282
-                'css_class' => 'large-text',
283
-                'format' => '%s',
284
-            ),
285
-            'content' => '',
286
-            //left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
287
-            'extra' => array(
288
-                'content' => array(
289
-                    'main' => array(
290
-                        'input' => 'wp_editor',
291
-                        'label' => __('Main Content', 'event_espresso'),
292
-                        'type' => 'string',
293
-                        'required' => true,
294
-                        'validation' => true,
295
-                        'format' => '%s',
296
-                        'rows' => '15',
297
-                    ),
298
-                    'event_list' => array(
299
-                        'input' => 'wp_editor',
300
-                        'label' => '[EVENT_LIST]',
301
-                        'type' => 'string',
302
-                        'required' => true,
303
-                        'validation' => true,
304
-                        'format' => '%s',
305
-                        'rows' => '15',
306
-                        'shortcodes_required' => array('[EVENT_LIST]'),
307
-                    ),
308
-                    'ticket_list' => array(
309
-                        'input' => 'textarea',
310
-                        'label' => '[TICKET_LIST]',
311
-                        'type' => 'string',
312
-                        'required' => true,
313
-                        'validation' => true,
314
-                        'format' => '%s',
315
-                        'css_class' => 'large-text',
316
-                        'rows' => '10',
317
-                        'shortcodes_required' => array('[TICKET_LIST]'),
318
-                    ),
319
-                    'ticket_line_item_no_pms' => array(
320
-                        'input' => 'textarea',
321
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
322
-                                'Ticket Line Item List with no Price Modifiers',
323
-                                'event_espresso'
324
-                            ),
325
-                        'type' => 'string',
326
-                        'required' => false,
327
-                        'validation' => true,
328
-                        'format' => '%s',
329
-                        'css_class' => 'large-text',
330
-                        'rows' => '5',
331
-                        'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
332
-                    ),
333
-                    'ticket_line_item_pms' => array(
334
-                        'input' => 'textarea',
335
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
336
-                                'Ticket Line Item List with Price Modifiers',
337
-                                'event_espresso'
338
-                            ),
339
-                        'type' => 'string',
340
-                        'required' => false,
341
-                        'validation' => true,
342
-                        'format' => '%s',
343
-                        'css_class' => 'large-text',
344
-                        'rows' => '5',
345
-                        'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
346
-                    ),
347
-                    'price_modifier_line_item_list' => array(
348
-                        'input' => 'textarea',
349
-                        'label' => '[PRICE_MODIFIER_LINE_ITEM_LIST]',
350
-                        'type' => 'string',
351
-                        'required' => false,
352
-                        'validation' => true,
353
-                        'format' => '%s',
354
-                        'css_class' => 'large-text',
355
-                        'rows' => '5',
356
-                        'shortcodes_required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
357
-                    ),
358
-                    'datetime_list' => array(
359
-                        'input' => 'textarea',
360
-                        'label' => '[DATETIME_LIST]',
361
-                        'type' => 'string',
362
-                        'required' => true,
363
-                        'validation' => true,
364
-                        'format' => '%s',
365
-                        'css_class' => 'large-text',
366
-                        'rows' => '5',
367
-                        'shortcodes_required' => array('[DATETIME_LIST]'),
368
-                    ),
369
-                    'attendee_list' => array(
370
-                        'input' => 'textarea',
371
-                        'label' => '[ATTENDEE_LIST]',
372
-                        'type' => 'string',
373
-                        'required' => true,
374
-                        'validation' => true,
375
-                        'format' => '%s',
376
-                        'css_class' => 'large-text',
377
-                        'rows' => '5',
378
-                        'shortcodes_required' => array('[ATTENDEE_LIST]'),
379
-                    ),
380
-                    'tax_line_item_list' => array(
381
-                        'input' => 'textarea',
382
-                        'label' => '[TAX_LINE_ITEM_LIST]',
383
-                        'type' => 'string',
384
-                        'required' => false,
385
-                        'validation' => true,
386
-                        'format' => '%s',
387
-                        'css_class' => 'large-text',
388
-                        'rows' => '5',
389
-                        'shortcodes_required' => array('[TAX_LINE_ITEM_LIST]'),
390
-                    ),
391
-                    'additional_line_item_list' => array(
392
-                        'input' => 'textarea',
393
-                        'label' => '[ADDITIONAL_LINE_ITEM_LIST]',
394
-                        'type' => 'string',
395
-                        'required' => false,
396
-                        'validation' => true,
397
-                        'format' => '%s',
398
-                        'css_class' => 'large-text',
399
-                        'rows' => '5',
400
-                        'shortcodes_required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
401
-                    ),
402
-                    'payment_list' => array(
403
-                        'input' => 'textarea',
404
-                        'label' => '[PAYMENT_LIST]',
405
-                        'type' => 'string',
406
-                        'required' => true,
407
-                        'validation' => true,
408
-                        'format' => '%s',
409
-                        'css_class' => 'large-text',
410
-                        'rows' => '5',
411
-                        'shortcodes_required' => array('[PAYMENT_LIST_*]'),
412
-                    ),
413
-                ),
414
-            ),
415
-        );
416
-    }
417
-
418
-
419
-    /**
420
-     * @see   definition of this method in parent
421
-     * @since 4.5.0
422
-     */
423
-    protected function _set_default_message_types()
424
-    {
425
-        $this->_default_message_types = array('receipt', 'invoice');
426
-    }
427
-
428
-
429
-    /**
430
-     * @see   definition of this method in parent
431
-     * @since 4.5.0
432
-     */
433
-    protected function _set_valid_message_types()
434
-    {
435
-        $this->_valid_message_types = array('receipt', 'invoice');
436
-    }
437
-
438
-
439
-    /**
440
-     * Displays the message in the browser.
441
-     *
442
-     * @since 4.5.0
443
-     * @return string.
444
-     */
445
-    protected function _send_message()
446
-    {
447
-        $this->_template_args = array(
448
-            'page_title' => $this->_subject,
449
-            'base_css' => $this->get_variation(
450
-                $this->_tmp_pack,
451
-                $this->_incoming_message_type->name,
452
-                true,
453
-                'base',
454
-                $this->_variation
455
-            ),
456
-            'print_css' => $this->get_variation(
457
-                $this->_tmp_pack,
458
-                $this->_incoming_message_type->name,
459
-                true,
460
-                'print',
461
-                $this->_variation
462
-            ),
463
-            'main_css' => $this->get_variation(
464
-                $this->_tmp_pack,
465
-                $this->_incoming_message_type->name,
466
-                true,
467
-                'main',
468
-                $this->_variation
469
-            ),
470
-            'main_body' => wpautop(
471
-                apply_filters(
472
-                    'FHEE__EE_Html_messenger___send_message__main_body',
473
-                    $this->_content,
474
-                    $this->_content,
475
-                    $this->_incoming_message_type
476
-                )
477
-            )
478
-        );
479
-        $this->_deregister_wp_hooks();
480
-        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
481
-        echo $this->_get_main_template();
482
-        exit();
483
-    }
484
-
485
-
486
-    /**
487
-     * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't
488
-     * interfere with our templates.  If users want to add any custom styles or scripts they must use the
489
-     * AHEE__EE_Html_messenger__enqueue_scripts_styles hook.
490
-     *
491
-     * @since 4.5.0
492
-     * @return void
493
-     */
494
-    protected function _deregister_wp_hooks()
495
-    {
496
-        remove_all_actions('wp_head');
497
-        remove_all_actions('wp_footer');
498
-        remove_all_actions('wp_print_footer_scripts');
499
-        remove_all_actions('wp_enqueue_scripts');
500
-        global $wp_scripts, $wp_styles;
501
-        $wp_scripts = $wp_styles = array();
502
-        //just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
503
-        add_action('wp_footer', 'wp_print_footer_scripts');
504
-        add_action('wp_print_footer_scripts', '_wp_footer_scripts');
505
-        add_action('wp_head', 'wp_enqueue_scripts');
506
-    }
507
-
508
-
509
-    /**
510
-     * Overwrite parent _get_main_template for display_html purposes.
511
-     *
512
-     * @since  4.5.0
513
-     * @param bool $preview
514
-     * @return string
515
-     */
516
-    protected function _get_main_template($preview = false)
517
-    {
518
-        $wrapper_template = $this->_tmp_pack->get_wrapper($this->name, 'main');
519
-        //include message type as a template arg
520
-        $this->_template_args['message_type'] = $this->_incoming_message_type;
521
-        return EEH_Template::display_template($wrapper_template, $this->_template_args, true);
522
-    }
523
-
524
-
525
-    /**
526
-     * @return string
527
-     */
528
-    protected function _preview()
529
-    {
530
-        return $this->_send_message();
531
-    }
532
-
533
-
534
-    protected function _set_admin_settings_fields()
535
-    {
536
-    }
537
-
538
-
539
-    /**
540
-     * add the "powered by EE" credit link to the HTML receipt and invoice
541
-     *
542
-     * @param string $content
543
-     * @param string $content_again
544
-     * @param \EE_message_type $incoming_message_type
545
-     * @return string
546
-     */
547
-    public function add_powered_by_credit_link_to_receipt_and_invoice(
548
-        $content = '',
549
-        $content_again = '',
550
-        EE_message_type $incoming_message_type
551
-    )
552
-    {
553
-        if (
554
-            ($incoming_message_type->name === 'invoice' || $incoming_message_type->name === 'receipt')
555
-            && apply_filters('FHEE_EE_Html_messenger__add_powered_by_credit_link_to_receipt_and_invoice', true)
556
-        ) {
557
-            $content .= \EEH_Template::powered_by_event_espresso(
558
-                    'aln-cntr',
559
-                    '',
560
-                    array('utm_content' => 'messages_system')
561
-                )
562
-                . EEH_HTML::div(EEH_HTML::p('&nbsp;'));
563
-        }
564
-        return $content;
565
-    }
19
+	/**
20
+	 * The following are the properties that this messenger requires for displaying the html
21
+	 */
22
+	/**
23
+	 * This is the html body generated by the template via the message type.
24
+	 *
25
+	 * @var string
26
+	 */
27
+	protected $_content;
28
+
29
+
30
+	/**
31
+	 * This is for the page title that gets displayed.  (Why use "subject"?  Because the "title" tag in html is
32
+	 * equivalent to the "subject" of the page.
33
+	 *
34
+	 * @var string
35
+	 */
36
+	protected $_subject;
37
+
38
+
39
+	/**
40
+	 * EE_Html_messenger constructor.
41
+	 */
42
+	public function __construct()
43
+	{
44
+		//set properties
45
+		$this->name = 'html';
46
+		$this->description = __('This messenger outputs a message to a browser for display.', 'event_espresso');
47
+		$this->label = array(
48
+			'singular' => __('html', 'event_espresso'),
49
+			'plural' => __('html', 'event_espresso'),
50
+		);
51
+		$this->activate_on_install = true;
52
+		// add the "powered by EE" credit link to the HTML receipt and invoice
53
+		add_filter(
54
+			'FHEE__EE_Html_messenger___send_message__main_body',
55
+			array($this, 'add_powered_by_credit_link_to_receipt_and_invoice'),
56
+			10,
57
+			3
58
+		);
59
+		parent::__construct();
60
+	}
61
+
62
+
63
+	/**
64
+	 * HTML Messenger desires execution immediately.
65
+	 *
66
+	 * @see    parent::send_now() for documentation.
67
+	 * @since  4.9.0
68
+	 * @return bool
69
+	 */
70
+	public function send_now()
71
+	{
72
+		return true;
73
+	}
74
+
75
+
76
+	/**
77
+	 * HTML Messenger allows an empty to field.
78
+	 *
79
+	 * @see    parent::allow_empty_to_field() for documentation
80
+	 * @since  4.9.0
81
+	 * @return bool
82
+	 */
83
+	public function allow_empty_to_field()
84
+	{
85
+		return true;
86
+	}
87
+
88
+
89
+	/**
90
+	 * @see abstract declaration in EE_messenger for details.
91
+	 */
92
+	protected function _set_admin_pages()
93
+	{
94
+		$this->admin_registered_pages = array('events_edit' => true);
95
+	}
96
+
97
+
98
+	/**
99
+	 * @see abstract declaration in EE_messenger for details.
100
+	 */
101
+	protected function _set_valid_shortcodes()
102
+	{
103
+		$this->_valid_shortcodes = array();
104
+	}
105
+
106
+
107
+	/**
108
+	 * @see abstract declaration in EE_messenger for details.
109
+	 */
110
+	protected function _set_validator_config()
111
+	{
112
+		$this->_validator_config = array(
113
+			'subject' => array(
114
+				'shortcodes' => array('organization', 'primary_registration_details', 'email', 'transaction'),
115
+			),
116
+			'content' => array(
117
+				'shortcodes' => array(
118
+					'organization',
119
+					'primary_registration_list',
120
+					'primary_registration_details',
121
+					'email',
122
+					'transaction',
123
+					'event_list',
124
+					'payment_list',
125
+					'venue',
126
+					'line_item_list',
127
+					'messenger',
128
+					'ticket_list',
129
+				),
130
+			),
131
+			'event_list' => array(
132
+				'shortcodes' => array(
133
+					'event',
134
+					'ticket_list',
135
+					'venue',
136
+					'primary_registration_details',
137
+					'primary_registration_list',
138
+					'event_author',
139
+				),
140
+				'required' => array('[EVENT_LIST]'),
141
+			),
142
+			'ticket_list' => array(
143
+				'shortcodes' => array(
144
+					'attendee_list',
145
+					'ticket',
146
+					'datetime_list',
147
+					'primary_registration_details',
148
+					'line_item_list',
149
+					'venue',
150
+				),
151
+				'required' => array('[TICKET_LIST]'),
152
+			),
153
+			'ticket_line_item_no_pms' => array(
154
+				'shortcodes' => array('line_item', 'ticket'),
155
+				'required' => array('[TICKET_LINE_ITEM_LIST]'),
156
+			),
157
+			'ticket_line_item_pms' => array(
158
+				'shortcodes' => array('line_item', 'ticket', 'line_item_list'),
159
+				'required' => array('[TICKET_LINE_ITEM_LIST]'),
160
+			),
161
+			'price_modifier_line_item_list' => array(
162
+				'shortcodes' => array('line_item'),
163
+				'required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
164
+			),
165
+			'datetime_list' => array(
166
+				'shortcodes' => array('datetime'),
167
+				'required' => array('[DATETIME_LIST]'),
168
+			),
169
+			'attendee_list' => array(
170
+				'shortcodes' => array('attendee'),
171
+				'required' => array('[ATTENDEE_LIST]'),
172
+			),
173
+			'tax_line_item_list' => array(
174
+				'shortcodes' => array('line_item'),
175
+				'required' => array('[TAX_LINE_ITEM_LIST]'),
176
+			),
177
+			'additional_line_item_list' => array(
178
+				'shortcodes' => array('line_item'),
179
+				'required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
180
+			),
181
+			'payment_list' => array(
182
+				'shortcodes' => array('payment'),
183
+				'required' => array('[PAYMENT_LIST_*]'),
184
+			),
185
+		);
186
+	}
187
+
188
+
189
+	/**
190
+	 * This is a method called from EE_messages when this messenger is a generating messenger and the sending messenger
191
+	 * is a different messenger.  Child messengers can set hooks for the sending messenger to callback on if necessary
192
+	 * (i.e. swap out css files or something else).
193
+	 *
194
+	 * @since 4.5.0
195
+	 * @param string $sending_messenger_name the name of the sending messenger so we only set the hooks needed.
196
+	 * @return void
197
+	 */
198
+	public function do_secondary_messenger_hooks($sending_messenger_name)
199
+	{
200
+		if ($sending_messenger_name = 'pdf') {
201
+			add_filter('EE_messenger__get_variation__variation', array($this, 'add_html_css'), 10, 8);
202
+		}
203
+	}
204
+
205
+
206
+	/**
207
+	 * @param                            $variation_path
208
+	 * @param \EE_Messages_Template_Pack $template_pack
209
+	 * @param                            $messenger_name
210
+	 * @param                            $message_type_name
211
+	 * @param                            $url
212
+	 * @param                            $type
213
+	 * @param                            $variation
214
+	 * @param                            $skip_filters
215
+	 * @return string
216
+	 */
217
+	public function add_html_css(
218
+		$variation_path,
219
+		EE_Messages_Template_Pack $template_pack,
220
+		$messenger_name,
221
+		$message_type_name,
222
+		$url,
223
+		$type,
224
+		$variation,
225
+		$skip_filters
226
+	)
227
+	{
228
+		$variation = $template_pack->get_variation(
229
+			$this->name,
230
+			$message_type_name,
231
+			$type,
232
+			$variation,
233
+			$url,
234
+			'.css',
235
+			$skip_filters
236
+		);
237
+		return $variation;
238
+	}
239
+
240
+
241
+	/**
242
+	 * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this
243
+	 * messenger can add their own js.
244
+	 *
245
+	 * @return void.
246
+	 */
247
+	public function enqueue_scripts_styles()
248
+	{
249
+		parent::enqueue_scripts_styles();
250
+		do_action('AHEE__EE_Html_messenger__enqueue_scripts_styles');
251
+	}
252
+
253
+
254
+	/**
255
+	 * _set_template_fields
256
+	 * This sets up the fields that a messenger requires for the message to go out.
257
+	 *
258
+	 * @access  protected
259
+	 * @return void
260
+	 */
261
+	protected function _set_template_fields()
262
+	{
263
+		// any extra template fields that are NOT used by the messenger
264
+		// but will get used by a messenger field for shortcode replacement
265
+		// get added to the 'extra' key in an associated array
266
+		// indexed by the messenger field they relate to.
267
+		// This is important for the Messages_admin to know what fields to display to the user.
268
+		// Also, notice that the "values" are equal to the field type
269
+		// that messages admin will use to know what kind of field to display.
270
+		// The values ALSO have one index labeled "shortcode".
271
+		// The values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE])
272
+		// is required in order for this extra field to be displayed.
273
+		//  If the required shortcode isn't part of the shortcodes array
274
+		// then the field is not needed and will not be displayed/parsed.
275
+		$this->_template_fields = array(
276
+			'subject' => array(
277
+				'input' => 'text',
278
+				'label' => __('Page Title', 'event_espresso'),
279
+				'type' => 'string',
280
+				'required' => true,
281
+				'validation' => true,
282
+				'css_class' => 'large-text',
283
+				'format' => '%s',
284
+			),
285
+			'content' => '',
286
+			//left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
287
+			'extra' => array(
288
+				'content' => array(
289
+					'main' => array(
290
+						'input' => 'wp_editor',
291
+						'label' => __('Main Content', 'event_espresso'),
292
+						'type' => 'string',
293
+						'required' => true,
294
+						'validation' => true,
295
+						'format' => '%s',
296
+						'rows' => '15',
297
+					),
298
+					'event_list' => array(
299
+						'input' => 'wp_editor',
300
+						'label' => '[EVENT_LIST]',
301
+						'type' => 'string',
302
+						'required' => true,
303
+						'validation' => true,
304
+						'format' => '%s',
305
+						'rows' => '15',
306
+						'shortcodes_required' => array('[EVENT_LIST]'),
307
+					),
308
+					'ticket_list' => array(
309
+						'input' => 'textarea',
310
+						'label' => '[TICKET_LIST]',
311
+						'type' => 'string',
312
+						'required' => true,
313
+						'validation' => true,
314
+						'format' => '%s',
315
+						'css_class' => 'large-text',
316
+						'rows' => '10',
317
+						'shortcodes_required' => array('[TICKET_LIST]'),
318
+					),
319
+					'ticket_line_item_no_pms' => array(
320
+						'input' => 'textarea',
321
+						'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
322
+								'Ticket Line Item List with no Price Modifiers',
323
+								'event_espresso'
324
+							),
325
+						'type' => 'string',
326
+						'required' => false,
327
+						'validation' => true,
328
+						'format' => '%s',
329
+						'css_class' => 'large-text',
330
+						'rows' => '5',
331
+						'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
332
+					),
333
+					'ticket_line_item_pms' => array(
334
+						'input' => 'textarea',
335
+						'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
336
+								'Ticket Line Item List with Price Modifiers',
337
+								'event_espresso'
338
+							),
339
+						'type' => 'string',
340
+						'required' => false,
341
+						'validation' => true,
342
+						'format' => '%s',
343
+						'css_class' => 'large-text',
344
+						'rows' => '5',
345
+						'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
346
+					),
347
+					'price_modifier_line_item_list' => array(
348
+						'input' => 'textarea',
349
+						'label' => '[PRICE_MODIFIER_LINE_ITEM_LIST]',
350
+						'type' => 'string',
351
+						'required' => false,
352
+						'validation' => true,
353
+						'format' => '%s',
354
+						'css_class' => 'large-text',
355
+						'rows' => '5',
356
+						'shortcodes_required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
357
+					),
358
+					'datetime_list' => array(
359
+						'input' => 'textarea',
360
+						'label' => '[DATETIME_LIST]',
361
+						'type' => 'string',
362
+						'required' => true,
363
+						'validation' => true,
364
+						'format' => '%s',
365
+						'css_class' => 'large-text',
366
+						'rows' => '5',
367
+						'shortcodes_required' => array('[DATETIME_LIST]'),
368
+					),
369
+					'attendee_list' => array(
370
+						'input' => 'textarea',
371
+						'label' => '[ATTENDEE_LIST]',
372
+						'type' => 'string',
373
+						'required' => true,
374
+						'validation' => true,
375
+						'format' => '%s',
376
+						'css_class' => 'large-text',
377
+						'rows' => '5',
378
+						'shortcodes_required' => array('[ATTENDEE_LIST]'),
379
+					),
380
+					'tax_line_item_list' => array(
381
+						'input' => 'textarea',
382
+						'label' => '[TAX_LINE_ITEM_LIST]',
383
+						'type' => 'string',
384
+						'required' => false,
385
+						'validation' => true,
386
+						'format' => '%s',
387
+						'css_class' => 'large-text',
388
+						'rows' => '5',
389
+						'shortcodes_required' => array('[TAX_LINE_ITEM_LIST]'),
390
+					),
391
+					'additional_line_item_list' => array(
392
+						'input' => 'textarea',
393
+						'label' => '[ADDITIONAL_LINE_ITEM_LIST]',
394
+						'type' => 'string',
395
+						'required' => false,
396
+						'validation' => true,
397
+						'format' => '%s',
398
+						'css_class' => 'large-text',
399
+						'rows' => '5',
400
+						'shortcodes_required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
401
+					),
402
+					'payment_list' => array(
403
+						'input' => 'textarea',
404
+						'label' => '[PAYMENT_LIST]',
405
+						'type' => 'string',
406
+						'required' => true,
407
+						'validation' => true,
408
+						'format' => '%s',
409
+						'css_class' => 'large-text',
410
+						'rows' => '5',
411
+						'shortcodes_required' => array('[PAYMENT_LIST_*]'),
412
+					),
413
+				),
414
+			),
415
+		);
416
+	}
417
+
418
+
419
+	/**
420
+	 * @see   definition of this method in parent
421
+	 * @since 4.5.0
422
+	 */
423
+	protected function _set_default_message_types()
424
+	{
425
+		$this->_default_message_types = array('receipt', 'invoice');
426
+	}
427
+
428
+
429
+	/**
430
+	 * @see   definition of this method in parent
431
+	 * @since 4.5.0
432
+	 */
433
+	protected function _set_valid_message_types()
434
+	{
435
+		$this->_valid_message_types = array('receipt', 'invoice');
436
+	}
437
+
438
+
439
+	/**
440
+	 * Displays the message in the browser.
441
+	 *
442
+	 * @since 4.5.0
443
+	 * @return string.
444
+	 */
445
+	protected function _send_message()
446
+	{
447
+		$this->_template_args = array(
448
+			'page_title' => $this->_subject,
449
+			'base_css' => $this->get_variation(
450
+				$this->_tmp_pack,
451
+				$this->_incoming_message_type->name,
452
+				true,
453
+				'base',
454
+				$this->_variation
455
+			),
456
+			'print_css' => $this->get_variation(
457
+				$this->_tmp_pack,
458
+				$this->_incoming_message_type->name,
459
+				true,
460
+				'print',
461
+				$this->_variation
462
+			),
463
+			'main_css' => $this->get_variation(
464
+				$this->_tmp_pack,
465
+				$this->_incoming_message_type->name,
466
+				true,
467
+				'main',
468
+				$this->_variation
469
+			),
470
+			'main_body' => wpautop(
471
+				apply_filters(
472
+					'FHEE__EE_Html_messenger___send_message__main_body',
473
+					$this->_content,
474
+					$this->_content,
475
+					$this->_incoming_message_type
476
+				)
477
+			)
478
+		);
479
+		$this->_deregister_wp_hooks();
480
+		add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
481
+		echo $this->_get_main_template();
482
+		exit();
483
+	}
484
+
485
+
486
+	/**
487
+	 * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't
488
+	 * interfere with our templates.  If users want to add any custom styles or scripts they must use the
489
+	 * AHEE__EE_Html_messenger__enqueue_scripts_styles hook.
490
+	 *
491
+	 * @since 4.5.0
492
+	 * @return void
493
+	 */
494
+	protected function _deregister_wp_hooks()
495
+	{
496
+		remove_all_actions('wp_head');
497
+		remove_all_actions('wp_footer');
498
+		remove_all_actions('wp_print_footer_scripts');
499
+		remove_all_actions('wp_enqueue_scripts');
500
+		global $wp_scripts, $wp_styles;
501
+		$wp_scripts = $wp_styles = array();
502
+		//just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
503
+		add_action('wp_footer', 'wp_print_footer_scripts');
504
+		add_action('wp_print_footer_scripts', '_wp_footer_scripts');
505
+		add_action('wp_head', 'wp_enqueue_scripts');
506
+	}
507
+
508
+
509
+	/**
510
+	 * Overwrite parent _get_main_template for display_html purposes.
511
+	 *
512
+	 * @since  4.5.0
513
+	 * @param bool $preview
514
+	 * @return string
515
+	 */
516
+	protected function _get_main_template($preview = false)
517
+	{
518
+		$wrapper_template = $this->_tmp_pack->get_wrapper($this->name, 'main');
519
+		//include message type as a template arg
520
+		$this->_template_args['message_type'] = $this->_incoming_message_type;
521
+		return EEH_Template::display_template($wrapper_template, $this->_template_args, true);
522
+	}
523
+
524
+
525
+	/**
526
+	 * @return string
527
+	 */
528
+	protected function _preview()
529
+	{
530
+		return $this->_send_message();
531
+	}
532
+
533
+
534
+	protected function _set_admin_settings_fields()
535
+	{
536
+	}
537
+
538
+
539
+	/**
540
+	 * add the "powered by EE" credit link to the HTML receipt and invoice
541
+	 *
542
+	 * @param string $content
543
+	 * @param string $content_again
544
+	 * @param \EE_message_type $incoming_message_type
545
+	 * @return string
546
+	 */
547
+	public function add_powered_by_credit_link_to_receipt_and_invoice(
548
+		$content = '',
549
+		$content_again = '',
550
+		EE_message_type $incoming_message_type
551
+	)
552
+	{
553
+		if (
554
+			($incoming_message_type->name === 'invoice' || $incoming_message_type->name === 'receipt')
555
+			&& apply_filters('FHEE_EE_Html_messenger__add_powered_by_credit_link_to_receipt_and_invoice', true)
556
+		) {
557
+			$content .= \EEH_Template::powered_by_event_espresso(
558
+					'aln-cntr',
559
+					'',
560
+					array('utm_content' => 'messages_system')
561
+				)
562
+				. EEH_HTML::div(EEH_HTML::p('&nbsp;'));
563
+		}
564
+		return $content;
565
+	}
566 566
 
567 567
 }
Please login to merge, or discard this patch.
core/domain/services/registration/CopyRegistrationService.php 2 patches
Indentation   +150 added lines, -150 removed lines patch added patch discarded remove patch
@@ -14,7 +14,7 @@  discard block
 block discarded – undo
14 14
 use RuntimeException;
15 15
 
16 16
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
17
-    exit('No direct script access allowed');
17
+	exit('No direct script access allowed');
18 18
 }
19 19
 
20 20
 
@@ -32,155 +32,155 @@  discard block
 block discarded – undo
32 32
 {
33 33
 
34 34
 
35
-    /**
36
-     * @param EE_Registration $target_registration
37
-     * @param EE_Registration $registration_to_copy
38
-     * @return bool
39
-     * @throws UnexpectedEntityException
40
-     * @throws EntityNotFoundException
41
-     * @throws RuntimeException
42
-     * @throws EE_Error
43
-     */
44
-    public function copyRegistrationDetails(
45
-        EE_Registration $target_registration,
46
-        EE_Registration $registration_to_copy
47
-    ) {
48
-        // copy attendee
49
-        $target_registration->set_attendee_id($registration_to_copy->attendee_ID());
50
-        $target_registration->updateStatusBasedOnTotalPaid(false);
51
-        $target_registration->save();
52
-        // get answers to previous reg questions
53
-        $answers = $this->reindexAnswersByQuestionId($registration_to_copy->answers());
54
-        // get questions to new event reg form
55
-        $new_event       = $target_registration->event();
56
-        $question_groups = $new_event->question_groups(
57
-            array(
58
-                array(
59
-                    'Event.EVT_ID'                     => $new_event->ID(),
60
-                    'Event_Question_Group.EQG_primary' => $registration_to_copy->is_primary_registrant(),
61
-                ),
62
-                'order_by' => array('QSG_order' => 'ASC'),
63
-            )
64
-        );
65
-        foreach ($question_groups as $question_group) {
66
-            if ($question_group instanceof \EE_Question_Group) {
67
-                foreach ($question_group->questions() as $question) {
68
-                    if ($question instanceof EE_Question) {
69
-                        $this->generateNewAnswer(
70
-                            $question,
71
-                            $target_registration,
72
-                            $answers
73
-                        );
74
-                    }
75
-                }
76
-            }
77
-        }
78
-        return true;
79
-    }
80
-
81
-
82
-
83
-    /**
84
-     * @param EE_Answer[] $answers
85
-     * @return array
86
-     * @throws EE_Error
87
-     */
88
-    protected function reindexAnswersByQuestionId(array $answers)
89
-    {
90
-        $reindexed_answers = array();
91
-        foreach ($answers as $answer) {
92
-            if ($answer instanceof EE_Answer) {
93
-                $reindexed_answers[ $answer->question_ID() ] = $answer->value();
94
-            }
95
-        }
96
-        return $reindexed_answers;
97
-    }
98
-
99
-
100
-
101
-    /**
102
-     * @param EE_Question      $question
103
-     * @param EE_Registration  $registration
104
-     * @param                  $previous_answers
105
-     * @return EE_Answer
106
-     * @throws UnexpectedEntityException
107
-     * @throws EE_Error
108
-     */
109
-    protected function generateNewAnswer(
110
-        EE_Question $question,
111
-        EE_Registration $registration,
112
-        $previous_answers
113
-    ) {
114
-        $old_answer_value = isset($previous_answers[ $question->ID() ])
115
-            ? $previous_answers[ $question->ID() ]
116
-            : '';
117
-        $new_answer       = EE_Answer::new_instance(
118
-            array(
119
-                'QST_ID'    => $question->ID(),
120
-                'REG_ID'    => $registration->ID(),
121
-                'ANS_value' => $old_answer_value,
122
-            )
123
-        );
124
-        if ( ! $new_answer instanceof EE_Answer) {
125
-            throw new UnexpectedEntityException($new_answer, 'EE_Answer');
126
-        }
127
-        $new_answer->save();
128
-        return $new_answer;
129
-    }
130
-
131
-
132
-
133
-    /**
134
-     * @param EE_Registration $target_registration
135
-     * @param EE_Registration $registration_to_copy
136
-     * @return bool
137
-     * @throws RuntimeException
138
-     * @throws UnexpectedEntityException
139
-     * @throws EE_Error
140
-     */
141
-    public function copyPaymentDetails(
142
-        EE_Registration $target_registration,
143
-        EE_Registration $registration_to_copy
144
-    ) {
145
-        $save = false;
146
-        $previous_registration_payments = $registration_to_copy->registration_payments();
147
-        $new_registration_payment_total = 0;
148
-        $registration_to_copy_total = $registration_to_copy->paid();
149
-        foreach ($previous_registration_payments as $previous_registration_payment) {
150
-            if (
151
-                $previous_registration_payment instanceof EE_Registration_Payment
152
-                && $previous_registration_payment->payment() instanceof EE_Payment
153
-                && $previous_registration_payment->payment()->is_approved()
154
-            ) {
155
-                $payment_amount = $previous_registration_payment->amount();
156
-                $new_registration_payment = EE_Registration_Payment::new_instance(
157
-                    array(
158
-                        'REG_ID'     => $target_registration->ID(),
159
-                        'PAY_ID'     => $previous_registration_payment->payment()->ID(),
160
-                        'RPY_amount' => $payment_amount,
161
-                    )
162
-                );
163
-                if ( ! $new_registration_payment instanceof EE_Registration_Payment) {
164
-                    throw new UnexpectedEntityException($new_registration_payment, 'EE_Registration_Payment');
165
-                }
166
-                $new_registration_payment->save();
167
-                // if new reg payment is good, then set old reg payment amount to zero
168
-                $previous_registration_payment->set_amount(0);
169
-                $previous_registration_payment->save();
170
-                // now  increment/decrement payment amounts
171
-                $new_registration_payment_total += $payment_amount;
172
-                $registration_to_copy_total -= $payment_amount;
173
-                $save = true;
174
-            }
175
-        }
176
-        if($save){
177
-            $target_registration->set_paid($new_registration_payment_total);
178
-            $target_registration->save();
179
-            $registration_to_copy->set_paid($registration_to_copy_total);
180
-            $registration_to_copy->save();
181
-        }
182
-        return true;
183
-    }
35
+	/**
36
+	 * @param EE_Registration $target_registration
37
+	 * @param EE_Registration $registration_to_copy
38
+	 * @return bool
39
+	 * @throws UnexpectedEntityException
40
+	 * @throws EntityNotFoundException
41
+	 * @throws RuntimeException
42
+	 * @throws EE_Error
43
+	 */
44
+	public function copyRegistrationDetails(
45
+		EE_Registration $target_registration,
46
+		EE_Registration $registration_to_copy
47
+	) {
48
+		// copy attendee
49
+		$target_registration->set_attendee_id($registration_to_copy->attendee_ID());
50
+		$target_registration->updateStatusBasedOnTotalPaid(false);
51
+		$target_registration->save();
52
+		// get answers to previous reg questions
53
+		$answers = $this->reindexAnswersByQuestionId($registration_to_copy->answers());
54
+		// get questions to new event reg form
55
+		$new_event       = $target_registration->event();
56
+		$question_groups = $new_event->question_groups(
57
+			array(
58
+				array(
59
+					'Event.EVT_ID'                     => $new_event->ID(),
60
+					'Event_Question_Group.EQG_primary' => $registration_to_copy->is_primary_registrant(),
61
+				),
62
+				'order_by' => array('QSG_order' => 'ASC'),
63
+			)
64
+		);
65
+		foreach ($question_groups as $question_group) {
66
+			if ($question_group instanceof \EE_Question_Group) {
67
+				foreach ($question_group->questions() as $question) {
68
+					if ($question instanceof EE_Question) {
69
+						$this->generateNewAnswer(
70
+							$question,
71
+							$target_registration,
72
+							$answers
73
+						);
74
+					}
75
+				}
76
+			}
77
+		}
78
+		return true;
79
+	}
80
+
81
+
82
+
83
+	/**
84
+	 * @param EE_Answer[] $answers
85
+	 * @return array
86
+	 * @throws EE_Error
87
+	 */
88
+	protected function reindexAnswersByQuestionId(array $answers)
89
+	{
90
+		$reindexed_answers = array();
91
+		foreach ($answers as $answer) {
92
+			if ($answer instanceof EE_Answer) {
93
+				$reindexed_answers[ $answer->question_ID() ] = $answer->value();
94
+			}
95
+		}
96
+		return $reindexed_answers;
97
+	}
98
+
99
+
100
+
101
+	/**
102
+	 * @param EE_Question      $question
103
+	 * @param EE_Registration  $registration
104
+	 * @param                  $previous_answers
105
+	 * @return EE_Answer
106
+	 * @throws UnexpectedEntityException
107
+	 * @throws EE_Error
108
+	 */
109
+	protected function generateNewAnswer(
110
+		EE_Question $question,
111
+		EE_Registration $registration,
112
+		$previous_answers
113
+	) {
114
+		$old_answer_value = isset($previous_answers[ $question->ID() ])
115
+			? $previous_answers[ $question->ID() ]
116
+			: '';
117
+		$new_answer       = EE_Answer::new_instance(
118
+			array(
119
+				'QST_ID'    => $question->ID(),
120
+				'REG_ID'    => $registration->ID(),
121
+				'ANS_value' => $old_answer_value,
122
+			)
123
+		);
124
+		if ( ! $new_answer instanceof EE_Answer) {
125
+			throw new UnexpectedEntityException($new_answer, 'EE_Answer');
126
+		}
127
+		$new_answer->save();
128
+		return $new_answer;
129
+	}
130
+
131
+
132
+
133
+	/**
134
+	 * @param EE_Registration $target_registration
135
+	 * @param EE_Registration $registration_to_copy
136
+	 * @return bool
137
+	 * @throws RuntimeException
138
+	 * @throws UnexpectedEntityException
139
+	 * @throws EE_Error
140
+	 */
141
+	public function copyPaymentDetails(
142
+		EE_Registration $target_registration,
143
+		EE_Registration $registration_to_copy
144
+	) {
145
+		$save = false;
146
+		$previous_registration_payments = $registration_to_copy->registration_payments();
147
+		$new_registration_payment_total = 0;
148
+		$registration_to_copy_total = $registration_to_copy->paid();
149
+		foreach ($previous_registration_payments as $previous_registration_payment) {
150
+			if (
151
+				$previous_registration_payment instanceof EE_Registration_Payment
152
+				&& $previous_registration_payment->payment() instanceof EE_Payment
153
+				&& $previous_registration_payment->payment()->is_approved()
154
+			) {
155
+				$payment_amount = $previous_registration_payment->amount();
156
+				$new_registration_payment = EE_Registration_Payment::new_instance(
157
+					array(
158
+						'REG_ID'     => $target_registration->ID(),
159
+						'PAY_ID'     => $previous_registration_payment->payment()->ID(),
160
+						'RPY_amount' => $payment_amount,
161
+					)
162
+				);
163
+				if ( ! $new_registration_payment instanceof EE_Registration_Payment) {
164
+					throw new UnexpectedEntityException($new_registration_payment, 'EE_Registration_Payment');
165
+				}
166
+				$new_registration_payment->save();
167
+				// if new reg payment is good, then set old reg payment amount to zero
168
+				$previous_registration_payment->set_amount(0);
169
+				$previous_registration_payment->save();
170
+				// now  increment/decrement payment amounts
171
+				$new_registration_payment_total += $payment_amount;
172
+				$registration_to_copy_total -= $payment_amount;
173
+				$save = true;
174
+			}
175
+		}
176
+		if($save){
177
+			$target_registration->set_paid($new_registration_payment_total);
178
+			$target_registration->save();
179
+			$registration_to_copy->set_paid($registration_to_copy_total);
180
+			$registration_to_copy->save();
181
+		}
182
+		return true;
183
+	}
184 184
 
185 185
 
186 186
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -90,7 +90,7 @@  discard block
 block discarded – undo
90 90
         $reindexed_answers = array();
91 91
         foreach ($answers as $answer) {
92 92
             if ($answer instanceof EE_Answer) {
93
-                $reindexed_answers[ $answer->question_ID() ] = $answer->value();
93
+                $reindexed_answers[$answer->question_ID()] = $answer->value();
94 94
             }
95 95
         }
96 96
         return $reindexed_answers;
@@ -111,8 +111,8 @@  discard block
 block discarded – undo
111 111
         EE_Registration $registration,
112 112
         $previous_answers
113 113
     ) {
114
-        $old_answer_value = isset($previous_answers[ $question->ID() ])
115
-            ? $previous_answers[ $question->ID() ]
114
+        $old_answer_value = isset($previous_answers[$question->ID()])
115
+            ? $previous_answers[$question->ID()]
116 116
             : '';
117 117
         $new_answer       = EE_Answer::new_instance(
118 118
             array(
@@ -173,7 +173,7 @@  discard block
 block discarded – undo
173 173
                 $save = true;
174 174
             }
175 175
         }
176
-        if($save){
176
+        if ($save) {
177 177
             $target_registration->set_paid($new_registration_payment_total);
178 178
             $target_registration->save();
179 179
             $registration_to_copy->set_paid($registration_to_copy_total);
Please login to merge, or discard this patch.
core/services/collections/iterators/CollectionFilterCallbackIterator.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -9,51 +9,51 @@
 block discarded – undo
9 9
 class CollectionFilterCallbackIterator extends FilterIterator
10 10
 {
11 11
 
12
-    /**
13
-     * Used for determining whether the iterated object in the Collection is "valid" or not.
14
-     * @var Closure
15
-     */
16
-    private $acceptance_callback;
17
-
18
-
19
-    /**
20
-     * CollectionFilterCallbackIterator constructor.
21
-     *
22
-     * @param Collection $collection
23
-     * @param Closure    $acceptance_callback  The closure will receive an instance of whatever object is stored on the
24
-     *                                         collection when iterating over the collection and should return boolean.
25
-     */
26
-    public function __construct(Collection $collection, Closure $acceptance_callback)
27
-    {
28
-        $this->acceptance_callback = $acceptance_callback;
29
-        parent::__construct($collection);
30
-    }
31
-
32
-    /**
33
-     * Check whether the current element of the iterator is acceptable
34
-     *
35
-     * @link  http://php.net/manual/en/filteriterator.accept.php
36
-     * @return bool true if the current element is acceptable, otherwise false.
37
-     */
38
-    public function accept()
39
-    {
40
-        $acceptance_callback = $this->acceptance_callback;
41
-        return $acceptance_callback($this->getInnerIterator()->current());
42
-    }
43
-
44
-
45
-
46
-    /**
47
-     * Returns a filtered array of objects from the collection using the provided acceptance callback
48
-     * @return array
49
-     */
50
-    public function getFiltered()
51
-    {
52
-        $filtered_array = array();
53
-        $this->rewind();
54
-        foreach ($this as $filtered_object) {
55
-            $filtered_array[] = $filtered_object;
56
-        }
57
-        return $filtered_array;
58
-    }
12
+	/**
13
+	 * Used for determining whether the iterated object in the Collection is "valid" or not.
14
+	 * @var Closure
15
+	 */
16
+	private $acceptance_callback;
17
+
18
+
19
+	/**
20
+	 * CollectionFilterCallbackIterator constructor.
21
+	 *
22
+	 * @param Collection $collection
23
+	 * @param Closure    $acceptance_callback  The closure will receive an instance of whatever object is stored on the
24
+	 *                                         collection when iterating over the collection and should return boolean.
25
+	 */
26
+	public function __construct(Collection $collection, Closure $acceptance_callback)
27
+	{
28
+		$this->acceptance_callback = $acceptance_callback;
29
+		parent::__construct($collection);
30
+	}
31
+
32
+	/**
33
+	 * Check whether the current element of the iterator is acceptable
34
+	 *
35
+	 * @link  http://php.net/manual/en/filteriterator.accept.php
36
+	 * @return bool true if the current element is acceptable, otherwise false.
37
+	 */
38
+	public function accept()
39
+	{
40
+		$acceptance_callback = $this->acceptance_callback;
41
+		return $acceptance_callback($this->getInnerIterator()->current());
42
+	}
43
+
44
+
45
+
46
+	/**
47
+	 * Returns a filtered array of objects from the collection using the provided acceptance callback
48
+	 * @return array
49
+	 */
50
+	public function getFiltered()
51
+	{
52
+		$filtered_array = array();
53
+		$this->rewind();
54
+		foreach ($this as $filtered_object) {
55
+			$filtered_array[] = $filtered_object;
56
+		}
57
+		return $filtered_array;
58
+	}
59 59
 }
Please login to merge, or discard this patch.
core/services/collections/iterators/FilterIteratorsHelper.php 1 patch
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -17,18 +17,18 @@
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * Uses CollectionFilterCallbackIterator on a provided collection with provided Closure for filtering each object
22
-     * in the collection.
23
-     * The closure receives an instance of the object and should return false if it is not "valid" and true if it is.
24
-     *
25
-     * @param Collection $collection
26
-     * @param Closure    $acceptance_callback
27
-     * @return array
28
-     */
29
-    public static function getFilteredObjectsFromCollection(Collection $collection, Closure $acceptance_callback)
30
-    {
31
-        $collection_filter_iterator = new CollectionFilterCallbackIterator($collection, $acceptance_callback);
32
-        return $collection_filter_iterator->getFiltered();
33
-    }
20
+	/**
21
+	 * Uses CollectionFilterCallbackIterator on a provided collection with provided Closure for filtering each object
22
+	 * in the collection.
23
+	 * The closure receives an instance of the object and should return false if it is not "valid" and true if it is.
24
+	 *
25
+	 * @param Collection $collection
26
+	 * @param Closure    $acceptance_callback
27
+	 * @return array
28
+	 */
29
+	public static function getFilteredObjectsFromCollection(Collection $collection, Closure $acceptance_callback)
30
+	{
31
+		$collection_filter_iterator = new CollectionFilterCallbackIterator($collection, $acceptance_callback);
32
+		return $collection_filter_iterator->getFiltered();
33
+	}
34 34
 }
35 35
\ No newline at end of file
Please login to merge, or discard this patch.
caffeinated/payment_methods/Paypal_Pro/EEG_Paypal_Pro.gateway.php 2 patches
Indentation   +588 added lines, -588 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (! defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('No direct script access allowed');
3
+	exit('No direct script access allowed');
4 4
 }
5 5
 
6 6
 
@@ -25,592 +25,592 @@  discard block
 block discarded – undo
25 25
 class EEG_Paypal_Pro extends EE_Onsite_Gateway
26 26
 {
27 27
 
28
-    /**
29
-     * @var $_paypal_api_username string
30
-     */
31
-    protected $_username = null;
32
-
33
-    /**
34
-     * @var $_password string
35
-     */
36
-    protected $_password = null;
37
-
38
-    /**
39
-     * @var $_signature string
40
-     */
41
-    protected $_signature = null;
42
-
43
-    /**
44
-     * @var $_credit_card_types array with the keys for credit card types accepted on this account
45
-     */
46
-    protected $_credit_card_types    = null;
47
-
48
-    protected $_currencies_supported = array(
49
-        'USD',
50
-        'GBP',
51
-        'CAD',
52
-        'AUD',
53
-        'BRL',
54
-        'CHF',
55
-        'CZK',
56
-        'DKK',
57
-        'EUR',
58
-        'HKD',
59
-        'HUF',
60
-        'ILS',
61
-        'JPY',
62
-        'MXN',
63
-        'MYR',
64
-        'NOK',
65
-        'NZD',
66
-        'PHP',
67
-        'PLN',
68
-        'SEK',
69
-        'SGD',
70
-        'THB',
71
-        'TRY',
72
-        'TWD',
73
-        'RUB',
74
-    );
75
-
76
-
77
-
78
-    /**
79
-     * @param EEI_Payment $payment
80
-     * @param array       $billing_info {
81
-     * @type string $credit_card
82
-     * @type string $credit_card_type
83
-     * @type string $exp_month always 2 characters
84
-     * @type string $exp_year always 4 characters
85
-     * @type string $cvv
86
-     * }
87
-     * @see      parent::do_direct_payment for more info
88
-     * @return EE_Payment|EEI_Payment
89
-     * @throws EE_Error
90
-     */
91
-    public function do_direct_payment($payment, $billing_info = null)
92
-    {
93
-        $transaction = $payment->transaction();
94
-        if (! $transaction instanceof EEI_Transaction) {
95
-            throw new EE_Error(
96
-                esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
97
-            );
98
-        }
99
-        $primary_registrant = $transaction->primary_registration();
100
-        if (! $primary_registrant instanceof EEI_Registration) {
101
-            throw new EE_Error(
102
-                esc_html__(
103
-                    'No primary registration on transaction while paying with PayPal Pro.',
104
-                    'event_espresso'
105
-                )
106
-            );
107
-        }
108
-        $attendee = $primary_registrant->attendee();
109
-        if (! $attendee instanceof EEI_Attendee) {
110
-            throw new EE_Error(
111
-                esc_html__(
112
-                    'No attendee on primary registration while paying with PayPal Pro.',
113
-                    'event_espresso'
114
-                )
115
-            );
116
-        }
117
-        $gateway_formatter = $this->_get_gateway_formatter();
118
-        $order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
119
-        //charge for the full amount. Show itemized list
120
-        if ($this->_can_easily_itemize_transaction_for($payment)) {
121
-            $item_num = 1;
122
-            $total_line_item = $transaction->total_line_item();
123
-            $order_items = array();
124
-            foreach ($total_line_item->get_items() as $line_item) {
125
-                //ignore line items with a quantity of 0
126
-                if ($line_item->quantity() == 0) {
127
-                    continue;
128
-                }
129
-                $item = array(
130
-                    // Item Name.  127 char max.
131
-                    'l_name'                 => substr(
132
-                        $gateway_formatter->formatLineItemName($line_item, $payment),
133
-                        0,
134
-                        127
135
-                    ),
136
-                    // Item description.  127 char max.
137
-                    'l_desc'                 => substr(
138
-                        $gateway_formatter->formatLineItemDesc($line_item, $payment),
139
-                        0,
140
-                        127
141
-                    ),
142
-                    // Cost of individual item.
143
-                    'l_amt'                  => $line_item->unit_price(),
144
-                    // Item Number.  127 char max.
145
-                    'l_number'               => $item_num++,
146
-                    // Item quantity.  Must be any positive integer.
147
-                    'l_qty'                  => $line_item->quantity(),
148
-                    // Item's sales tax amount.
149
-                    'l_taxamt'               => '',
150
-                    // eBay auction number of item.
151
-                    'l_ebayitemnumber'       => '',
152
-                    // eBay transaction ID of purchased item.
153
-                    'l_ebayitemauctiontxnid' => '',
154
-                    // eBay order ID for the item.
155
-                    'l_ebayitemorderid'      => '',
156
-                );
157
-                // add to array of all items
158
-                array_push($order_items, $item);
159
-            }
160
-            $item_amount = $total_line_item->get_items_total();
161
-            $tax_amount = $total_line_item->get_total_tax();
162
-        } else {
163
-            $order_items = array();
164
-            $item_amount = $payment->amount();
165
-            $tax_amount = 0;
166
-            array_push($order_items, array(
167
-                // Item Name.  127 char max.
168
-                'l_name'   => substr(
169
-                    $gateway_formatter->formatPartialPaymentLineItemName($payment),
170
-                    0,
171
-                    127
172
-                ),
173
-                // Item description.  127 char max.
174
-                'l_desc'   => substr(
175
-                    $gateway_formatter->formatPartialPaymentLineItemDesc($payment),
176
-                    0,
177
-                    127
178
-                ),
179
-                // Cost of individual item.
180
-                'l_amt'    => $payment->amount(),
181
-                // Item Number.  127 char max.
182
-                'l_number' => 1,
183
-                // Item quantity.  Must be any positive integer.
184
-                'l_qty'    => 1,
185
-            ));
186
-        }
187
-        // Populate data arrays with order data.
188
-        $DPFields = array(
189
-            // How you want to obtain payment ?
190
-            // Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
191
-            // Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
192
-            'paymentaction'    => 'Sale',
193
-            // Required.  IP address of the payer's browser.
194
-            'ipaddress'        => $_SERVER['REMOTE_ADDR'],
195
-            // Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
196
-            'returnfmfdetails' => '1',
197
-        );
198
-        $CCDetails = array(
199
-            // Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
200
-            // If Maestro or Solo, the currency code must be GBP.
201
-            //  In addition, either start date or issue number must be specified.
202
-            'creditcardtype' => $billing_info['credit_card_type'],
203
-            // Required.  Credit card number.  No spaces or punctuation.
204
-            'acct'           => $billing_info['credit_card'],
205
-            // Required.  Credit card expiration date.  Format is MMYYYY
206
-            'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
207
-            // Requirements determined by your PayPal account settings.  Security digits for credit card.
208
-            'cvv2'           => $billing_info['cvv'],
209
-        );
210
-        $PayerInfo = array(
211
-            // Email address of payer.
212
-            'email'       => $billing_info['email'],
213
-            // Unique PayPal customer ID for payer.
214
-            'payerid'     => '',
215
-            // Status of payer.  Values are verified or unverified
216
-            'payerstatus' => '',
217
-            // Payer's business name.
218
-            'business'    => '',
219
-        );
220
-        $PayerName = array(
221
-            // Payer's salutation.  20 char max.
222
-            'salutation' => '',
223
-            // Payer's first name.  25 char max.
224
-            'firstname'  => substr($billing_info['first_name'], 0, 25),
225
-            // Payer's middle name.  25 char max.
226
-            'middlename' => '',
227
-            // Payer's last name.  25 char max.
228
-            'lastname'   => substr($billing_info['last_name'], 0, 25),
229
-            // Payer's suffix.  12 char max.
230
-            'suffix'     => '',
231
-        );
232
-        $BillingAddress = array(
233
-            // Required.  First street address.
234
-            'street'      => $billing_info['address'],
235
-            // Second street address.
236
-            'street2'     => $billing_info['address2'],
237
-            // Required.  Name of City.
238
-            'city'        => $billing_info['city'],
239
-            // Required. Name of State or Province.
240
-            'state'       => substr($billing_info['state'], 0, 40),
241
-            // Required.  Country code.
242
-            'countrycode' => $billing_info['country'],
243
-            // Required.  Postal code of payer.
244
-            'zip'         => $billing_info['zip'],
245
-        );
246
-        //check if the registration info contains the needed fields for paypal pro
247
-        //(see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
248
-        if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
249
-            $use_registration_address_info = true;
250
-        } else {
251
-            $use_registration_address_info = false;
252
-        }
253
-        //so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
254
-        // If not, use the billing info again
255
-        $ShippingAddress = array(
256
-            'shiptoname'     => substr($use_registration_address_info
257
-                ? $attendee->full_name()
258
-                : $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
259
-            'shiptostreet'   => substr($use_registration_address_info
260
-                ? $attendee->address()
261
-                : $billing_info['address'], 0, 100),
262
-            'shiptostreet2'  => substr($use_registration_address_info
263
-                ? $attendee->address2() : $billing_info['address2'], 0, 100),
264
-            'shiptocity'     => substr($use_registration_address_info
265
-                ? $attendee->city()
266
-                : $billing_info['city'], 0, 40),
267
-            'state'          => substr($use_registration_address_info
268
-                ? $attendee->state_name()
269
-                : $billing_info['state'], 0, 40),
270
-            'shiptocountry'  => $use_registration_address_info
271
-                ? $attendee->country_ID()
272
-                : $billing_info['country'],
273
-            'shiptozip'      => substr($use_registration_address_info
274
-                ? $attendee->zip()
275
-                : $billing_info['zip'], 0, 20),
276
-            'shiptophonenum' => substr($use_registration_address_info
277
-                ? $attendee->phone()
278
-                : $billing_info['phone'], 0, 20),
279
-        );
280
-        $PaymentDetails = array(
281
-            // Required.  Total amount of order, including shipping, handling, and tax.
282
-            'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
283
-            // Required.  Three-letter currency code.  Default is USD.
284
-            'currencycode' => $payment->currency_code(),
285
-            // Required if you include itemized cart details. (L_AMTn, etc.)
286
-            //Subtotal of items not including S&H, or tax.
287
-            'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
288
-            // Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
289
-            'shippingamt'  => '',
290
-            // Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
291
-            'handlingamt'  => '',
292
-            // Required if you specify itemized cart tax details.
293
-            // Sum of tax for all items on the order.  Total sales tax.
294
-            'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
295
-            // Description of the order the customer is purchasing.  127 char max.
296
-            'desc'         => $order_description,
297
-            // Free-form field for your own use.  256 char max.
298
-            'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
299
-            // Your own invoice or tracking number
300
-            'invnum'       => wp_generate_password(12, false),//$transaction->ID(),
301
-            // URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
302
-            'notifyurl'    => '',
303
-            'buttonsource' => 'EventEspresso_SP',//EE will blow up if you change this
304
-        );
305
-        // Wrap all data arrays into a single, "master" array which will be passed into the class function.
306
-        $PayPalRequestData = array(
307
-            'DPFields'        => $DPFields,
308
-            'CCDetails'       => $CCDetails,
309
-            'PayerInfo'       => $PayerInfo,
310
-            'PayerName'       => $PayerName,
311
-            'BillingAddress'  => $BillingAddress,
312
-            'ShippingAddress' => $ShippingAddress,
313
-            'PaymentDetails'  => $PaymentDetails,
314
-            'OrderItems'      => $order_items,
315
-        );
316
-        $this->_log_clean_request($PayPalRequestData, $payment);
317
-        try {
318
-            $PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
319
-            //remove PCI-sensitive data so it doesn't get stored
320
-            $PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
321
-            $message = isset($PayPalResult['L_LONGMESSAGE0']) ? $PayPalResult['L_LONGMESSAGE0'] : $PayPalResult['ACK'];
322
-            if (empty($PayPalResult['RAWRESPONSE'])) {
323
-                $payment->set_status($this->_pay_model->failed_status());
324
-                $payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
325
-                $payment->set_details($PayPalResult);
326
-            } else {
327
-                if ($this->_APICallSuccessful($PayPalResult)) {
328
-                    $payment->set_status($this->_pay_model->approved_status());
329
-                } else {
330
-                    $payment->set_status($this->_pay_model->declined_status());
331
-                }
332
-                //make sure we interpret the AMT as a float, not an international string
333
-                // (where periods are thousand separators)
334
-                $payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
335
-                $payment->set_gateway_response($message);
336
-                $payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
337
-                    ? $PayPalResult['TRANSACTIONID']
338
-                    : null);
339
-                $primary_registration_code = $primary_registrant instanceof EE_Registration
340
-                    ? $primary_registrant->reg_code()
341
-                    : '';
342
-                $payment->set_extra_accntng($primary_registration_code);
343
-                $payment->set_details($PayPalResult);
344
-            }
345
-        } catch (Exception $e) {
346
-            $payment->set_status($this->_pay_model->failed_status());
347
-            $payment->set_gateway_response($e->getMessage());
348
-        }
349
-        //$payment->set_status( $this->_pay_model->declined_status() );
350
-        //$payment->set_gateway_response( '' );
351
-        return $payment;
352
-    }
353
-
354
-
355
-
356
-    /**
357
-     * CLeans out sensitive CC data and then logs it, and returns the cleaned request
358
-     *
359
-     * @param array       $request
360
-     * @param EEI_Payment $payment
361
-     * @return void
362
-     */
363
-    private function _log_clean_request($request, $payment)
364
-    {
365
-        $cleaned_request_data = $request;
366
-        unset($cleaned_request_data['CCDetails']['acct']);
367
-        unset($cleaned_request_data['CCDetails']['cvv2']);
368
-        unset($cleaned_request_data['CCDetails']['expdate']);
369
-        $this->log(array('Paypal Request' => $cleaned_request_data), $payment);
370
-    }
371
-
372
-
373
-
374
-    /**
375
-     * Cleans the response, logs it, and returns it
376
-     *
377
-     * @param array       $response
378
-     * @param EEI_Payment $payment
379
-     * @return array cleaned
380
-     */
381
-    private function _log_clean_response($response, $payment)
382
-    {
383
-        unset($response['REQUESTDATA']['CREDITCARDTYPE']);
384
-        unset($response['REQUESTDATA']['ACCT']);
385
-        unset($response['REQUESTDATA']['EXPDATE']);
386
-        unset($response['REQUESTDATA']['CVV2']);
387
-        unset($response['RAWREQUEST']);
388
-        $this->log(array('Paypal Response' => $response), $payment);
389
-        return $response;
390
-    }
391
-
392
-
393
-
394
-    /**
395
-     * @param $DataArray
396
-     * @return array
397
-     */
398
-    private function prep_and_curl_request($DataArray)
399
-    {
400
-        // Create empty holders for each portion of the NVP string
401
-        $DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
402
-        $CCDetailsNVP = '';
403
-        $PayerInfoNVP = '';
404
-        $PayerNameNVP = '';
405
-        $BillingAddressNVP = '';
406
-        $ShippingAddressNVP = '';
407
-        $PaymentDetailsNVP = '';
408
-        $OrderItemsNVP = '';
409
-        $Secure3DNVP = '';
410
-        // DP Fields
411
-        $DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
412
-        foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
413
-            $DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
414
-        }
415
-        // CC Details Fields
416
-        $CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
417
-        foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
418
-            $CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
419
-        }
420
-        // PayerInfo Type Fields
421
-        $PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
422
-        foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
423
-            $PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
424
-        }
425
-        // Payer Name Fields
426
-        $PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
427
-        foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
428
-            $PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
429
-        }
430
-        // Address Fields (Billing)
431
-        $BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
432
-        foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
433
-            $BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
434
-        }
435
-        // Payment Details Type Fields
436
-        $PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
437
-        foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
438
-            $PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
439
-        }
440
-        // Payment Details Item Type Fields
441
-        $OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
442
-        $n = 0;
443
-        foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
444
-            $CurrentItem = $OrderItems[$OrderItemsVar];
445
-            foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
446
-                $OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
447
-            }
448
-            $n++;
449
-        }
450
-        // Ship To Address Fields
451
-        $ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
452
-        foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
453
-            $ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
454
-        }
455
-        // 3D Secure Fields
456
-        $Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
457
-        foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
458
-            $Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
459
-        }
460
-        // Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
461
-        $NVPRequest = 'USER='
462
-                      . $this->_username
463
-                      . '&PWD='
464
-                      . $this->_password
465
-                      . '&VERSION=64.0'
466
-                      . '&SIGNATURE='
467
-                      . $this->_signature
468
-                      . $DPFieldsNVP
469
-                      . $CCDetailsNVP
470
-                      . $PayerInfoNVP
471
-                      . $PayerNameNVP
472
-                      . $BillingAddressNVP
473
-                      . $PaymentDetailsNVP
474
-                      . $OrderItemsNVP
475
-                      . $ShippingAddressNVP
476
-                      . $Secure3DNVP;
477
-        $NVPResponse = $this->_CURLRequest($NVPRequest);
478
-        $NVPRequestArray = $this->_NVPToArray($NVPRequest);
479
-        $NVPResponseArray = $this->_NVPToArray($NVPResponse);
480
-        $Errors = $this->_GetErrors($NVPResponseArray);
481
-        $NVPResponseArray['ERRORS'] = $Errors;
482
-        $NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
483
-        $NVPResponseArray['RAWREQUEST'] = $NVPRequest;
484
-        $NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
485
-        return $NVPResponseArray;
486
-    }
487
-
488
-
489
-
490
-    /**
491
-     * @param $Request
492
-     * @return mixed
493
-     */
494
-    private function _CURLRequest($Request)
495
-    {
496
-        $EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
497
-        $curl = curl_init();
498
-        curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
499
-        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
500
-        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
501
-        curl_setopt($curl, CURLOPT_URL, $EndPointURL);
502
-        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
503
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
504
-        curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
505
-        //execute the curl POST
506
-        $Response = curl_exec($curl);
507
-        curl_close($curl);
508
-        return $Response;
509
-    }
510
-
511
-
512
-
513
-    /**
514
-     * @param $NVPString
515
-     * @return array
516
-     */
517
-    private function _NVPToArray($NVPString)
518
-    {
519
-        // prepare responses into array
520
-        $proArray = array();
521
-        while (strlen($NVPString)) {
522
-            // name
523
-            $keypos = strpos($NVPString, '=');
524
-            $keyval = substr($NVPString, 0, $keypos);
525
-            // value
526
-            $valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
527
-            $valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
528
-            // decoding the response
529
-            $proArray[$keyval] = urldecode($valval);
530
-            $NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
531
-        }
532
-        return $proArray;
533
-    }
534
-
535
-
536
-
537
-    /**
538
-     * @param array $PayPalResult
539
-     * @return bool
540
-     */
541
-    private function _APICallSuccessful($PayPalResult)
542
-    {
543
-        $approved = false;
544
-        // check main response message from PayPal
545
-        if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
546
-            $ack = strtoupper($PayPalResult['ACK']);
547
-            $approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
548
-        }
549
-        return $approved;
550
-    }
551
-
552
-
553
-
554
-    /**
555
-     * @param $DataArray
556
-     * @return array
557
-     */
558
-    private function _GetErrors($DataArray)
559
-    {
560
-        $Errors = array();
561
-        $n = 0;
562
-        while (isset($DataArray['L_ERRORCODE' . $n . ''])) {
563
-            $LErrorCode = isset($DataArray['L_ERRORCODE' . $n . '']) ? $DataArray['L_ERRORCODE' . $n . ''] : '';
564
-            $LShortMessage = isset($DataArray['L_SHORTMESSAGE' . $n . ''])
565
-                ? $DataArray['L_SHORTMESSAGE' . $n . '']
566
-                : '';
567
-            $LLongMessage = isset($DataArray['L_LONGMESSAGE' . $n . ''])
568
-                ? $DataArray['L_LONGMESSAGE' . $n . '']
569
-                : '';
570
-            $LSeverityCode = isset($DataArray['L_SEVERITYCODE' . $n . ''])
571
-                ? $DataArray['L_SEVERITYCODE' . $n . '']
572
-                : '';
573
-            $CurrentItem = array(
574
-                'L_ERRORCODE'    => $LErrorCode,
575
-                'L_SHORTMESSAGE' => $LShortMessage,
576
-                'L_LONGMESSAGE'  => $LLongMessage,
577
-                'L_SEVERITYCODE' => $LSeverityCode,
578
-            );
579
-            array_push($Errors, $CurrentItem);
580
-            $n++;
581
-        }
582
-        return $Errors;
583
-    }
584
-
585
-
586
-
587
-    /**
588
-     *        nothing to see here...  move along....
589
-     *
590
-     * @access protected
591
-     * @param $Errors
592
-     * @return string
593
-     */
594
-    private function _DisplayErrors($Errors)
595
-    {
596
-        $error = '';
597
-        foreach ($Errors as $ErrorVar => $ErrorVal) {
598
-            $CurrentError = $Errors[$ErrorVar];
599
-            foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
600
-                $CurrentVarName = '';
601
-                if ($CurrentErrorVar == 'L_ERRORCODE') {
602
-                    $CurrentVarName = 'Error Code';
603
-                } elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
604
-                    $CurrentVarName = 'Short Message';
605
-                } elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
606
-                    $CurrentVarName = 'Long Message';
607
-                } elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
608
-                    $CurrentVarName = 'Severity Code';
609
-                }
610
-                $error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
611
-            }
612
-        }
613
-        return $error;
614
-    }
28
+	/**
29
+	 * @var $_paypal_api_username string
30
+	 */
31
+	protected $_username = null;
32
+
33
+	/**
34
+	 * @var $_password string
35
+	 */
36
+	protected $_password = null;
37
+
38
+	/**
39
+	 * @var $_signature string
40
+	 */
41
+	protected $_signature = null;
42
+
43
+	/**
44
+	 * @var $_credit_card_types array with the keys for credit card types accepted on this account
45
+	 */
46
+	protected $_credit_card_types    = null;
47
+
48
+	protected $_currencies_supported = array(
49
+		'USD',
50
+		'GBP',
51
+		'CAD',
52
+		'AUD',
53
+		'BRL',
54
+		'CHF',
55
+		'CZK',
56
+		'DKK',
57
+		'EUR',
58
+		'HKD',
59
+		'HUF',
60
+		'ILS',
61
+		'JPY',
62
+		'MXN',
63
+		'MYR',
64
+		'NOK',
65
+		'NZD',
66
+		'PHP',
67
+		'PLN',
68
+		'SEK',
69
+		'SGD',
70
+		'THB',
71
+		'TRY',
72
+		'TWD',
73
+		'RUB',
74
+	);
75
+
76
+
77
+
78
+	/**
79
+	 * @param EEI_Payment $payment
80
+	 * @param array       $billing_info {
81
+	 * @type string $credit_card
82
+	 * @type string $credit_card_type
83
+	 * @type string $exp_month always 2 characters
84
+	 * @type string $exp_year always 4 characters
85
+	 * @type string $cvv
86
+	 * }
87
+	 * @see      parent::do_direct_payment for more info
88
+	 * @return EE_Payment|EEI_Payment
89
+	 * @throws EE_Error
90
+	 */
91
+	public function do_direct_payment($payment, $billing_info = null)
92
+	{
93
+		$transaction = $payment->transaction();
94
+		if (! $transaction instanceof EEI_Transaction) {
95
+			throw new EE_Error(
96
+				esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
97
+			);
98
+		}
99
+		$primary_registrant = $transaction->primary_registration();
100
+		if (! $primary_registrant instanceof EEI_Registration) {
101
+			throw new EE_Error(
102
+				esc_html__(
103
+					'No primary registration on transaction while paying with PayPal Pro.',
104
+					'event_espresso'
105
+				)
106
+			);
107
+		}
108
+		$attendee = $primary_registrant->attendee();
109
+		if (! $attendee instanceof EEI_Attendee) {
110
+			throw new EE_Error(
111
+				esc_html__(
112
+					'No attendee on primary registration while paying with PayPal Pro.',
113
+					'event_espresso'
114
+				)
115
+			);
116
+		}
117
+		$gateway_formatter = $this->_get_gateway_formatter();
118
+		$order_description = substr($gateway_formatter->formatOrderDescription($payment), 0, 127);
119
+		//charge for the full amount. Show itemized list
120
+		if ($this->_can_easily_itemize_transaction_for($payment)) {
121
+			$item_num = 1;
122
+			$total_line_item = $transaction->total_line_item();
123
+			$order_items = array();
124
+			foreach ($total_line_item->get_items() as $line_item) {
125
+				//ignore line items with a quantity of 0
126
+				if ($line_item->quantity() == 0) {
127
+					continue;
128
+				}
129
+				$item = array(
130
+					// Item Name.  127 char max.
131
+					'l_name'                 => substr(
132
+						$gateway_formatter->formatLineItemName($line_item, $payment),
133
+						0,
134
+						127
135
+					),
136
+					// Item description.  127 char max.
137
+					'l_desc'                 => substr(
138
+						$gateway_formatter->formatLineItemDesc($line_item, $payment),
139
+						0,
140
+						127
141
+					),
142
+					// Cost of individual item.
143
+					'l_amt'                  => $line_item->unit_price(),
144
+					// Item Number.  127 char max.
145
+					'l_number'               => $item_num++,
146
+					// Item quantity.  Must be any positive integer.
147
+					'l_qty'                  => $line_item->quantity(),
148
+					// Item's sales tax amount.
149
+					'l_taxamt'               => '',
150
+					// eBay auction number of item.
151
+					'l_ebayitemnumber'       => '',
152
+					// eBay transaction ID of purchased item.
153
+					'l_ebayitemauctiontxnid' => '',
154
+					// eBay order ID for the item.
155
+					'l_ebayitemorderid'      => '',
156
+				);
157
+				// add to array of all items
158
+				array_push($order_items, $item);
159
+			}
160
+			$item_amount = $total_line_item->get_items_total();
161
+			$tax_amount = $total_line_item->get_total_tax();
162
+		} else {
163
+			$order_items = array();
164
+			$item_amount = $payment->amount();
165
+			$tax_amount = 0;
166
+			array_push($order_items, array(
167
+				// Item Name.  127 char max.
168
+				'l_name'   => substr(
169
+					$gateway_formatter->formatPartialPaymentLineItemName($payment),
170
+					0,
171
+					127
172
+				),
173
+				// Item description.  127 char max.
174
+				'l_desc'   => substr(
175
+					$gateway_formatter->formatPartialPaymentLineItemDesc($payment),
176
+					0,
177
+					127
178
+				),
179
+				// Cost of individual item.
180
+				'l_amt'    => $payment->amount(),
181
+				// Item Number.  127 char max.
182
+				'l_number' => 1,
183
+				// Item quantity.  Must be any positive integer.
184
+				'l_qty'    => 1,
185
+			));
186
+		}
187
+		// Populate data arrays with order data.
188
+		$DPFields = array(
189
+			// How you want to obtain payment ?
190
+			// Authorization indicates the payment is a basic auth subject to settlement with Auth & Capture.
191
+			// Sale indicates that this is a final sale for which you are requesting payment.  Default is Sale.
192
+			'paymentaction'    => 'Sale',
193
+			// Required.  IP address of the payer's browser.
194
+			'ipaddress'        => $_SERVER['REMOTE_ADDR'],
195
+			// Flag to determine whether you want the results returned by FMF.  1 or 0.  Default is 0.
196
+			'returnfmfdetails' => '1',
197
+		);
198
+		$CCDetails = array(
199
+			// Required. Type of credit card.  Visa, MasterCard, Discover, Amex, Maestro, Solo.
200
+			// If Maestro or Solo, the currency code must be GBP.
201
+			//  In addition, either start date or issue number must be specified.
202
+			'creditcardtype' => $billing_info['credit_card_type'],
203
+			// Required.  Credit card number.  No spaces or punctuation.
204
+			'acct'           => $billing_info['credit_card'],
205
+			// Required.  Credit card expiration date.  Format is MMYYYY
206
+			'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
207
+			// Requirements determined by your PayPal account settings.  Security digits for credit card.
208
+			'cvv2'           => $billing_info['cvv'],
209
+		);
210
+		$PayerInfo = array(
211
+			// Email address of payer.
212
+			'email'       => $billing_info['email'],
213
+			// Unique PayPal customer ID for payer.
214
+			'payerid'     => '',
215
+			// Status of payer.  Values are verified or unverified
216
+			'payerstatus' => '',
217
+			// Payer's business name.
218
+			'business'    => '',
219
+		);
220
+		$PayerName = array(
221
+			// Payer's salutation.  20 char max.
222
+			'salutation' => '',
223
+			// Payer's first name.  25 char max.
224
+			'firstname'  => substr($billing_info['first_name'], 0, 25),
225
+			// Payer's middle name.  25 char max.
226
+			'middlename' => '',
227
+			// Payer's last name.  25 char max.
228
+			'lastname'   => substr($billing_info['last_name'], 0, 25),
229
+			// Payer's suffix.  12 char max.
230
+			'suffix'     => '',
231
+		);
232
+		$BillingAddress = array(
233
+			// Required.  First street address.
234
+			'street'      => $billing_info['address'],
235
+			// Second street address.
236
+			'street2'     => $billing_info['address2'],
237
+			// Required.  Name of City.
238
+			'city'        => $billing_info['city'],
239
+			// Required. Name of State or Province.
240
+			'state'       => substr($billing_info['state'], 0, 40),
241
+			// Required.  Country code.
242
+			'countrycode' => $billing_info['country'],
243
+			// Required.  Postal code of payer.
244
+			'zip'         => $billing_info['zip'],
245
+		);
246
+		//check if the registration info contains the needed fields for paypal pro
247
+		//(see https://developer.paypal.com/docs/classic/api/merchant/DoDirectPayment_API_Operation_NVP/)
248
+		if ($attendee->address() && $attendee->city() && $attendee->country_ID()) {
249
+			$use_registration_address_info = true;
250
+		} else {
251
+			$use_registration_address_info = false;
252
+		}
253
+		//so if the attendee has enough data to fill out PayPal Pro's shipping info, use it.
254
+		// If not, use the billing info again
255
+		$ShippingAddress = array(
256
+			'shiptoname'     => substr($use_registration_address_info
257
+				? $attendee->full_name()
258
+				: $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
259
+			'shiptostreet'   => substr($use_registration_address_info
260
+				? $attendee->address()
261
+				: $billing_info['address'], 0, 100),
262
+			'shiptostreet2'  => substr($use_registration_address_info
263
+				? $attendee->address2() : $billing_info['address2'], 0, 100),
264
+			'shiptocity'     => substr($use_registration_address_info
265
+				? $attendee->city()
266
+				: $billing_info['city'], 0, 40),
267
+			'state'          => substr($use_registration_address_info
268
+				? $attendee->state_name()
269
+				: $billing_info['state'], 0, 40),
270
+			'shiptocountry'  => $use_registration_address_info
271
+				? $attendee->country_ID()
272
+				: $billing_info['country'],
273
+			'shiptozip'      => substr($use_registration_address_info
274
+				? $attendee->zip()
275
+				: $billing_info['zip'], 0, 20),
276
+			'shiptophonenum' => substr($use_registration_address_info
277
+				? $attendee->phone()
278
+				: $billing_info['phone'], 0, 20),
279
+		);
280
+		$PaymentDetails = array(
281
+			// Required.  Total amount of order, including shipping, handling, and tax.
282
+			'amt'          => $gateway_formatter->formatCurrency($payment->amount()),
283
+			// Required.  Three-letter currency code.  Default is USD.
284
+			'currencycode' => $payment->currency_code(),
285
+			// Required if you include itemized cart details. (L_AMTn, etc.)
286
+			//Subtotal of items not including S&H, or tax.
287
+			'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
288
+			// Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
289
+			'shippingamt'  => '',
290
+			// Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
291
+			'handlingamt'  => '',
292
+			// Required if you specify itemized cart tax details.
293
+			// Sum of tax for all items on the order.  Total sales tax.
294
+			'taxamt'       => $gateway_formatter->formatCurrency($tax_amount),
295
+			// Description of the order the customer is purchasing.  127 char max.
296
+			'desc'         => $order_description,
297
+			// Free-form field for your own use.  256 char max.
298
+			'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
299
+			// Your own invoice or tracking number
300
+			'invnum'       => wp_generate_password(12, false),//$transaction->ID(),
301
+			// URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
302
+			'notifyurl'    => '',
303
+			'buttonsource' => 'EventEspresso_SP',//EE will blow up if you change this
304
+		);
305
+		// Wrap all data arrays into a single, "master" array which will be passed into the class function.
306
+		$PayPalRequestData = array(
307
+			'DPFields'        => $DPFields,
308
+			'CCDetails'       => $CCDetails,
309
+			'PayerInfo'       => $PayerInfo,
310
+			'PayerName'       => $PayerName,
311
+			'BillingAddress'  => $BillingAddress,
312
+			'ShippingAddress' => $ShippingAddress,
313
+			'PaymentDetails'  => $PaymentDetails,
314
+			'OrderItems'      => $order_items,
315
+		);
316
+		$this->_log_clean_request($PayPalRequestData, $payment);
317
+		try {
318
+			$PayPalResult = $this->prep_and_curl_request($PayPalRequestData);
319
+			//remove PCI-sensitive data so it doesn't get stored
320
+			$PayPalResult = $this->_log_clean_response($PayPalResult, $payment);
321
+			$message = isset($PayPalResult['L_LONGMESSAGE0']) ? $PayPalResult['L_LONGMESSAGE0'] : $PayPalResult['ACK'];
322
+			if (empty($PayPalResult['RAWRESPONSE'])) {
323
+				$payment->set_status($this->_pay_model->failed_status());
324
+				$payment->set_gateway_response(__('No response received from Paypal Pro', 'event_espresso'));
325
+				$payment->set_details($PayPalResult);
326
+			} else {
327
+				if ($this->_APICallSuccessful($PayPalResult)) {
328
+					$payment->set_status($this->_pay_model->approved_status());
329
+				} else {
330
+					$payment->set_status($this->_pay_model->declined_status());
331
+				}
332
+				//make sure we interpret the AMT as a float, not an international string
333
+				// (where periods are thousand separators)
334
+				$payment->set_amount(isset($PayPalResult['AMT']) ? floatval($PayPalResult['AMT']) : 0);
335
+				$payment->set_gateway_response($message);
336
+				$payment->set_txn_id_chq_nmbr(isset($PayPalResult['TRANSACTIONID'])
337
+					? $PayPalResult['TRANSACTIONID']
338
+					: null);
339
+				$primary_registration_code = $primary_registrant instanceof EE_Registration
340
+					? $primary_registrant->reg_code()
341
+					: '';
342
+				$payment->set_extra_accntng($primary_registration_code);
343
+				$payment->set_details($PayPalResult);
344
+			}
345
+		} catch (Exception $e) {
346
+			$payment->set_status($this->_pay_model->failed_status());
347
+			$payment->set_gateway_response($e->getMessage());
348
+		}
349
+		//$payment->set_status( $this->_pay_model->declined_status() );
350
+		//$payment->set_gateway_response( '' );
351
+		return $payment;
352
+	}
353
+
354
+
355
+
356
+	/**
357
+	 * CLeans out sensitive CC data and then logs it, and returns the cleaned request
358
+	 *
359
+	 * @param array       $request
360
+	 * @param EEI_Payment $payment
361
+	 * @return void
362
+	 */
363
+	private function _log_clean_request($request, $payment)
364
+	{
365
+		$cleaned_request_data = $request;
366
+		unset($cleaned_request_data['CCDetails']['acct']);
367
+		unset($cleaned_request_data['CCDetails']['cvv2']);
368
+		unset($cleaned_request_data['CCDetails']['expdate']);
369
+		$this->log(array('Paypal Request' => $cleaned_request_data), $payment);
370
+	}
371
+
372
+
373
+
374
+	/**
375
+	 * Cleans the response, logs it, and returns it
376
+	 *
377
+	 * @param array       $response
378
+	 * @param EEI_Payment $payment
379
+	 * @return array cleaned
380
+	 */
381
+	private function _log_clean_response($response, $payment)
382
+	{
383
+		unset($response['REQUESTDATA']['CREDITCARDTYPE']);
384
+		unset($response['REQUESTDATA']['ACCT']);
385
+		unset($response['REQUESTDATA']['EXPDATE']);
386
+		unset($response['REQUESTDATA']['CVV2']);
387
+		unset($response['RAWREQUEST']);
388
+		$this->log(array('Paypal Response' => $response), $payment);
389
+		return $response;
390
+	}
391
+
392
+
393
+
394
+	/**
395
+	 * @param $DataArray
396
+	 * @return array
397
+	 */
398
+	private function prep_and_curl_request($DataArray)
399
+	{
400
+		// Create empty holders for each portion of the NVP string
401
+		$DPFieldsNVP = '&METHOD=DoDirectPayment&BUTTONSOURCE=AngellEYE_PHP_Class_DDP';
402
+		$CCDetailsNVP = '';
403
+		$PayerInfoNVP = '';
404
+		$PayerNameNVP = '';
405
+		$BillingAddressNVP = '';
406
+		$ShippingAddressNVP = '';
407
+		$PaymentDetailsNVP = '';
408
+		$OrderItemsNVP = '';
409
+		$Secure3DNVP = '';
410
+		// DP Fields
411
+		$DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
412
+		foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
413
+			$DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
414
+		}
415
+		// CC Details Fields
416
+		$CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
417
+		foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
418
+			$CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
419
+		}
420
+		// PayerInfo Type Fields
421
+		$PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
422
+		foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
423
+			$PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
424
+		}
425
+		// Payer Name Fields
426
+		$PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
427
+		foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
428
+			$PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
429
+		}
430
+		// Address Fields (Billing)
431
+		$BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
432
+		foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
433
+			$BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
434
+		}
435
+		// Payment Details Type Fields
436
+		$PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
437
+		foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
438
+			$PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
439
+		}
440
+		// Payment Details Item Type Fields
441
+		$OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
442
+		$n = 0;
443
+		foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
444
+			$CurrentItem = $OrderItems[$OrderItemsVar];
445
+			foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
446
+				$OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
447
+			}
448
+			$n++;
449
+		}
450
+		// Ship To Address Fields
451
+		$ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
452
+		foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
453
+			$ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
454
+		}
455
+		// 3D Secure Fields
456
+		$Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
457
+		foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
458
+			$Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
459
+		}
460
+		// Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
461
+		$NVPRequest = 'USER='
462
+					  . $this->_username
463
+					  . '&PWD='
464
+					  . $this->_password
465
+					  . '&VERSION=64.0'
466
+					  . '&SIGNATURE='
467
+					  . $this->_signature
468
+					  . $DPFieldsNVP
469
+					  . $CCDetailsNVP
470
+					  . $PayerInfoNVP
471
+					  . $PayerNameNVP
472
+					  . $BillingAddressNVP
473
+					  . $PaymentDetailsNVP
474
+					  . $OrderItemsNVP
475
+					  . $ShippingAddressNVP
476
+					  . $Secure3DNVP;
477
+		$NVPResponse = $this->_CURLRequest($NVPRequest);
478
+		$NVPRequestArray = $this->_NVPToArray($NVPRequest);
479
+		$NVPResponseArray = $this->_NVPToArray($NVPResponse);
480
+		$Errors = $this->_GetErrors($NVPResponseArray);
481
+		$NVPResponseArray['ERRORS'] = $Errors;
482
+		$NVPResponseArray['REQUESTDATA'] = $NVPRequestArray;
483
+		$NVPResponseArray['RAWREQUEST'] = $NVPRequest;
484
+		$NVPResponseArray['RAWRESPONSE'] = $NVPResponse;
485
+		return $NVPResponseArray;
486
+	}
487
+
488
+
489
+
490
+	/**
491
+	 * @param $Request
492
+	 * @return mixed
493
+	 */
494
+	private function _CURLRequest($Request)
495
+	{
496
+		$EndPointURL = $this->_debug_mode ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
497
+		$curl = curl_init();
498
+		curl_setopt($curl, CURLOPT_VERBOSE, apply_filters('FHEE__EEG_Paypal_Pro__CurlRequest__CURLOPT_VERBOSE', true));
499
+		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
500
+		curl_setopt($curl, CURLOPT_TIMEOUT, 60);
501
+		curl_setopt($curl, CURLOPT_URL, $EndPointURL);
502
+		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
503
+		curl_setopt($curl, CURLOPT_POSTFIELDS, $Request);
504
+		curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
505
+		//execute the curl POST
506
+		$Response = curl_exec($curl);
507
+		curl_close($curl);
508
+		return $Response;
509
+	}
510
+
511
+
512
+
513
+	/**
514
+	 * @param $NVPString
515
+	 * @return array
516
+	 */
517
+	private function _NVPToArray($NVPString)
518
+	{
519
+		// prepare responses into array
520
+		$proArray = array();
521
+		while (strlen($NVPString)) {
522
+			// name
523
+			$keypos = strpos($NVPString, '=');
524
+			$keyval = substr($NVPString, 0, $keypos);
525
+			// value
526
+			$valuepos = strpos($NVPString, '&') ? strpos($NVPString, '&') : strlen($NVPString);
527
+			$valval = substr($NVPString, $keypos + 1, $valuepos - $keypos - 1);
528
+			// decoding the response
529
+			$proArray[$keyval] = urldecode($valval);
530
+			$NVPString = substr($NVPString, $valuepos + 1, strlen($NVPString));
531
+		}
532
+		return $proArray;
533
+	}
534
+
535
+
536
+
537
+	/**
538
+	 * @param array $PayPalResult
539
+	 * @return bool
540
+	 */
541
+	private function _APICallSuccessful($PayPalResult)
542
+	{
543
+		$approved = false;
544
+		// check main response message from PayPal
545
+		if (isset($PayPalResult['ACK']) && ! empty($PayPalResult['ACK'])) {
546
+			$ack = strtoupper($PayPalResult['ACK']);
547
+			$approved = ($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING' || $ack == 'PARTIALSUCCESS') ? true : false;
548
+		}
549
+		return $approved;
550
+	}
551
+
552
+
553
+
554
+	/**
555
+	 * @param $DataArray
556
+	 * @return array
557
+	 */
558
+	private function _GetErrors($DataArray)
559
+	{
560
+		$Errors = array();
561
+		$n = 0;
562
+		while (isset($DataArray['L_ERRORCODE' . $n . ''])) {
563
+			$LErrorCode = isset($DataArray['L_ERRORCODE' . $n . '']) ? $DataArray['L_ERRORCODE' . $n . ''] : '';
564
+			$LShortMessage = isset($DataArray['L_SHORTMESSAGE' . $n . ''])
565
+				? $DataArray['L_SHORTMESSAGE' . $n . '']
566
+				: '';
567
+			$LLongMessage = isset($DataArray['L_LONGMESSAGE' . $n . ''])
568
+				? $DataArray['L_LONGMESSAGE' . $n . '']
569
+				: '';
570
+			$LSeverityCode = isset($DataArray['L_SEVERITYCODE' . $n . ''])
571
+				? $DataArray['L_SEVERITYCODE' . $n . '']
572
+				: '';
573
+			$CurrentItem = array(
574
+				'L_ERRORCODE'    => $LErrorCode,
575
+				'L_SHORTMESSAGE' => $LShortMessage,
576
+				'L_LONGMESSAGE'  => $LLongMessage,
577
+				'L_SEVERITYCODE' => $LSeverityCode,
578
+			);
579
+			array_push($Errors, $CurrentItem);
580
+			$n++;
581
+		}
582
+		return $Errors;
583
+	}
584
+
585
+
586
+
587
+	/**
588
+	 *        nothing to see here...  move along....
589
+	 *
590
+	 * @access protected
591
+	 * @param $Errors
592
+	 * @return string
593
+	 */
594
+	private function _DisplayErrors($Errors)
595
+	{
596
+		$error = '';
597
+		foreach ($Errors as $ErrorVar => $ErrorVal) {
598
+			$CurrentError = $Errors[$ErrorVar];
599
+			foreach ($CurrentError as $CurrentErrorVar => $CurrentErrorVal) {
600
+				$CurrentVarName = '';
601
+				if ($CurrentErrorVar == 'L_ERRORCODE') {
602
+					$CurrentVarName = 'Error Code';
603
+				} elseif ($CurrentErrorVar == 'L_SHORTMESSAGE') {
604
+					$CurrentVarName = 'Short Message';
605
+				} elseif ($CurrentErrorVar == 'L_LONGMESSAGE') {
606
+					$CurrentVarName = 'Long Message';
607
+				} elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
608
+					$CurrentVarName = 'Severity Code';
609
+				}
610
+				$error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
611
+			}
612
+		}
613
+		return $error;
614
+	}
615 615
 }
616 616
 // End of file EEG_Paypal_Pro.gateway.php
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if (! defined('EVENT_ESPRESSO_VERSION')) {
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3 3
     exit('No direct script access allowed');
4 4
 }
5 5
 
@@ -91,13 +91,13 @@  discard block
 block discarded – undo
91 91
     public function do_direct_payment($payment, $billing_info = null)
92 92
     {
93 93
         $transaction = $payment->transaction();
94
-        if (! $transaction instanceof EEI_Transaction) {
94
+        if ( ! $transaction instanceof EEI_Transaction) {
95 95
             throw new EE_Error(
96 96
                 esc_html__('No transaction for payment while paying with PayPal Pro.', 'event_espresso')
97 97
             );
98 98
         }
99 99
         $primary_registrant = $transaction->primary_registration();
100
-        if (! $primary_registrant instanceof EEI_Registration) {
100
+        if ( ! $primary_registrant instanceof EEI_Registration) {
101 101
             throw new EE_Error(
102 102
                 esc_html__(
103 103
                     'No primary registration on transaction while paying with PayPal Pro.',
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
             );
107 107
         }
108 108
         $attendee = $primary_registrant->attendee();
109
-        if (! $attendee instanceof EEI_Attendee) {
109
+        if ( ! $attendee instanceof EEI_Attendee) {
110 110
             throw new EE_Error(
111 111
                 esc_html__(
112 112
                     'No attendee on primary registration while paying with PayPal Pro.',
@@ -203,7 +203,7 @@  discard block
 block discarded – undo
203 203
             // Required.  Credit card number.  No spaces or punctuation.
204 204
             'acct'           => $billing_info['credit_card'],
205 205
             // Required.  Credit card expiration date.  Format is MMYYYY
206
-            'expdate'        => $billing_info['exp_month'] . $billing_info['exp_year'],
206
+            'expdate'        => $billing_info['exp_month'].$billing_info['exp_year'],
207 207
             // Requirements determined by your PayPal account settings.  Security digits for credit card.
208 208
             'cvv2'           => $billing_info['cvv'],
209 209
         );
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
         $ShippingAddress = array(
256 256
             'shiptoname'     => substr($use_registration_address_info
257 257
                 ? $attendee->full_name()
258
-                : $billing_info['first_name'] . ' ' . $billing_info['last_name'], 0, 32),
258
+                : $billing_info['first_name'].' '.$billing_info['last_name'], 0, 32),
259 259
             'shiptostreet'   => substr($use_registration_address_info
260 260
                 ? $attendee->address()
261 261
                 : $billing_info['address'], 0, 100),
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
             'currencycode' => $payment->currency_code(),
285 285
             // Required if you include itemized cart details. (L_AMTn, etc.)
286 286
             //Subtotal of items not including S&H, or tax.
287
-            'itemamt'      => $gateway_formatter->formatCurrency($item_amount),//
287
+            'itemamt'      => $gateway_formatter->formatCurrency($item_amount), //
288 288
             // Total shipping costs for the order.  If you specify shippingamt, you must also specify itemamt.
289 289
             'shippingamt'  => '',
290 290
             // Total handling costs for the order.  If you specify handlingamt, you must also specify itemamt.
@@ -297,10 +297,10 @@  discard block
 block discarded – undo
297 297
             // Free-form field for your own use.  256 char max.
298 298
             'custom'       => $primary_registrant ? $primary_registrant->ID() : '',
299 299
             // Your own invoice or tracking number
300
-            'invnum'       => wp_generate_password(12, false),//$transaction->ID(),
300
+            'invnum'       => wp_generate_password(12, false), //$transaction->ID(),
301 301
             // URL for receiving Instant Payment Notifications.  This overrides what your profile is set to use.
302 302
             'notifyurl'    => '',
303
-            'buttonsource' => 'EventEspresso_SP',//EE will blow up if you change this
303
+            'buttonsource' => 'EventEspresso_SP', //EE will blow up if you change this
304 304
         );
305 305
         // Wrap all data arrays into a single, "master" array which will be passed into the class function.
306 306
         $PayPalRequestData = array(
@@ -410,32 +410,32 @@  discard block
 block discarded – undo
410 410
         // DP Fields
411 411
         $DPFields = isset($DataArray['DPFields']) ? $DataArray['DPFields'] : array();
412 412
         foreach ($DPFields as $DPFieldsVar => $DPFieldsVal) {
413
-            $DPFieldsNVP .= '&' . strtoupper($DPFieldsVar) . '=' . urlencode($DPFieldsVal);
413
+            $DPFieldsNVP .= '&'.strtoupper($DPFieldsVar).'='.urlencode($DPFieldsVal);
414 414
         }
415 415
         // CC Details Fields
416 416
         $CCDetails = isset($DataArray['CCDetails']) ? $DataArray['CCDetails'] : array();
417 417
         foreach ($CCDetails as $CCDetailsVar => $CCDetailsVal) {
418
-            $CCDetailsNVP .= '&' . strtoupper($CCDetailsVar) . '=' . urlencode($CCDetailsVal);
418
+            $CCDetailsNVP .= '&'.strtoupper($CCDetailsVar).'='.urlencode($CCDetailsVal);
419 419
         }
420 420
         // PayerInfo Type Fields
421 421
         $PayerInfo = isset($DataArray['PayerInfo']) ? $DataArray['PayerInfo'] : array();
422 422
         foreach ($PayerInfo as $PayerInfoVar => $PayerInfoVal) {
423
-            $PayerInfoNVP .= '&' . strtoupper($PayerInfoVar) . '=' . urlencode($PayerInfoVal);
423
+            $PayerInfoNVP .= '&'.strtoupper($PayerInfoVar).'='.urlencode($PayerInfoVal);
424 424
         }
425 425
         // Payer Name Fields
426 426
         $PayerName = isset($DataArray['PayerName']) ? $DataArray['PayerName'] : array();
427 427
         foreach ($PayerName as $PayerNameVar => $PayerNameVal) {
428
-            $PayerNameNVP .= '&' . strtoupper($PayerNameVar) . '=' . urlencode($PayerNameVal);
428
+            $PayerNameNVP .= '&'.strtoupper($PayerNameVar).'='.urlencode($PayerNameVal);
429 429
         }
430 430
         // Address Fields (Billing)
431 431
         $BillingAddress = isset($DataArray['BillingAddress']) ? $DataArray['BillingAddress'] : array();
432 432
         foreach ($BillingAddress as $BillingAddressVar => $BillingAddressVal) {
433
-            $BillingAddressNVP .= '&' . strtoupper($BillingAddressVar) . '=' . urlencode($BillingAddressVal);
433
+            $BillingAddressNVP .= '&'.strtoupper($BillingAddressVar).'='.urlencode($BillingAddressVal);
434 434
         }
435 435
         // Payment Details Type Fields
436 436
         $PaymentDetails = isset($DataArray['PaymentDetails']) ? $DataArray['PaymentDetails'] : array();
437 437
         foreach ($PaymentDetails as $PaymentDetailsVar => $PaymentDetailsVal) {
438
-            $PaymentDetailsNVP .= '&' . strtoupper($PaymentDetailsVar) . '=' . urlencode($PaymentDetailsVal);
438
+            $PaymentDetailsNVP .= '&'.strtoupper($PaymentDetailsVar).'='.urlencode($PaymentDetailsVal);
439 439
         }
440 440
         // Payment Details Item Type Fields
441 441
         $OrderItems = isset($DataArray['OrderItems']) ? $DataArray['OrderItems'] : array();
@@ -443,19 +443,19 @@  discard block
 block discarded – undo
443 443
         foreach ($OrderItems as $OrderItemsVar => $OrderItemsVal) {
444 444
             $CurrentItem = $OrderItems[$OrderItemsVar];
445 445
             foreach ($CurrentItem as $CurrentItemVar => $CurrentItemVal) {
446
-                $OrderItemsNVP .= '&' . strtoupper($CurrentItemVar) . $n . '=' . urlencode($CurrentItemVal);
446
+                $OrderItemsNVP .= '&'.strtoupper($CurrentItemVar).$n.'='.urlencode($CurrentItemVal);
447 447
             }
448 448
             $n++;
449 449
         }
450 450
         // Ship To Address Fields
451 451
         $ShippingAddress = isset($DataArray['ShippingAddress']) ? $DataArray['ShippingAddress'] : array();
452 452
         foreach ($ShippingAddress as $ShippingAddressVar => $ShippingAddressVal) {
453
-            $ShippingAddressNVP .= '&' . strtoupper($ShippingAddressVar) . '=' . urlencode($ShippingAddressVal);
453
+            $ShippingAddressNVP .= '&'.strtoupper($ShippingAddressVar).'='.urlencode($ShippingAddressVal);
454 454
         }
455 455
         // 3D Secure Fields
456 456
         $Secure3D = isset($DataArray['Secure3D']) ? $DataArray['Secure3D'] : array();
457 457
         foreach ($Secure3D as $Secure3DVar => $Secure3DVal) {
458
-            $Secure3DNVP .= '&' . strtoupper($Secure3DVar) . '=' . urlencode($Secure3DVal);
458
+            $Secure3DNVP .= '&'.strtoupper($Secure3DVar).'='.urlencode($Secure3DVal);
459 459
         }
460 460
         // Now that we have each chunk we need to go ahead and append them all together for our entire NVP string
461 461
         $NVPRequest = 'USER='
@@ -559,16 +559,16 @@  discard block
 block discarded – undo
559 559
     {
560 560
         $Errors = array();
561 561
         $n = 0;
562
-        while (isset($DataArray['L_ERRORCODE' . $n . ''])) {
563
-            $LErrorCode = isset($DataArray['L_ERRORCODE' . $n . '']) ? $DataArray['L_ERRORCODE' . $n . ''] : '';
564
-            $LShortMessage = isset($DataArray['L_SHORTMESSAGE' . $n . ''])
565
-                ? $DataArray['L_SHORTMESSAGE' . $n . '']
562
+        while (isset($DataArray['L_ERRORCODE'.$n.''])) {
563
+            $LErrorCode = isset($DataArray['L_ERRORCODE'.$n.'']) ? $DataArray['L_ERRORCODE'.$n.''] : '';
564
+            $LShortMessage = isset($DataArray['L_SHORTMESSAGE'.$n.''])
565
+                ? $DataArray['L_SHORTMESSAGE'.$n.'']
566 566
                 : '';
567
-            $LLongMessage = isset($DataArray['L_LONGMESSAGE' . $n . ''])
568
-                ? $DataArray['L_LONGMESSAGE' . $n . '']
567
+            $LLongMessage = isset($DataArray['L_LONGMESSAGE'.$n.''])
568
+                ? $DataArray['L_LONGMESSAGE'.$n.'']
569 569
                 : '';
570
-            $LSeverityCode = isset($DataArray['L_SEVERITYCODE' . $n . ''])
571
-                ? $DataArray['L_SEVERITYCODE' . $n . '']
570
+            $LSeverityCode = isset($DataArray['L_SEVERITYCODE'.$n.''])
571
+                ? $DataArray['L_SEVERITYCODE'.$n.'']
572 572
                 : '';
573 573
             $CurrentItem = array(
574 574
                 'L_ERRORCODE'    => $LErrorCode,
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
                 } elseif ($CurrentErrorVar == 'L_SEVERITYCODE') {
608 608
                     $CurrentVarName = 'Severity Code';
609 609
                 }
610
-                $error .= '<br />' . $CurrentVarName . ': ' . $CurrentErrorVal;
610
+                $error .= '<br />'.$CurrentVarName.': '.$CurrentErrorVal;
611 611
             }
612 612
         }
613 613
         return $error;
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/EEG_Paypal_Express.gateway.php 2 patches
Indentation   +671 added lines, -671 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if (! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('NO direct script access allowed');
2
+	exit('NO direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -16,680 +16,680 @@  discard block
 block discarded – undo
16 16
  */
17 17
 //Quickfix to address https://events.codebasehq.com/projects/event-espresso/tickets/11089 ASAP
18 18
 if (! function_exists('mb_strcut')) {
19
-    /**
20
-     * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
21
-     * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
22
-     * @param $string
23
-     * @param $start
24
-     * @param $length
25
-     * @return bool|string
26
-     */
27
-    function mb_strcut($string, $start, $length = null)
28
-    {
29
-        return mb_substr($string, $start, $length);
30
-    }
19
+	/**
20
+	 * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
21
+	 * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
22
+	 * @param $string
23
+	 * @param $start
24
+	 * @param $length
25
+	 * @return bool|string
26
+	 */
27
+	function mb_strcut($string, $start, $length = null)
28
+	{
29
+		return mb_substr($string, $start, $length);
30
+	}
31 31
 }
32 32
 class EEG_Paypal_Express extends EE_Offsite_Gateway
33 33
 {
34 34
 
35
-    /**
36
-     * Merchant API Username.
37
-     *
38
-     * @var string
39
-     */
40
-    protected $_api_username;
41
-
42
-    /**
43
-     * Merchant API Password.
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_api_password;
48
-
49
-    /**
50
-     * API Signature.
51
-     *
52
-     * @var string
53
-     */
54
-    protected $_api_signature;
55
-
56
-    /**
57
-     * Request Shipping address on PP checkout page.
58
-     *
59
-     * @var string
60
-     */
61
-    protected $_request_shipping_addr;
62
-
63
-    /**
64
-     * Business/personal logo.
65
-     *
66
-     * @var string
67
-     */
68
-    protected $_image_url;
69
-
70
-    /**
71
-     * gateway URL variable
72
-     *
73
-     * @var string
74
-     */
75
-    protected $_base_gateway_url = '';
76
-
77
-
78
-
79
-    /**
80
-     * EEG_Paypal_Express constructor.
81
-     */
82
-    public function __construct()
83
-    {
84
-        $this->_currencies_supported = array(
85
-            'USD',
86
-            'AUD',
87
-            'BRL',
88
-            'CAD',
89
-            'CZK',
90
-            'DKK',
91
-            'EUR',
92
-            'HKD',
93
-            'HUF',
94
-            'ILS',
95
-            'JPY',
96
-            'MYR',
97
-            'MXN',
98
-            'NOK',
99
-            'NZD',
100
-            'PHP',
101
-            'PLN',
102
-            'GBP',
103
-            'RUB',
104
-            'SGD',
105
-            'SEK',
106
-            'CHF',
107
-            'TWD',
108
-            'THB',
109
-            'TRY',
110
-        );
111
-        parent::__construct();
112
-    }
113
-
114
-
115
-
116
-    /**
117
-     * Sets the gateway URL variable based on whether debug mode is enabled or not.
118
-     *
119
-     * @param array $settings_array
120
-     */
121
-    public function set_settings($settings_array)
122
-    {
123
-        parent::set_settings($settings_array);
124
-        // Redirect URL.
125
-        $this->_base_gateway_url = $this->_debug_mode
126
-            ? 'https://api-3t.sandbox.paypal.com/nvp'
127
-            : 'https://api-3t.paypal.com/nvp';
128
-    }
129
-
130
-
131
-
132
-    /**
133
-     * @param EEI_Payment $payment
134
-     * @param array       $billing_info
135
-     * @param string      $return_url
136
-     * @param string      $notify_url
137
-     * @param string      $cancel_url
138
-     * @return \EE_Payment|\EEI_Payment
139
-     * @throws \EE_Error
140
-     */
141
-    public function set_redirection_info(
142
-        $payment,
143
-        $billing_info = array(),
144
-        $return_url = null,
145
-        $notify_url = null,
146
-        $cancel_url = null
147
-    ) {
148
-        if (! $payment instanceof EEI_Payment) {
149
-            $payment->set_gateway_response(
150
-                esc_html__(
151
-                    'Error. No associated payment was found.',
152
-                    'event_espresso'
153
-                )
154
-            );
155
-            $payment->set_status($this->_pay_model->failed_status());
156
-            return $payment;
157
-        }
158
-        $transaction = $payment->transaction();
159
-        if (! $transaction instanceof EEI_Transaction) {
160
-            $payment->set_gateway_response(
161
-                esc_html__(
162
-                    'Could not process this payment because it has no associated transaction.',
163
-                    'event_espresso'
164
-                )
165
-            );
166
-            $payment->set_status($this->_pay_model->failed_status());
167
-            return $payment;
168
-        }
169
-        $gateway_formatter = $this->_get_gateway_formatter();
170
-        $order_description = mb_strcut($gateway_formatter->formatOrderDescription($payment), 0, 127);
171
-        $primary_registration = $transaction->primary_registration();
172
-        $primary_attendee = $primary_registration instanceof EE_Registration
173
-            ? $primary_registration->attendee()
174
-            : false;
175
-        $locale = explode('-', get_bloginfo('language'));
176
-        // Gather request parameters.
177
-        $token_request_dtls = array(
178
-            'METHOD'                         => 'SetExpressCheckout',
179
-            'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
180
-            'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
181
-            'PAYMENTREQUEST_0_DESC'          => $order_description,
182
-            'RETURNURL'                      => $return_url,
183
-            'CANCELURL'                      => $cancel_url,
184
-            'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
185
-            // Buyer does not need to create a PayPal account to check out.
186
-            // This is referred to as PayPal Account Optional.
187
-            'SOLUTIONTYPE'                   => 'Sole',
188
-            //EE will blow up if you change this
189
-            'BUTTONSOURCE'                   => 'EventEspresso_SP',
190
-            // Locale of the pages displayed by PayPal during Express Checkout.
191
-            'LOCALECODE'                     => $locale[1]
192
-        );
193
-        // Show itemized list.
194
-        $itemized_list = $this->itemize_list($payment, $transaction);
195
-        $token_request_dtls = array_merge($token_request_dtls, $itemized_list);
196
-        // Automatically filling out shipping and contact information.
197
-        if ($this->_request_shipping_addr && $primary_attendee instanceof EEI_Attendee) {
198
-            // If you do not pass the shipping address, PayPal obtains it from the buyer's account profile.
199
-            $token_request_dtls['NOSHIPPING'] = '2';
200
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET'] = $primary_attendee->address();
201
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $primary_attendee->address2();
202
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOCITY'] = $primary_attendee->city();
203
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTATE'] = $primary_attendee->state_abbrev();
204
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $primary_attendee->country_ID();
205
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOZIP'] = $primary_attendee->zip();
206
-            $token_request_dtls['PAYMENTREQUEST_0_EMAIL'] = $primary_attendee->email();
207
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $primary_attendee->phone();
208
-        } elseif (! $this->_request_shipping_addr) {
209
-            // Do not request shipping details on the PP Checkout page.
210
-            $token_request_dtls['NOSHIPPING'] = '1';
211
-            $token_request_dtls['REQCONFIRMSHIPPING'] = '0';
212
-        }
213
-        // Used a business/personal logo on the PayPal page.
214
-        if (! empty($this->_image_url)) {
215
-            $token_request_dtls['LOGOIMG'] = $this->_image_url;
216
-        }
217
-        $token_request_dtls = apply_filters(
218
-            'FHEE__EEG_Paypal_Express__set_redirection_info__arguments',
219
-            $token_request_dtls,
220
-            $this
221
-        );
222
-        // Request PayPal token.
223
-        $token_request_response = $this->_ppExpress_request($token_request_dtls, 'Payment Token', $payment);
224
-        $token_rstatus = $this->_ppExpress_check_response($token_request_response);
225
-        $response_args = (isset($token_rstatus['args']) && is_array($token_rstatus['args']))
226
-            ? $token_rstatus['args']
227
-            : array();
228
-        if ($token_rstatus['status']) {
229
-            // We got the Token so we may continue with the payment and redirect the client.
230
-            $payment->set_details($response_args);
231
-            $gateway_url = $this->_debug_mode ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com';
232
-            $payment->set_redirect_url(
233
-                $gateway_url
234
-                . '/checkoutnow?useraction=commit&cmd=_express-checkout&token='
235
-                . $response_args['TOKEN']
236
-            );
237
-        } else {
238
-            if (isset($response_args['L_ERRORCODE'])) {
239
-                $payment->set_gateway_response($response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']);
240
-            } else {
241
-                $payment->set_gateway_response(
242
-                    esc_html__(
243
-                        'Error occurred while trying to setup the Express Checkout.',
244
-                        'event_espresso'
245
-                    )
246
-                );
247
-            }
248
-            $payment->set_details($response_args);
249
-            $payment->set_status($this->_pay_model->failed_status());
250
-        }
251
-        return $payment;
252
-    }
253
-
254
-
255
-
256
-    /**
257
-     * @param array           $update_info {
258
-     * @type string           $gateway_txn_id
259
-     * @type string status an EEMI_Payment status
260
-     *                                     }
261
-     * @param EEI_Transaction $transaction
262
-     * @return EEI_Payment
263
-     */
264
-    public function handle_payment_update($update_info, $transaction)
265
-    {
266
-        $payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : null;
267
-        if ($payment instanceof EEI_Payment) {
268
-            $this->log(array('Return from Authorization' => $update_info), $payment);
269
-            $transaction = $payment->transaction();
270
-            if (! $transaction instanceof EEI_Transaction) {
271
-                $payment->set_gateway_response(
272
-                    esc_html__(
273
-                        'Could not process this payment because it has no associated transaction.',
274
-                        'event_espresso'
275
-                    )
276
-                );
277
-                $payment->set_status($this->_pay_model->failed_status());
278
-                return $payment;
279
-            }
280
-            $primary_registrant = $transaction->primary_registration();
281
-            $payment_details = $payment->details();
282
-            // Check if we still have the token.
283
-            if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
284
-                $payment->set_status($this->_pay_model->failed_status());
285
-                return $payment;
286
-            }
287
-            $cdetails_request_dtls = array(
288
-                'METHOD' => 'GetExpressCheckoutDetails',
289
-                'TOKEN'  => $payment_details['TOKEN'],
290
-            );
291
-            // Request Customer Details.
292
-            $cdetails_request_response = $this->_ppExpress_request(
293
-                $cdetails_request_dtls,
294
-                'Customer Details',
295
-                $payment
296
-            );
297
-            $cdetails_rstatus = $this->_ppExpress_check_response($cdetails_request_response);
298
-            $cdata_response_args = (isset($cdetails_rstatus['args']) && is_array($cdetails_rstatus['args']))
299
-                ? $cdetails_rstatus['args']
300
-                : array();
301
-            if ($cdetails_rstatus['status']) {
302
-                // We got the PayerID so now we can Complete the transaction.
303
-                $docheckout_request_dtls = array(
304
-                    'METHOD'                         => 'DoExpressCheckoutPayment',
305
-                    'PAYERID'                        => $cdata_response_args['PAYERID'],
306
-                    'TOKEN'                          => $payment_details['TOKEN'],
307
-                    'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
308
-                    'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
309
-                    'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
310
-                    //EE will blow up if you change this
311
-                    'BUTTONSOURCE'                   => 'EventEspresso_SP',
312
-                );
313
-                 // Include itemized list.
314
-                $itemized_list = $this->itemize_list(
315
-                    $payment,
316
-                    $transaction,
317
-                    $cdata_response_args
318
-                );
319
-                $docheckout_request_dtls = array_merge($docheckout_request_dtls, $itemized_list);
320
-                // Payment Checkout/Capture.
321
-                $docheckout_request_response = $this->_ppExpress_request(
322
-                    $docheckout_request_dtls,
323
-                    'Do Payment',
324
-                    $payment
325
-                );
326
-                $docheckout_rstatus = $this->_ppExpress_check_response($docheckout_request_response);
327
-                $docheckout_response_args = (isset($docheckout_rstatus['args']) && is_array($docheckout_rstatus['args']))
328
-                    ? $docheckout_rstatus['args']
329
-                    : array();
330
-                if ($docheckout_rstatus['status']) {
331
-                    // All is well, payment approved.
332
-                    $primary_registration_code = $primary_registrant instanceof EE_Registration ?
333
-                        $primary_registrant->reg_code()
334
-                        : '';
335
-                    $payment->set_extra_accntng($primary_registration_code);
336
-                    $payment->set_amount(isset($docheckout_response_args['PAYMENTINFO_0_AMT'])
337
-                        ? (float)$docheckout_response_args['PAYMENTINFO_0_AMT']
338
-                        : 0);
339
-                    $payment->set_txn_id_chq_nmbr(isset($docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'])
340
-                        ? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID']
341
-                        : null);
342
-                    $payment->set_details($cdata_response_args);
343
-                    $payment->set_gateway_response(isset($docheckout_response_args['PAYMENTINFO_0_ACK'])
344
-                        ? $docheckout_response_args['PAYMENTINFO_0_ACK']
345
-                        : '');
346
-                    $payment->set_status($this->_pay_model->approved_status());
347
-                } else {
348
-                    if (isset($docheckout_response_args['L_ERRORCODE'])) {
349
-                        $payment->set_gateway_response(
350
-                            $docheckout_response_args['L_ERRORCODE']
351
-                            . '; '
352
-                            . $docheckout_response_args['L_SHORTMESSAGE']
353
-                        );
354
-                    } else {
355
-                        $payment->set_gateway_response(
356
-                            esc_html__(
357
-                                'Error occurred while trying to Capture the funds.',
358
-                                'event_espresso'
359
-                            )
360
-                        );
361
-                    }
362
-                    $payment->set_details($docheckout_response_args);
363
-                    $payment->set_status($this->_pay_model->declined_status());
364
-                }
365
-            } else {
366
-                if (isset($cdata_response_args['L_ERRORCODE'])) {
367
-                    $payment->set_gateway_response(
368
-                        $cdata_response_args['L_ERRORCODE']
369
-                        . '; '
370
-                        . $cdata_response_args['L_SHORTMESSAGE']
371
-                    );
372
-                } else {
373
-                    $payment->set_gateway_response(
374
-                        esc_html__(
375
-                            'Error occurred while trying to get payment Details from PayPal.',
376
-                            'event_espresso'
377
-                        )
378
-                    );
379
-                }
380
-                $payment->set_details($cdata_response_args);
381
-                $payment->set_status($this->_pay_model->failed_status());
382
-            }
383
-        } else {
384
-            $payment->set_gateway_response(
385
-                esc_html__(
386
-                    'Error occurred while trying to process the payment.',
387
-                    'event_espresso'
388
-                )
389
-            );
390
-            $payment->set_status($this->_pay_model->failed_status());
391
-        }
392
-        return $payment;
393
-    }
394
-
395
-
396
-
397
-    /**
398
-     *  Make a list of items that are in the giver transaction.
399
-     *
400
-     * @param EEI_Payment     $payment
401
-     * @param EEI_Transaction $transaction
402
-     * @param array           $request_response_args Data from a previous communication with PP.
403
-     * @return array
404
-     */
405
-    public function itemize_list(EEI_Payment $payment, EEI_Transaction $transaction, $request_response_args = array())
406
-    {
407
-        $itemized_list = array();
408
-        $gateway_formatter = $this->_get_gateway_formatter();
409
-        // If we have data from a previous communication with PP (on this transaction) we may use that for our list...
410
-        if (
411
-            ! empty($request_response_args)
412
-            && array_key_exists('L_PAYMENTREQUEST_0_AMT0', $request_response_args)
413
-            && array_key_exists('PAYMENTREQUEST_0_ITEMAMT', $request_response_args)
414
-        ) {
415
-            foreach ($request_response_args as $arg_key => $arg_val) {
416
-                if (
417
-                    strpos($arg_key, 'PAYMENTREQUEST_') !== false
418
-                    && strpos($arg_key, 'NOTIFYURL') === false
419
-                ) {
420
-                    $itemized_list[$arg_key] = $arg_val;
421
-                }
422
-            }
423
-            // If we got only a few Items then something is not right.
424
-            if (count($itemized_list) > 2) {
425
-                return $itemized_list;
426
-            } else {
427
-                if (WP_DEBUG) {
428
-                    throw new EE_Error(
429
-                        sprintf(
430
-                            esc_html__(
431
-                                // @codingStandardsIgnoreStart
432
-                                'Unable to continue with the checkout because a proper purchase list could not be generated. The purchased list we could have sent was %1$s',
433
-                                // @codingStandardsIgnoreEnd
434
-                                'event_espresso'
435
-                            ),
436
-                            wp_json_encode($itemized_list)
437
-                        )
438
-                    );
439
-                }
440
-                // Reset the list and log an error, maybe allow to try and generate a new list (below).
441
-                $itemized_list = array();
442
-                $this->log(
443
-                    array(
444
-                        esc_html__(
445
-                            'Could not generate a proper item list with:',
446
-                            'event_espresso'
447
-                        ) => $request_response_args
448
-                    ),
449
-                    $payment
450
-                );
451
-            }
452
-        }
453
-        // ...otherwise we generate a new list for this transaction.
454
-        if ($this->_money->compare_floats($payment->amount(), $transaction->total(), '==')) {
455
-            $item_num = 0;
456
-            $itemized_sum = 0;
457
-            $total_line_items = $transaction->total_line_item();
458
-            // Go through each item in the list.
459
-            foreach ($total_line_items->get_items() as $line_item) {
460
-                if ($line_item instanceof EE_Line_Item) {
461
-                    // PayPal doesn't like line items with 0.00 amount, so we may skip those.
462
-                    if (EEH_Money::compare_floats($line_item->total(), '0.00', '==')) {
463
-                        continue;
464
-                    }
465
-                    $unit_price = $line_item->unit_price();
466
-                    $line_item_quantity = $line_item->quantity();
467
-                    // This is a discount.
468
-                    if ($line_item->is_percent()) {
469
-                        $unit_price = $line_item->total();
470
-                        $line_item_quantity = 1;
471
-                    }
472
-                    // Item Name.
473
-                    $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
474
-                        $gateway_formatter->formatLineItemName($line_item, $payment),
475
-                        0,
476
-                        127
477
-                    );
478
-                    // Item description.
479
-                    $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = mb_strcut(
480
-                        $gateway_formatter->formatLineItemDesc($line_item, $payment),
481
-                        0,
482
-                        127
483
-                    );
484
-                    // Cost of individual item.
485
-                    $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $gateway_formatter->formatCurrency($unit_price);
486
-                    // Item Number.
487
-                    $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
488
-                    // Item quantity.
489
-                    $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = $line_item_quantity;
490
-                    // Digital item is sold.
491
-                    $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
492
-                    $itemized_sum += $line_item->total();
493
-                    ++$item_num;
494
-                }
495
-            }
496
-            // Item's sales S/H and tax amount.
497
-            $itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $total_line_items->get_items_total();
498
-            $itemized_list['PAYMENTREQUEST_0_TAXAMT'] = $total_line_items->get_total_tax();
499
-            $itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
500
-            $itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
501
-            $itemized_sum_diff_from_txn_total = round(
502
-                $transaction->total() - $itemized_sum - $total_line_items->get_total_tax(),
503
-                2
504
-            );
505
-            // If we were not able to recognize some item like promotion, surcharge or cancellation,
506
-            // add the difference as an extra line item.
507
-            if ($this->_money->compare_floats($itemized_sum_diff_from_txn_total, 0, '!=')) {
508
-                // Item Name.
509
-                $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
510
-                    esc_html__(
511
-                        'Other (promotion/surcharge/cancellation)',
512
-                        'event_espresso'
513
-                    ),
514
-                    0,
515
-                    127
516
-                );
517
-                // Item description.
518
-                $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = '';
519
-                // Cost of individual item.
520
-                $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $gateway_formatter->formatCurrency(
521
-                    $itemized_sum_diff_from_txn_total
522
-                );
523
-                // Item Number.
524
-                $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
525
-                // Item quantity.
526
-                $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = 1;
527
-                // Digital item is sold.
528
-                $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
529
-                $item_num++;
530
-            }
531
-        } else {
532
-            // Just one Item.
533
-            // Item Name.
534
-            $itemized_list['L_PAYMENTREQUEST_0_NAME0'] = mb_strcut(
535
-                $gateway_formatter->formatPartialPaymentLineItemName($payment),
536
-                0,
537
-                127
538
-            );
539
-            // Item description.
540
-            $itemized_list['L_PAYMENTREQUEST_0_DESC0'] = mb_strcut(
541
-                $gateway_formatter->formatPartialPaymentLineItemDesc($payment),
542
-                0,
543
-                127
544
-            );
545
-            // Cost of individual item.
546
-            $itemized_list['L_PAYMENTREQUEST_0_AMT0'] = $gateway_formatter->formatCurrency($payment->amount());
547
-            // Item Number.
548
-            $itemized_list['L_PAYMENTREQUEST_0_NUMBER0'] = 1;
549
-            // Item quantity.
550
-            $itemized_list['L_PAYMENTREQUEST_0_QTY0'] = 1;
551
-            // Digital item is sold.
552
-            $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical';
553
-            // Item's sales S/H and tax amount.
554
-            $itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $gateway_formatter->formatCurrency($payment->amount());
555
-            $itemized_list['PAYMENTREQUEST_0_TAXAMT'] = '0';
556
-            $itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
557
-            $itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
558
-        }
559
-        return $itemized_list;
560
-    }
561
-
562
-
563
-
564
-    /**
565
-     *  Make the Express checkout request.
566
-     *
567
-     * @param array       $request_params
568
-     * @param string      $request_text
569
-     * @param EEI_Payment $payment
570
-     * @return mixed
571
-     */
572
-    public function _ppExpress_request($request_params, $request_text, $payment)
573
-    {
574
-        $request_dtls = array(
575
-            'VERSION'   => '204.0',
576
-            'USER'      => urlencode($this->_api_username),
577
-            'PWD'       => urlencode($this->_api_password),
578
-            'SIGNATURE' => urlencode($this->_api_signature),
579
-        );
580
-        $dtls = array_merge($request_dtls, $request_params);
581
-        $this->_log_clean_request($dtls, $payment, $request_text . ' Request');
582
-        // Request Customer Details.
583
-        $request_response = wp_remote_post(
584
-            $this->_base_gateway_url,
585
-            array(
586
-                'method'      => 'POST',
587
-                'timeout'     => 45,
588
-                'httpversion' => '1.1',
589
-                'cookies'     => array(),
590
-                'headers'     => array(),
591
-                'body'        => http_build_query($dtls),
592
-            )
593
-        );
594
-        // Log the response.
595
-        $this->log(array($request_text . ' Response' => $request_response), $payment);
596
-        return $request_response;
597
-    }
598
-
599
-
600
-
601
-    /**
602
-     *  Check the response status.
603
-     *
604
-     * @param mixed $request_response
605
-     * @return array
606
-     */
607
-    public function _ppExpress_check_response($request_response)
608
-    {
609
-        if (is_wp_error($request_response) || empty($request_response['body'])) {
610
-            // If we got here then there was an error in this request.
611
-            return array('status' => false, 'args' => $request_response);
612
-        }
613
-        $response_args = array();
614
-        parse_str(urldecode($request_response['body']), $response_args);
615
-        if (! isset($response_args['ACK'])) {
616
-            return array('status' => false, 'args' => $request_response);
617
-        }
618
-        if (
619
-            (
620
-                isset($response_args['PAYERID'])
621
-                || isset($response_args['TOKEN'])
622
-                || isset($response_args['PAYMENTINFO_0_TRANSACTIONID'])
623
-                || (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed')
624
-            )
625
-            && in_array($response_args['ACK'], array('Success', 'SuccessWithWarning'), true)
626
-        ) {
627
-            // Response status OK, return response parameters for further processing.
628
-            return array('status' => true, 'args' => $response_args);
629
-        }
630
-        $errors = $this->_get_errors($response_args);
631
-        return array('status' => false, 'args' => $errors);
632
-    }
633
-
634
-
635
-
636
-    /**
637
-     *  Log a "Cleared" request.
638
-     *
639
-     * @param array       $request
640
-     * @param EEI_Payment $payment
641
-     * @param string      $info
642
-     * @return void
643
-     */
644
-    private function _log_clean_request($request, $payment, $info)
645
-    {
646
-        $cleaned_request_data = $request;
647
-        unset($cleaned_request_data['PWD'], $cleaned_request_data['USER'], $cleaned_request_data['SIGNATURE']);
648
-        $this->log(array($info => $cleaned_request_data), $payment);
649
-    }
650
-
651
-
652
-
653
-    /**
654
-     *  Get error from the response data.
655
-     *
656
-     * @param array $data_array
657
-     * @return array
658
-     */
659
-    private function _get_errors($data_array)
660
-    {
661
-        $errors = array();
662
-        $n = 0;
663
-        while (isset($data_array["L_ERRORCODE{$n}"])) {
664
-            $l_error_code = isset($data_array["L_ERRORCODE{$n}"])
665
-                ? $data_array["L_ERRORCODE{$n}"]
666
-                : '';
667
-            $l_severity_code = isset($data_array["L_SEVERITYCODE{$n}"])
668
-                ? $data_array["L_SEVERITYCODE{$n}"]
669
-                : '';
670
-            $l_short_message = isset($data_array["L_SHORTMESSAGE{$n}"])
671
-                ? $data_array["L_SHORTMESSAGE{$n}"]
672
-                : '';
673
-            $l_long_message = isset($data_array["L_LONGMESSAGE{$n}"])
674
-                ? $data_array["L_LONGMESSAGE{$n}"]
675
-                : '';
676
-            if ($n === 0) {
677
-                $errors = array(
678
-                    'L_ERRORCODE'    => $l_error_code,
679
-                    'L_SHORTMESSAGE' => $l_short_message,
680
-                    'L_LONGMESSAGE'  => $l_long_message,
681
-                    'L_SEVERITYCODE' => $l_severity_code,
682
-                );
683
-            } else {
684
-                $errors['L_ERRORCODE'] .= ', ' . $l_error_code;
685
-                $errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
686
-                $errors['L_LONGMESSAGE'] .= ', ' . $l_long_message;
687
-                $errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
688
-            }
689
-            $n++;
690
-        }
691
-        return $errors;
692
-    }
35
+	/**
36
+	 * Merchant API Username.
37
+	 *
38
+	 * @var string
39
+	 */
40
+	protected $_api_username;
41
+
42
+	/**
43
+	 * Merchant API Password.
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_api_password;
48
+
49
+	/**
50
+	 * API Signature.
51
+	 *
52
+	 * @var string
53
+	 */
54
+	protected $_api_signature;
55
+
56
+	/**
57
+	 * Request Shipping address on PP checkout page.
58
+	 *
59
+	 * @var string
60
+	 */
61
+	protected $_request_shipping_addr;
62
+
63
+	/**
64
+	 * Business/personal logo.
65
+	 *
66
+	 * @var string
67
+	 */
68
+	protected $_image_url;
69
+
70
+	/**
71
+	 * gateway URL variable
72
+	 *
73
+	 * @var string
74
+	 */
75
+	protected $_base_gateway_url = '';
76
+
77
+
78
+
79
+	/**
80
+	 * EEG_Paypal_Express constructor.
81
+	 */
82
+	public function __construct()
83
+	{
84
+		$this->_currencies_supported = array(
85
+			'USD',
86
+			'AUD',
87
+			'BRL',
88
+			'CAD',
89
+			'CZK',
90
+			'DKK',
91
+			'EUR',
92
+			'HKD',
93
+			'HUF',
94
+			'ILS',
95
+			'JPY',
96
+			'MYR',
97
+			'MXN',
98
+			'NOK',
99
+			'NZD',
100
+			'PHP',
101
+			'PLN',
102
+			'GBP',
103
+			'RUB',
104
+			'SGD',
105
+			'SEK',
106
+			'CHF',
107
+			'TWD',
108
+			'THB',
109
+			'TRY',
110
+		);
111
+		parent::__construct();
112
+	}
113
+
114
+
115
+
116
+	/**
117
+	 * Sets the gateway URL variable based on whether debug mode is enabled or not.
118
+	 *
119
+	 * @param array $settings_array
120
+	 */
121
+	public function set_settings($settings_array)
122
+	{
123
+		parent::set_settings($settings_array);
124
+		// Redirect URL.
125
+		$this->_base_gateway_url = $this->_debug_mode
126
+			? 'https://api-3t.sandbox.paypal.com/nvp'
127
+			: 'https://api-3t.paypal.com/nvp';
128
+	}
129
+
130
+
131
+
132
+	/**
133
+	 * @param EEI_Payment $payment
134
+	 * @param array       $billing_info
135
+	 * @param string      $return_url
136
+	 * @param string      $notify_url
137
+	 * @param string      $cancel_url
138
+	 * @return \EE_Payment|\EEI_Payment
139
+	 * @throws \EE_Error
140
+	 */
141
+	public function set_redirection_info(
142
+		$payment,
143
+		$billing_info = array(),
144
+		$return_url = null,
145
+		$notify_url = null,
146
+		$cancel_url = null
147
+	) {
148
+		if (! $payment instanceof EEI_Payment) {
149
+			$payment->set_gateway_response(
150
+				esc_html__(
151
+					'Error. No associated payment was found.',
152
+					'event_espresso'
153
+				)
154
+			);
155
+			$payment->set_status($this->_pay_model->failed_status());
156
+			return $payment;
157
+		}
158
+		$transaction = $payment->transaction();
159
+		if (! $transaction instanceof EEI_Transaction) {
160
+			$payment->set_gateway_response(
161
+				esc_html__(
162
+					'Could not process this payment because it has no associated transaction.',
163
+					'event_espresso'
164
+				)
165
+			);
166
+			$payment->set_status($this->_pay_model->failed_status());
167
+			return $payment;
168
+		}
169
+		$gateway_formatter = $this->_get_gateway_formatter();
170
+		$order_description = mb_strcut($gateway_formatter->formatOrderDescription($payment), 0, 127);
171
+		$primary_registration = $transaction->primary_registration();
172
+		$primary_attendee = $primary_registration instanceof EE_Registration
173
+			? $primary_registration->attendee()
174
+			: false;
175
+		$locale = explode('-', get_bloginfo('language'));
176
+		// Gather request parameters.
177
+		$token_request_dtls = array(
178
+			'METHOD'                         => 'SetExpressCheckout',
179
+			'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
180
+			'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
181
+			'PAYMENTREQUEST_0_DESC'          => $order_description,
182
+			'RETURNURL'                      => $return_url,
183
+			'CANCELURL'                      => $cancel_url,
184
+			'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
185
+			// Buyer does not need to create a PayPal account to check out.
186
+			// This is referred to as PayPal Account Optional.
187
+			'SOLUTIONTYPE'                   => 'Sole',
188
+			//EE will blow up if you change this
189
+			'BUTTONSOURCE'                   => 'EventEspresso_SP',
190
+			// Locale of the pages displayed by PayPal during Express Checkout.
191
+			'LOCALECODE'                     => $locale[1]
192
+		);
193
+		// Show itemized list.
194
+		$itemized_list = $this->itemize_list($payment, $transaction);
195
+		$token_request_dtls = array_merge($token_request_dtls, $itemized_list);
196
+		// Automatically filling out shipping and contact information.
197
+		if ($this->_request_shipping_addr && $primary_attendee instanceof EEI_Attendee) {
198
+			// If you do not pass the shipping address, PayPal obtains it from the buyer's account profile.
199
+			$token_request_dtls['NOSHIPPING'] = '2';
200
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET'] = $primary_attendee->address();
201
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $primary_attendee->address2();
202
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOCITY'] = $primary_attendee->city();
203
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTATE'] = $primary_attendee->state_abbrev();
204
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $primary_attendee->country_ID();
205
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOZIP'] = $primary_attendee->zip();
206
+			$token_request_dtls['PAYMENTREQUEST_0_EMAIL'] = $primary_attendee->email();
207
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $primary_attendee->phone();
208
+		} elseif (! $this->_request_shipping_addr) {
209
+			// Do not request shipping details on the PP Checkout page.
210
+			$token_request_dtls['NOSHIPPING'] = '1';
211
+			$token_request_dtls['REQCONFIRMSHIPPING'] = '0';
212
+		}
213
+		// Used a business/personal logo on the PayPal page.
214
+		if (! empty($this->_image_url)) {
215
+			$token_request_dtls['LOGOIMG'] = $this->_image_url;
216
+		}
217
+		$token_request_dtls = apply_filters(
218
+			'FHEE__EEG_Paypal_Express__set_redirection_info__arguments',
219
+			$token_request_dtls,
220
+			$this
221
+		);
222
+		// Request PayPal token.
223
+		$token_request_response = $this->_ppExpress_request($token_request_dtls, 'Payment Token', $payment);
224
+		$token_rstatus = $this->_ppExpress_check_response($token_request_response);
225
+		$response_args = (isset($token_rstatus['args']) && is_array($token_rstatus['args']))
226
+			? $token_rstatus['args']
227
+			: array();
228
+		if ($token_rstatus['status']) {
229
+			// We got the Token so we may continue with the payment and redirect the client.
230
+			$payment->set_details($response_args);
231
+			$gateway_url = $this->_debug_mode ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com';
232
+			$payment->set_redirect_url(
233
+				$gateway_url
234
+				. '/checkoutnow?useraction=commit&cmd=_express-checkout&token='
235
+				. $response_args['TOKEN']
236
+			);
237
+		} else {
238
+			if (isset($response_args['L_ERRORCODE'])) {
239
+				$payment->set_gateway_response($response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']);
240
+			} else {
241
+				$payment->set_gateway_response(
242
+					esc_html__(
243
+						'Error occurred while trying to setup the Express Checkout.',
244
+						'event_espresso'
245
+					)
246
+				);
247
+			}
248
+			$payment->set_details($response_args);
249
+			$payment->set_status($this->_pay_model->failed_status());
250
+		}
251
+		return $payment;
252
+	}
253
+
254
+
255
+
256
+	/**
257
+	 * @param array           $update_info {
258
+	 * @type string           $gateway_txn_id
259
+	 * @type string status an EEMI_Payment status
260
+	 *                                     }
261
+	 * @param EEI_Transaction $transaction
262
+	 * @return EEI_Payment
263
+	 */
264
+	public function handle_payment_update($update_info, $transaction)
265
+	{
266
+		$payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : null;
267
+		if ($payment instanceof EEI_Payment) {
268
+			$this->log(array('Return from Authorization' => $update_info), $payment);
269
+			$transaction = $payment->transaction();
270
+			if (! $transaction instanceof EEI_Transaction) {
271
+				$payment->set_gateway_response(
272
+					esc_html__(
273
+						'Could not process this payment because it has no associated transaction.',
274
+						'event_espresso'
275
+					)
276
+				);
277
+				$payment->set_status($this->_pay_model->failed_status());
278
+				return $payment;
279
+			}
280
+			$primary_registrant = $transaction->primary_registration();
281
+			$payment_details = $payment->details();
282
+			// Check if we still have the token.
283
+			if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
284
+				$payment->set_status($this->_pay_model->failed_status());
285
+				return $payment;
286
+			}
287
+			$cdetails_request_dtls = array(
288
+				'METHOD' => 'GetExpressCheckoutDetails',
289
+				'TOKEN'  => $payment_details['TOKEN'],
290
+			);
291
+			// Request Customer Details.
292
+			$cdetails_request_response = $this->_ppExpress_request(
293
+				$cdetails_request_dtls,
294
+				'Customer Details',
295
+				$payment
296
+			);
297
+			$cdetails_rstatus = $this->_ppExpress_check_response($cdetails_request_response);
298
+			$cdata_response_args = (isset($cdetails_rstatus['args']) && is_array($cdetails_rstatus['args']))
299
+				? $cdetails_rstatus['args']
300
+				: array();
301
+			if ($cdetails_rstatus['status']) {
302
+				// We got the PayerID so now we can Complete the transaction.
303
+				$docheckout_request_dtls = array(
304
+					'METHOD'                         => 'DoExpressCheckoutPayment',
305
+					'PAYERID'                        => $cdata_response_args['PAYERID'],
306
+					'TOKEN'                          => $payment_details['TOKEN'],
307
+					'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
308
+					'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
309
+					'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
310
+					//EE will blow up if you change this
311
+					'BUTTONSOURCE'                   => 'EventEspresso_SP',
312
+				);
313
+				 // Include itemized list.
314
+				$itemized_list = $this->itemize_list(
315
+					$payment,
316
+					$transaction,
317
+					$cdata_response_args
318
+				);
319
+				$docheckout_request_dtls = array_merge($docheckout_request_dtls, $itemized_list);
320
+				// Payment Checkout/Capture.
321
+				$docheckout_request_response = $this->_ppExpress_request(
322
+					$docheckout_request_dtls,
323
+					'Do Payment',
324
+					$payment
325
+				);
326
+				$docheckout_rstatus = $this->_ppExpress_check_response($docheckout_request_response);
327
+				$docheckout_response_args = (isset($docheckout_rstatus['args']) && is_array($docheckout_rstatus['args']))
328
+					? $docheckout_rstatus['args']
329
+					: array();
330
+				if ($docheckout_rstatus['status']) {
331
+					// All is well, payment approved.
332
+					$primary_registration_code = $primary_registrant instanceof EE_Registration ?
333
+						$primary_registrant->reg_code()
334
+						: '';
335
+					$payment->set_extra_accntng($primary_registration_code);
336
+					$payment->set_amount(isset($docheckout_response_args['PAYMENTINFO_0_AMT'])
337
+						? (float)$docheckout_response_args['PAYMENTINFO_0_AMT']
338
+						: 0);
339
+					$payment->set_txn_id_chq_nmbr(isset($docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'])
340
+						? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID']
341
+						: null);
342
+					$payment->set_details($cdata_response_args);
343
+					$payment->set_gateway_response(isset($docheckout_response_args['PAYMENTINFO_0_ACK'])
344
+						? $docheckout_response_args['PAYMENTINFO_0_ACK']
345
+						: '');
346
+					$payment->set_status($this->_pay_model->approved_status());
347
+				} else {
348
+					if (isset($docheckout_response_args['L_ERRORCODE'])) {
349
+						$payment->set_gateway_response(
350
+							$docheckout_response_args['L_ERRORCODE']
351
+							. '; '
352
+							. $docheckout_response_args['L_SHORTMESSAGE']
353
+						);
354
+					} else {
355
+						$payment->set_gateway_response(
356
+							esc_html__(
357
+								'Error occurred while trying to Capture the funds.',
358
+								'event_espresso'
359
+							)
360
+						);
361
+					}
362
+					$payment->set_details($docheckout_response_args);
363
+					$payment->set_status($this->_pay_model->declined_status());
364
+				}
365
+			} else {
366
+				if (isset($cdata_response_args['L_ERRORCODE'])) {
367
+					$payment->set_gateway_response(
368
+						$cdata_response_args['L_ERRORCODE']
369
+						. '; '
370
+						. $cdata_response_args['L_SHORTMESSAGE']
371
+					);
372
+				} else {
373
+					$payment->set_gateway_response(
374
+						esc_html__(
375
+							'Error occurred while trying to get payment Details from PayPal.',
376
+							'event_espresso'
377
+						)
378
+					);
379
+				}
380
+				$payment->set_details($cdata_response_args);
381
+				$payment->set_status($this->_pay_model->failed_status());
382
+			}
383
+		} else {
384
+			$payment->set_gateway_response(
385
+				esc_html__(
386
+					'Error occurred while trying to process the payment.',
387
+					'event_espresso'
388
+				)
389
+			);
390
+			$payment->set_status($this->_pay_model->failed_status());
391
+		}
392
+		return $payment;
393
+	}
394
+
395
+
396
+
397
+	/**
398
+	 *  Make a list of items that are in the giver transaction.
399
+	 *
400
+	 * @param EEI_Payment     $payment
401
+	 * @param EEI_Transaction $transaction
402
+	 * @param array           $request_response_args Data from a previous communication with PP.
403
+	 * @return array
404
+	 */
405
+	public function itemize_list(EEI_Payment $payment, EEI_Transaction $transaction, $request_response_args = array())
406
+	{
407
+		$itemized_list = array();
408
+		$gateway_formatter = $this->_get_gateway_formatter();
409
+		// If we have data from a previous communication with PP (on this transaction) we may use that for our list...
410
+		if (
411
+			! empty($request_response_args)
412
+			&& array_key_exists('L_PAYMENTREQUEST_0_AMT0', $request_response_args)
413
+			&& array_key_exists('PAYMENTREQUEST_0_ITEMAMT', $request_response_args)
414
+		) {
415
+			foreach ($request_response_args as $arg_key => $arg_val) {
416
+				if (
417
+					strpos($arg_key, 'PAYMENTREQUEST_') !== false
418
+					&& strpos($arg_key, 'NOTIFYURL') === false
419
+				) {
420
+					$itemized_list[$arg_key] = $arg_val;
421
+				}
422
+			}
423
+			// If we got only a few Items then something is not right.
424
+			if (count($itemized_list) > 2) {
425
+				return $itemized_list;
426
+			} else {
427
+				if (WP_DEBUG) {
428
+					throw new EE_Error(
429
+						sprintf(
430
+							esc_html__(
431
+								// @codingStandardsIgnoreStart
432
+								'Unable to continue with the checkout because a proper purchase list could not be generated. The purchased list we could have sent was %1$s',
433
+								// @codingStandardsIgnoreEnd
434
+								'event_espresso'
435
+							),
436
+							wp_json_encode($itemized_list)
437
+						)
438
+					);
439
+				}
440
+				// Reset the list and log an error, maybe allow to try and generate a new list (below).
441
+				$itemized_list = array();
442
+				$this->log(
443
+					array(
444
+						esc_html__(
445
+							'Could not generate a proper item list with:',
446
+							'event_espresso'
447
+						) => $request_response_args
448
+					),
449
+					$payment
450
+				);
451
+			}
452
+		}
453
+		// ...otherwise we generate a new list for this transaction.
454
+		if ($this->_money->compare_floats($payment->amount(), $transaction->total(), '==')) {
455
+			$item_num = 0;
456
+			$itemized_sum = 0;
457
+			$total_line_items = $transaction->total_line_item();
458
+			// Go through each item in the list.
459
+			foreach ($total_line_items->get_items() as $line_item) {
460
+				if ($line_item instanceof EE_Line_Item) {
461
+					// PayPal doesn't like line items with 0.00 amount, so we may skip those.
462
+					if (EEH_Money::compare_floats($line_item->total(), '0.00', '==')) {
463
+						continue;
464
+					}
465
+					$unit_price = $line_item->unit_price();
466
+					$line_item_quantity = $line_item->quantity();
467
+					// This is a discount.
468
+					if ($line_item->is_percent()) {
469
+						$unit_price = $line_item->total();
470
+						$line_item_quantity = 1;
471
+					}
472
+					// Item Name.
473
+					$itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
474
+						$gateway_formatter->formatLineItemName($line_item, $payment),
475
+						0,
476
+						127
477
+					);
478
+					// Item description.
479
+					$itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = mb_strcut(
480
+						$gateway_formatter->formatLineItemDesc($line_item, $payment),
481
+						0,
482
+						127
483
+					);
484
+					// Cost of individual item.
485
+					$itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $gateway_formatter->formatCurrency($unit_price);
486
+					// Item Number.
487
+					$itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
488
+					// Item quantity.
489
+					$itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = $line_item_quantity;
490
+					// Digital item is sold.
491
+					$itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
492
+					$itemized_sum += $line_item->total();
493
+					++$item_num;
494
+				}
495
+			}
496
+			// Item's sales S/H and tax amount.
497
+			$itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $total_line_items->get_items_total();
498
+			$itemized_list['PAYMENTREQUEST_0_TAXAMT'] = $total_line_items->get_total_tax();
499
+			$itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
500
+			$itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
501
+			$itemized_sum_diff_from_txn_total = round(
502
+				$transaction->total() - $itemized_sum - $total_line_items->get_total_tax(),
503
+				2
504
+			);
505
+			// If we were not able to recognize some item like promotion, surcharge or cancellation,
506
+			// add the difference as an extra line item.
507
+			if ($this->_money->compare_floats($itemized_sum_diff_from_txn_total, 0, '!=')) {
508
+				// Item Name.
509
+				$itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
510
+					esc_html__(
511
+						'Other (promotion/surcharge/cancellation)',
512
+						'event_espresso'
513
+					),
514
+					0,
515
+					127
516
+				);
517
+				// Item description.
518
+				$itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = '';
519
+				// Cost of individual item.
520
+				$itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $gateway_formatter->formatCurrency(
521
+					$itemized_sum_diff_from_txn_total
522
+				);
523
+				// Item Number.
524
+				$itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
525
+				// Item quantity.
526
+				$itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = 1;
527
+				// Digital item is sold.
528
+				$itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
529
+				$item_num++;
530
+			}
531
+		} else {
532
+			// Just one Item.
533
+			// Item Name.
534
+			$itemized_list['L_PAYMENTREQUEST_0_NAME0'] = mb_strcut(
535
+				$gateway_formatter->formatPartialPaymentLineItemName($payment),
536
+				0,
537
+				127
538
+			);
539
+			// Item description.
540
+			$itemized_list['L_PAYMENTREQUEST_0_DESC0'] = mb_strcut(
541
+				$gateway_formatter->formatPartialPaymentLineItemDesc($payment),
542
+				0,
543
+				127
544
+			);
545
+			// Cost of individual item.
546
+			$itemized_list['L_PAYMENTREQUEST_0_AMT0'] = $gateway_formatter->formatCurrency($payment->amount());
547
+			// Item Number.
548
+			$itemized_list['L_PAYMENTREQUEST_0_NUMBER0'] = 1;
549
+			// Item quantity.
550
+			$itemized_list['L_PAYMENTREQUEST_0_QTY0'] = 1;
551
+			// Digital item is sold.
552
+			$itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical';
553
+			// Item's sales S/H and tax amount.
554
+			$itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $gateway_formatter->formatCurrency($payment->amount());
555
+			$itemized_list['PAYMENTREQUEST_0_TAXAMT'] = '0';
556
+			$itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
557
+			$itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
558
+		}
559
+		return $itemized_list;
560
+	}
561
+
562
+
563
+
564
+	/**
565
+	 *  Make the Express checkout request.
566
+	 *
567
+	 * @param array       $request_params
568
+	 * @param string      $request_text
569
+	 * @param EEI_Payment $payment
570
+	 * @return mixed
571
+	 */
572
+	public function _ppExpress_request($request_params, $request_text, $payment)
573
+	{
574
+		$request_dtls = array(
575
+			'VERSION'   => '204.0',
576
+			'USER'      => urlencode($this->_api_username),
577
+			'PWD'       => urlencode($this->_api_password),
578
+			'SIGNATURE' => urlencode($this->_api_signature),
579
+		);
580
+		$dtls = array_merge($request_dtls, $request_params);
581
+		$this->_log_clean_request($dtls, $payment, $request_text . ' Request');
582
+		// Request Customer Details.
583
+		$request_response = wp_remote_post(
584
+			$this->_base_gateway_url,
585
+			array(
586
+				'method'      => 'POST',
587
+				'timeout'     => 45,
588
+				'httpversion' => '1.1',
589
+				'cookies'     => array(),
590
+				'headers'     => array(),
591
+				'body'        => http_build_query($dtls),
592
+			)
593
+		);
594
+		// Log the response.
595
+		$this->log(array($request_text . ' Response' => $request_response), $payment);
596
+		return $request_response;
597
+	}
598
+
599
+
600
+
601
+	/**
602
+	 *  Check the response status.
603
+	 *
604
+	 * @param mixed $request_response
605
+	 * @return array
606
+	 */
607
+	public function _ppExpress_check_response($request_response)
608
+	{
609
+		if (is_wp_error($request_response) || empty($request_response['body'])) {
610
+			// If we got here then there was an error in this request.
611
+			return array('status' => false, 'args' => $request_response);
612
+		}
613
+		$response_args = array();
614
+		parse_str(urldecode($request_response['body']), $response_args);
615
+		if (! isset($response_args['ACK'])) {
616
+			return array('status' => false, 'args' => $request_response);
617
+		}
618
+		if (
619
+			(
620
+				isset($response_args['PAYERID'])
621
+				|| isset($response_args['TOKEN'])
622
+				|| isset($response_args['PAYMENTINFO_0_TRANSACTIONID'])
623
+				|| (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed')
624
+			)
625
+			&& in_array($response_args['ACK'], array('Success', 'SuccessWithWarning'), true)
626
+		) {
627
+			// Response status OK, return response parameters for further processing.
628
+			return array('status' => true, 'args' => $response_args);
629
+		}
630
+		$errors = $this->_get_errors($response_args);
631
+		return array('status' => false, 'args' => $errors);
632
+	}
633
+
634
+
635
+
636
+	/**
637
+	 *  Log a "Cleared" request.
638
+	 *
639
+	 * @param array       $request
640
+	 * @param EEI_Payment $payment
641
+	 * @param string      $info
642
+	 * @return void
643
+	 */
644
+	private function _log_clean_request($request, $payment, $info)
645
+	{
646
+		$cleaned_request_data = $request;
647
+		unset($cleaned_request_data['PWD'], $cleaned_request_data['USER'], $cleaned_request_data['SIGNATURE']);
648
+		$this->log(array($info => $cleaned_request_data), $payment);
649
+	}
650
+
651
+
652
+
653
+	/**
654
+	 *  Get error from the response data.
655
+	 *
656
+	 * @param array $data_array
657
+	 * @return array
658
+	 */
659
+	private function _get_errors($data_array)
660
+	{
661
+		$errors = array();
662
+		$n = 0;
663
+		while (isset($data_array["L_ERRORCODE{$n}"])) {
664
+			$l_error_code = isset($data_array["L_ERRORCODE{$n}"])
665
+				? $data_array["L_ERRORCODE{$n}"]
666
+				: '';
667
+			$l_severity_code = isset($data_array["L_SEVERITYCODE{$n}"])
668
+				? $data_array["L_SEVERITYCODE{$n}"]
669
+				: '';
670
+			$l_short_message = isset($data_array["L_SHORTMESSAGE{$n}"])
671
+				? $data_array["L_SHORTMESSAGE{$n}"]
672
+				: '';
673
+			$l_long_message = isset($data_array["L_LONGMESSAGE{$n}"])
674
+				? $data_array["L_LONGMESSAGE{$n}"]
675
+				: '';
676
+			if ($n === 0) {
677
+				$errors = array(
678
+					'L_ERRORCODE'    => $l_error_code,
679
+					'L_SHORTMESSAGE' => $l_short_message,
680
+					'L_LONGMESSAGE'  => $l_long_message,
681
+					'L_SEVERITYCODE' => $l_severity_code,
682
+				);
683
+			} else {
684
+				$errors['L_ERRORCODE'] .= ', ' . $l_error_code;
685
+				$errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
686
+				$errors['L_LONGMESSAGE'] .= ', ' . $l_long_message;
687
+				$errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
688
+			}
689
+			$n++;
690
+		}
691
+		return $errors;
692
+	}
693 693
 
694 694
 }
695 695
 // End of file EEG_Paypal_Express.gateway.php
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (! defined('EVENT_ESPRESSO_VERSION')) {
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
     exit('NO direct script access allowed');
3 3
 }
4 4
 
@@ -15,7 +15,7 @@  discard block
 block discarded – undo
15 15
  * ----------------------------------------------
16 16
  */
17 17
 //Quickfix to address https://events.codebasehq.com/projects/event-espresso/tickets/11089 ASAP
18
-if (! function_exists('mb_strcut')) {
18
+if ( ! function_exists('mb_strcut')) {
19 19
     /**
20 20
      * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
21 21
      * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
         $notify_url = null,
146 146
         $cancel_url = null
147 147
     ) {
148
-        if (! $payment instanceof EEI_Payment) {
148
+        if ( ! $payment instanceof EEI_Payment) {
149 149
             $payment->set_gateway_response(
150 150
                 esc_html__(
151 151
                     'Error. No associated payment was found.',
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
             return $payment;
157 157
         }
158 158
         $transaction = $payment->transaction();
159
-        if (! $transaction instanceof EEI_Transaction) {
159
+        if ( ! $transaction instanceof EEI_Transaction) {
160 160
             $payment->set_gateway_response(
161 161
                 esc_html__(
162 162
                     'Could not process this payment because it has no associated transaction.',
@@ -205,13 +205,13 @@  discard block
 block discarded – undo
205 205
             $token_request_dtls['PAYMENTREQUEST_0_SHIPTOZIP'] = $primary_attendee->zip();
206 206
             $token_request_dtls['PAYMENTREQUEST_0_EMAIL'] = $primary_attendee->email();
207 207
             $token_request_dtls['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $primary_attendee->phone();
208
-        } elseif (! $this->_request_shipping_addr) {
208
+        } elseif ( ! $this->_request_shipping_addr) {
209 209
             // Do not request shipping details on the PP Checkout page.
210 210
             $token_request_dtls['NOSHIPPING'] = '1';
211 211
             $token_request_dtls['REQCONFIRMSHIPPING'] = '0';
212 212
         }
213 213
         // Used a business/personal logo on the PayPal page.
214
-        if (! empty($this->_image_url)) {
214
+        if ( ! empty($this->_image_url)) {
215 215
             $token_request_dtls['LOGOIMG'] = $this->_image_url;
216 216
         }
217 217
         $token_request_dtls = apply_filters(
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
             );
237 237
         } else {
238 238
             if (isset($response_args['L_ERRORCODE'])) {
239
-                $payment->set_gateway_response($response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']);
239
+                $payment->set_gateway_response($response_args['L_ERRORCODE'].'; '.$response_args['L_SHORTMESSAGE']);
240 240
             } else {
241 241
                 $payment->set_gateway_response(
242 242
                     esc_html__(
@@ -267,7 +267,7 @@  discard block
 block discarded – undo
267 267
         if ($payment instanceof EEI_Payment) {
268 268
             $this->log(array('Return from Authorization' => $update_info), $payment);
269 269
             $transaction = $payment->transaction();
270
-            if (! $transaction instanceof EEI_Transaction) {
270
+            if ( ! $transaction instanceof EEI_Transaction) {
271 271
                 $payment->set_gateway_response(
272 272
                     esc_html__(
273 273
                         'Could not process this payment because it has no associated transaction.',
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
             $primary_registrant = $transaction->primary_registration();
281 281
             $payment_details = $payment->details();
282 282
             // Check if we still have the token.
283
-            if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
283
+            if ( ! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
284 284
                 $payment->set_status($this->_pay_model->failed_status());
285 285
                 return $payment;
286 286
             }
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
                         : '';
335 335
                     $payment->set_extra_accntng($primary_registration_code);
336 336
                     $payment->set_amount(isset($docheckout_response_args['PAYMENTINFO_0_AMT'])
337
-                        ? (float)$docheckout_response_args['PAYMENTINFO_0_AMT']
337
+                        ? (float) $docheckout_response_args['PAYMENTINFO_0_AMT']
338 338
                         : 0);
339 339
                     $payment->set_txn_id_chq_nmbr(isset($docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'])
340 340
                         ? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID']
@@ -470,25 +470,25 @@  discard block
 block discarded – undo
470 470
                         $line_item_quantity = 1;
471 471
                     }
472 472
                     // Item Name.
473
-                    $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
473
+                    $itemized_list['L_PAYMENTREQUEST_0_NAME'.$item_num] = mb_strcut(
474 474
                         $gateway_formatter->formatLineItemName($line_item, $payment),
475 475
                         0,
476 476
                         127
477 477
                     );
478 478
                     // Item description.
479
-                    $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = mb_strcut(
479
+                    $itemized_list['L_PAYMENTREQUEST_0_DESC'.$item_num] = mb_strcut(
480 480
                         $gateway_formatter->formatLineItemDesc($line_item, $payment),
481 481
                         0,
482 482
                         127
483 483
                     );
484 484
                     // Cost of individual item.
485
-                    $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $gateway_formatter->formatCurrency($unit_price);
485
+                    $itemized_list['L_PAYMENTREQUEST_0_AMT'.$item_num] = $gateway_formatter->formatCurrency($unit_price);
486 486
                     // Item Number.
487
-                    $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
487
+                    $itemized_list['L_PAYMENTREQUEST_0_NUMBER'.$item_num] = $item_num + 1;
488 488
                     // Item quantity.
489
-                    $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = $line_item_quantity;
489
+                    $itemized_list['L_PAYMENTREQUEST_0_QTY'.$item_num] = $line_item_quantity;
490 490
                     // Digital item is sold.
491
-                    $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
491
+                    $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY'.$item_num] = 'Physical';
492 492
                     $itemized_sum += $line_item->total();
493 493
                     ++$item_num;
494 494
                 }
@@ -506,7 +506,7 @@  discard block
 block discarded – undo
506 506
             // add the difference as an extra line item.
507 507
             if ($this->_money->compare_floats($itemized_sum_diff_from_txn_total, 0, '!=')) {
508 508
                 // Item Name.
509
-                $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
509
+                $itemized_list['L_PAYMENTREQUEST_0_NAME'.$item_num] = mb_strcut(
510 510
                     esc_html__(
511 511
                         'Other (promotion/surcharge/cancellation)',
512 512
                         'event_espresso'
@@ -515,17 +515,17 @@  discard block
 block discarded – undo
515 515
                     127
516 516
                 );
517 517
                 // Item description.
518
-                $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = '';
518
+                $itemized_list['L_PAYMENTREQUEST_0_DESC'.$item_num] = '';
519 519
                 // Cost of individual item.
520
-                $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $gateway_formatter->formatCurrency(
520
+                $itemized_list['L_PAYMENTREQUEST_0_AMT'.$item_num] = $gateway_formatter->formatCurrency(
521 521
                     $itemized_sum_diff_from_txn_total
522 522
                 );
523 523
                 // Item Number.
524
-                $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
524
+                $itemized_list['L_PAYMENTREQUEST_0_NUMBER'.$item_num] = $item_num + 1;
525 525
                 // Item quantity.
526
-                $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = 1;
526
+                $itemized_list['L_PAYMENTREQUEST_0_QTY'.$item_num] = 1;
527 527
                 // Digital item is sold.
528
-                $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
528
+                $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY'.$item_num] = 'Physical';
529 529
                 $item_num++;
530 530
             }
531 531
         } else {
@@ -578,7 +578,7 @@  discard block
 block discarded – undo
578 578
             'SIGNATURE' => urlencode($this->_api_signature),
579 579
         );
580 580
         $dtls = array_merge($request_dtls, $request_params);
581
-        $this->_log_clean_request($dtls, $payment, $request_text . ' Request');
581
+        $this->_log_clean_request($dtls, $payment, $request_text.' Request');
582 582
         // Request Customer Details.
583 583
         $request_response = wp_remote_post(
584 584
             $this->_base_gateway_url,
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
             )
593 593
         );
594 594
         // Log the response.
595
-        $this->log(array($request_text . ' Response' => $request_response), $payment);
595
+        $this->log(array($request_text.' Response' => $request_response), $payment);
596 596
         return $request_response;
597 597
     }
598 598
 
@@ -612,7 +612,7 @@  discard block
 block discarded – undo
612 612
         }
613 613
         $response_args = array();
614 614
         parse_str(urldecode($request_response['body']), $response_args);
615
-        if (! isset($response_args['ACK'])) {
615
+        if ( ! isset($response_args['ACK'])) {
616 616
             return array('status' => false, 'args' => $request_response);
617 617
         }
618 618
         if (
@@ -681,10 +681,10 @@  discard block
 block discarded – undo
681 681
                     'L_SEVERITYCODE' => $l_severity_code,
682 682
                 );
683 683
             } else {
684
-                $errors['L_ERRORCODE'] .= ', ' . $l_error_code;
685
-                $errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
686
-                $errors['L_LONGMESSAGE'] .= ', ' . $l_long_message;
687
-                $errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
684
+                $errors['L_ERRORCODE'] .= ', '.$l_error_code;
685
+                $errors['L_SHORTMESSAGE'] .= ', '.$l_short_message;
686
+                $errors['L_LONGMESSAGE'] .= ', '.$l_long_message;
687
+                $errors['L_SEVERITYCODE'] .= ', '.$l_severity_code;
688 688
             }
689 689
             $n++;
690 690
         }
Please login to merge, or discard this patch.
core/libraries/messages/messenger/EE_Email_messenger.class.php 2 patches
Indentation   +637 added lines, -637 removed lines patch added patch discarded remove patch
@@ -8,641 +8,641 @@
 block discarded – undo
8 8
 class EE_Email_messenger extends EE_messenger
9 9
 {
10 10
 
11
-    /**
12
-     * To field for email
13
-     * @var string
14
-     */
15
-    protected $_to = '';
16
-
17
-
18
-    /**
19
-     * CC field for email.
20
-     * @var string
21
-     */
22
-    protected $_cc = '';
23
-
24
-    /**
25
-     * From field for email
26
-     * @var string
27
-     */
28
-    protected $_from = '';
29
-
30
-
31
-    /**
32
-     * Subject field for email
33
-     * @var string
34
-     */
35
-    protected $_subject = '';
36
-
37
-
38
-    /**
39
-     * Content field for email
40
-     * @var string
41
-     */
42
-    protected $_content = '';
43
-
44
-
45
-    /**
46
-     * constructor
47
-     *
48
-     * @access public
49
-     */
50
-    public function __construct()
51
-    {
52
-        //set name and description properties
53
-        $this->name                = 'email';
54
-        $this->description         = sprintf(
55
-            esc_html__(
56
-                'This messenger delivers messages via email using the built-in %s function included with WordPress',
57
-                'event_espresso'
58
-            ),
59
-            '<code>wp_mail</code>'
60
-        );
61
-        $this->label               = array(
62
-            'singular' => esc_html__('email', 'event_espresso'),
63
-            'plural'   => esc_html__('emails', 'event_espresso'),
64
-        );
65
-        $this->activate_on_install = true;
66
-
67
-        //we're using defaults so let's call parent constructor that will take care of setting up all the other
68
-        // properties
69
-        parent::__construct();
70
-    }
71
-
72
-
73
-    /**
74
-     * see abstract declaration in parent class for details.
75
-     */
76
-    protected function _set_admin_pages()
77
-    {
78
-        $this->admin_registered_pages = array(
79
-            'events_edit' => true,
80
-        );
81
-    }
82
-
83
-
84
-    /**
85
-     * see abstract declaration in parent class for details
86
-     */
87
-    protected function _set_valid_shortcodes()
88
-    {
89
-        //remember by leaving the other fields not set, those fields will inherit the valid shortcodes from the
90
-        // message type.
91
-        $this->_valid_shortcodes = array(
92
-            'to'   => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
93
-            'cc' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
94
-            'from' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
95
-        );
96
-    }
97
-
98
-
99
-    /**
100
-     * see abstract declaration in parent class for details
101
-     *
102
-     * @access protected
103
-     * @return void
104
-     */
105
-    protected function _set_validator_config()
106
-    {
107
-        $valid_shortcodes = $this->get_valid_shortcodes();
108
-
109
-        $this->_validator_config = array(
110
-            'to'            => array(
111
-                'shortcodes' => $valid_shortcodes['to'],
112
-                'type'       => 'email',
113
-            ),
114
-            'cc' => array(
115
-                'shortcodes' => $valid_shortcodes['to'],
116
-                'type' => 'email',
117
-            ),
118
-            'from'          => array(
119
-                'shortcodes' => $valid_shortcodes['from'],
120
-                'type'       => 'email',
121
-            ),
122
-            'subject'       => array(
123
-                'shortcodes' => array(
124
-                    'organization',
125
-                    'primary_registration_details',
126
-                    'event_author',
127
-                    'primary_registration_details',
128
-                    'recipient_details',
129
-                ),
130
-            ),
131
-            'content'       => array(
132
-                'shortcodes' => array(
133
-                    'event_list',
134
-                    'attendee_list',
135
-                    'ticket_list',
136
-                    'organization',
137
-                    'primary_registration_details',
138
-                    'primary_registration_list',
139
-                    'event_author',
140
-                    'recipient_details',
141
-                    'recipient_list',
142
-                    'transaction',
143
-                    'messenger',
144
-                ),
145
-            ),
146
-            'attendee_list' => array(
147
-                'shortcodes' => array('attendee', 'event_list', 'ticket_list'),
148
-                'required'   => array('[ATTENDEE_LIST]'),
149
-            ),
150
-            'event_list'    => array(
151
-                'shortcodes' => array(
152
-                    'event',
153
-                    'attendee_list',
154
-                    'ticket_list',
155
-                    'venue',
156
-                    'datetime_list',
157
-                    'attendee',
158
-                    'primary_registration_details',
159
-                    'primary_registration_list',
160
-                    'event_author',
161
-                    'recipient_details',
162
-                    'recipient_list',
163
-                ),
164
-                'required'   => array('[EVENT_LIST]'),
165
-            ),
166
-            'ticket_list'   => array(
167
-                'shortcodes' => array(
168
-                    'event_list',
169
-                    'attendee_list',
170
-                    'ticket',
171
-                    'datetime_list',
172
-                    'primary_registration_details',
173
-                    'recipient_details',
174
-                ),
175
-                'required'   => array('[TICKET_LIST]'),
176
-            ),
177
-            'datetime_list' => array(
178
-                'shortcodes' => array('datetime'),
179
-                'required'   => array('[DATETIME_LIST]'),
180
-            ),
181
-        );
182
-    }
183
-
184
-
185
-    /**
186
-     * @see   parent EE_messenger class for docs
187
-     * @since 4.5.0
188
-     */
189
-    public function do_secondary_messenger_hooks($sending_messenger_name)
190
-    {
191
-        if ($sending_messenger_name = 'html') {
192
-            add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
193
-        }
194
-    }
195
-
196
-
197
-    public function add_email_css(
198
-        $variation_path,
199
-        $messenger,
200
-        $message_type,
201
-        $type,
202
-        $variation,
203
-        $file_extension,
204
-        $url,
205
-        EE_Messages_Template_Pack $template_pack
206
-    ) {
207
-        //prevent recursion on this callback.
208
-        remove_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10);
209
-        $variation = $this->get_variation($template_pack, $message_type, $url, 'main', $variation, false);
210
-
211
-        add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
212
-        return $variation;
213
-    }
214
-
215
-
216
-    /**
217
-     * See parent for details
218
-     *
219
-     * @access protected
220
-     * @return void
221
-     */
222
-    protected function _set_test_settings_fields()
223
-    {
224
-        $this->_test_settings_fields = array(
225
-            'to'      => array(
226
-                'input'      => 'text',
227
-                'label'      => esc_html__('Send a test email to', 'event_espresso'),
228
-                'type'       => 'email',
229
-                'required'   => true,
230
-                'validation' => true,
231
-                'css_class'  => 'large-text',
232
-                'format'     => '%s',
233
-                'default'    => get_bloginfo('admin_email'),
234
-            ),
235
-            'subject' => array(
236
-                'input'      => 'hidden',
237
-                'label'      => '',
238
-                'type'       => 'string',
239
-                'required'   => false,
240
-                'validation' => false,
241
-                'format'     => '%s',
242
-                'value'      => sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')),
243
-                'default'    => '',
244
-                'css_class'  => '',
245
-            ),
246
-        );
247
-    }
248
-
249
-
250
-    /**
251
-     * _set_template_fields
252
-     * This sets up the fields that a messenger requires for the message to go out.
253
-     *
254
-     * @access  protected
255
-     * @return void
256
-     */
257
-    protected function _set_template_fields()
258
-    {
259
-        // any extra template fields that are NOT used by the messenger but will get used by a messenger field for
260
-        // shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field
261
-        // they relate to.  This is important for the Messages_admin to know what fields to display to the user.
262
-        //  Also, notice that the "values" are equal to the field type that messages admin will use to know what
263
-        // kind of field to display. The values ALSO have one index labeled "shortcode".  the values in that array
264
-        // indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be
265
-        // displayed.  If the required shortcode isn't part of the shortcodes array then the field is not needed and
266
-        // will not be displayed/parsed.
267
-        $this->_template_fields = array(
268
-            'to'      => array(
269
-                'input'      => 'text',
270
-                'label'      => esc_html_x(
271
-                    'To',
272
-                    'Label for the "To" field for email addresses',
273
-                    'event_espresso'
274
-                ),
275
-                'type'       => 'string',
276
-                'required'   => true,
277
-                'validation' => true,
278
-                'css_class'  => 'large-text',
279
-                'format'     => '%s',
280
-            ),
281
-            'cc'      => array(
282
-                'input'      => 'text',
283
-                'label'      => esc_html_x(
284
-                    'CC',
285
-                    'Label for the "Carbon Copy" field used for additional email addresses',
286
-                    'event_espresso'
287
-                ),
288
-                'type'       => 'string',
289
-                'required'   => false,
290
-                'validation' => true,
291
-                'css_class'  => 'large-text',
292
-                'format'     => '%s',
293
-            ),
294
-            'from'    => array(
295
-                'input'      => 'text',
296
-                'label'      => esc_html_x(
297
-                    'From',
298
-                    'Label for the "From" field for email addresses.',
299
-                    'event_espresso'
300
-                ),
301
-                'type'       => 'string',
302
-                'required'   => true,
303
-                'validation' => true,
304
-                'css_class'  => 'large-text',
305
-                'format'     => '%s',
306
-            ),
307
-            'subject' => array(
308
-                'input'      => 'text',
309
-                'label'      => esc_html_x(
310
-                    'Subject',
311
-                    'Label for the "Subject" field (short description of contents) for emails.',
312
-                    'event_espresso'
313
-                ),
314
-                'type'       => 'string',
315
-                'required'   => true,
316
-                'validation' => true,
317
-                'css_class'  => 'large-text',
318
-                'format'     => '%s',
319
-            ),
320
-            'content' => '',
321
-            //left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
322
-            'extra'   => array(
323
-                'content' => array(
324
-                    'main'          => array(
325
-                        'input'      => 'wp_editor',
326
-                        'label'      => esc_html__('Main Content', 'event_espresso'),
327
-                        'type'       => 'string',
328
-                        'required'   => true,
329
-                        'validation' => true,
330
-                        'format'     => '%s',
331
-                        'rows'       => '15',
332
-                    ),
333
-                    'event_list'    => array(
334
-                        'input'               => 'wp_editor',
335
-                        'label'               => '[EVENT_LIST]',
336
-                        'type'                => 'string',
337
-                        'required'            => true,
338
-                        'validation'          => true,
339
-                        'format'              => '%s',
340
-                        'rows'                => '15',
341
-                        'shortcodes_required' => array('[EVENT_LIST]'),
342
-                    ),
343
-                    'attendee_list' => array(
344
-                        'input'               => 'textarea',
345
-                        'label'               => '[ATTENDEE_LIST]',
346
-                        'type'                => 'string',
347
-                        'required'            => true,
348
-                        'validation'          => true,
349
-                        'format'              => '%s',
350
-                        'css_class'           => 'large-text',
351
-                        'rows'                => '5',
352
-                        'shortcodes_required' => array('[ATTENDEE_LIST]'),
353
-                    ),
354
-                    'ticket_list'   => array(
355
-                        'input'               => 'textarea',
356
-                        'label'               => '[TICKET_LIST]',
357
-                        'type'                => 'string',
358
-                        'required'            => true,
359
-                        'validation'          => true,
360
-                        'format'              => '%s',
361
-                        'css_class'           => 'large-text',
362
-                        'rows'                => '10',
363
-                        'shortcodes_required' => array('[TICKET_LIST]'),
364
-                    ),
365
-                    'datetime_list' => array(
366
-                        'input'               => 'textarea',
367
-                        'label'               => '[DATETIME_LIST]',
368
-                        'type'                => 'string',
369
-                        'required'            => true,
370
-                        'validation'          => true,
371
-                        'format'              => '%s',
372
-                        'css_class'           => 'large-text',
373
-                        'rows'                => '10',
374
-                        'shortcodes_required' => array('[DATETIME_LIST]'),
375
-                    ),
376
-                ),
377
-            ),
378
-        );
379
-    }
380
-
381
-
382
-    /**
383
-     * See definition of this class in parent
384
-     */
385
-    protected function _set_default_message_types()
386
-    {
387
-        $this->_default_message_types = array(
388
-            'payment',
389
-            'payment_refund',
390
-            'registration',
391
-            'not_approved_registration',
392
-            'pending_approval',
393
-        );
394
-    }
395
-
396
-
397
-    /**
398
-     * @see   definition of this class in parent
399
-     * @since 4.5.0
400
-     */
401
-    protected function _set_valid_message_types()
402
-    {
403
-        $this->_valid_message_types = array(
404
-            'payment',
405
-            'registration',
406
-            'not_approved_registration',
407
-            'declined_registration',
408
-            'cancelled_registration',
409
-            'pending_approval',
410
-            'registration_summary',
411
-            'payment_reminder',
412
-            'payment_declined',
413
-            'payment_refund',
414
-        );
415
-    }
416
-
417
-
418
-    /**
419
-     * setting up admin_settings_fields for messenger.
420
-     */
421
-    protected function _set_admin_settings_fields()
422
-    {
423
-    }
424
-
425
-    /**
426
-     * We just deliver the messages don't kill us!!
427
-     *
428
-     * @return bool|WP_Error true if message delivered, false if it didn't deliver OR bubble up any error object if
429
-     *              present.
430
-     * @throws EE_Error
431
-     * @throws \TijsVerkoyen\CssToInlineStyles\Exception
432
-     */
433
-    protected function _send_message()
434
-    {
435
-        $success = wp_mail(
436
-            $this->_to,
437
-            $this->_subject,
438
-            $this->_body(),
439
-            $this->_headers()
440
-        );
441
-        if (! $success) {
442
-            EE_Error::add_error(
443
-                sprintf(
444
-                    esc_html__(
445
-                        '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',
446
-                        'event_espresso'
447
-                    ),
448
-                    $this->_to,
449
-                    $this->_from,
450
-                    '<br />'
451
-                ),
452
-                __FILE__,
453
-                __FUNCTION__,
454
-                __LINE__
455
-            );
456
-        }
457
-        return $success;
458
-    }
459
-
460
-
461
-    /**
462
-     * see parent for definition
463
-     *
464
-     * @return string html body of the message content and the related css.
465
-     * @throws EE_Error
466
-     * @throws \TijsVerkoyen\CssToInlineStyles\Exception
467
-     */
468
-    protected function _preview()
469
-    {
470
-        return $this->_body(true);
471
-    }
472
-
473
-
474
-    /**
475
-     * Setup headers for email
476
-     *
477
-     * @access protected
478
-     * @return string formatted header for email
479
-     */
480
-    protected function _headers()
481
-    {
482
-        $this->_ensure_has_from_email_address();
483
-        $from    = $this->_from;
484
-        $headers = array(
485
-            'From:' . $from,
486
-            'Reply-To:' . $from,
487
-            'Content-Type:text/html; charset=utf-8',
488
-        );
489
-
490
-        if (! empty($this->_cc)) {
491
-            $headers[] = 'cc: ' . $this->_cc;
492
-        }
493
-
494
-        //but wait!  Header's for the from is NOT reliable because some plugins don't respect From: as set in the
495
-        // header.
496
-        add_filter('wp_mail_from', array($this, 'set_from_address'), 100);
497
-        add_filter('wp_mail_from_name', array($this, 'set_from_name'), 100);
498
-        return apply_filters('FHEE__EE_Email_messenger___headers', $headers, $this->_incoming_message_type, $this);
499
-    }
500
-
501
-
502
-    /**
503
-     * This simply ensures that the from address is not empty.  If it is, then we use whatever is set as the site email
504
-     * address for the from address to avoid problems with sending emails.
505
-     */
506
-    protected function _ensure_has_from_email_address()
507
-    {
508
-        if (empty($this->_from)) {
509
-            $this->_from = get_bloginfo('admin_email');
510
-        }
511
-    }
512
-
513
-
514
-    /**
515
-     * This simply parses whatever is set as the $_from address and determines if it is in the format {name} <{email}>
516
-     * or just {email} and returns an array with the "from_name" and "from_email" as the values. Note from_name *MAY*
517
-     * be empty
518
-     *
519
-     * @since 4.3.1
520
-     * @return array
521
-     */
522
-    private function _parse_from()
523
-    {
524
-        if (strpos($this->_from, '<') !== false) {
525
-            $from_name = substr($this->_from, 0, strpos($this->_from, '<') - 1);
526
-            $from_name = str_replace('"', '', $from_name);
527
-            $from_name = trim($from_name);
528
-
529
-            $from_email = substr($this->_from, strpos($this->_from, '<') + 1);
530
-            $from_email = str_replace('>', '', $from_email);
531
-            $from_email = trim($from_email);
532
-        } elseif (trim($this->_from) !== '') {
533
-            $from_name  = '';
534
-            $from_email = trim($this->_from);
535
-        } else {
536
-            $from_name = $from_email = '';
537
-        }
538
-        return array($from_name, $from_email);
539
-    }
540
-
541
-
542
-    /**
543
-     * Callback for the wp_mail_from filter.
544
-     *
545
-     * @since 4.3.1
546
-     * @param string $from_email What the original from_email is.
547
-     * @return string
548
-     */
549
-    public function set_from_address($from_email)
550
-    {
551
-        $parsed_from = $this->_parse_from();
552
-        //includes fallback if the parsing failed.
553
-        $from_email = is_array($parsed_from) && ! empty($parsed_from[1])
554
-            ? $parsed_from[1]
555
-            : get_bloginfo('admin_email');
556
-        return $from_email;
557
-    }
558
-
559
-
560
-    /**
561
-     * Callback fro the wp_mail_from_name filter.
562
-     *
563
-     * @since 4.3.1
564
-     * @param string $from_name The original from_name.
565
-     * @return string
566
-     */
567
-    public function set_from_name($from_name)
568
-    {
569
-        $parsed_from = $this->_parse_from();
570
-        if (is_array($parsed_from) && ! empty($parsed_from[0])) {
571
-            $from_name = $parsed_from[0];
572
-        }
573
-
574
-        //if from name is "WordPress" let's sub in the site name instead (more friendly!)
575
-        $from_name = $from_name == 'WordPress' ? get_bloginfo() : $from_name;
576
-
577
-        return $from_name;
578
-    }
579
-
580
-
581
-    /**
582
-     * setup body for email
583
-     *
584
-     * @param bool $preview will determine whether this is preview template or not.
585
-     * @return string formatted body for email.
586
-     * @throws EE_Error
587
-     * @throws \TijsVerkoyen\CssToInlineStyles\Exception
588
-     */
589
-    protected function _body($preview = false)
590
-    {
591
-        //setup template args!
592
-        $this->_template_args = array(
593
-            'subject'   => $this->_subject,
594
-            'from'      => $this->_from,
595
-            'main_body' => wpautop($this->_content),
596
-        );
597
-        $body                 = $this->_get_main_template($preview);
598
-
599
-        /**
600
-         * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched.
601
-         *
602
-         * @type    bool $preview Indicates whether a preview is being generated or not.
603
-         * @return  bool    true  indicates to use the inliner, false bypasses it.
604
-         */
605
-        if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) {
606
-            //require CssToInlineStyles library and its dependencies via composer autoloader
607
-            require_once EE_THIRD_PARTY . 'cssinliner/vendor/autoload.php';
608
-
609
-            //now if this isn't a preview, let's setup the body so it has inline styles
610
-            if (! $preview || ($preview && defined('DOING_AJAX'))) {
611
-                $style = file_get_contents(
612
-                    $this->get_variation(
613
-                        $this->_tmp_pack,
614
-                        $this->_incoming_message_type->name,
615
-                        false,
616
-                        'main',
617
-                        $this->_variation
618
-                    ),
619
-                    true
620
-                );
621
-                $CSS   = new TijsVerkoyen\CssToInlineStyles\CssToInlineStyles($body, $style);
622
-                //for some reason the library has a bracket and new line at the beginning.  This takes care of that.
623
-                $body  = ltrim($CSS->convert(true), ">\n");
624
-                //see https://events.codebasehq.com/projects/event-espresso/tickets/8609
625
-                $body  = ltrim($body, "<?");
626
-            }
627
-
628
-        }
629
-        return $body;
630
-    }
631
-
632
-
633
-    /**
634
-     * This just returns any existing test settings that might be saved in the database
635
-     *
636
-     * @access public
637
-     * @return array
638
-     */
639
-    public function get_existing_test_settings()
640
-    {
641
-        $settings = parent::get_existing_test_settings();
642
-        //override subject if present because we always want it to be fresh.
643
-        if (is_array($settings) && ! empty($settings['subject'])) {
644
-            $settings['subject'] = sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name'));
645
-        }
646
-        return $settings;
647
-    }
11
+	/**
12
+	 * To field for email
13
+	 * @var string
14
+	 */
15
+	protected $_to = '';
16
+
17
+
18
+	/**
19
+	 * CC field for email.
20
+	 * @var string
21
+	 */
22
+	protected $_cc = '';
23
+
24
+	/**
25
+	 * From field for email
26
+	 * @var string
27
+	 */
28
+	protected $_from = '';
29
+
30
+
31
+	/**
32
+	 * Subject field for email
33
+	 * @var string
34
+	 */
35
+	protected $_subject = '';
36
+
37
+
38
+	/**
39
+	 * Content field for email
40
+	 * @var string
41
+	 */
42
+	protected $_content = '';
43
+
44
+
45
+	/**
46
+	 * constructor
47
+	 *
48
+	 * @access public
49
+	 */
50
+	public function __construct()
51
+	{
52
+		//set name and description properties
53
+		$this->name                = 'email';
54
+		$this->description         = sprintf(
55
+			esc_html__(
56
+				'This messenger delivers messages via email using the built-in %s function included with WordPress',
57
+				'event_espresso'
58
+			),
59
+			'<code>wp_mail</code>'
60
+		);
61
+		$this->label               = array(
62
+			'singular' => esc_html__('email', 'event_espresso'),
63
+			'plural'   => esc_html__('emails', 'event_espresso'),
64
+		);
65
+		$this->activate_on_install = true;
66
+
67
+		//we're using defaults so let's call parent constructor that will take care of setting up all the other
68
+		// properties
69
+		parent::__construct();
70
+	}
71
+
72
+
73
+	/**
74
+	 * see abstract declaration in parent class for details.
75
+	 */
76
+	protected function _set_admin_pages()
77
+	{
78
+		$this->admin_registered_pages = array(
79
+			'events_edit' => true,
80
+		);
81
+	}
82
+
83
+
84
+	/**
85
+	 * see abstract declaration in parent class for details
86
+	 */
87
+	protected function _set_valid_shortcodes()
88
+	{
89
+		//remember by leaving the other fields not set, those fields will inherit the valid shortcodes from the
90
+		// message type.
91
+		$this->_valid_shortcodes = array(
92
+			'to'   => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
93
+			'cc' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
94
+			'from' => array('email', 'event_author', 'primary_registration_details', 'recipient_details'),
95
+		);
96
+	}
97
+
98
+
99
+	/**
100
+	 * see abstract declaration in parent class for details
101
+	 *
102
+	 * @access protected
103
+	 * @return void
104
+	 */
105
+	protected function _set_validator_config()
106
+	{
107
+		$valid_shortcodes = $this->get_valid_shortcodes();
108
+
109
+		$this->_validator_config = array(
110
+			'to'            => array(
111
+				'shortcodes' => $valid_shortcodes['to'],
112
+				'type'       => 'email',
113
+			),
114
+			'cc' => array(
115
+				'shortcodes' => $valid_shortcodes['to'],
116
+				'type' => 'email',
117
+			),
118
+			'from'          => array(
119
+				'shortcodes' => $valid_shortcodes['from'],
120
+				'type'       => 'email',
121
+			),
122
+			'subject'       => array(
123
+				'shortcodes' => array(
124
+					'organization',
125
+					'primary_registration_details',
126
+					'event_author',
127
+					'primary_registration_details',
128
+					'recipient_details',
129
+				),
130
+			),
131
+			'content'       => array(
132
+				'shortcodes' => array(
133
+					'event_list',
134
+					'attendee_list',
135
+					'ticket_list',
136
+					'organization',
137
+					'primary_registration_details',
138
+					'primary_registration_list',
139
+					'event_author',
140
+					'recipient_details',
141
+					'recipient_list',
142
+					'transaction',
143
+					'messenger',
144
+				),
145
+			),
146
+			'attendee_list' => array(
147
+				'shortcodes' => array('attendee', 'event_list', 'ticket_list'),
148
+				'required'   => array('[ATTENDEE_LIST]'),
149
+			),
150
+			'event_list'    => array(
151
+				'shortcodes' => array(
152
+					'event',
153
+					'attendee_list',
154
+					'ticket_list',
155
+					'venue',
156
+					'datetime_list',
157
+					'attendee',
158
+					'primary_registration_details',
159
+					'primary_registration_list',
160
+					'event_author',
161
+					'recipient_details',
162
+					'recipient_list',
163
+				),
164
+				'required'   => array('[EVENT_LIST]'),
165
+			),
166
+			'ticket_list'   => array(
167
+				'shortcodes' => array(
168
+					'event_list',
169
+					'attendee_list',
170
+					'ticket',
171
+					'datetime_list',
172
+					'primary_registration_details',
173
+					'recipient_details',
174
+				),
175
+				'required'   => array('[TICKET_LIST]'),
176
+			),
177
+			'datetime_list' => array(
178
+				'shortcodes' => array('datetime'),
179
+				'required'   => array('[DATETIME_LIST]'),
180
+			),
181
+		);
182
+	}
183
+
184
+
185
+	/**
186
+	 * @see   parent EE_messenger class for docs
187
+	 * @since 4.5.0
188
+	 */
189
+	public function do_secondary_messenger_hooks($sending_messenger_name)
190
+	{
191
+		if ($sending_messenger_name = 'html') {
192
+			add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
193
+		}
194
+	}
195
+
196
+
197
+	public function add_email_css(
198
+		$variation_path,
199
+		$messenger,
200
+		$message_type,
201
+		$type,
202
+		$variation,
203
+		$file_extension,
204
+		$url,
205
+		EE_Messages_Template_Pack $template_pack
206
+	) {
207
+		//prevent recursion on this callback.
208
+		remove_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10);
209
+		$variation = $this->get_variation($template_pack, $message_type, $url, 'main', $variation, false);
210
+
211
+		add_filter('FHEE__EE_Messages_Template_Pack__get_variation', array($this, 'add_email_css'), 10, 8);
212
+		return $variation;
213
+	}
214
+
215
+
216
+	/**
217
+	 * See parent for details
218
+	 *
219
+	 * @access protected
220
+	 * @return void
221
+	 */
222
+	protected function _set_test_settings_fields()
223
+	{
224
+		$this->_test_settings_fields = array(
225
+			'to'      => array(
226
+				'input'      => 'text',
227
+				'label'      => esc_html__('Send a test email to', 'event_espresso'),
228
+				'type'       => 'email',
229
+				'required'   => true,
230
+				'validation' => true,
231
+				'css_class'  => 'large-text',
232
+				'format'     => '%s',
233
+				'default'    => get_bloginfo('admin_email'),
234
+			),
235
+			'subject' => array(
236
+				'input'      => 'hidden',
237
+				'label'      => '',
238
+				'type'       => 'string',
239
+				'required'   => false,
240
+				'validation' => false,
241
+				'format'     => '%s',
242
+				'value'      => sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name')),
243
+				'default'    => '',
244
+				'css_class'  => '',
245
+			),
246
+		);
247
+	}
248
+
249
+
250
+	/**
251
+	 * _set_template_fields
252
+	 * This sets up the fields that a messenger requires for the message to go out.
253
+	 *
254
+	 * @access  protected
255
+	 * @return void
256
+	 */
257
+	protected function _set_template_fields()
258
+	{
259
+		// any extra template fields that are NOT used by the messenger but will get used by a messenger field for
260
+		// shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field
261
+		// they relate to.  This is important for the Messages_admin to know what fields to display to the user.
262
+		//  Also, notice that the "values" are equal to the field type that messages admin will use to know what
263
+		// kind of field to display. The values ALSO have one index labeled "shortcode".  the values in that array
264
+		// indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be
265
+		// displayed.  If the required shortcode isn't part of the shortcodes array then the field is not needed and
266
+		// will not be displayed/parsed.
267
+		$this->_template_fields = array(
268
+			'to'      => array(
269
+				'input'      => 'text',
270
+				'label'      => esc_html_x(
271
+					'To',
272
+					'Label for the "To" field for email addresses',
273
+					'event_espresso'
274
+				),
275
+				'type'       => 'string',
276
+				'required'   => true,
277
+				'validation' => true,
278
+				'css_class'  => 'large-text',
279
+				'format'     => '%s',
280
+			),
281
+			'cc'      => array(
282
+				'input'      => 'text',
283
+				'label'      => esc_html_x(
284
+					'CC',
285
+					'Label for the "Carbon Copy" field used for additional email addresses',
286
+					'event_espresso'
287
+				),
288
+				'type'       => 'string',
289
+				'required'   => false,
290
+				'validation' => true,
291
+				'css_class'  => 'large-text',
292
+				'format'     => '%s',
293
+			),
294
+			'from'    => array(
295
+				'input'      => 'text',
296
+				'label'      => esc_html_x(
297
+					'From',
298
+					'Label for the "From" field for email addresses.',
299
+					'event_espresso'
300
+				),
301
+				'type'       => 'string',
302
+				'required'   => true,
303
+				'validation' => true,
304
+				'css_class'  => 'large-text',
305
+				'format'     => '%s',
306
+			),
307
+			'subject' => array(
308
+				'input'      => 'text',
309
+				'label'      => esc_html_x(
310
+					'Subject',
311
+					'Label for the "Subject" field (short description of contents) for emails.',
312
+					'event_espresso'
313
+				),
314
+				'type'       => 'string',
315
+				'required'   => true,
316
+				'validation' => true,
317
+				'css_class'  => 'large-text',
318
+				'format'     => '%s',
319
+			),
320
+			'content' => '',
321
+			//left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
322
+			'extra'   => array(
323
+				'content' => array(
324
+					'main'          => array(
325
+						'input'      => 'wp_editor',
326
+						'label'      => esc_html__('Main Content', 'event_espresso'),
327
+						'type'       => 'string',
328
+						'required'   => true,
329
+						'validation' => true,
330
+						'format'     => '%s',
331
+						'rows'       => '15',
332
+					),
333
+					'event_list'    => array(
334
+						'input'               => 'wp_editor',
335
+						'label'               => '[EVENT_LIST]',
336
+						'type'                => 'string',
337
+						'required'            => true,
338
+						'validation'          => true,
339
+						'format'              => '%s',
340
+						'rows'                => '15',
341
+						'shortcodes_required' => array('[EVENT_LIST]'),
342
+					),
343
+					'attendee_list' => array(
344
+						'input'               => 'textarea',
345
+						'label'               => '[ATTENDEE_LIST]',
346
+						'type'                => 'string',
347
+						'required'            => true,
348
+						'validation'          => true,
349
+						'format'              => '%s',
350
+						'css_class'           => 'large-text',
351
+						'rows'                => '5',
352
+						'shortcodes_required' => array('[ATTENDEE_LIST]'),
353
+					),
354
+					'ticket_list'   => array(
355
+						'input'               => 'textarea',
356
+						'label'               => '[TICKET_LIST]',
357
+						'type'                => 'string',
358
+						'required'            => true,
359
+						'validation'          => true,
360
+						'format'              => '%s',
361
+						'css_class'           => 'large-text',
362
+						'rows'                => '10',
363
+						'shortcodes_required' => array('[TICKET_LIST]'),
364
+					),
365
+					'datetime_list' => array(
366
+						'input'               => 'textarea',
367
+						'label'               => '[DATETIME_LIST]',
368
+						'type'                => 'string',
369
+						'required'            => true,
370
+						'validation'          => true,
371
+						'format'              => '%s',
372
+						'css_class'           => 'large-text',
373
+						'rows'                => '10',
374
+						'shortcodes_required' => array('[DATETIME_LIST]'),
375
+					),
376
+				),
377
+			),
378
+		);
379
+	}
380
+
381
+
382
+	/**
383
+	 * See definition of this class in parent
384
+	 */
385
+	protected function _set_default_message_types()
386
+	{
387
+		$this->_default_message_types = array(
388
+			'payment',
389
+			'payment_refund',
390
+			'registration',
391
+			'not_approved_registration',
392
+			'pending_approval',
393
+		);
394
+	}
395
+
396
+
397
+	/**
398
+	 * @see   definition of this class in parent
399
+	 * @since 4.5.0
400
+	 */
401
+	protected function _set_valid_message_types()
402
+	{
403
+		$this->_valid_message_types = array(
404
+			'payment',
405
+			'registration',
406
+			'not_approved_registration',
407
+			'declined_registration',
408
+			'cancelled_registration',
409
+			'pending_approval',
410
+			'registration_summary',
411
+			'payment_reminder',
412
+			'payment_declined',
413
+			'payment_refund',
414
+		);
415
+	}
416
+
417
+
418
+	/**
419
+	 * setting up admin_settings_fields for messenger.
420
+	 */
421
+	protected function _set_admin_settings_fields()
422
+	{
423
+	}
424
+
425
+	/**
426
+	 * We just deliver the messages don't kill us!!
427
+	 *
428
+	 * @return bool|WP_Error true if message delivered, false if it didn't deliver OR bubble up any error object if
429
+	 *              present.
430
+	 * @throws EE_Error
431
+	 * @throws \TijsVerkoyen\CssToInlineStyles\Exception
432
+	 */
433
+	protected function _send_message()
434
+	{
435
+		$success = wp_mail(
436
+			$this->_to,
437
+			$this->_subject,
438
+			$this->_body(),
439
+			$this->_headers()
440
+		);
441
+		if (! $success) {
442
+			EE_Error::add_error(
443
+				sprintf(
444
+					esc_html__(
445
+						'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',
446
+						'event_espresso'
447
+					),
448
+					$this->_to,
449
+					$this->_from,
450
+					'<br />'
451
+				),
452
+				__FILE__,
453
+				__FUNCTION__,
454
+				__LINE__
455
+			);
456
+		}
457
+		return $success;
458
+	}
459
+
460
+
461
+	/**
462
+	 * see parent for definition
463
+	 *
464
+	 * @return string html body of the message content and the related css.
465
+	 * @throws EE_Error
466
+	 * @throws \TijsVerkoyen\CssToInlineStyles\Exception
467
+	 */
468
+	protected function _preview()
469
+	{
470
+		return $this->_body(true);
471
+	}
472
+
473
+
474
+	/**
475
+	 * Setup headers for email
476
+	 *
477
+	 * @access protected
478
+	 * @return string formatted header for email
479
+	 */
480
+	protected function _headers()
481
+	{
482
+		$this->_ensure_has_from_email_address();
483
+		$from    = $this->_from;
484
+		$headers = array(
485
+			'From:' . $from,
486
+			'Reply-To:' . $from,
487
+			'Content-Type:text/html; charset=utf-8',
488
+		);
489
+
490
+		if (! empty($this->_cc)) {
491
+			$headers[] = 'cc: ' . $this->_cc;
492
+		}
493
+
494
+		//but wait!  Header's for the from is NOT reliable because some plugins don't respect From: as set in the
495
+		// header.
496
+		add_filter('wp_mail_from', array($this, 'set_from_address'), 100);
497
+		add_filter('wp_mail_from_name', array($this, 'set_from_name'), 100);
498
+		return apply_filters('FHEE__EE_Email_messenger___headers', $headers, $this->_incoming_message_type, $this);
499
+	}
500
+
501
+
502
+	/**
503
+	 * This simply ensures that the from address is not empty.  If it is, then we use whatever is set as the site email
504
+	 * address for the from address to avoid problems with sending emails.
505
+	 */
506
+	protected function _ensure_has_from_email_address()
507
+	{
508
+		if (empty($this->_from)) {
509
+			$this->_from = get_bloginfo('admin_email');
510
+		}
511
+	}
512
+
513
+
514
+	/**
515
+	 * This simply parses whatever is set as the $_from address and determines if it is in the format {name} <{email}>
516
+	 * or just {email} and returns an array with the "from_name" and "from_email" as the values. Note from_name *MAY*
517
+	 * be empty
518
+	 *
519
+	 * @since 4.3.1
520
+	 * @return array
521
+	 */
522
+	private function _parse_from()
523
+	{
524
+		if (strpos($this->_from, '<') !== false) {
525
+			$from_name = substr($this->_from, 0, strpos($this->_from, '<') - 1);
526
+			$from_name = str_replace('"', '', $from_name);
527
+			$from_name = trim($from_name);
528
+
529
+			$from_email = substr($this->_from, strpos($this->_from, '<') + 1);
530
+			$from_email = str_replace('>', '', $from_email);
531
+			$from_email = trim($from_email);
532
+		} elseif (trim($this->_from) !== '') {
533
+			$from_name  = '';
534
+			$from_email = trim($this->_from);
535
+		} else {
536
+			$from_name = $from_email = '';
537
+		}
538
+		return array($from_name, $from_email);
539
+	}
540
+
541
+
542
+	/**
543
+	 * Callback for the wp_mail_from filter.
544
+	 *
545
+	 * @since 4.3.1
546
+	 * @param string $from_email What the original from_email is.
547
+	 * @return string
548
+	 */
549
+	public function set_from_address($from_email)
550
+	{
551
+		$parsed_from = $this->_parse_from();
552
+		//includes fallback if the parsing failed.
553
+		$from_email = is_array($parsed_from) && ! empty($parsed_from[1])
554
+			? $parsed_from[1]
555
+			: get_bloginfo('admin_email');
556
+		return $from_email;
557
+	}
558
+
559
+
560
+	/**
561
+	 * Callback fro the wp_mail_from_name filter.
562
+	 *
563
+	 * @since 4.3.1
564
+	 * @param string $from_name The original from_name.
565
+	 * @return string
566
+	 */
567
+	public function set_from_name($from_name)
568
+	{
569
+		$parsed_from = $this->_parse_from();
570
+		if (is_array($parsed_from) && ! empty($parsed_from[0])) {
571
+			$from_name = $parsed_from[0];
572
+		}
573
+
574
+		//if from name is "WordPress" let's sub in the site name instead (more friendly!)
575
+		$from_name = $from_name == 'WordPress' ? get_bloginfo() : $from_name;
576
+
577
+		return $from_name;
578
+	}
579
+
580
+
581
+	/**
582
+	 * setup body for email
583
+	 *
584
+	 * @param bool $preview will determine whether this is preview template or not.
585
+	 * @return string formatted body for email.
586
+	 * @throws EE_Error
587
+	 * @throws \TijsVerkoyen\CssToInlineStyles\Exception
588
+	 */
589
+	protected function _body($preview = false)
590
+	{
591
+		//setup template args!
592
+		$this->_template_args = array(
593
+			'subject'   => $this->_subject,
594
+			'from'      => $this->_from,
595
+			'main_body' => wpautop($this->_content),
596
+		);
597
+		$body                 = $this->_get_main_template($preview);
598
+
599
+		/**
600
+		 * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched.
601
+		 *
602
+		 * @type    bool $preview Indicates whether a preview is being generated or not.
603
+		 * @return  bool    true  indicates to use the inliner, false bypasses it.
604
+		 */
605
+		if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) {
606
+			//require CssToInlineStyles library and its dependencies via composer autoloader
607
+			require_once EE_THIRD_PARTY . 'cssinliner/vendor/autoload.php';
608
+
609
+			//now if this isn't a preview, let's setup the body so it has inline styles
610
+			if (! $preview || ($preview && defined('DOING_AJAX'))) {
611
+				$style = file_get_contents(
612
+					$this->get_variation(
613
+						$this->_tmp_pack,
614
+						$this->_incoming_message_type->name,
615
+						false,
616
+						'main',
617
+						$this->_variation
618
+					),
619
+					true
620
+				);
621
+				$CSS   = new TijsVerkoyen\CssToInlineStyles\CssToInlineStyles($body, $style);
622
+				//for some reason the library has a bracket and new line at the beginning.  This takes care of that.
623
+				$body  = ltrim($CSS->convert(true), ">\n");
624
+				//see https://events.codebasehq.com/projects/event-espresso/tickets/8609
625
+				$body  = ltrim($body, "<?");
626
+			}
627
+
628
+		}
629
+		return $body;
630
+	}
631
+
632
+
633
+	/**
634
+	 * This just returns any existing test settings that might be saved in the database
635
+	 *
636
+	 * @access public
637
+	 * @return array
638
+	 */
639
+	public function get_existing_test_settings()
640
+	{
641
+		$settings = parent::get_existing_test_settings();
642
+		//override subject if present because we always want it to be fresh.
643
+		if (is_array($settings) && ! empty($settings['subject'])) {
644
+			$settings['subject'] = sprintf(__('Test email sent from %s', 'event_espresso'), get_bloginfo('name'));
645
+		}
646
+		return $settings;
647
+	}
648 648
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -58,7 +58,7 @@  discard block
 block discarded – undo
58 58
             ),
59 59
             '<code>wp_mail</code>'
60 60
         );
61
-        $this->label               = array(
61
+        $this->label = array(
62 62
             'singular' => esc_html__('email', 'event_espresso'),
63 63
             'plural'   => esc_html__('emails', 'event_espresso'),
64 64
         );
@@ -438,7 +438,7 @@  discard block
 block discarded – undo
438 438
             $this->_body(),
439 439
             $this->_headers()
440 440
         );
441
-        if (! $success) {
441
+        if ( ! $success) {
442 442
             EE_Error::add_error(
443 443
                 sprintf(
444 444
                     esc_html__(
@@ -482,13 +482,13 @@  discard block
 block discarded – undo
482 482
         $this->_ensure_has_from_email_address();
483 483
         $from    = $this->_from;
484 484
         $headers = array(
485
-            'From:' . $from,
486
-            'Reply-To:' . $from,
485
+            'From:'.$from,
486
+            'Reply-To:'.$from,
487 487
             'Content-Type:text/html; charset=utf-8',
488 488
         );
489 489
 
490
-        if (! empty($this->_cc)) {
491
-            $headers[] = 'cc: ' . $this->_cc;
490
+        if ( ! empty($this->_cc)) {
491
+            $headers[] = 'cc: '.$this->_cc;
492 492
         }
493 493
 
494 494
         //but wait!  Header's for the from is NOT reliable because some plugins don't respect From: as set in the
@@ -594,7 +594,7 @@  discard block
 block discarded – undo
594 594
             'from'      => $this->_from,
595 595
             'main_body' => wpautop($this->_content),
596 596
         );
597
-        $body                 = $this->_get_main_template($preview);
597
+        $body = $this->_get_main_template($preview);
598 598
 
599 599
         /**
600 600
          * This filter allows one to bypass the CSSToInlineStyles tool and leave the body untouched.
@@ -604,10 +604,10 @@  discard block
 block discarded – undo
604 604
          */
605 605
         if (apply_filters('FHEE__EE_Email_messenger__apply_CSSInliner ', true, $preview)) {
606 606
             //require CssToInlineStyles library and its dependencies via composer autoloader
607
-            require_once EE_THIRD_PARTY . 'cssinliner/vendor/autoload.php';
607
+            require_once EE_THIRD_PARTY.'cssinliner/vendor/autoload.php';
608 608
 
609 609
             //now if this isn't a preview, let's setup the body so it has inline styles
610
-            if (! $preview || ($preview && defined('DOING_AJAX'))) {
610
+            if ( ! $preview || ($preview && defined('DOING_AJAX'))) {
611 611
                 $style = file_get_contents(
612 612
                     $this->get_variation(
613 613
                         $this->_tmp_pack,
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Generator.lib.php 1 patch
Indentation   +969 added lines, -969 removed lines patch added patch discarded remove patch
@@ -13,973 +13,973 @@
 block discarded – undo
13 13
 {
14 14
 
15 15
 
16
-    /**
17
-     * @type EE_Messages_Data_Handler_Collection
18
-     */
19
-    protected $_data_handler_collection;
20
-
21
-    /**
22
-     * @type  EE_Message_Template_Group_Collection
23
-     */
24
-    protected $_template_collection;
25
-
26
-    /**
27
-     * This will hold the data handler for the current EE_Message being generated.
28
-     *
29
-     * @type EE_Messages_incoming_data
30
-     */
31
-    protected $_current_data_handler;
32
-
33
-    /**
34
-     * This holds the EE_Messages_Queue that contains the messages to generate.
35
-     *
36
-     * @type EE_Messages_Queue
37
-     */
38
-    protected $_generation_queue;
39
-
40
-    /**
41
-     * This holds the EE_Messages_Queue that will store the generated EE_Message objects.
42
-     *
43
-     * @type EE_Messages_Queue
44
-     */
45
-    protected $_ready_queue;
46
-
47
-    /**
48
-     * This is a container for any error messages that get created through the generation
49
-     * process.
50
-     *
51
-     * @type array
52
-     */
53
-    protected $_error_msg = array();
54
-
55
-    /**
56
-     * Flag used to set when the current EE_Message in the generation queue has been verified.
57
-     *
58
-     * @type bool
59
-     */
60
-    protected $_verified = false;
61
-
62
-    /**
63
-     * This will hold the current messenger object corresponding with the current EE_Message in the generation queue.
64
-     *
65
-     * @type EE_messenger
66
-     */
67
-    protected $_current_messenger;
68
-
69
-    /**
70
-     * This will hold the current message type object corresponding with the current EE_Message in the generation queue.
71
-     *
72
-     * @type EE_message_type
73
-     */
74
-    protected $_current_message_type;
75
-
76
-    /**
77
-     * @type EEH_Parse_Shortcodes
78
-     */
79
-    protected $_shortcode_parser;
80
-
81
-
82
-    /**
83
-     * @param EE_Messages_Queue                     $generation_queue
84
-     * @param \EE_Messages_Queue                    $ready_queue
85
-     * @param \EE_Messages_Data_Handler_Collection  $data_handler_collection
86
-     * @param \EE_Message_Template_Group_Collection $template_collection
87
-     * @param \EEH_Parse_Shortcodes                 $shortcode_parser
88
-     */
89
-    public function __construct(
90
-        EE_Messages_Queue $generation_queue,
91
-        EE_Messages_Queue $ready_queue,
92
-        EE_Messages_Data_Handler_Collection $data_handler_collection,
93
-        EE_Message_Template_Group_Collection $template_collection,
94
-        EEH_Parse_Shortcodes $shortcode_parser
95
-    ) {
96
-        $this->_generation_queue        = $generation_queue;
97
-        $this->_ready_queue             = $ready_queue;
98
-        $this->_data_handler_collection = $data_handler_collection;
99
-        $this->_template_collection     = $template_collection;
100
-        $this->_shortcode_parser        = $shortcode_parser;
101
-    }
102
-
103
-
104
-    /**
105
-     * @return EE_Messages_Queue
106
-     */
107
-    public function generation_queue()
108
-    {
109
-        return $this->_generation_queue;
110
-    }
111
-
112
-
113
-    /**
114
-     *  This iterates through the provided queue and generates the EE_Message objects.
115
-     *  When iterating through the queue, the queued item that served as the base for generating other EE_Message
116
-     *  objects gets removed and the new EE_Message objects get added to a NEW queue.  The NEW queue is then returned
117
-     *  for the caller to decide what to do with it.
118
-     *
119
-     * @param   bool $save Whether to save the EE_Message objects in the new queue or just return.
120
-     * @return EE_Messages_Queue The new queue for holding generated EE_Message objects.
121
-     * @throws EE_Error
122
-     * @throws ReflectionException
123
-     */
124
-    public function generate($save = true)
125
-    {
126
-        //iterate through the messages in the queue, generate, and add to new queue.
127
-        $this->_generation_queue->get_message_repository()->rewind();
128
-        while ($this->_generation_queue->get_message_repository()->valid()) {
129
-            //reset "current" properties
130
-            $this->_reset_current_properties();
131
-
132
-            /** @type EE_Message $msg */
133
-            $msg = $this->_generation_queue->get_message_repository()->current();
134
-
135
-            /**
136
-             * need to get the next object and capture it for setting manually after deletes.  The reason is that when
137
-             * an object is removed from the repo then valid for the next object will fail.
138
-             */
139
-            $this->_generation_queue->get_message_repository()->next();
140
-            $next_msg = $this->_generation_queue->get_message_repository()->current();
141
-            //restore pointer to current item
142
-            $this->_generation_queue->get_message_repository()->set_current($msg);
143
-
144
-            //skip and delete if the current $msg is NOT incomplete (queued for generation)
145
-            if ($msg->STS_ID() !== EEM_Message::status_incomplete) {
146
-                //we keep this item in the db just remove from the repo.
147
-                $this->_generation_queue->get_message_repository()->remove($msg);
148
-                //next item
149
-                $this->_generation_queue->get_message_repository()->set_current($next_msg);
150
-                continue;
151
-            }
152
-
153
-            if ($this->_verify()) {
154
-                //let's get generating!
155
-                $this->_generate();
156
-            }
157
-
158
-            //don't persist debug_only messages if the messages system is not in debug mode.
159
-            if ($msg->STS_ID() === EEM_Message::status_debug_only
160
-                && ! EEM_Message::debug()
161
-            ) {
162
-                do_action(
163
-                    'AHEE__EE_Messages_Generator__generate__before_debug_delete',
164
-                    $msg,
165
-                    $this->_error_msg,
166
-                    $this->_current_messenger,
167
-                    $this->_current_message_type,
168
-                    $this->_current_data_handler
169
-                );
170
-                $this->_generation_queue->get_message_repository()->delete();
171
-                $this->_generation_queue->get_message_repository()->set_current($next_msg);
172
-                continue;
173
-            }
174
-
175
-            //if there are error messages then let's set the status and the error message.
176
-            if ($this->_error_msg) {
177
-                //if the status is already debug only, then let's leave it at that.
178
-                if ($msg->STS_ID() !== EEM_Message::status_debug_only) {
179
-                    $msg->set_STS_ID(EEM_Message::status_failed);
180
-                }
181
-                do_action(
182
-                    'AHEE__EE_Messages_Generator__generate__processing_failed_message',
183
-                    $msg,
184
-                    $this->_error_msg,
185
-                    $this->_current_messenger,
186
-                    $this->_current_message_type,
187
-                    $this->_current_data_handler
188
-                );
189
-                $msg->set_error_message(
190
-                    esc_html__('Message failed to generate for the following reasons: ', 'event_espresso')
191
-                    . "\n"
192
-                    . implode("\n", $this->_error_msg)
193
-                );
194
-                $msg->set_modified(time());
195
-            } else {
196
-                do_action(
197
-                    'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete',
198
-                    $msg,
199
-                    $this->_error_msg,
200
-                    $this->_current_messenger,
201
-                    $this->_current_message_type,
202
-                    $this->_current_data_handler
203
-                );
204
-                //remove from db
205
-                $this->_generation_queue->get_message_repository()->delete();
206
-            }
207
-            //next item
208
-            $this->_generation_queue->get_message_repository()->set_current($next_msg);
209
-        }
210
-
211
-        //generation queue is ALWAYS saved to record any errors in the generation process.
212
-        $this->_generation_queue->save();
213
-
214
-        /**
215
-         * save _ready_queue if flag set.
216
-         * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method.  This
217
-         * means if a field was added that is not a valid database column.  The EE_Message was already saved to the db
218
-         * so a EE_Extra_Meta entry could be created and attached to the EE_Message.  In those cases the save flag is
219
-         * irrelevant.
220
-         */
221
-        if ($save) {
222
-            $this->_ready_queue->save();
223
-        }
224
-
225
-        //final reset of properties
226
-        $this->_reset_current_properties();
227
-
228
-        return $this->_ready_queue;
229
-    }
230
-
231
-
232
-    /**
233
-     * This resets all the properties used for holding "current" values corresponding to the current EE_Message object
234
-     * in the generation queue.
235
-     */
236
-    protected function _reset_current_properties()
237
-    {
238
-        $this->_verified = false;
239
-        //make sure any _data value in the current message type is reset
240
-        if ($this->_current_message_type instanceof EE_message_type) {
241
-            $this->_current_message_type->reset_data();
242
-        }
243
-        $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null;
244
-    }
245
-
246
-
247
-    /**
248
-     * This proceeds with the actual generation of a message.  By the time this is called, there should already be a
249
-     * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the
250
-     * _generating_queue.
251
-     *
252
-     * @return bool Whether the message was successfully generated or not.
253
-     * @throws EE_Error
254
-     * @throws InvalidArgumentException
255
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
256
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
257
-     */
258
-    protected function _generate()
259
-    {
260
-        //double check verification has run and that everything is ready to work with (saves us having to validate
261
-        // everything again).
262
-        if (! $this->_verified) {
263
-            return false; //get out because we don't have a valid setup to work with.
264
-        }
265
-
266
-
267
-        try {
268
-            $addressees = $this->_current_message_type->get_addressees(
269
-                $this->_current_data_handler,
270
-                $this->_generation_queue->get_message_repository()->current()->context()
271
-            );
272
-        } catch (EE_Error $e) {
273
-            $this->_error_msg[] = $e->getMessage();
274
-            return false;
275
-        }
276
-
277
-
278
-        //if no addressees then get out because there is nothing to generation (possible bad data).
279
-        if (! $this->_valid_addressees($addressees)) {
280
-            do_action(
281
-                'AHEE__EE_Messages_Generator___generate__invalid_addressees',
282
-                $this->_generation_queue->get_message_repository()->current(),
283
-                $addressees,
284
-                $this->_current_messenger,
285
-                $this->_current_message_type,
286
-                $this->_current_data_handler
287
-            );
288
-            $this->_generation_queue->get_message_repository()->current()->set_STS_ID(
289
-                EEM_Message::status_debug_only
290
-            );
291
-            $this->_error_msg[] = esc_html__(
292
-                'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects.  There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.',
293
-                'event_espresso'
294
-            );
295
-            return false;
296
-        }
297
-
298
-        $message_template_group = $this->_get_message_template_group();
299
-
300
-        //in the unlikely event there is no EE_Message_Template_Group available, get out!
301
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
302
-            $this->_error_msg[] = esc_html__(
303
-                'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
304
-                'event_espresso'
305
-            );
306
-            return false;
307
-        }
308
-
309
-        //get formatted templates for using to parse and setup EE_Message objects.
310
-        $templates = $this->_get_templates($message_template_group);
311
-
312
-
313
-        //setup new EE_Message objects (and add to _ready_queue)
314
-        return $this->_assemble_messages($addressees, $templates, $message_template_group);
315
-    }
316
-
317
-
318
-    /**
319
-     * Retrieves the message template group being used for generating messages.
320
-     * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times.
321
-     *
322
-     * @return EE_Message_Template_Group|null
323
-     * @throws EE_Error
324
-     * @throws InvalidArgumentException
325
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
326
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
327
-     */
328
-    protected function _get_message_template_group()
329
-    {
330
-        //first see if there is a specific message template group requested (current message in the queue has a specific
331
-        //GRP_ID
332
-        $message_template_group = $this->_specific_message_template_group_from_queue();
333
-        if ($message_template_group instanceof EE_Message_Template_Group) {
334
-            return $message_template_group;
335
-        }
336
-
337
-        //get event_ids from the datahandler so we can check to see if there's already a message template group for them
338
-        //in the collection.
339
-        $event_ids              = $this->_get_event_ids_from_current_data_handler();
340
-        $message_template_group = $this->_template_collection->get_by_key(
341
-            $this->_template_collection->getKey(
342
-                $this->_current_messenger->name,
343
-                $this->_current_message_type->name,
344
-                $event_ids
345
-            )
346
-        );
347
-
348
-        //if we have a message template group then no need to hit the database, just return it.
349
-        if ($message_template_group instanceof EE_Message_Template_Group) {
350
-            return $message_template_group;
351
-        }
352
-
353
-        //okay made it here, so let's get the global group first for this messenger and message type to ensure
354
-        //there is no override set.
355
-        $global_message_template_group =
356
-            $this->_get_global_message_template_group_for_current_messenger_and_message_type();
357
-
358
-        if ($global_message_template_group instanceof EE_Message_Template_Group
359
-            && $global_message_template_group->get('MTP_is_override')
360
-        ) {
361
-            return $global_message_template_group;
362
-        }
363
-
364
-        //if we're still here, that means there was no message template group for the events in the collection and
365
-        //the global message template group for the messenger and message type is not set for override.  So next step is
366
-        //to see if there is a common shared custom message template group for this set of events.
367
-        $message_template_group = $this->_get_shared_message_template_for_events($event_ids);
368
-        if ($message_template_group instanceof EE_Message_Template_Group) {
369
-            return $message_template_group;
370
-        }
371
-
372
-        //STILL here?  Okay that means the fallback is to just use the global message template group for this event set.
373
-        //So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this request)
374
-        //and return it.
375
-        if ($global_message_template_group instanceof EE_Message_Template_Group) {
376
-            $this->_template_collection->add(
377
-                $global_message_template_group,
378
-                $event_ids
379
-            );
380
-            return $global_message_template_group;
381
-        }
382
-
383
-        //if we land here that means there's NO active message template group for this set.
384
-        //TODO this will be a good target for some optimization down the road.  Whenever there is no active message
385
-        //template group for a given event set then cache that result so we don't repeat the logic.  However, for now,
386
-        //this should likely bit hit rarely enough that it's not a significant issue.
387
-        return null;
388
-    }
389
-
390
-
391
-    /**
392
-     * This checks the current message in the queue and determines if there is a specific Message Template Group
393
-     * requested for that message.
394
-     *
395
-     * @return EE_Message_Template_Group|null
396
-     * @throws EE_Error
397
-     * @throws InvalidArgumentException
398
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
399
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
400
-     */
401
-    protected function _specific_message_template_group_from_queue()
402
-    {
403
-        //is there a GRP_ID already on the EE_Message object?  If there is, then a specific template has been requested
404
-        //so let's use that.
405
-        $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID();
406
-
407
-        if ($GRP_ID) {
408
-            //attempt to retrieve from repo first
409
-            $message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
410
-            if ($message_template_group instanceof EE_Message_Template_Group) {
411
-                return $message_template_group;  //got it!
412
-            }
413
-
414
-            //nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
415
-            //is not valid, so we'll continue on in the code assuming there's NO GRP_ID.
416
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
417
-            if ($message_template_group instanceof EE_Message_Template_Group) {
418
-                $this->_template_collection->add($message_template_group);
419
-                return $message_template_group;
420
-            }
421
-        }
422
-        return null;
423
-    }
424
-
425
-
426
-    /**
427
-     * Returns whether the event ids passed in all share the same message template group for the current message type
428
-     * and messenger.
429
-     *
430
-     * @param array $event_ids
431
-     * @return bool true means they DO share the same message template group, false means they don't.
432
-     * @throws EE_Error
433
-     * @throws InvalidArgumentException
434
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
435
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
436
-     */
437
-    protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
438
-    {
439
-        foreach ($this->_current_data_handler->events as $event) {
440
-            $event_ids[$event['ID']] = $event['ID'];
441
-        }
442
-        $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
443
-            array(
444
-                array(
445
-                    'Event.EVT_ID'           => array('IN', $event_ids),
446
-                    'MTP_messenger'    => $this->_current_messenger->name,
447
-                    'MTP_message_type' => $this->_current_message_type->name,
448
-                ),
449
-            ),
450
-            'GRP_ID',
451
-            true
452
-        );
453
-        return $count_of_message_template_groups === 1;
454
-    }
455
-
456
-
457
-    /**
458
-     * This will get the shared message template group for events that are in the current data handler but ONLY if
459
-     * there's a single shared message template group among all the events.  Otherwise it returns null.
460
-     *
461
-     * @param array $event_ids
462
-     * @return EE_Message_Template_Group|null
463
-     * @throws EE_Error
464
-     * @throws InvalidArgumentException
465
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
466
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
467
-     */
468
-    protected function _get_shared_message_template_for_events(array $event_ids)
469
-    {
470
-        $message_template_group = null;
471
-        if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) {
472
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one(
473
-                array(
474
-                    array(
475
-                        'Event.EVT_ID'           => array('IN', $event_ids),
476
-                        'MTP_messenger'    => $this->_current_messenger->name,
477
-                        'MTP_message_type' => $this->_current_message_type->name,
478
-                        'MTP_is_active'    => true,
479
-                    ),
480
-                    'group_by' => 'GRP_ID',
481
-                )
482
-            );
483
-            //store this in the collection if its valid
484
-            if ($message_template_group instanceof EE_Message_Template_Group) {
485
-                $this->_template_collection->add(
486
-                    $message_template_group,
487
-                    $event_ids
488
-                );
489
-            }
490
-        }
491
-        return $message_template_group;
492
-    }
493
-
494
-
495
-    /**
496
-     * Retrieves the global message template group for the current messenger and message type.
497
-     *
498
-     * @return EE_Message_Template_Group|null
499
-     * @throws EE_Error
500
-     * @throws InvalidArgumentException
501
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
502
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
503
-     */
504
-    protected function _get_global_message_template_group_for_current_messenger_and_message_type()
505
-    {
506
-        //first check the collection (we use an array with 0 in it to represent global groups).
507
-        $global_message_template_group = $this->_template_collection->get_by_key(
508
-            $this->_template_collection->getKey(
509
-                $this->_current_messenger->name,
510
-                $this->_current_message_type->name,
511
-                array(0)
512
-            )
513
-        );
514
-
515
-        //if we don't have a group lets hit the db.
516
-        if (! $global_message_template_group instanceof EE_Message_Template_Group) {
517
-            $global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
518
-                array(
519
-                    array(
520
-                        'MTP_messenger'    => $this->_current_messenger->name,
521
-                        'MTP_message_type' => $this->_current_message_type->name,
522
-                        'MTP_is_active'    => true,
523
-                        'MTP_is_global'    => true,
524
-                    ),
525
-                )
526
-            );
527
-            //if we have a group, add it to the collection.
528
-            if ($global_message_template_group instanceof EE_Message_Template_Group) {
529
-                $this->_template_collection->add(
530
-                    $global_message_template_group,
531
-                    array(0)
532
-                );
533
-            }
534
-        }
535
-        return $global_message_template_group;
536
-    }
537
-
538
-
539
-    /**
540
-     * Returns an array of event ids for all the events within the current data handler.
541
-     *
542
-     * @return array
543
-     */
544
-    protected function _get_event_ids_from_current_data_handler()
545
-    {
546
-        $event_ids = array();
547
-        foreach ($this->_current_data_handler->events as $event) {
548
-            $event_ids[$event['ID']] = $event['ID'];
549
-        }
550
-        return $event_ids;
551
-    }
552
-
553
-
554
-    /**
555
-     *  Retrieves formatted array of template information for each context specific to the given
556
-     *  EE_Message_Template_Group
557
-     *
558
-     * @param EE_Message_Template_Group $message_template_group
559
-     * @return array The returned array is in this structure:
560
-     *                          array(
561
-     *                          'field_name' => array(
562
-     *                          'context' => 'content'
563
-     *                          )
564
-     *                          )
565
-     * @throws EE_Error
566
-     */
567
-    protected function _get_templates(EE_Message_Template_Group $message_template_group)
568
-    {
569
-        $templates         = array();
570
-        $context_templates = $message_template_group->context_templates();
571
-        foreach ($context_templates as $context => $template_fields) {
572
-            foreach ($template_fields as $template_field => $template_obj) {
573
-                if (! $template_obj instanceof EE_Message_Template) {
574
-                    continue;
575
-                }
576
-                $templates[$template_field][$context] = $template_obj->get('MTP_content');
577
-            }
578
-        }
579
-        return $templates;
580
-    }
581
-
582
-
583
-    /**
584
-     * Assembles new fully generated EE_Message objects and adds to _ready_queue
585
-     *
586
-     * @param array                     $addressees  Array of EE_Messages_Addressee objects indexed by message type
587
-     *                                               context.
588
-     * @param array                     $templates   formatted array of templates used for parsing data.
589
-     * @param EE_Message_Template_Group $message_template_group
590
-     * @return bool true if message generation went a-ok.  false if some sort of exception occurred.  Note: The
591
-     *                                               method will attempt to generate ALL EE_Message objects and add to
592
-     *                                               the _ready_queue.  Successfully generated messages get added to the
593
-     *                                               queue with EEM_Message::status_idle, unsuccessfully generated
594
-     *                                               messages will get added to the queue as EEM_Message::status_failed.
595
-     *                                               Very rarely should "false" be returned from this method.
596
-     * @throws EE_Error
597
-     */
598
-    protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group)
599
-    {
600
-
601
-        //if templates are empty then get out because we can't generate anything.
602
-        if (! $templates) {
603
-            $this->_error_msg[] = esc_html__(
604
-                'Unable to assemble messages because there are no templates retrieved for generating the messages with',
605
-                'event_espresso'
606
-            );
607
-            return false;
608
-        }
609
-
610
-        //We use this as the counter for generated messages because don't forget we may be executing this inside of a
611
-        //generation_queue.  So _ready_queue may have generated EE_Message objects already.
612
-        $generated_count = 0;
613
-        foreach ($addressees as $context => $recipients) {
614
-            foreach ($recipients as $recipient) {
615
-                $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group);
616
-                if ($message instanceof EE_Message) {
617
-                    $this->_ready_queue->add(
618
-                        $message,
619
-                        array(),
620
-                        $this->_generation_queue->get_message_repository()->is_preview(),
621
-                        $this->_generation_queue->get_message_repository()->is_test_send()
622
-                    );
623
-                    $generated_count++;
624
-                }
625
-
626
-                //if the current MSG being generated is for a test send then we'll only use ONE message in the
627
-                // generation.
628
-                if ($this->_generation_queue->get_message_repository()->is_test_send()) {
629
-                    break 2;
630
-                }
631
-            }
632
-        }
633
-
634
-        //if there are no generated messages then something else fatal went wrong.
635
-        return $generated_count > 0;
636
-    }
637
-
638
-
639
-    /**
640
-     * @param string                    $context   The context for the generated message.
641
-     * @param EE_Messages_Addressee     $recipient
642
-     * @param array                     $templates formatted array of templates used for parsing data.
643
-     * @param EE_Message_Template_Group $message_template_group
644
-     * @return bool|EE_Message
645
-     * @throws EE_Error
646
-     */
647
-    protected function _setup_message_object(
648
-        $context,
649
-        EE_Messages_Addressee $recipient,
650
-        $templates,
651
-        EE_Message_Template_Group $message_template_group
652
-    ) {
653
-        //stuff we already know
654
-        $transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0;
655
-        $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction
656
-            ? $this->_current_data_handler->txn->ID()
657
-            : $transaction_id;
658
-        $message_fields = array(
659
-            'GRP_ID'           => $message_template_group->ID(),
660
-            'TXN_ID'           => $transaction_id,
661
-            'MSG_messenger'    => $this->_current_messenger->name,
662
-            'MSG_message_type' => $this->_current_message_type->name,
663
-            'MSG_context'      => $context,
664
-        );
665
-
666
-        //recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab
667
-        // the info from the att_obj found in the EE_Messages_Addressee object.
668
-        if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) {
669
-            $message_fields['MSG_recipient_ID']   = $recipient->att_obj instanceof EE_Attendee
670
-                ? $recipient->att_obj->ID()
671
-                : 0;
672
-            $message_fields['MSG_recipient_type'] = 'Attendee';
673
-        } else {
674
-            $message_fields['MSG_recipient_ID']   = $recipient->recipient_id;
675
-            $message_fields['MSG_recipient_type'] = $recipient->recipient_type;
676
-        }
677
-        $message = EE_Message_Factory::create($message_fields);
678
-
679
-        //grab valid shortcodes for shortcode parser
680
-        $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes();
681
-        $m_shortcodes  = $this->_current_messenger->get_valid_shortcodes();
682
-
683
-        //if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing
684
-        if ((
685
-                (
686
-                    empty($templates['to'][$context])
687
-                    && ! $this->_current_messenger->allow_empty_to_field()
688
-                )
689
-                || ! $message_template_group->is_context_active($context)
690
-            )
691
-            && ! $this->_generation_queue->get_message_repository()->is_preview()
692
-        ) {
693
-            //we silently exit here and do NOT record a fail because the message is "turned off" by having no "to"
694
-            //field.
695
-            return false;
696
-        }
697
-        $error_msg = array();
698
-        foreach ($templates as $field => $field_context) {
699
-            $error_msg = array();
700
-            //let's setup the valid shortcodes for the incoming context.
701
-            $valid_shortcodes = $mt_shortcodes[$context];
702
-            //merge in valid shortcodes for the field.
703
-            $shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes;
704
-            if (isset($templates[$field][$context])) {
705
-                //prefix field.
706
-                $column_name = 'MSG_' . $field;
707
-                try {
708
-                    $content = $this->_shortcode_parser->parse_message_template(
709
-                        $templates[$field][$context],
710
-                        $recipient,
711
-                        $shortcodes,
712
-                        $this->_current_message_type,
713
-                        $this->_current_messenger,
714
-                        $message
715
-                    );
716
-                    //the model field removes slashes when setting (usually necessary when the input is from the
717
-                    //request) but this value is from another model and has no slashes. So add them so it matchces
718
-                    //what the field expected (otherwise slashes will have been stripped from this an extra time)
719
-                    $message->set_field_or_extra_meta($column_name, addslashes($content));
720
-                } catch (EE_Error $e) {
721
-                    $error_msg[] = sprintf(
722
-                        esc_html__(
723
-                            'There was a problem generating the content for the field %s: %s',
724
-                            'event_espresso'
725
-                        ),
726
-                        $field,
727
-                        $e->getMessage()
728
-                    );
729
-                    $message->set_STS_ID(EEM_Message::status_failed);
730
-                }
731
-            }
732
-        }
733
-
734
-        if ($message->STS_ID() === EEM_Message::status_failed) {
735
-            $error_msg = esc_html__('There were problems generating this message:', 'event_espresso')
736
-                         . "\n"
737
-                         . implode("\n", $error_msg);
738
-            $message->set_error_message($error_msg);
739
-        } else {
740
-            $message->set_STS_ID(EEM_Message::status_idle);
741
-        }
742
-        return $message;
743
-    }
744
-
745
-
746
-    /**
747
-     * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate
748
-     * error message if either is missing.
749
-     *
750
-     * @return bool true means there were no errors, false means there were errors.
751
-     * @throws EE_Error
752
-     * @throws ReflectionException
753
-     */
754
-    protected function _verify()
755
-    {
756
-        //reset error message to an empty array.
757
-        $this->_error_msg = array();
758
-        $valid            = true;
759
-        $valid            = $valid ? $this->_validate_messenger_and_message_type() : $valid;
760
-        $valid            = $valid ? $this->_validate_and_setup_data() : $valid;
761
-
762
-        //set the verified flag so we know everything has been validated.
763
-        $this->_verified = $valid;
764
-
765
-        return $valid;
766
-    }
767
-
768
-
769
-    /**
770
-     * This accepts an array and validates that it is an array indexed by context with each value being an array of
771
-     * EE_Messages_Addressee objects.
772
-     *
773
-     * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[]
774
-     * @return bool
775
-     */
776
-    protected function _valid_addressees($addressees)
777
-    {
778
-        if (! $addressees || ! is_array($addressees)) {
779
-            return false;
780
-        }
781
-
782
-        foreach ($addressees as $addressee_array) {
783
-            foreach ($addressee_array as $addressee) {
784
-                if (! $addressee instanceof EE_Messages_Addressee) {
785
-                    return false;
786
-                }
787
-            }
788
-        }
789
-        return true;
790
-    }
791
-
792
-
793
-    /**
794
-     * This validates the messenger, message type, and presences of generation data for the current EE_Message in the
795
-     * queue. This process sets error messages if something is wrong.
796
-     *
797
-     * @return bool   true is if there are no errors.  false is if there is.
798
-     */
799
-    protected function _validate_messenger_and_message_type()
800
-    {
801
-
802
-        //first are there any existing error messages?  If so then return.
803
-        if ($this->_error_msg) {
804
-            return false;
805
-        }
806
-        /** @type EE_Message $message */
807
-        $message = $this->_generation_queue->get_message_repository()->current();
808
-        try {
809
-            $this->_current_messenger = $message->valid_messenger(true)
810
-                ? $message->messenger_object()
811
-                : null;
812
-        } catch (Exception $e) {
813
-            $this->_error_msg[] = $e->getMessage();
814
-        }
815
-        try {
816
-            $this->_current_message_type = $message->valid_message_type(true)
817
-                ? $message->message_type_object()
818
-                : null;
819
-        } catch (Exception $e) {
820
-            $this->_error_msg[] = $e->getMessage();
821
-        }
822
-
823
-        /**
824
-         * Check if there is any generation data, but only if this is not for a preview.
825
-         */
826
-        if (! $this->_generation_queue->get_message_repository()->get_generation_data()
827
-            && (
828
-                ! $this->_generation_queue->get_message_repository()->is_preview()
829
-                && $this->_generation_queue->get_message_repository()->get_data_handler()
830
-                   !== 'EE_Messages_Preview_incoming_data'
831
-            )
832
-        ) {
833
-            $this->_error_msg[] = esc_html__(
834
-                'There is no generation data for this message. Unable to generate.',
835
-                'event_espresso'
836
-            );
837
-        }
838
-
839
-        return empty($this->_error_msg);
840
-    }
841
-
842
-
843
-    /**
844
-     * This method retrieves the expected data handler for the message type and validates the generation data for that
845
-     * data handler.
846
-     *
847
-     * @return bool true means there are no errors.  false means there were errors (and handler did not get setup).
848
-     * @throws EE_Error
849
-     * @throws ReflectionException
850
-     */
851
-    protected function _validate_and_setup_data()
852
-    {
853
-
854
-        //First, are there any existing error messages?  If so, return because if there were errors elsewhere this can't
855
-        //be used anyways.
856
-        if ($this->_error_msg) {
857
-            return false;
858
-        }
859
-
860
-        $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data();
861
-
862
-        /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/
863
-        $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
864
-            ? $this->_generation_queue->get_message_repository()->get_data_handler()
865
-            : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
866
-
867
-        //If this EE_Message is for a preview, then let's switch out to the preview data handler.
868
-        if ($this->_generation_queue->get_message_repository()->is_preview()) {
869
-            $data_handler_class_name = 'EE_Messages_Preview_incoming_data';
870
-        }
871
-
872
-        //First get the class name for the data handler (and also verifies it exists.
873
-        if (! class_exists($data_handler_class_name)) {
874
-            $this->_error_msg[] = sprintf(
875
-                esc_html__(
876
-                    'The included data handler class name does not match any valid, accessible, "%1$s" classes.  Looking for %2$s.',
877
-                    'event_espresso'
878
-                ),
879
-                'EE_Messages_incoming_data',
880
-                $data_handler_class_name
881
-            );
882
-            return false;
883
-        }
884
-
885
-        //convert generation_data for data_handler_instantiation.
886
-        $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data);
887
-
888
-        //note, this may set error messages as well.
889
-        $this->_set_data_handler($generation_data, $data_handler_class_name);
890
-
891
-        return empty($this->_error_msg);
892
-    }
893
-
894
-
895
-    /**
896
-     * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and
897
-     * adds it to the _data repository.
898
-     *
899
-     * @param mixed  $generating_data           This is data expected by the instantiated data handler.
900
-     * @param string $data_handler_class_name   This is the reference string indicating what data handler is being
901
-     *                                          instantiated.
902
-     * @return void .
903
-     * @throws EE_Error
904
-     * @throws ReflectionException
905
-     */
906
-    protected function _set_data_handler($generating_data, $data_handler_class_name)
907
-    {
908
-        //valid classname for the data handler.  Now let's setup the key for the data handler repository to see if there
909
-        //is already a ready data handler in the repository.
910
-        $this->_current_data_handler = $this->_data_handler_collection->get_by_key(
911
-            $this->_data_handler_collection->get_key(
912
-                $data_handler_class_name,
913
-                $generating_data
914
-            )
915
-        );
916
-        if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
917
-            //no saved data_handler in the repo so let's set one up and add it to the repo.
918
-            try {
919
-                $this->_current_data_handler = new $data_handler_class_name($generating_data);
920
-                $this->_data_handler_collection->add($this->_current_data_handler, $generating_data);
921
-            } catch (EE_Error $e) {
922
-                $this->_error_msg[] = $e->get_error();
923
-            }
924
-        }
925
-    }
926
-
927
-
928
-    /**
929
-     * The queued EE_Message for generation does not save the data used for generation as objects
930
-     * because serialization of those objects could be problematic if the data is saved to the db.
931
-     * So this method calls the static method on the associated data_handler for the given message_type
932
-     * and that preps the data for later instantiation when generating.
933
-     *
934
-     * @param EE_Message_To_Generate $message_to_generate
935
-     * @param bool                   $preview Indicate whether this is being used for a preview or not.
936
-     * @return mixed Prepped data for persisting to the queue.  false is returned if unable to prep data.
937
-     */
938
-    protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview)
939
-    {
940
-        /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
941
-        $data_handler = $message_to_generate->get_data_handler_class_name($preview);
942
-        if (! $message_to_generate->valid()) {
943
-            return false; //unable to get the data because the info in the EE_Message_To_Generate class is invalid.
944
-        }
945
-        return $data_handler::convert_data_for_persistent_storage($message_to_generate->data());
946
-    }
947
-
948
-
949
-    /**
950
-     * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue.
951
-     *
952
-     * @param EE_Message_To_Generate $message_to_generate
953
-     * @param bool                   $test_send Whether this is just a test send or not.  Typically used for previews.
954
-     * @throws InvalidArgumentException
955
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
956
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
957
-     */
958
-    public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false)
959
-    {
960
-        //prep data
961
-        $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview());
962
-
963
-        $message = $message_to_generate->get_EE_Message();
964
-
965
-        //is there a GRP_ID in the request?
966
-        if ($GRP_ID = EE_Registry::instance()->REQ->get('GRP_ID')) {
967
-            $message->set_GRP_ID($GRP_ID);
968
-        }
969
-
970
-        if ($data === false) {
971
-            $message->set_STS_ID(EEM_Message::status_failed);
972
-            $message->set_error_message(
973
-                esc_html__(
974
-                    'Unable to prepare data for persistence to the database.',
975
-                    'event_espresso'
976
-                )
977
-            );
978
-        } else {
979
-            //make sure that the data handler is cached on the message as well
980
-            $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name();
981
-        }
982
-
983
-        $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send);
984
-    }
16
+	/**
17
+	 * @type EE_Messages_Data_Handler_Collection
18
+	 */
19
+	protected $_data_handler_collection;
20
+
21
+	/**
22
+	 * @type  EE_Message_Template_Group_Collection
23
+	 */
24
+	protected $_template_collection;
25
+
26
+	/**
27
+	 * This will hold the data handler for the current EE_Message being generated.
28
+	 *
29
+	 * @type EE_Messages_incoming_data
30
+	 */
31
+	protected $_current_data_handler;
32
+
33
+	/**
34
+	 * This holds the EE_Messages_Queue that contains the messages to generate.
35
+	 *
36
+	 * @type EE_Messages_Queue
37
+	 */
38
+	protected $_generation_queue;
39
+
40
+	/**
41
+	 * This holds the EE_Messages_Queue that will store the generated EE_Message objects.
42
+	 *
43
+	 * @type EE_Messages_Queue
44
+	 */
45
+	protected $_ready_queue;
46
+
47
+	/**
48
+	 * This is a container for any error messages that get created through the generation
49
+	 * process.
50
+	 *
51
+	 * @type array
52
+	 */
53
+	protected $_error_msg = array();
54
+
55
+	/**
56
+	 * Flag used to set when the current EE_Message in the generation queue has been verified.
57
+	 *
58
+	 * @type bool
59
+	 */
60
+	protected $_verified = false;
61
+
62
+	/**
63
+	 * This will hold the current messenger object corresponding with the current EE_Message in the generation queue.
64
+	 *
65
+	 * @type EE_messenger
66
+	 */
67
+	protected $_current_messenger;
68
+
69
+	/**
70
+	 * This will hold the current message type object corresponding with the current EE_Message in the generation queue.
71
+	 *
72
+	 * @type EE_message_type
73
+	 */
74
+	protected $_current_message_type;
75
+
76
+	/**
77
+	 * @type EEH_Parse_Shortcodes
78
+	 */
79
+	protected $_shortcode_parser;
80
+
81
+
82
+	/**
83
+	 * @param EE_Messages_Queue                     $generation_queue
84
+	 * @param \EE_Messages_Queue                    $ready_queue
85
+	 * @param \EE_Messages_Data_Handler_Collection  $data_handler_collection
86
+	 * @param \EE_Message_Template_Group_Collection $template_collection
87
+	 * @param \EEH_Parse_Shortcodes                 $shortcode_parser
88
+	 */
89
+	public function __construct(
90
+		EE_Messages_Queue $generation_queue,
91
+		EE_Messages_Queue $ready_queue,
92
+		EE_Messages_Data_Handler_Collection $data_handler_collection,
93
+		EE_Message_Template_Group_Collection $template_collection,
94
+		EEH_Parse_Shortcodes $shortcode_parser
95
+	) {
96
+		$this->_generation_queue        = $generation_queue;
97
+		$this->_ready_queue             = $ready_queue;
98
+		$this->_data_handler_collection = $data_handler_collection;
99
+		$this->_template_collection     = $template_collection;
100
+		$this->_shortcode_parser        = $shortcode_parser;
101
+	}
102
+
103
+
104
+	/**
105
+	 * @return EE_Messages_Queue
106
+	 */
107
+	public function generation_queue()
108
+	{
109
+		return $this->_generation_queue;
110
+	}
111
+
112
+
113
+	/**
114
+	 *  This iterates through the provided queue and generates the EE_Message objects.
115
+	 *  When iterating through the queue, the queued item that served as the base for generating other EE_Message
116
+	 *  objects gets removed and the new EE_Message objects get added to a NEW queue.  The NEW queue is then returned
117
+	 *  for the caller to decide what to do with it.
118
+	 *
119
+	 * @param   bool $save Whether to save the EE_Message objects in the new queue or just return.
120
+	 * @return EE_Messages_Queue The new queue for holding generated EE_Message objects.
121
+	 * @throws EE_Error
122
+	 * @throws ReflectionException
123
+	 */
124
+	public function generate($save = true)
125
+	{
126
+		//iterate through the messages in the queue, generate, and add to new queue.
127
+		$this->_generation_queue->get_message_repository()->rewind();
128
+		while ($this->_generation_queue->get_message_repository()->valid()) {
129
+			//reset "current" properties
130
+			$this->_reset_current_properties();
131
+
132
+			/** @type EE_Message $msg */
133
+			$msg = $this->_generation_queue->get_message_repository()->current();
134
+
135
+			/**
136
+			 * need to get the next object and capture it for setting manually after deletes.  The reason is that when
137
+			 * an object is removed from the repo then valid for the next object will fail.
138
+			 */
139
+			$this->_generation_queue->get_message_repository()->next();
140
+			$next_msg = $this->_generation_queue->get_message_repository()->current();
141
+			//restore pointer to current item
142
+			$this->_generation_queue->get_message_repository()->set_current($msg);
143
+
144
+			//skip and delete if the current $msg is NOT incomplete (queued for generation)
145
+			if ($msg->STS_ID() !== EEM_Message::status_incomplete) {
146
+				//we keep this item in the db just remove from the repo.
147
+				$this->_generation_queue->get_message_repository()->remove($msg);
148
+				//next item
149
+				$this->_generation_queue->get_message_repository()->set_current($next_msg);
150
+				continue;
151
+			}
152
+
153
+			if ($this->_verify()) {
154
+				//let's get generating!
155
+				$this->_generate();
156
+			}
157
+
158
+			//don't persist debug_only messages if the messages system is not in debug mode.
159
+			if ($msg->STS_ID() === EEM_Message::status_debug_only
160
+				&& ! EEM_Message::debug()
161
+			) {
162
+				do_action(
163
+					'AHEE__EE_Messages_Generator__generate__before_debug_delete',
164
+					$msg,
165
+					$this->_error_msg,
166
+					$this->_current_messenger,
167
+					$this->_current_message_type,
168
+					$this->_current_data_handler
169
+				);
170
+				$this->_generation_queue->get_message_repository()->delete();
171
+				$this->_generation_queue->get_message_repository()->set_current($next_msg);
172
+				continue;
173
+			}
174
+
175
+			//if there are error messages then let's set the status and the error message.
176
+			if ($this->_error_msg) {
177
+				//if the status is already debug only, then let's leave it at that.
178
+				if ($msg->STS_ID() !== EEM_Message::status_debug_only) {
179
+					$msg->set_STS_ID(EEM_Message::status_failed);
180
+				}
181
+				do_action(
182
+					'AHEE__EE_Messages_Generator__generate__processing_failed_message',
183
+					$msg,
184
+					$this->_error_msg,
185
+					$this->_current_messenger,
186
+					$this->_current_message_type,
187
+					$this->_current_data_handler
188
+				);
189
+				$msg->set_error_message(
190
+					esc_html__('Message failed to generate for the following reasons: ', 'event_espresso')
191
+					. "\n"
192
+					. implode("\n", $this->_error_msg)
193
+				);
194
+				$msg->set_modified(time());
195
+			} else {
196
+				do_action(
197
+					'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete',
198
+					$msg,
199
+					$this->_error_msg,
200
+					$this->_current_messenger,
201
+					$this->_current_message_type,
202
+					$this->_current_data_handler
203
+				);
204
+				//remove from db
205
+				$this->_generation_queue->get_message_repository()->delete();
206
+			}
207
+			//next item
208
+			$this->_generation_queue->get_message_repository()->set_current($next_msg);
209
+		}
210
+
211
+		//generation queue is ALWAYS saved to record any errors in the generation process.
212
+		$this->_generation_queue->save();
213
+
214
+		/**
215
+		 * save _ready_queue if flag set.
216
+		 * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method.  This
217
+		 * means if a field was added that is not a valid database column.  The EE_Message was already saved to the db
218
+		 * so a EE_Extra_Meta entry could be created and attached to the EE_Message.  In those cases the save flag is
219
+		 * irrelevant.
220
+		 */
221
+		if ($save) {
222
+			$this->_ready_queue->save();
223
+		}
224
+
225
+		//final reset of properties
226
+		$this->_reset_current_properties();
227
+
228
+		return $this->_ready_queue;
229
+	}
230
+
231
+
232
+	/**
233
+	 * This resets all the properties used for holding "current" values corresponding to the current EE_Message object
234
+	 * in the generation queue.
235
+	 */
236
+	protected function _reset_current_properties()
237
+	{
238
+		$this->_verified = false;
239
+		//make sure any _data value in the current message type is reset
240
+		if ($this->_current_message_type instanceof EE_message_type) {
241
+			$this->_current_message_type->reset_data();
242
+		}
243
+		$this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null;
244
+	}
245
+
246
+
247
+	/**
248
+	 * This proceeds with the actual generation of a message.  By the time this is called, there should already be a
249
+	 * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the
250
+	 * _generating_queue.
251
+	 *
252
+	 * @return bool Whether the message was successfully generated or not.
253
+	 * @throws EE_Error
254
+	 * @throws InvalidArgumentException
255
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
256
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
257
+	 */
258
+	protected function _generate()
259
+	{
260
+		//double check verification has run and that everything is ready to work with (saves us having to validate
261
+		// everything again).
262
+		if (! $this->_verified) {
263
+			return false; //get out because we don't have a valid setup to work with.
264
+		}
265
+
266
+
267
+		try {
268
+			$addressees = $this->_current_message_type->get_addressees(
269
+				$this->_current_data_handler,
270
+				$this->_generation_queue->get_message_repository()->current()->context()
271
+			);
272
+		} catch (EE_Error $e) {
273
+			$this->_error_msg[] = $e->getMessage();
274
+			return false;
275
+		}
276
+
277
+
278
+		//if no addressees then get out because there is nothing to generation (possible bad data).
279
+		if (! $this->_valid_addressees($addressees)) {
280
+			do_action(
281
+				'AHEE__EE_Messages_Generator___generate__invalid_addressees',
282
+				$this->_generation_queue->get_message_repository()->current(),
283
+				$addressees,
284
+				$this->_current_messenger,
285
+				$this->_current_message_type,
286
+				$this->_current_data_handler
287
+			);
288
+			$this->_generation_queue->get_message_repository()->current()->set_STS_ID(
289
+				EEM_Message::status_debug_only
290
+			);
291
+			$this->_error_msg[] = esc_html__(
292
+				'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects.  There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.',
293
+				'event_espresso'
294
+			);
295
+			return false;
296
+		}
297
+
298
+		$message_template_group = $this->_get_message_template_group();
299
+
300
+		//in the unlikely event there is no EE_Message_Template_Group available, get out!
301
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
302
+			$this->_error_msg[] = esc_html__(
303
+				'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
304
+				'event_espresso'
305
+			);
306
+			return false;
307
+		}
308
+
309
+		//get formatted templates for using to parse and setup EE_Message objects.
310
+		$templates = $this->_get_templates($message_template_group);
311
+
312
+
313
+		//setup new EE_Message objects (and add to _ready_queue)
314
+		return $this->_assemble_messages($addressees, $templates, $message_template_group);
315
+	}
316
+
317
+
318
+	/**
319
+	 * Retrieves the message template group being used for generating messages.
320
+	 * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times.
321
+	 *
322
+	 * @return EE_Message_Template_Group|null
323
+	 * @throws EE_Error
324
+	 * @throws InvalidArgumentException
325
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
326
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
327
+	 */
328
+	protected function _get_message_template_group()
329
+	{
330
+		//first see if there is a specific message template group requested (current message in the queue has a specific
331
+		//GRP_ID
332
+		$message_template_group = $this->_specific_message_template_group_from_queue();
333
+		if ($message_template_group instanceof EE_Message_Template_Group) {
334
+			return $message_template_group;
335
+		}
336
+
337
+		//get event_ids from the datahandler so we can check to see if there's already a message template group for them
338
+		//in the collection.
339
+		$event_ids              = $this->_get_event_ids_from_current_data_handler();
340
+		$message_template_group = $this->_template_collection->get_by_key(
341
+			$this->_template_collection->getKey(
342
+				$this->_current_messenger->name,
343
+				$this->_current_message_type->name,
344
+				$event_ids
345
+			)
346
+		);
347
+
348
+		//if we have a message template group then no need to hit the database, just return it.
349
+		if ($message_template_group instanceof EE_Message_Template_Group) {
350
+			return $message_template_group;
351
+		}
352
+
353
+		//okay made it here, so let's get the global group first for this messenger and message type to ensure
354
+		//there is no override set.
355
+		$global_message_template_group =
356
+			$this->_get_global_message_template_group_for_current_messenger_and_message_type();
357
+
358
+		if ($global_message_template_group instanceof EE_Message_Template_Group
359
+			&& $global_message_template_group->get('MTP_is_override')
360
+		) {
361
+			return $global_message_template_group;
362
+		}
363
+
364
+		//if we're still here, that means there was no message template group for the events in the collection and
365
+		//the global message template group for the messenger and message type is not set for override.  So next step is
366
+		//to see if there is a common shared custom message template group for this set of events.
367
+		$message_template_group = $this->_get_shared_message_template_for_events($event_ids);
368
+		if ($message_template_group instanceof EE_Message_Template_Group) {
369
+			return $message_template_group;
370
+		}
371
+
372
+		//STILL here?  Okay that means the fallback is to just use the global message template group for this event set.
373
+		//So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this request)
374
+		//and return it.
375
+		if ($global_message_template_group instanceof EE_Message_Template_Group) {
376
+			$this->_template_collection->add(
377
+				$global_message_template_group,
378
+				$event_ids
379
+			);
380
+			return $global_message_template_group;
381
+		}
382
+
383
+		//if we land here that means there's NO active message template group for this set.
384
+		//TODO this will be a good target for some optimization down the road.  Whenever there is no active message
385
+		//template group for a given event set then cache that result so we don't repeat the logic.  However, for now,
386
+		//this should likely bit hit rarely enough that it's not a significant issue.
387
+		return null;
388
+	}
389
+
390
+
391
+	/**
392
+	 * This checks the current message in the queue and determines if there is a specific Message Template Group
393
+	 * requested for that message.
394
+	 *
395
+	 * @return EE_Message_Template_Group|null
396
+	 * @throws EE_Error
397
+	 * @throws InvalidArgumentException
398
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
399
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
400
+	 */
401
+	protected function _specific_message_template_group_from_queue()
402
+	{
403
+		//is there a GRP_ID already on the EE_Message object?  If there is, then a specific template has been requested
404
+		//so let's use that.
405
+		$GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID();
406
+
407
+		if ($GRP_ID) {
408
+			//attempt to retrieve from repo first
409
+			$message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
410
+			if ($message_template_group instanceof EE_Message_Template_Group) {
411
+				return $message_template_group;  //got it!
412
+			}
413
+
414
+			//nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
415
+			//is not valid, so we'll continue on in the code assuming there's NO GRP_ID.
416
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
417
+			if ($message_template_group instanceof EE_Message_Template_Group) {
418
+				$this->_template_collection->add($message_template_group);
419
+				return $message_template_group;
420
+			}
421
+		}
422
+		return null;
423
+	}
424
+
425
+
426
+	/**
427
+	 * Returns whether the event ids passed in all share the same message template group for the current message type
428
+	 * and messenger.
429
+	 *
430
+	 * @param array $event_ids
431
+	 * @return bool true means they DO share the same message template group, false means they don't.
432
+	 * @throws EE_Error
433
+	 * @throws InvalidArgumentException
434
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
435
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
436
+	 */
437
+	protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
438
+	{
439
+		foreach ($this->_current_data_handler->events as $event) {
440
+			$event_ids[$event['ID']] = $event['ID'];
441
+		}
442
+		$count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
443
+			array(
444
+				array(
445
+					'Event.EVT_ID'           => array('IN', $event_ids),
446
+					'MTP_messenger'    => $this->_current_messenger->name,
447
+					'MTP_message_type' => $this->_current_message_type->name,
448
+				),
449
+			),
450
+			'GRP_ID',
451
+			true
452
+		);
453
+		return $count_of_message_template_groups === 1;
454
+	}
455
+
456
+
457
+	/**
458
+	 * This will get the shared message template group for events that are in the current data handler but ONLY if
459
+	 * there's a single shared message template group among all the events.  Otherwise it returns null.
460
+	 *
461
+	 * @param array $event_ids
462
+	 * @return EE_Message_Template_Group|null
463
+	 * @throws EE_Error
464
+	 * @throws InvalidArgumentException
465
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
466
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
467
+	 */
468
+	protected function _get_shared_message_template_for_events(array $event_ids)
469
+	{
470
+		$message_template_group = null;
471
+		if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) {
472
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one(
473
+				array(
474
+					array(
475
+						'Event.EVT_ID'           => array('IN', $event_ids),
476
+						'MTP_messenger'    => $this->_current_messenger->name,
477
+						'MTP_message_type' => $this->_current_message_type->name,
478
+						'MTP_is_active'    => true,
479
+					),
480
+					'group_by' => 'GRP_ID',
481
+				)
482
+			);
483
+			//store this in the collection if its valid
484
+			if ($message_template_group instanceof EE_Message_Template_Group) {
485
+				$this->_template_collection->add(
486
+					$message_template_group,
487
+					$event_ids
488
+				);
489
+			}
490
+		}
491
+		return $message_template_group;
492
+	}
493
+
494
+
495
+	/**
496
+	 * Retrieves the global message template group for the current messenger and message type.
497
+	 *
498
+	 * @return EE_Message_Template_Group|null
499
+	 * @throws EE_Error
500
+	 * @throws InvalidArgumentException
501
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
502
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
503
+	 */
504
+	protected function _get_global_message_template_group_for_current_messenger_and_message_type()
505
+	{
506
+		//first check the collection (we use an array with 0 in it to represent global groups).
507
+		$global_message_template_group = $this->_template_collection->get_by_key(
508
+			$this->_template_collection->getKey(
509
+				$this->_current_messenger->name,
510
+				$this->_current_message_type->name,
511
+				array(0)
512
+			)
513
+		);
514
+
515
+		//if we don't have a group lets hit the db.
516
+		if (! $global_message_template_group instanceof EE_Message_Template_Group) {
517
+			$global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
518
+				array(
519
+					array(
520
+						'MTP_messenger'    => $this->_current_messenger->name,
521
+						'MTP_message_type' => $this->_current_message_type->name,
522
+						'MTP_is_active'    => true,
523
+						'MTP_is_global'    => true,
524
+					),
525
+				)
526
+			);
527
+			//if we have a group, add it to the collection.
528
+			if ($global_message_template_group instanceof EE_Message_Template_Group) {
529
+				$this->_template_collection->add(
530
+					$global_message_template_group,
531
+					array(0)
532
+				);
533
+			}
534
+		}
535
+		return $global_message_template_group;
536
+	}
537
+
538
+
539
+	/**
540
+	 * Returns an array of event ids for all the events within the current data handler.
541
+	 *
542
+	 * @return array
543
+	 */
544
+	protected function _get_event_ids_from_current_data_handler()
545
+	{
546
+		$event_ids = array();
547
+		foreach ($this->_current_data_handler->events as $event) {
548
+			$event_ids[$event['ID']] = $event['ID'];
549
+		}
550
+		return $event_ids;
551
+	}
552
+
553
+
554
+	/**
555
+	 *  Retrieves formatted array of template information for each context specific to the given
556
+	 *  EE_Message_Template_Group
557
+	 *
558
+	 * @param EE_Message_Template_Group $message_template_group
559
+	 * @return array The returned array is in this structure:
560
+	 *                          array(
561
+	 *                          'field_name' => array(
562
+	 *                          'context' => 'content'
563
+	 *                          )
564
+	 *                          )
565
+	 * @throws EE_Error
566
+	 */
567
+	protected function _get_templates(EE_Message_Template_Group $message_template_group)
568
+	{
569
+		$templates         = array();
570
+		$context_templates = $message_template_group->context_templates();
571
+		foreach ($context_templates as $context => $template_fields) {
572
+			foreach ($template_fields as $template_field => $template_obj) {
573
+				if (! $template_obj instanceof EE_Message_Template) {
574
+					continue;
575
+				}
576
+				$templates[$template_field][$context] = $template_obj->get('MTP_content');
577
+			}
578
+		}
579
+		return $templates;
580
+	}
581
+
582
+
583
+	/**
584
+	 * Assembles new fully generated EE_Message objects and adds to _ready_queue
585
+	 *
586
+	 * @param array                     $addressees  Array of EE_Messages_Addressee objects indexed by message type
587
+	 *                                               context.
588
+	 * @param array                     $templates   formatted array of templates used for parsing data.
589
+	 * @param EE_Message_Template_Group $message_template_group
590
+	 * @return bool true if message generation went a-ok.  false if some sort of exception occurred.  Note: The
591
+	 *                                               method will attempt to generate ALL EE_Message objects and add to
592
+	 *                                               the _ready_queue.  Successfully generated messages get added to the
593
+	 *                                               queue with EEM_Message::status_idle, unsuccessfully generated
594
+	 *                                               messages will get added to the queue as EEM_Message::status_failed.
595
+	 *                                               Very rarely should "false" be returned from this method.
596
+	 * @throws EE_Error
597
+	 */
598
+	protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group)
599
+	{
600
+
601
+		//if templates are empty then get out because we can't generate anything.
602
+		if (! $templates) {
603
+			$this->_error_msg[] = esc_html__(
604
+				'Unable to assemble messages because there are no templates retrieved for generating the messages with',
605
+				'event_espresso'
606
+			);
607
+			return false;
608
+		}
609
+
610
+		//We use this as the counter for generated messages because don't forget we may be executing this inside of a
611
+		//generation_queue.  So _ready_queue may have generated EE_Message objects already.
612
+		$generated_count = 0;
613
+		foreach ($addressees as $context => $recipients) {
614
+			foreach ($recipients as $recipient) {
615
+				$message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group);
616
+				if ($message instanceof EE_Message) {
617
+					$this->_ready_queue->add(
618
+						$message,
619
+						array(),
620
+						$this->_generation_queue->get_message_repository()->is_preview(),
621
+						$this->_generation_queue->get_message_repository()->is_test_send()
622
+					);
623
+					$generated_count++;
624
+				}
625
+
626
+				//if the current MSG being generated is for a test send then we'll only use ONE message in the
627
+				// generation.
628
+				if ($this->_generation_queue->get_message_repository()->is_test_send()) {
629
+					break 2;
630
+				}
631
+			}
632
+		}
633
+
634
+		//if there are no generated messages then something else fatal went wrong.
635
+		return $generated_count > 0;
636
+	}
637
+
638
+
639
+	/**
640
+	 * @param string                    $context   The context for the generated message.
641
+	 * @param EE_Messages_Addressee     $recipient
642
+	 * @param array                     $templates formatted array of templates used for parsing data.
643
+	 * @param EE_Message_Template_Group $message_template_group
644
+	 * @return bool|EE_Message
645
+	 * @throws EE_Error
646
+	 */
647
+	protected function _setup_message_object(
648
+		$context,
649
+		EE_Messages_Addressee $recipient,
650
+		$templates,
651
+		EE_Message_Template_Group $message_template_group
652
+	) {
653
+		//stuff we already know
654
+		$transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0;
655
+		$transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction
656
+			? $this->_current_data_handler->txn->ID()
657
+			: $transaction_id;
658
+		$message_fields = array(
659
+			'GRP_ID'           => $message_template_group->ID(),
660
+			'TXN_ID'           => $transaction_id,
661
+			'MSG_messenger'    => $this->_current_messenger->name,
662
+			'MSG_message_type' => $this->_current_message_type->name,
663
+			'MSG_context'      => $context,
664
+		);
665
+
666
+		//recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab
667
+		// the info from the att_obj found in the EE_Messages_Addressee object.
668
+		if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) {
669
+			$message_fields['MSG_recipient_ID']   = $recipient->att_obj instanceof EE_Attendee
670
+				? $recipient->att_obj->ID()
671
+				: 0;
672
+			$message_fields['MSG_recipient_type'] = 'Attendee';
673
+		} else {
674
+			$message_fields['MSG_recipient_ID']   = $recipient->recipient_id;
675
+			$message_fields['MSG_recipient_type'] = $recipient->recipient_type;
676
+		}
677
+		$message = EE_Message_Factory::create($message_fields);
678
+
679
+		//grab valid shortcodes for shortcode parser
680
+		$mt_shortcodes = $this->_current_message_type->get_valid_shortcodes();
681
+		$m_shortcodes  = $this->_current_messenger->get_valid_shortcodes();
682
+
683
+		//if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing
684
+		if ((
685
+				(
686
+					empty($templates['to'][$context])
687
+					&& ! $this->_current_messenger->allow_empty_to_field()
688
+				)
689
+				|| ! $message_template_group->is_context_active($context)
690
+			)
691
+			&& ! $this->_generation_queue->get_message_repository()->is_preview()
692
+		) {
693
+			//we silently exit here and do NOT record a fail because the message is "turned off" by having no "to"
694
+			//field.
695
+			return false;
696
+		}
697
+		$error_msg = array();
698
+		foreach ($templates as $field => $field_context) {
699
+			$error_msg = array();
700
+			//let's setup the valid shortcodes for the incoming context.
701
+			$valid_shortcodes = $mt_shortcodes[$context];
702
+			//merge in valid shortcodes for the field.
703
+			$shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes;
704
+			if (isset($templates[$field][$context])) {
705
+				//prefix field.
706
+				$column_name = 'MSG_' . $field;
707
+				try {
708
+					$content = $this->_shortcode_parser->parse_message_template(
709
+						$templates[$field][$context],
710
+						$recipient,
711
+						$shortcodes,
712
+						$this->_current_message_type,
713
+						$this->_current_messenger,
714
+						$message
715
+					);
716
+					//the model field removes slashes when setting (usually necessary when the input is from the
717
+					//request) but this value is from another model and has no slashes. So add them so it matchces
718
+					//what the field expected (otherwise slashes will have been stripped from this an extra time)
719
+					$message->set_field_or_extra_meta($column_name, addslashes($content));
720
+				} catch (EE_Error $e) {
721
+					$error_msg[] = sprintf(
722
+						esc_html__(
723
+							'There was a problem generating the content for the field %s: %s',
724
+							'event_espresso'
725
+						),
726
+						$field,
727
+						$e->getMessage()
728
+					);
729
+					$message->set_STS_ID(EEM_Message::status_failed);
730
+				}
731
+			}
732
+		}
733
+
734
+		if ($message->STS_ID() === EEM_Message::status_failed) {
735
+			$error_msg = esc_html__('There were problems generating this message:', 'event_espresso')
736
+						 . "\n"
737
+						 . implode("\n", $error_msg);
738
+			$message->set_error_message($error_msg);
739
+		} else {
740
+			$message->set_STS_ID(EEM_Message::status_idle);
741
+		}
742
+		return $message;
743
+	}
744
+
745
+
746
+	/**
747
+	 * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate
748
+	 * error message if either is missing.
749
+	 *
750
+	 * @return bool true means there were no errors, false means there were errors.
751
+	 * @throws EE_Error
752
+	 * @throws ReflectionException
753
+	 */
754
+	protected function _verify()
755
+	{
756
+		//reset error message to an empty array.
757
+		$this->_error_msg = array();
758
+		$valid            = true;
759
+		$valid            = $valid ? $this->_validate_messenger_and_message_type() : $valid;
760
+		$valid            = $valid ? $this->_validate_and_setup_data() : $valid;
761
+
762
+		//set the verified flag so we know everything has been validated.
763
+		$this->_verified = $valid;
764
+
765
+		return $valid;
766
+	}
767
+
768
+
769
+	/**
770
+	 * This accepts an array and validates that it is an array indexed by context with each value being an array of
771
+	 * EE_Messages_Addressee objects.
772
+	 *
773
+	 * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[]
774
+	 * @return bool
775
+	 */
776
+	protected function _valid_addressees($addressees)
777
+	{
778
+		if (! $addressees || ! is_array($addressees)) {
779
+			return false;
780
+		}
781
+
782
+		foreach ($addressees as $addressee_array) {
783
+			foreach ($addressee_array as $addressee) {
784
+				if (! $addressee instanceof EE_Messages_Addressee) {
785
+					return false;
786
+				}
787
+			}
788
+		}
789
+		return true;
790
+	}
791
+
792
+
793
+	/**
794
+	 * This validates the messenger, message type, and presences of generation data for the current EE_Message in the
795
+	 * queue. This process sets error messages if something is wrong.
796
+	 *
797
+	 * @return bool   true is if there are no errors.  false is if there is.
798
+	 */
799
+	protected function _validate_messenger_and_message_type()
800
+	{
801
+
802
+		//first are there any existing error messages?  If so then return.
803
+		if ($this->_error_msg) {
804
+			return false;
805
+		}
806
+		/** @type EE_Message $message */
807
+		$message = $this->_generation_queue->get_message_repository()->current();
808
+		try {
809
+			$this->_current_messenger = $message->valid_messenger(true)
810
+				? $message->messenger_object()
811
+				: null;
812
+		} catch (Exception $e) {
813
+			$this->_error_msg[] = $e->getMessage();
814
+		}
815
+		try {
816
+			$this->_current_message_type = $message->valid_message_type(true)
817
+				? $message->message_type_object()
818
+				: null;
819
+		} catch (Exception $e) {
820
+			$this->_error_msg[] = $e->getMessage();
821
+		}
822
+
823
+		/**
824
+		 * Check if there is any generation data, but only if this is not for a preview.
825
+		 */
826
+		if (! $this->_generation_queue->get_message_repository()->get_generation_data()
827
+			&& (
828
+				! $this->_generation_queue->get_message_repository()->is_preview()
829
+				&& $this->_generation_queue->get_message_repository()->get_data_handler()
830
+				   !== 'EE_Messages_Preview_incoming_data'
831
+			)
832
+		) {
833
+			$this->_error_msg[] = esc_html__(
834
+				'There is no generation data for this message. Unable to generate.',
835
+				'event_espresso'
836
+			);
837
+		}
838
+
839
+		return empty($this->_error_msg);
840
+	}
841
+
842
+
843
+	/**
844
+	 * This method retrieves the expected data handler for the message type and validates the generation data for that
845
+	 * data handler.
846
+	 *
847
+	 * @return bool true means there are no errors.  false means there were errors (and handler did not get setup).
848
+	 * @throws EE_Error
849
+	 * @throws ReflectionException
850
+	 */
851
+	protected function _validate_and_setup_data()
852
+	{
853
+
854
+		//First, are there any existing error messages?  If so, return because if there were errors elsewhere this can't
855
+		//be used anyways.
856
+		if ($this->_error_msg) {
857
+			return false;
858
+		}
859
+
860
+		$generation_data = $this->_generation_queue->get_message_repository()->get_generation_data();
861
+
862
+		/** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/
863
+		$data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
864
+			? $this->_generation_queue->get_message_repository()->get_data_handler()
865
+			: 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
866
+
867
+		//If this EE_Message is for a preview, then let's switch out to the preview data handler.
868
+		if ($this->_generation_queue->get_message_repository()->is_preview()) {
869
+			$data_handler_class_name = 'EE_Messages_Preview_incoming_data';
870
+		}
871
+
872
+		//First get the class name for the data handler (and also verifies it exists.
873
+		if (! class_exists($data_handler_class_name)) {
874
+			$this->_error_msg[] = sprintf(
875
+				esc_html__(
876
+					'The included data handler class name does not match any valid, accessible, "%1$s" classes.  Looking for %2$s.',
877
+					'event_espresso'
878
+				),
879
+				'EE_Messages_incoming_data',
880
+				$data_handler_class_name
881
+			);
882
+			return false;
883
+		}
884
+
885
+		//convert generation_data for data_handler_instantiation.
886
+		$generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data);
887
+
888
+		//note, this may set error messages as well.
889
+		$this->_set_data_handler($generation_data, $data_handler_class_name);
890
+
891
+		return empty($this->_error_msg);
892
+	}
893
+
894
+
895
+	/**
896
+	 * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and
897
+	 * adds it to the _data repository.
898
+	 *
899
+	 * @param mixed  $generating_data           This is data expected by the instantiated data handler.
900
+	 * @param string $data_handler_class_name   This is the reference string indicating what data handler is being
901
+	 *                                          instantiated.
902
+	 * @return void .
903
+	 * @throws EE_Error
904
+	 * @throws ReflectionException
905
+	 */
906
+	protected function _set_data_handler($generating_data, $data_handler_class_name)
907
+	{
908
+		//valid classname for the data handler.  Now let's setup the key for the data handler repository to see if there
909
+		//is already a ready data handler in the repository.
910
+		$this->_current_data_handler = $this->_data_handler_collection->get_by_key(
911
+			$this->_data_handler_collection->get_key(
912
+				$data_handler_class_name,
913
+				$generating_data
914
+			)
915
+		);
916
+		if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
917
+			//no saved data_handler in the repo so let's set one up and add it to the repo.
918
+			try {
919
+				$this->_current_data_handler = new $data_handler_class_name($generating_data);
920
+				$this->_data_handler_collection->add($this->_current_data_handler, $generating_data);
921
+			} catch (EE_Error $e) {
922
+				$this->_error_msg[] = $e->get_error();
923
+			}
924
+		}
925
+	}
926
+
927
+
928
+	/**
929
+	 * The queued EE_Message for generation does not save the data used for generation as objects
930
+	 * because serialization of those objects could be problematic if the data is saved to the db.
931
+	 * So this method calls the static method on the associated data_handler for the given message_type
932
+	 * and that preps the data for later instantiation when generating.
933
+	 *
934
+	 * @param EE_Message_To_Generate $message_to_generate
935
+	 * @param bool                   $preview Indicate whether this is being used for a preview or not.
936
+	 * @return mixed Prepped data for persisting to the queue.  false is returned if unable to prep data.
937
+	 */
938
+	protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview)
939
+	{
940
+		/** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
941
+		$data_handler = $message_to_generate->get_data_handler_class_name($preview);
942
+		if (! $message_to_generate->valid()) {
943
+			return false; //unable to get the data because the info in the EE_Message_To_Generate class is invalid.
944
+		}
945
+		return $data_handler::convert_data_for_persistent_storage($message_to_generate->data());
946
+	}
947
+
948
+
949
+	/**
950
+	 * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue.
951
+	 *
952
+	 * @param EE_Message_To_Generate $message_to_generate
953
+	 * @param bool                   $test_send Whether this is just a test send or not.  Typically used for previews.
954
+	 * @throws InvalidArgumentException
955
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
956
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
957
+	 */
958
+	public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false)
959
+	{
960
+		//prep data
961
+		$data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview());
962
+
963
+		$message = $message_to_generate->get_EE_Message();
964
+
965
+		//is there a GRP_ID in the request?
966
+		if ($GRP_ID = EE_Registry::instance()->REQ->get('GRP_ID')) {
967
+			$message->set_GRP_ID($GRP_ID);
968
+		}
969
+
970
+		if ($data === false) {
971
+			$message->set_STS_ID(EEM_Message::status_failed);
972
+			$message->set_error_message(
973
+				esc_html__(
974
+					'Unable to prepare data for persistence to the database.',
975
+					'event_espresso'
976
+				)
977
+			);
978
+		} else {
979
+			//make sure that the data handler is cached on the message as well
980
+			$data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name();
981
+		}
982
+
983
+		$this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send);
984
+	}
985 985
 }
Please login to merge, or discard this patch.
caffeinated/payment_methods/Aim/EEG_Aim.gateway.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -362,7 +362,7 @@
 block discarded – undo
362 362
     /**
363 363
      * Posts the request to AuthorizeNet & returns response.
364 364
      *
365
-     * @param $payment
365
+     * @param EEI_Payment $payment
366 366
      * @return \EE_AuthorizeNetAIM_Response
367 367
      */
368 368
     private function _sendRequest($payment)
Please login to merge, or discard this patch.
Indentation   +603 added lines, -603 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 if (! defined('EVENT_ESPRESSO_VERSION')) {
4
-    exit('NO direct script access allowed');
4
+	exit('NO direct script access allowed');
5 5
 }
6 6
 
7 7
 
@@ -29,424 +29,424 @@  discard block
 block discarded – undo
29 29
 class EEG_Aim extends EE_Onsite_Gateway
30 30
 {
31 31
 
32
-    const LIVE_URL    = 'https://secure2.authorize.net/gateway/transact.dll'; //Authnet URL
33
-
34
-    const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll';
35
-
36
-    protected $_login_id;
37
-
38
-    protected $_transaction_key;
39
-
40
-    protected $_server;
41
-
42
-    protected $_currencies_supported = array(
43
-        'AUD',
44
-        'USD',
45
-        'CAD',
46
-        'EUR',
47
-        'GBP',
48
-        'NZD',
49
-    );
50
-
51
-    /**
52
-     * Whether to send test transactions (even to live site)
53
-     *
54
-     * @var boolean
55
-     */
56
-    protected $_test_transactions;
57
-
58
-    private $VERIFY_PEER = false;
59
-
60
-    private $_x_post_fields = array(
61
-        "version"        => "3.1",
62
-        "delim_char"     => ",",
63
-        "delim_data"     => "TRUE",
64
-        "relay_response" => "FALSE",
65
-        "encap_char"     => "|",
66
-    );
67
-
68
-    private $_additional_line_items = array();
69
-
70
-    /**
71
-     * A list of all fields in the AIM API.
72
-     * Used to warn user if they try to set a field not offered in the API.
73
-     */
74
-    private $_all_aim_fields = array(
75
-        "address",
76
-        "allow_partial_auth",
77
-        "amount",
78
-        "auth_code",
79
-        "authentication_indicator",
80
-        "bank_aba_code",
81
-        "bank_acct_name",
82
-        "bank_acct_num",
83
-        "bank_acct_type",
84
-        "bank_check_number",
85
-        "bank_name",
86
-        "card_code",
87
-        "card_num",
88
-        "cardholder_authentication_value",
89
-        "city",
90
-        "company",
91
-        "country",
92
-        "cust_id",
93
-        "customer_ip",
94
-        "delim_char",
95
-        "delim_data",
96
-        "description",
97
-        "duplicate_window",
98
-        "duty",
99
-        "echeck_type",
100
-        "email",
101
-        "email_customer",
102
-        "encap_char",
103
-        "exp_date",
104
-        "fax",
105
-        "first_name",
106
-        "footer_email_receipt",
107
-        "freight",
108
-        "header_email_receipt",
109
-        "invoice_num",
110
-        "last_name",
111
-        "line_item",
112
-        "login",
113
-        "method",
114
-        "phone",
115
-        "po_num",
116
-        "recurring_billing",
117
-        "relay_response",
118
-        "ship_to_address",
119
-        "ship_to_city",
120
-        "ship_to_company",
121
-        "ship_to_country",
122
-        "ship_to_first_name",
123
-        "ship_to_last_name",
124
-        "ship_to_state",
125
-        "ship_to_zip",
126
-        "split_tender_id",
127
-        "state",
128
-        "tax",
129
-        "tax_exempt",
130
-        "test_request",
131
-        "tran_key",
132
-        "trans_id",
133
-        "type",
134
-        "version",
135
-        "zip",
136
-        "solution_id"
137
-    );
138
-
139
-
140
-    /**
141
-     * Gets the URL where the request should go. This is filterable
142
-     *
143
-     * @return string
144
-     */
145
-    protected function _get_server_url()
146
-    {
147
-        return apply_filters(
148
-            'FHEE__EEG_Aim___get_server_url',
149
-            $this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL,
150
-            $this
151
-        );
152
-    }
153
-
154
-
155
-    /**
156
-     * TEMPORARY CALLBACK! Do not use
157
-     * Callback which filters the server url. This is added so site admins can revert to using
158
-     * the old AIM server in case Akamai service breaks their integration.
159
-     * Using Akamai will, however, be mandatory on June 30th 2016 Authorize.net
160
-     * (see http://www.authorize.net/support/akamaifaqs/#firewall?utm_campaign=April%202016%20Technical%20Updates%20for%20Merchants.html&utm_medium=email&utm_source=Eloqua&elqTrackId=46103bdc375c411a979c2f658fc99074&elq=7026706360154fee9b6d588b27d8eb6a&elqaid=506&elqat=1&elqCampaignId=343)
161
-     * Once that happens, this will be obsolete and WILL BE REMOVED.
162
-     *
163
-     * @param string $url
164
-     * @param EEG_Aim $gateway_object
165
-     * @return string
166
-     */
167
-    public function possibly_use_deprecated_aim_server($url, EEG_Aim $gateway_object)
168
-    {
169
-        if ($gateway_object->_server === 'authorize.net' && ! $gateway_object->_debug_mode) {
170
-            return 'https://secure.authorize.net/gateway/transact.dll';
171
-        } else {
172
-            return $url;
173
-        }
174
-    }
175
-
176
-
177
-    /**
178
-     * Asks the gateway to do whatever it does to process the payment. Onsite gateways will
179
-     * usually send a request directly to the payment provider and update the payment's status based on that;
180
-     * whereas offsite gateways will usually just update the payment with the URL and query parameters to use
181
-     * for sending the request via http_remote_request()
182
-     *
183
-     * @param EEI_Payment $payment
184
-     * @param array $billing_info {
185
-     *  @type $credit_card string
186
-     *  @type $cvv string
187
-     *  @type $exp_month string
188
-     *  @type $exp_year string
189
-     *  @see parent::do_direct_payment
190
-     * }
191
-     * @return EEI_Payment updated
192
-     */
193
-    public function do_direct_payment($payment, $billing_info = null)
194
-    {
195
-        add_filter('FHEE__EEG_Aim___get_server_url', array($this, 'possibly_use_deprecated_aim_server'), 10, 2);
196
-        // Enable test mode if needed
197
-        //4007000000027  <-- test successful visa
198
-        //4222222222222  <-- test failure card number
199
-
200
-        $item_num = 1;
201
-        $transaction = $payment->transaction();
202
-        $gateway_formatter = $this->_get_gateway_formatter();
203
-        $order_description = $gateway_formatter->formatOrderDescription($payment);
204
-        $primary_registrant = $transaction->primary_registration();
205
-        //if we're are charging for the full amount, show the normal line items
206
-        //and the itemized total adds up properly
207
-        if ($this->_can_easily_itemize_transaction_for($payment)) {
208
-            $total_line_item = $transaction->total_line_item();
209
-            foreach ($total_line_item->get_items() as $line_item) {
210
-                if ($line_item->quantity() == 0) {
211
-                    continue;
212
-                }
213
-                $this->addLineItem(
214
-                    $item_num++,
215
-                    $gateway_formatter->formatLineItemName($line_item, $payment),
216
-                    $gateway_formatter->formatLineItemDesc($line_item, $payment),
217
-                    $line_item->quantity(),
218
-                    $line_item->unit_price(),
219
-                    'N'
220
-                );
221
-                $order_description .= $line_item->desc().', ';
222
-            }
223
-            foreach($total_line_item->tax_descendants() as $tax_line_item) {
224
-                $this->addLineItem(
225
-                    $item_num++,
226
-                    $tax_line_item->name(),
227
-                    $tax_line_item->desc(),
228
-                    1,
229
-                    $tax_line_item->total(),
230
-                    'N'
231
-                );
232
-            }
233
-        }
234
-
235
-        //start transaction
236
-        //if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id
237
-        $partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363';
238
-        $this->setField('solution_id', $partner_id);
239
-        $this->setField('amount', $gateway_formatter->formatCurrency($payment->amount()));
240
-        $this->setField('description', substr(rtrim($order_description, ', '), 0, 255));
241
-        $this->_set_sensitive_billing_data($billing_info);
242
-        $this->setField('first_name', $billing_info['first_name']);
243
-        $this->setField('last_name', $billing_info['last_name']);
244
-        $this->setField('email', $billing_info['email']);
245
-        $this->setField('company', $billing_info['company']);
246
-        $this->setField('address', $billing_info['address'].' '.$billing_info['address2']);
247
-        $this->setField('city', $billing_info['city']);
248
-        $this->setField('state', $billing_info['state']);
249
-        $this->setField('country', $billing_info['country']);
250
-        $this->setField('zip', $billing_info['zip']);
251
-        $this->setField('fax', $billing_info['fax']);
252
-        $this->setField('cust_id', $primary_registrant->ID());
253
-        $this->setField('phone', $billing_info['phone']);
254
-        //invoice_num would be nice to have it be unique per SPCO page-load, that way if users
255
-        //press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
256
-        //in which case, we need to generate teh invoice num per request right here...
257
-        $this->setField('invoice_num', wp_generate_password(12, false));//$billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
258
-        //tell AIM that any duplicates sent in the next 5 minutes are to be ignored
259
-        $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
260
-
261
-        if ($this->_test_transactions) {
262
-            $this->test_request = "true";
263
-        }
264
-
265
-        //Capture response
266
-        $this->type = "AUTH_CAPTURE";
267
-        $response = $this->_sendRequest($payment);
268
-        if (! empty($response)) {
269
-            if ($response->error_message) {
270
-                $payment->set_status($this->_pay_model->failed_status());
271
-                $payment->set_gateway_response($response->error_message);
272
-            } else {
273
-                $payment_status = $response->approved
274
-                    ? $this->_pay_model->approved_status()
275
-                    : $this->_pay_model->declined_status();
276
-                $payment->set_status($payment_status);
277
-                //make sure we interpret the AMT as a float, not an international string (where periods are thousand separators)
278
-                $payment->set_amount((float) $response->amount);
279
-                $payment->set_gateway_response(
280
-                    sprintf(
281
-                        esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'),
282
-                        $response->response_reason_text,
283
-                        $response->response_reason_code
284
-                    )
285
-                );
286
-                if ($this->_debug_mode) {
287
-                    $txn_id = $response->invoice_number;
288
-                } else {
289
-                    $txn_id = $response->transaction_id;
290
-                }
291
-                $payment->set_txn_id_chq_nmbr($txn_id);
292
-            }
293
-            $payment->set_extra_accntng($primary_registrant->reg_code());
294
-            $payment->set_details(print_r($response, true));
295
-        } else {
296
-            $payment->set_status($this->_pay_model->failed_status());
297
-            $payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso'));
298
-            $payment->set_details(print_r($response, true));
299
-        }
300
-        return $payment;
301
-    }
302
-
303
-
304
-    /**
305
-     * Sets billing data for the upcoming request to AIM that is considered sensitive;
306
-     * also this method can be overridden by children classes to easily change
307
-     * what billing data gets sent
308
-     *
309
-     * @param array $billing_info
310
-     */
311
-    protected function _set_sensitive_billing_data($billing_info)
312
-    {
313
-        $this->setField('card_num', $billing_info['credit_card']);
314
-        $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
315
-        $this->setField('card_code', $billing_info['cvv']);
316
-    }
317
-
318
-
319
-    /**
320
-     * Add a line item.
321
-     *
322
-     * @param string $item_id
323
-     * @param string $item_name
324
-     * @param string $item_description
325
-     * @param string $item_quantity
326
-     * @param string $item_unit_price
327
-     * @param string $item_taxable
328
-     */
329
-    public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable)
330
-    {
331
-        $args = array(
332
-            substr($item_id, 0, 31),
333
-            substr($item_name, 0, 31),
334
-            substr($item_description, 0, 255),
335
-            number_format(abs($item_quantity), 2, '.', ''),
336
-            number_format(abs($item_unit_price), 2, '.', ''),
337
-            $item_taxable === 'N' ? 'N' : 'Y'
338
-        );
339
-        $this->_additional_line_items[] = implode('<|>', $args);
340
-    }
341
-
342
-
343
-    /**
344
-     * Set an individual name/value pair. This will append x_ to the name
345
-     * before posting.
346
-     *
347
-     * @param string $name
348
-     * @param string $value
349
-     * @throws AuthorizeNetException
350
-     */
351
-    protected function setField($name, $value)
352
-    {
353
-        if (in_array($name, $this->_all_aim_fields)) {
354
-            $this->_x_post_fields[$name] = $value;
355
-        } else {
356
-            throw new AuthorizeNetException("Error: no field $name exists in the AIM API.
32
+	const LIVE_URL    = 'https://secure2.authorize.net/gateway/transact.dll'; //Authnet URL
33
+
34
+	const SANDBOX_URL = 'https://test.authorize.net/gateway/transact.dll';
35
+
36
+	protected $_login_id;
37
+
38
+	protected $_transaction_key;
39
+
40
+	protected $_server;
41
+
42
+	protected $_currencies_supported = array(
43
+		'AUD',
44
+		'USD',
45
+		'CAD',
46
+		'EUR',
47
+		'GBP',
48
+		'NZD',
49
+	);
50
+
51
+	/**
52
+	 * Whether to send test transactions (even to live site)
53
+	 *
54
+	 * @var boolean
55
+	 */
56
+	protected $_test_transactions;
57
+
58
+	private $VERIFY_PEER = false;
59
+
60
+	private $_x_post_fields = array(
61
+		"version"        => "3.1",
62
+		"delim_char"     => ",",
63
+		"delim_data"     => "TRUE",
64
+		"relay_response" => "FALSE",
65
+		"encap_char"     => "|",
66
+	);
67
+
68
+	private $_additional_line_items = array();
69
+
70
+	/**
71
+	 * A list of all fields in the AIM API.
72
+	 * Used to warn user if they try to set a field not offered in the API.
73
+	 */
74
+	private $_all_aim_fields = array(
75
+		"address",
76
+		"allow_partial_auth",
77
+		"amount",
78
+		"auth_code",
79
+		"authentication_indicator",
80
+		"bank_aba_code",
81
+		"bank_acct_name",
82
+		"bank_acct_num",
83
+		"bank_acct_type",
84
+		"bank_check_number",
85
+		"bank_name",
86
+		"card_code",
87
+		"card_num",
88
+		"cardholder_authentication_value",
89
+		"city",
90
+		"company",
91
+		"country",
92
+		"cust_id",
93
+		"customer_ip",
94
+		"delim_char",
95
+		"delim_data",
96
+		"description",
97
+		"duplicate_window",
98
+		"duty",
99
+		"echeck_type",
100
+		"email",
101
+		"email_customer",
102
+		"encap_char",
103
+		"exp_date",
104
+		"fax",
105
+		"first_name",
106
+		"footer_email_receipt",
107
+		"freight",
108
+		"header_email_receipt",
109
+		"invoice_num",
110
+		"last_name",
111
+		"line_item",
112
+		"login",
113
+		"method",
114
+		"phone",
115
+		"po_num",
116
+		"recurring_billing",
117
+		"relay_response",
118
+		"ship_to_address",
119
+		"ship_to_city",
120
+		"ship_to_company",
121
+		"ship_to_country",
122
+		"ship_to_first_name",
123
+		"ship_to_last_name",
124
+		"ship_to_state",
125
+		"ship_to_zip",
126
+		"split_tender_id",
127
+		"state",
128
+		"tax",
129
+		"tax_exempt",
130
+		"test_request",
131
+		"tran_key",
132
+		"trans_id",
133
+		"type",
134
+		"version",
135
+		"zip",
136
+		"solution_id"
137
+	);
138
+
139
+
140
+	/**
141
+	 * Gets the URL where the request should go. This is filterable
142
+	 *
143
+	 * @return string
144
+	 */
145
+	protected function _get_server_url()
146
+	{
147
+		return apply_filters(
148
+			'FHEE__EEG_Aim___get_server_url',
149
+			$this->_debug_mode ? self::SANDBOX_URL : self::LIVE_URL,
150
+			$this
151
+		);
152
+	}
153
+
154
+
155
+	/**
156
+	 * TEMPORARY CALLBACK! Do not use
157
+	 * Callback which filters the server url. This is added so site admins can revert to using
158
+	 * the old AIM server in case Akamai service breaks their integration.
159
+	 * Using Akamai will, however, be mandatory on June 30th 2016 Authorize.net
160
+	 * (see http://www.authorize.net/support/akamaifaqs/#firewall?utm_campaign=April%202016%20Technical%20Updates%20for%20Merchants.html&utm_medium=email&utm_source=Eloqua&elqTrackId=46103bdc375c411a979c2f658fc99074&elq=7026706360154fee9b6d588b27d8eb6a&elqaid=506&elqat=1&elqCampaignId=343)
161
+	 * Once that happens, this will be obsolete and WILL BE REMOVED.
162
+	 *
163
+	 * @param string $url
164
+	 * @param EEG_Aim $gateway_object
165
+	 * @return string
166
+	 */
167
+	public function possibly_use_deprecated_aim_server($url, EEG_Aim $gateway_object)
168
+	{
169
+		if ($gateway_object->_server === 'authorize.net' && ! $gateway_object->_debug_mode) {
170
+			return 'https://secure.authorize.net/gateway/transact.dll';
171
+		} else {
172
+			return $url;
173
+		}
174
+	}
175
+
176
+
177
+	/**
178
+	 * Asks the gateway to do whatever it does to process the payment. Onsite gateways will
179
+	 * usually send a request directly to the payment provider and update the payment's status based on that;
180
+	 * whereas offsite gateways will usually just update the payment with the URL and query parameters to use
181
+	 * for sending the request via http_remote_request()
182
+	 *
183
+	 * @param EEI_Payment $payment
184
+	 * @param array $billing_info {
185
+	 *  @type $credit_card string
186
+	 *  @type $cvv string
187
+	 *  @type $exp_month string
188
+	 *  @type $exp_year string
189
+	 *  @see parent::do_direct_payment
190
+	 * }
191
+	 * @return EEI_Payment updated
192
+	 */
193
+	public function do_direct_payment($payment, $billing_info = null)
194
+	{
195
+		add_filter('FHEE__EEG_Aim___get_server_url', array($this, 'possibly_use_deprecated_aim_server'), 10, 2);
196
+		// Enable test mode if needed
197
+		//4007000000027  <-- test successful visa
198
+		//4222222222222  <-- test failure card number
199
+
200
+		$item_num = 1;
201
+		$transaction = $payment->transaction();
202
+		$gateway_formatter = $this->_get_gateway_formatter();
203
+		$order_description = $gateway_formatter->formatOrderDescription($payment);
204
+		$primary_registrant = $transaction->primary_registration();
205
+		//if we're are charging for the full amount, show the normal line items
206
+		//and the itemized total adds up properly
207
+		if ($this->_can_easily_itemize_transaction_for($payment)) {
208
+			$total_line_item = $transaction->total_line_item();
209
+			foreach ($total_line_item->get_items() as $line_item) {
210
+				if ($line_item->quantity() == 0) {
211
+					continue;
212
+				}
213
+				$this->addLineItem(
214
+					$item_num++,
215
+					$gateway_formatter->formatLineItemName($line_item, $payment),
216
+					$gateway_formatter->formatLineItemDesc($line_item, $payment),
217
+					$line_item->quantity(),
218
+					$line_item->unit_price(),
219
+					'N'
220
+				);
221
+				$order_description .= $line_item->desc().', ';
222
+			}
223
+			foreach($total_line_item->tax_descendants() as $tax_line_item) {
224
+				$this->addLineItem(
225
+					$item_num++,
226
+					$tax_line_item->name(),
227
+					$tax_line_item->desc(),
228
+					1,
229
+					$tax_line_item->total(),
230
+					'N'
231
+				);
232
+			}
233
+		}
234
+
235
+		//start transaction
236
+		//if in debug mode, use authorize.net's sandbox id; otherwise use the Event Espresso partner id
237
+		$partner_id = $this->_debug_mode ? 'AAA100302' : 'AAA105363';
238
+		$this->setField('solution_id', $partner_id);
239
+		$this->setField('amount', $gateway_formatter->formatCurrency($payment->amount()));
240
+		$this->setField('description', substr(rtrim($order_description, ', '), 0, 255));
241
+		$this->_set_sensitive_billing_data($billing_info);
242
+		$this->setField('first_name', $billing_info['first_name']);
243
+		$this->setField('last_name', $billing_info['last_name']);
244
+		$this->setField('email', $billing_info['email']);
245
+		$this->setField('company', $billing_info['company']);
246
+		$this->setField('address', $billing_info['address'].' '.$billing_info['address2']);
247
+		$this->setField('city', $billing_info['city']);
248
+		$this->setField('state', $billing_info['state']);
249
+		$this->setField('country', $billing_info['country']);
250
+		$this->setField('zip', $billing_info['zip']);
251
+		$this->setField('fax', $billing_info['fax']);
252
+		$this->setField('cust_id', $primary_registrant->ID());
253
+		$this->setField('phone', $billing_info['phone']);
254
+		//invoice_num would be nice to have it be unique per SPCO page-load, that way if users
255
+		//press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
256
+		//in which case, we need to generate teh invoice num per request right here...
257
+		$this->setField('invoice_num', wp_generate_password(12, false));//$billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
258
+		//tell AIM that any duplicates sent in the next 5 minutes are to be ignored
259
+		$this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
260
+
261
+		if ($this->_test_transactions) {
262
+			$this->test_request = "true";
263
+		}
264
+
265
+		//Capture response
266
+		$this->type = "AUTH_CAPTURE";
267
+		$response = $this->_sendRequest($payment);
268
+		if (! empty($response)) {
269
+			if ($response->error_message) {
270
+				$payment->set_status($this->_pay_model->failed_status());
271
+				$payment->set_gateway_response($response->error_message);
272
+			} else {
273
+				$payment_status = $response->approved
274
+					? $this->_pay_model->approved_status()
275
+					: $this->_pay_model->declined_status();
276
+				$payment->set_status($payment_status);
277
+				//make sure we interpret the AMT as a float, not an international string (where periods are thousand separators)
278
+				$payment->set_amount((float) $response->amount);
279
+				$payment->set_gateway_response(
280
+					sprintf(
281
+						esc_html__('%1$s (Reason Code: %2$s)', 'event_espresso'),
282
+						$response->response_reason_text,
283
+						$response->response_reason_code
284
+					)
285
+				);
286
+				if ($this->_debug_mode) {
287
+					$txn_id = $response->invoice_number;
288
+				} else {
289
+					$txn_id = $response->transaction_id;
290
+				}
291
+				$payment->set_txn_id_chq_nmbr($txn_id);
292
+			}
293
+			$payment->set_extra_accntng($primary_registrant->reg_code());
294
+			$payment->set_details(print_r($response, true));
295
+		} else {
296
+			$payment->set_status($this->_pay_model->failed_status());
297
+			$payment->set_gateway_response(__("There was no response from Authorize.net", 'event_espresso'));
298
+			$payment->set_details(print_r($response, true));
299
+		}
300
+		return $payment;
301
+	}
302
+
303
+
304
+	/**
305
+	 * Sets billing data for the upcoming request to AIM that is considered sensitive;
306
+	 * also this method can be overridden by children classes to easily change
307
+	 * what billing data gets sent
308
+	 *
309
+	 * @param array $billing_info
310
+	 */
311
+	protected function _set_sensitive_billing_data($billing_info)
312
+	{
313
+		$this->setField('card_num', $billing_info['credit_card']);
314
+		$this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
315
+		$this->setField('card_code', $billing_info['cvv']);
316
+	}
317
+
318
+
319
+	/**
320
+	 * Add a line item.
321
+	 *
322
+	 * @param string $item_id
323
+	 * @param string $item_name
324
+	 * @param string $item_description
325
+	 * @param string $item_quantity
326
+	 * @param string $item_unit_price
327
+	 * @param string $item_taxable
328
+	 */
329
+	public function addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable)
330
+	{
331
+		$args = array(
332
+			substr($item_id, 0, 31),
333
+			substr($item_name, 0, 31),
334
+			substr($item_description, 0, 255),
335
+			number_format(abs($item_quantity), 2, '.', ''),
336
+			number_format(abs($item_unit_price), 2, '.', ''),
337
+			$item_taxable === 'N' ? 'N' : 'Y'
338
+		);
339
+		$this->_additional_line_items[] = implode('<|>', $args);
340
+	}
341
+
342
+
343
+	/**
344
+	 * Set an individual name/value pair. This will append x_ to the name
345
+	 * before posting.
346
+	 *
347
+	 * @param string $name
348
+	 * @param string $value
349
+	 * @throws AuthorizeNetException
350
+	 */
351
+	protected function setField($name, $value)
352
+	{
353
+		if (in_array($name, $this->_all_aim_fields)) {
354
+			$this->_x_post_fields[$name] = $value;
355
+		} else {
356
+			throw new AuthorizeNetException("Error: no field $name exists in the AIM API.
357 357
             To set a custom field use setCustomField('field','value') instead.");
358
-        }
359
-    }
360
-
361
-
362
-    /**
363
-     * Posts the request to AuthorizeNet & returns response.
364
-     *
365
-     * @param $payment
366
-     * @return \EE_AuthorizeNetAIM_Response
367
-     */
368
-    private function _sendRequest($payment)
369
-    {
370
-        $this->_x_post_fields['login'] = $this->_login_id;
371
-        $this->_x_post_fields['tran_key'] = $this->_transaction_key;
372
-        $x_keys = array();
373
-        foreach ($this->_x_post_fields as $key => $value) {
374
-            $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
375
-        }
376
-        // Add line items
377
-        foreach ($this->_additional_line_items as $key => $value) {
378
-            $x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
379
-        }
380
-        $this->_log_clean_request($x_keys, $payment);
381
-        $post_url = $this->_get_server_url();
382
-        $curl_request = curl_init($post_url);
383
-        $post_body = implode("&", $x_keys);
384
-        curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body);
385
-        curl_setopt($curl_request, CURLOPT_HEADER, 0);
386
-        curl_setopt($curl_request, CURLOPT_TIMEOUT, 45);
387
-        curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
388
-        curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
389
-        if ($this->VERIFY_PEER) {
390
-            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
391
-        } else {
392
-            curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
393
-        }
394
-
395
-        if (preg_match('/xml/', $post_url)) {
396
-            curl_setopt($curl_request, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
397
-        }
398
-
399
-        $response = curl_exec($curl_request);
400
-
401
-        curl_close($curl_request);
402
-        $response_obj =  new EE_AuthorizeNetAIM_Response($response);
403
-
404
-        return $this->_log_and_clean_response($response_obj, $payment);
405
-    }
406
-
407
-
408
-    /**
409
-     * Logs the clean data only
410
-     *
411
-     * @param array $request_array
412
-     * @param EEI_Payment $payment
413
-     */
414
-    protected function _log_clean_request($request_array, $payment)
415
-    {
416
-        $keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date');
417
-        foreach ($request_array as $index => $keyvaltogether) {
418
-            foreach ($keys_to_filter_out as $key) {
419
-                if (strpos($keyvaltogether, $key) === 0) {
420
-                    //found it at the first character
421
-                    //so its one of them
422
-                    unset($request_array[$index]);
423
-                }
424
-            }
425
-        }
426
-        $this->log(
427
-            array(
428
-                'AIM Request sent:' => $request_array,
429
-                'Server URL'        => $this->_get_server_url()
430
-            ),
431
-            $payment
432
-        );
433
-    }
434
-
435
-
436
-
437
-    /**
438
-     * Logs the response and cleans it
439
-     *
440
-     * @param EE_AuthorizeNetAIM_Response $response_obj
441
-     * @param EE_Payment                  $payment
442
-     * @return \EE_AuthorizeNetAIM_Response
443
-     */
444
-    private function _log_and_clean_response($response_obj, $payment)
445
-    {
446
-        $response_obj->account_number = '';
447
-        $this->log(array('AIM Response received:' => (array)$response_obj), $payment);
448
-        return $response_obj;
449
-    }
358
+		}
359
+	}
360
+
361
+
362
+	/**
363
+	 * Posts the request to AuthorizeNet & returns response.
364
+	 *
365
+	 * @param $payment
366
+	 * @return \EE_AuthorizeNetAIM_Response
367
+	 */
368
+	private function _sendRequest($payment)
369
+	{
370
+		$this->_x_post_fields['login'] = $this->_login_id;
371
+		$this->_x_post_fields['tran_key'] = $this->_transaction_key;
372
+		$x_keys = array();
373
+		foreach ($this->_x_post_fields as $key => $value) {
374
+			$x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
375
+		}
376
+		// Add line items
377
+		foreach ($this->_additional_line_items as $key => $value) {
378
+			$x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
379
+		}
380
+		$this->_log_clean_request($x_keys, $payment);
381
+		$post_url = $this->_get_server_url();
382
+		$curl_request = curl_init($post_url);
383
+		$post_body = implode("&", $x_keys);
384
+		curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post_body);
385
+		curl_setopt($curl_request, CURLOPT_HEADER, 0);
386
+		curl_setopt($curl_request, CURLOPT_TIMEOUT, 45);
387
+		curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
388
+		curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
389
+		if ($this->VERIFY_PEER) {
390
+			curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
391
+		} else {
392
+			curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
393
+		}
394
+
395
+		if (preg_match('/xml/', $post_url)) {
396
+			curl_setopt($curl_request, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
397
+		}
398
+
399
+		$response = curl_exec($curl_request);
400
+
401
+		curl_close($curl_request);
402
+		$response_obj =  new EE_AuthorizeNetAIM_Response($response);
403
+
404
+		return $this->_log_and_clean_response($response_obj, $payment);
405
+	}
406
+
407
+
408
+	/**
409
+	 * Logs the clean data only
410
+	 *
411
+	 * @param array $request_array
412
+	 * @param EEI_Payment $payment
413
+	 */
414
+	protected function _log_clean_request($request_array, $payment)
415
+	{
416
+		$keys_to_filter_out = array('x_card_num', 'x_card_code', 'x_exp_date');
417
+		foreach ($request_array as $index => $keyvaltogether) {
418
+			foreach ($keys_to_filter_out as $key) {
419
+				if (strpos($keyvaltogether, $key) === 0) {
420
+					//found it at the first character
421
+					//so its one of them
422
+					unset($request_array[$index]);
423
+				}
424
+			}
425
+		}
426
+		$this->log(
427
+			array(
428
+				'AIM Request sent:' => $request_array,
429
+				'Server URL'        => $this->_get_server_url()
430
+			),
431
+			$payment
432
+		);
433
+	}
434
+
435
+
436
+
437
+	/**
438
+	 * Logs the response and cleans it
439
+	 *
440
+	 * @param EE_AuthorizeNetAIM_Response $response_obj
441
+	 * @param EE_Payment                  $payment
442
+	 * @return \EE_AuthorizeNetAIM_Response
443
+	 */
444
+	private function _log_and_clean_response($response_obj, $payment)
445
+	{
446
+		$response_obj->account_number = '';
447
+		$this->log(array('AIM Response received:' => (array)$response_obj), $payment);
448
+		return $response_obj;
449
+	}
450 450
 }
451 451
 
452 452
 
@@ -462,193 +462,193 @@  discard block
 block discarded – undo
462 462
 class EE_AuthorizeNetAIM_Response
463 463
 {
464 464
 
465
-    const APPROVED = '1';
466
-    const DECLINED = '2';
467
-    const ERROR = '3';
468
-    const HELD = '4';
469
-
470
-    protected $_x_post_fields = array(
471
-        "version"        => "3.1",
472
-        "delim_char"     => ",",
473
-        "delim_data"     => "TRUE",
474
-        "relay_response" => "FALSE",
475
-        "encap_char"     => "|",
476
-    );
477
-    public $approved;
478
-    public $declined;
479
-    public $error;
480
-    public $held;
481
-    public $response_code;
482
-    public $response_subcode;
483
-    public $response_reason_code;
484
-    public $response_reason_text;
485
-    public $authorization_code;
486
-    public $avs_response;
487
-    public $transaction_id;
488
-    public $invoice_number;
489
-    public $description;
490
-    public $amount;
491
-    public $method;
492
-    public $transaction_type;
493
-    public $customer_id;
494
-    public $first_name;
495
-    public $last_name;
496
-    public $company;
497
-    public $address;
498
-    public $city;
499
-    public $state;
500
-    public $zip_code;
501
-    public $country;
502
-    public $phone;
503
-    public $fax;
504
-    public $email_address;
505
-    public $ship_to_first_name;
506
-    public $ship_to_last_name;
507
-    public $ship_to_company;
508
-    public $ship_to_address;
509
-    public $ship_to_city;
510
-    public $ship_to_state;
511
-    public $ship_to_zip_code;
512
-    public $ship_to_country;
513
-    public $tax;
514
-    public $duty;
515
-    public $freight;
516
-    public $tax_exempt;
517
-    public $purchase_order_number;
518
-    public $md5_hash;
519
-    public $card_code_response;
520
-    public $cavv_response; // cardholder_authentication_verification_response
521
-    public $account_number;
522
-    public $card_type;
523
-    public $split_tender_id;
524
-    public $requested_amount;
525
-    public $balance_on_card;
526
-    public $response; // The response string from AuthorizeNet.
527
-    public $error_message;
528
-    private $_response_array = array(); // An array with the split response.
529
-
530
-
531
-    /**
532
-     * Constructor. Parses the AuthorizeNet response string
533
-     *
534
-     * @param string $response The response from the AuthNet server.
535
-     * @var string   $delimiter The delimiter used (default is ",")
536
-     * @var string   $encap_char The encap_char used (default is "|")
537
-     * @var array    $custom_fields Any custom fields set in the request.
538
-     */
539
-
540
-    public function __construct($response)
541
-    {
542
-        $encap_char = $this->_x_post_fields['encap_char'];
543
-        $delimiter = $this->_x_post_fields['delim_char'];
544
-        if ($response) {
545
-            // Split Array
546
-            $this->response = $response;
547
-            if ($encap_char) {
548
-                $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
549
-            } else {
550
-                $this->_response_array = explode($delimiter, $response);
551
-            }
552
-
553
-            /**
554
-             * If AuthorizeNet doesn't return a delimited response.
555
-             */
556
-            if (count($this->_response_array) < 10) {
557
-                $this->approved = false;
558
-                $this->error = true;
559
-                $this->error_message = sprintf(
560
-                    esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'),
561
-                    esc_html($response)
562
-                );
563
-                return;
564
-            }
565
-
566
-
567
-
568
-            // Set all fields
569
-            $this->response_code = $this->_response_array[0];
570
-            $this->response_subcode = $this->_response_array[1];
571
-            $this->response_reason_code = $this->_response_array[2];
572
-            $this->response_reason_text = $this->_response_array[3];
573
-            $this->authorization_code = $this->_response_array[4];
574
-            $this->avs_response = $this->_response_array[5];
575
-            $this->transaction_id = $this->_response_array[6];
576
-            $this->invoice_number = $this->_response_array[7];
577
-            $this->description = $this->_response_array[8];
578
-            $this->amount = $this->_response_array[9];
579
-            $this->method = $this->_response_array[10];
580
-            $this->transaction_type = $this->_response_array[11];
581
-            $this->customer_id = $this->_response_array[12];
582
-            $this->first_name = $this->_response_array[13];
583
-            $this->last_name = $this->_response_array[14];
584
-            $this->company = $this->_response_array[15];
585
-            $this->address = $this->_response_array[16];
586
-            $this->city = $this->_response_array[17];
587
-            $this->state = $this->_response_array[18];
588
-            $this->zip_code = $this->_response_array[19];
589
-            $this->country = $this->_response_array[20];
590
-            $this->phone = $this->_response_array[21];
591
-            $this->fax = $this->_response_array[22];
592
-            $this->email_address = $this->_response_array[23];
593
-            $this->ship_to_first_name = $this->_response_array[24];
594
-            $this->ship_to_last_name = $this->_response_array[25];
595
-            $this->ship_to_company = $this->_response_array[26];
596
-            $this->ship_to_address = $this->_response_array[27];
597
-            $this->ship_to_city = $this->_response_array[28];
598
-            $this->ship_to_state = $this->_response_array[29];
599
-            $this->ship_to_zip_code = $this->_response_array[30];
600
-            $this->ship_to_country = $this->_response_array[31];
601
-            $this->tax = $this->_response_array[32];
602
-            $this->duty = $this->_response_array[33];
603
-            $this->freight = $this->_response_array[34];
604
-            $this->tax_exempt = $this->_response_array[35];
605
-            $this->purchase_order_number = $this->_response_array[36];
606
-            $this->md5_hash = $this->_response_array[37];
607
-            $this->card_code_response = $this->_response_array[38];
608
-            $this->cavv_response = $this->_response_array[39];
609
-            $this->account_number = $this->_response_array[50];
610
-            $this->card_type = $this->_response_array[51];
611
-            $this->split_tender_id = $this->_response_array[52];
612
-            $this->requested_amount = $this->_response_array[53];
613
-            $this->balance_on_card = $this->_response_array[54];
614
-
615
-            $this->approved = ($this->response_code === self::APPROVED);
616
-            $this->declined = ($this->response_code === self::DECLINED);
617
-            $this->error = ($this->response_code === self::ERROR);
618
-            $this->held = ($this->response_code === self::HELD);
619
-        } else {
620
-            $this->approved = false;
621
-            $this->error = true;
622
-            $this->error_message = esc_html__(
623
-                'Error connecting to Authorize.net',
624
-                'event_espresso'
625
-            );
626
-        }
627
-    }
465
+	const APPROVED = '1';
466
+	const DECLINED = '2';
467
+	const ERROR = '3';
468
+	const HELD = '4';
469
+
470
+	protected $_x_post_fields = array(
471
+		"version"        => "3.1",
472
+		"delim_char"     => ",",
473
+		"delim_data"     => "TRUE",
474
+		"relay_response" => "FALSE",
475
+		"encap_char"     => "|",
476
+	);
477
+	public $approved;
478
+	public $declined;
479
+	public $error;
480
+	public $held;
481
+	public $response_code;
482
+	public $response_subcode;
483
+	public $response_reason_code;
484
+	public $response_reason_text;
485
+	public $authorization_code;
486
+	public $avs_response;
487
+	public $transaction_id;
488
+	public $invoice_number;
489
+	public $description;
490
+	public $amount;
491
+	public $method;
492
+	public $transaction_type;
493
+	public $customer_id;
494
+	public $first_name;
495
+	public $last_name;
496
+	public $company;
497
+	public $address;
498
+	public $city;
499
+	public $state;
500
+	public $zip_code;
501
+	public $country;
502
+	public $phone;
503
+	public $fax;
504
+	public $email_address;
505
+	public $ship_to_first_name;
506
+	public $ship_to_last_name;
507
+	public $ship_to_company;
508
+	public $ship_to_address;
509
+	public $ship_to_city;
510
+	public $ship_to_state;
511
+	public $ship_to_zip_code;
512
+	public $ship_to_country;
513
+	public $tax;
514
+	public $duty;
515
+	public $freight;
516
+	public $tax_exempt;
517
+	public $purchase_order_number;
518
+	public $md5_hash;
519
+	public $card_code_response;
520
+	public $cavv_response; // cardholder_authentication_verification_response
521
+	public $account_number;
522
+	public $card_type;
523
+	public $split_tender_id;
524
+	public $requested_amount;
525
+	public $balance_on_card;
526
+	public $response; // The response string from AuthorizeNet.
527
+	public $error_message;
528
+	private $_response_array = array(); // An array with the split response.
529
+
530
+
531
+	/**
532
+	 * Constructor. Parses the AuthorizeNet response string
533
+	 *
534
+	 * @param string $response The response from the AuthNet server.
535
+	 * @var string   $delimiter The delimiter used (default is ",")
536
+	 * @var string   $encap_char The encap_char used (default is "|")
537
+	 * @var array    $custom_fields Any custom fields set in the request.
538
+	 */
539
+
540
+	public function __construct($response)
541
+	{
542
+		$encap_char = $this->_x_post_fields['encap_char'];
543
+		$delimiter = $this->_x_post_fields['delim_char'];
544
+		if ($response) {
545
+			// Split Array
546
+			$this->response = $response;
547
+			if ($encap_char) {
548
+				$this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
549
+			} else {
550
+				$this->_response_array = explode($delimiter, $response);
551
+			}
552
+
553
+			/**
554
+			 * If AuthorizeNet doesn't return a delimited response.
555
+			 */
556
+			if (count($this->_response_array) < 10) {
557
+				$this->approved = false;
558
+				$this->error = true;
559
+				$this->error_message = sprintf(
560
+					esc_html__('Unrecognized response from Authorize.net: %1$s', 'event_espresso'),
561
+					esc_html($response)
562
+				);
563
+				return;
564
+			}
565
+
566
+
567
+
568
+			// Set all fields
569
+			$this->response_code = $this->_response_array[0];
570
+			$this->response_subcode = $this->_response_array[1];
571
+			$this->response_reason_code = $this->_response_array[2];
572
+			$this->response_reason_text = $this->_response_array[3];
573
+			$this->authorization_code = $this->_response_array[4];
574
+			$this->avs_response = $this->_response_array[5];
575
+			$this->transaction_id = $this->_response_array[6];
576
+			$this->invoice_number = $this->_response_array[7];
577
+			$this->description = $this->_response_array[8];
578
+			$this->amount = $this->_response_array[9];
579
+			$this->method = $this->_response_array[10];
580
+			$this->transaction_type = $this->_response_array[11];
581
+			$this->customer_id = $this->_response_array[12];
582
+			$this->first_name = $this->_response_array[13];
583
+			$this->last_name = $this->_response_array[14];
584
+			$this->company = $this->_response_array[15];
585
+			$this->address = $this->_response_array[16];
586
+			$this->city = $this->_response_array[17];
587
+			$this->state = $this->_response_array[18];
588
+			$this->zip_code = $this->_response_array[19];
589
+			$this->country = $this->_response_array[20];
590
+			$this->phone = $this->_response_array[21];
591
+			$this->fax = $this->_response_array[22];
592
+			$this->email_address = $this->_response_array[23];
593
+			$this->ship_to_first_name = $this->_response_array[24];
594
+			$this->ship_to_last_name = $this->_response_array[25];
595
+			$this->ship_to_company = $this->_response_array[26];
596
+			$this->ship_to_address = $this->_response_array[27];
597
+			$this->ship_to_city = $this->_response_array[28];
598
+			$this->ship_to_state = $this->_response_array[29];
599
+			$this->ship_to_zip_code = $this->_response_array[30];
600
+			$this->ship_to_country = $this->_response_array[31];
601
+			$this->tax = $this->_response_array[32];
602
+			$this->duty = $this->_response_array[33];
603
+			$this->freight = $this->_response_array[34];
604
+			$this->tax_exempt = $this->_response_array[35];
605
+			$this->purchase_order_number = $this->_response_array[36];
606
+			$this->md5_hash = $this->_response_array[37];
607
+			$this->card_code_response = $this->_response_array[38];
608
+			$this->cavv_response = $this->_response_array[39];
609
+			$this->account_number = $this->_response_array[50];
610
+			$this->card_type = $this->_response_array[51];
611
+			$this->split_tender_id = $this->_response_array[52];
612
+			$this->requested_amount = $this->_response_array[53];
613
+			$this->balance_on_card = $this->_response_array[54];
614
+
615
+			$this->approved = ($this->response_code === self::APPROVED);
616
+			$this->declined = ($this->response_code === self::DECLINED);
617
+			$this->error = ($this->response_code === self::ERROR);
618
+			$this->held = ($this->response_code === self::HELD);
619
+		} else {
620
+			$this->approved = false;
621
+			$this->error = true;
622
+			$this->error_message = esc_html__(
623
+				'Error connecting to Authorize.net',
624
+				'event_espresso'
625
+			);
626
+		}
627
+	}
628 628
 }
629 629
 
630 630
 if (! class_exists('AuthorizeNetException')) {
631
-    /**
632
-     * Class AuthorizeNetException
633
-     *
634
-     * @package    AuthorizeNet
635
-     */
636
-    class AuthorizeNetException extends Exception
637
-    {
638
-
639
-        /**
640
-         * Construct the exception. Note: The message is NOT binary safe.
641
-         *
642
-         * @link http://php.net/manual/en/exception.construct.php
643
-         * @param string $message [optional] The Exception message to throw.
644
-         * @param int $code [optional] The Exception code.
645
-         * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0
646
-         * @since 5.1.0
647
-         */
648
-        public function __construct($message = "", $code = 0, Exception $previous = null)
649
-        {
650
-            parent::__construct($message, $code, $previous);
651
-        }
652
-    }
631
+	/**
632
+	 * Class AuthorizeNetException
633
+	 *
634
+	 * @package    AuthorizeNet
635
+	 */
636
+	class AuthorizeNetException extends Exception
637
+	{
638
+
639
+		/**
640
+		 * Construct the exception. Note: The message is NOT binary safe.
641
+		 *
642
+		 * @link http://php.net/manual/en/exception.construct.php
643
+		 * @param string $message [optional] The Exception message to throw.
644
+		 * @param int $code [optional] The Exception code.
645
+		 * @param Exception $previous [optional] The previous exception used for the exception chaining. Since 5.3.0
646
+		 * @since 5.1.0
647
+		 */
648
+		public function __construct($message = "", $code = 0, Exception $previous = null)
649
+		{
650
+			parent::__construct($message, $code, $previous);
651
+		}
652
+	}
653 653
 }
654 654
 // End of file EEG_Aim.gateway.php
655 655
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-if (! defined('EVENT_ESPRESSO_VERSION')) {
3
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
4 4
     exit('NO direct script access allowed');
5 5
 }
6 6
 
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
                 );
221 221
                 $order_description .= $line_item->desc().', ';
222 222
             }
223
-            foreach($total_line_item->tax_descendants() as $tax_line_item) {
223
+            foreach ($total_line_item->tax_descendants() as $tax_line_item) {
224 224
                 $this->addLineItem(
225 225
                     $item_num++,
226 226
                     $tax_line_item->name(),
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
         //invoice_num would be nice to have it be unique per SPCO page-load, that way if users
255 255
         //press back, they don't submit a duplicate. However, we may be keeping the user on teh same spco page
256 256
         //in which case, we need to generate teh invoice num per request right here...
257
-        $this->setField('invoice_num', wp_generate_password(12, false));//$billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
257
+        $this->setField('invoice_num', wp_generate_password(12, false)); //$billing_info['_reg-page-billing-invoice-'.$this->_gateway_name]['value']);
258 258
         //tell AIM that any duplicates sent in the next 5 minutes are to be ignored
259 259
         $this->setField('duplicate_window', 5 * MINUTE_IN_SECONDS);
260 260
 
@@ -265,7 +265,7 @@  discard block
 block discarded – undo
265 265
         //Capture response
266 266
         $this->type = "AUTH_CAPTURE";
267 267
         $response = $this->_sendRequest($payment);
268
-        if (! empty($response)) {
268
+        if ( ! empty($response)) {
269 269
             if ($response->error_message) {
270 270
                 $payment->set_status($this->_pay_model->failed_status());
271 271
                 $payment->set_gateway_response($response->error_message);
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
     protected function _set_sensitive_billing_data($billing_info)
312 312
     {
313 313
         $this->setField('card_num', $billing_info['credit_card']);
314
-        $this->setField('exp_date', $billing_info['exp_month'] . $billing_info['exp_year']);
314
+        $this->setField('exp_date', $billing_info['exp_month'].$billing_info['exp_year']);
315 315
         $this->setField('card_code', $billing_info['cvv']);
316 316
     }
317 317
 
@@ -371,11 +371,11 @@  discard block
 block discarded – undo
371 371
         $this->_x_post_fields['tran_key'] = $this->_transaction_key;
372 372
         $x_keys = array();
373 373
         foreach ($this->_x_post_fields as $key => $value) {
374
-            $x_keys[] = "x_$key=" . urlencode($this->_get_unsupported_character_remover()->format($value));
374
+            $x_keys[] = "x_$key=".urlencode($this->_get_unsupported_character_remover()->format($value));
375 375
         }
376 376
         // Add line items
377 377
         foreach ($this->_additional_line_items as $key => $value) {
378
-            $x_keys[] =  "x_line_item=" . urlencode($this->_get_unsupported_character_remover()->format($value));
378
+            $x_keys[] = "x_line_item=".urlencode($this->_get_unsupported_character_remover()->format($value));
379 379
         }
380 380
         $this->_log_clean_request($x_keys, $payment);
381 381
         $post_url = $this->_get_server_url();
@@ -387,7 +387,7 @@  discard block
 block discarded – undo
387 387
         curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
388 388
         curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);
389 389
         if ($this->VERIFY_PEER) {
390
-            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__) . '/ssl/cert.pem');
390
+            curl_setopt($curl_request, CURLOPT_CAINFO, dirname(__DIR__).'/ssl/cert.pem');
391 391
         } else {
392 392
             curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
393 393
         }
@@ -399,7 +399,7 @@  discard block
 block discarded – undo
399 399
         $response = curl_exec($curl_request);
400 400
 
401 401
         curl_close($curl_request);
402
-        $response_obj =  new EE_AuthorizeNetAIM_Response($response);
402
+        $response_obj = new EE_AuthorizeNetAIM_Response($response);
403 403
 
404 404
         return $this->_log_and_clean_response($response_obj, $payment);
405 405
     }
@@ -444,7 +444,7 @@  discard block
 block discarded – undo
444 444
     private function _log_and_clean_response($response_obj, $payment)
445 445
     {
446 446
         $response_obj->account_number = '';
447
-        $this->log(array('AIM Response received:' => (array)$response_obj), $payment);
447
+        $this->log(array('AIM Response received:' => (array) $response_obj), $payment);
448 448
         return $response_obj;
449 449
     }
450 450
 }
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
             // Split Array
546 546
             $this->response = $response;
547 547
             if ($encap_char) {
548
-                $this->_response_array = explode($encap_char . $delimiter . $encap_char, substr($response, 1, -1));
548
+                $this->_response_array = explode($encap_char.$delimiter.$encap_char, substr($response, 1, -1));
549 549
             } else {
550 550
                 $this->_response_array = explode($delimiter, $response);
551 551
             }
@@ -627,7 +627,7 @@  discard block
 block discarded – undo
627 627
     }
628 628
 }
629 629
 
630
-if (! class_exists('AuthorizeNetException')) {
630
+if ( ! class_exists('AuthorizeNetException')) {
631 631
     /**
632 632
      * Class AuthorizeNetException
633 633
      *
Please login to merge, or discard this patch.