Passed
Push — master ( 258987...4a6585 )
by Brian
09:29 queued 04:10
created

wpinv_get_emails()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 1
c 2
b 0
f 0
dl 0
loc 2
rs 10
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * Contains email functions.
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/*
10
|--------------------------------------------------------------------------
11
| Email Template functions.
12
|--------------------------------------------------------------------------
13
*/
14
15
/**
16
 * Generates the email header.
17
 */
18
function wpinv_email_header( $email_heading ) {
19
    wpinv_get_template( 'emails/wpinv-email-header.php', compact( 'email_heading' ) );
20
}
21
add_action( 'wpinv_email_header', 'wpinv_email_header' );
22
23
24
/**
25
 * Generates the email footer.
26
 */
27
function wpinv_email_footer() {
28
    wpinv_get_template( 'emails/wpinv-email-footer.php' );
29
}
30
add_action( 'wpinv_email_footer', 'wpinv_email_footer' );
31
32
33
/**
34
 * Display invoice details in emails.
35
 * 
36
 * @param WPInv_Invoice $invoice
37
 * @param string $email_type
38
 * @param bool $sent_to_admin
39
 */
40
function wpinv_email_invoice_details( $invoice,  $email_type, $sent_to_admin ) {
41
42
    $args = compact( 'invoice', 'email_type', 'sent_to_admin' );
43
    wpinv_get_template( 'emails/wpinv-email-invoice-details.php', $args );
44
45
}
46
add_action( 'wpinv_email_invoice_details', 'wpinv_email_invoice_details', 10, 3 );
47
48
49
/**
50
 * Display line items in emails.
51
 * 
52
 * @param WPInv_Invoice $invoice
53
 * @param string $email_type
54
 * @param bool $sent_to_admin
55
 */
56
function wpinv_email_invoice_items( $invoice, $email_type, $sent_to_admin ) {
57
58
    // Prepare line items.
59
    $columns = getpaid_invoice_item_columns( $invoice );
60
    $columns = apply_filters( 'getpaid_invoice_line_items_table_columns', $columns, $invoice );
61
62
    // Load the template.
63
    wpinv_get_template( 'emails/wpinv-email-invoice-items.php', compact( 'invoice', 'columns', 'email_type', 'sent_to_admin' ) );
64
65
}
66
add_action( 'wpinv_email_invoice_items', 'wpinv_email_invoice_items', 10, 3 );
67
68
69
/**
70
 * Display billing details in emails.
71
 * 
72
 * @param WPInv_Invoice $invoice
73
 * @param string $email_type
74
 * @param bool $sent_to_admin
75
 */
76
function wpinv_email_billing_details( $invoice, $email_type, $sent_to_admin ) {
77
78
    $args = compact( 'invoice', 'email_type', 'sent_to_admin' );
79
    wpinv_get_template( 'emails/wpinv-email-billing-details.php', $args );
80
81
}
82
add_action( 'wpinv_email_billing_details', 'wpinv_email_billing_details', 10, 3 );
83
84
/**
85
 * Returns email css.
86
 * 
87
 */
88
function getpaid_get_email_css() {
89
90
    $css = wpinv_get_template_html( 'emails/wpinv-email-styles.php' );
91
    return apply_filters( 'wpinv_email_styles', $css );
92
93
}
94
95
/**
96
 * Inline styles to email content.
97
 * 
98
 * @param string $content
99
 * @return string
100
 * 
101
 */
102
function wpinv_email_style_body( $content ) {
103
104
    $css = getpaid_get_email_css();
105
106
    // Inline the css.
107
    try {
108
        $emogrifier = new Emogrifier( $content, $css );
109
        $_content   = $emogrifier->emogrify();
110
        $content    = $_content;
111
    } catch ( Exception $e ) {
112
        wpinv_error_log( $e->getMessage(), 'emogrifier' );
113
    }
114
115
    return $content;
116
}
117
118
119
// Backwards compatibility.
120
function wpinv_init_transactional_emails() {
121
    foreach ( apply_filters( 'wpinv_email_actions', array() ) as $action ) {
122
        add_action( $action, 'wpinv_send_transactional_email', 10, 10 );
123
    }
124
}
125
add_action( 'init', 'wpinv_init_transactional_emails' );
126
127
128
129
130
131
132
133
function wpinv_send_transactional_email() {
134
    $args       = func_get_args();
135
    $function   = current_filter() . '_notification';
136
    do_action_ref_array( $function, $args );
137
}
138
139
function wpinv_mail_get_from_address() {
140
    $from_address = apply_filters( 'wpinv_mail_from_address', wpinv_get_option( 'email_from' ) );
141
    return sanitize_email( $from_address );
0 ignored issues
show
Bug introduced by
It seems like $from_address can also be of type array; however, parameter $email of sanitize_email() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

141
    return sanitize_email( /** @scrutinizer ignore-type */ $from_address );
Loading history...
142
}
143
144
function wpinv_mail_get_from_name() {
145
    $from_name = apply_filters( 'wpinv_mail_from_name', wpinv_get_option( 'email_from_name' ) );
146
    return wp_specialchars_decode( esc_html( $from_name ), ENT_QUOTES );
0 ignored issues
show
Bug introduced by
It seems like $from_name can also be of type array; however, parameter $text of esc_html() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
    return wp_specialchars_decode( esc_html( /** @scrutinizer ignore-type */ $from_name ), ENT_QUOTES );
Loading history...
147
}
148
149
function wpinv_mail_admin_bcc_active( $mail_type = '' ) {
150
    $active = apply_filters( 'wpinv_mail_admin_bcc_active', wpinv_get_option( 'email_' . $mail_type . '_admin_bcc' ) );
151
    return ( $active ? true : false );
152
}
153
    
154
function wpinv_mail_get_content_type(  $content_type = 'text/html', $email_type = 'html' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $content_type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

154
function wpinv_mail_get_content_type(  /** @scrutinizer ignore-unused */ $content_type = 'text/html', $email_type = 'html' ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
155
    $email_type = apply_filters( 'wpinv_mail_content_type', $email_type );
156
157
    switch ( $email_type ) {
158
        case 'html' :
159
            $content_type = 'text/html';
160
            break;
161
        case 'multipart' :
162
            $content_type = 'multipart/alternative';
163
            break;
164
        default :
165
            $content_type = 'text/plain';
166
            break;
167
    }
168
169
    return $content_type;
170
}
171
172
/**
173
 * Sends a single email.
174
 * 
175
 * @param string|array $to The recipient's email or an array of recipient emails.
176
 * @param string       $subject The email subject.
177
 * @param string       $message The email content.
178
 * @param mixed        $deprecated
179
 * @param array        $attachments Any files to attach to the email.
180
 * @param string|array $cc An email or array of extra emails to send a copy of the email to.
181
 */
182
function wpinv_mail_send( $to, $subject, $message, $deprecated, $attachments = array(), $cc = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $deprecated is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

182
function wpinv_mail_send( $to, $subject, $message, /** @scrutinizer ignore-unused */ $deprecated, $attachments = array(), $cc = array() ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
183
184
    $mailer  = new GetPaid_Notification_Email_Sender();
185
    $message = wpinv_email_style_body( $message );
186
    $to      = array_merge( wpinv_parse_list( $to ), wpinv_parse_list( $cc ) );
187
188
	return $mailer->send(
189
        $to,
190
        $subject,
191
        $message,
192
        $attachments
193
    );
194
195
}
196
197
/**
198
 * Returns an array of email settings.
199
 * 
200
 * @return array
201
 */
202
function wpinv_get_emails() {
203
    return apply_filters( 'wpinv_get_emails', wpinv_get_data( 'email-settings' ) );
204
}
205
206
/**
207
 * Filter email settings.
208
 * 
209
 * @param array $settings
210
 * @return array
211
 */
212
function wpinv_settings_emails( $settings = array() ) {
213
    $settings = array_merge( $settings, wpinv_get_emails() );
214
    return apply_filters( 'wpinv_settings_get_emails', $settings );
215
}
216
add_filter( 'wpinv_settings_emails', 'wpinv_settings_emails', 10, 1 );
217
218
/**
219
 * Filter email section names.
220
 * 
221
 */
222
function wpinv_settings_sections_emails( $settings ) {
223
    foreach  ( wpinv_get_emails() as $key => $email) {
224
        $settings[$key] = ! empty( $email['email_' . $key . '_header']['name'] ) ? strip_tags( $email['email_' . $key . '_header']['name'] ) : strip_tags( $key );
225
    }
226
227
    return $settings;    
228
}
229
add_filter( 'wpinv_settings_sections_emails', 'wpinv_settings_sections_emails', 10, 1 );
230
231
function wpinv_email_is_enabled( $email_type ) {
232
    $emails = wpinv_get_emails();
233
    $enabled = isset( $emails[$email_type] ) && wpinv_get_option( 'email_'. $email_type . '_active', 0 ) ? true : false;
234
235
    return apply_filters( 'wpinv_email_is_enabled', $enabled, $email_type );
236
}
237
238
function wpinv_email_get_recipient( $email_type = '', $invoice_id = 0, $invoice = array() ) {
239
    switch ( $email_type ) {
240
        case 'new_invoice':
241
        case 'cancelled_invoice':
242
        case 'failed_invoice':
243
            $recipient  = wpinv_get_admin_email();
244
        break;
245
        default:
246
            $invoice    = !empty( $invoice ) && is_object( $invoice ) ? $invoice : ( $invoice_id > 0 ? wpinv_get_invoice( $invoice_id ) : NULL );
247
            $recipient  = !empty( $invoice ) ? $invoice->get_email() : '';
248
        break;
249
    }
250
251
    return apply_filters( 'wpinv_email_recipient', $recipient, $email_type, $invoice_id, $invoice );
252
}
253
254
/**
255
 * Returns invoice CC recipients
256
 */
257
function wpinv_email_get_cc_recipients( $email_type = '', $invoice_id = 0, $invoice = array() ) {
258
    switch ( $email_type ) {
259
        case 'new_invoice':
260
        case 'cancelled_invoice':
261
        case 'failed_invoice':
262
            return array();
263
        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
264
        default:
265
            $invoice    = !empty( $invoice ) && is_object( $invoice ) ? $invoice : ( $invoice_id > 0 ? wpinv_get_invoice( $invoice_id ) : NULL );
266
            $recipient  = empty( $invoice ) ? '' : get_post_meta( $invoice->ID, 'wpinv_email_cc', true );
267
            if ( empty( $recipient ) ) {
268
                return array();
269
            }
270
            return  array_filter( array_map( 'trim', explode( ',', $recipient ) ) );
271
        break;
272
    }
273
274
}
275
276
function wpinv_email_get_subject( $email_type = '', $invoice_id = 0, $invoice = array() ) {
277
    $subject    = wpinv_get_option( 'email_' . $email_type . '_subject' );
278
    $subject    = __( $subject, 'invoicing' );
0 ignored issues
show
Bug introduced by
$subject of type array is incompatible with the type string expected by parameter $text of __(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

278
    $subject    = __( /** @scrutinizer ignore-type */ $subject, 'invoicing' );
Loading history...
279
280
    $subject    = wpinv_email_format_text( $subject, $invoice );
281
282
    return apply_filters( 'wpinv_email_subject', $subject, $email_type, $invoice_id, $invoice );
283
}
284
285
function wpinv_email_get_heading( $email_type = '', $invoice_id = 0, $invoice = array() ) {
286
    $email_heading = wpinv_get_option( 'email_' . $email_type . '_heading' );
287
    $email_heading = __( $email_heading, 'invoicing' );
0 ignored issues
show
Bug introduced by
$email_heading of type array is incompatible with the type string expected by parameter $text of __(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

287
    $email_heading = __( /** @scrutinizer ignore-type */ $email_heading, 'invoicing' );
Loading history...
288
289
    $email_heading = wpinv_email_format_text( $email_heading, $invoice );
290
291
    return apply_filters( 'wpinv_email_heading', $email_heading, $email_type, $invoice_id, $invoice );
292
}
293
294
function wpinv_email_get_content( $email_type = '', $invoice_id = 0, $invoice = array() ) {
295
    $content    = wpinv_get_option( 'email_' . $email_type . '_body' );
296
    $content    = __( $content, 'invoicing' );
0 ignored issues
show
Bug introduced by
$content of type array is incompatible with the type string expected by parameter $text of __(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

296
    $content    = __( /** @scrutinizer ignore-type */ $content, 'invoicing' );
Loading history...
297
298
    $content    = wpinv_email_format_text( $content, $invoice );
299
300
    return apply_filters( 'wpinv_email_content', $content, $email_type, $invoice_id, $invoice );
301
}
302
303
function wpinv_email_get_headers( $email_type = '', $invoice_id = 0, $invoice = array() ) {
304
    $from_name = wpinv_mail_get_from_address();
305
    $from_email = wpinv_mail_get_from_address();
306
    
307
    $invoice    = !empty( $invoice ) && is_object( $invoice ) ? $invoice : ( $invoice_id > 0 ? wpinv_get_invoice( $invoice_id ) : NULL );
308
    
309
    $headers    = "From: " . stripslashes_deep( html_entity_decode( $from_name, ENT_COMPAT, 'UTF-8' ) ) . " <$from_email>\r\n";
310
    $headers    .= "Reply-To: ". $from_email . "\r\n";
311
    $headers    .= "Content-Type: " . wpinv_mail_get_content_type() . "\r\n";
312
    
313
    return apply_filters( 'wpinv_email_headers', $headers, $email_type, $invoice_id, $invoice );
314
}
315
316
function wpinv_email_get_attachments( $email_type = '', $invoice_id = 0, $invoice = array() ) {
317
    $attachments = array();
318
    
319
    return apply_filters( 'wpinv_email_attachments', $attachments, $email_type, $invoice_id, $invoice );
320
}
321
322
/**
323
 * Searches for and replaces certain placeholders in an email.
324
 */
325
function wpinv_email_format_text( $content, $invoice ) {
326
327
    $replace_array = array(
328
        '{site_title}'      => wpinv_get_blogname(),
329
        '{date}'            => date_i18n( get_option( 'date_format' ), (int) current_time( 'timestamp' ) ),
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date_i18n() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

329
        '{date}'            => date_i18n( /** @scrutinizer ignore-type */ get_option( 'date_format' ), (int) current_time( 'timestamp' ) ),
Loading history...
330
    );
331
332
    $invoice = new WPInv_Invoice( $invoice );
333
334
    if ( $invoice->get_id() ) {
335
336
        $replace_array = array_merge(
337
            $replace_array, 
338
            array(
339
                '{name}'            => sanitize_text_field( $invoice->get_user_full_name() ),
340
                '{full_name}'       => sanitize_text_field( $invoice->get_user_full_name() ),
341
                '{first_name}'      => sanitize_text_field( $invoice->get_first_name() ),
342
                '{last_name}'       => sanitize_text_field( $invoice->get_last_name() ),
343
                '{email}'           => sanitize_email( $invoice->get_email() ),
344
                '{invoice_number}'  => sanitize_text_field( $invoice->get_number() ),
345
                '{invoice_total}'   => wpinv_price( wpinv_format_amount( $invoice->get_total( true ) ) ),
0 ignored issues
show
Unused Code introduced by
The call to WPInv_Invoice::get_total() has too many arguments starting with true. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

345
                '{invoice_total}'   => wpinv_price( wpinv_format_amount( $invoice->/** @scrutinizer ignore-call */ get_total( true ) ) ),

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
346
                '{invoice_link}'    => esc_url( $invoice->get_view_url() ),
347
                '{invoice_pay_link}'=> esc_url( $invoice->get_checkout_payment_url() ),
348
                '{invoice_date}'    => date( get_option( 'date_format' ), strtotime( $invoice->get_date_created(), current_time( 'timestamp' ) ) ),
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format') can also be of type false; however, parameter $format of date() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

348
                '{invoice_date}'    => date( /** @scrutinizer ignore-type */ get_option( 'date_format' ), strtotime( $invoice->get_date_created(), current_time( 'timestamp' ) ) ),
Loading history...
349
                '{invoice_due_date}'=> date( get_option( 'date_format' ), strtotime( $invoice->get_due_date(), current_time( 'timestamp' ) ) ),
350
                '{invoice_quote}'   => sanitize_text_field( $invoice->get_type() ),
351
                '{invoice_label}'   => sanitize_text_field( ucfirst( $invoice->get_type() ) ),
352
                '{is_was}'          => strtotime( $invoice->get_due_date() ) < current_time( 'timestamp' ) ? __( 'was', 'invoicing' ) : __( 'is', 'invoicing' ),
353
            )
354
        );
355
356
    }
357
358
    // Let third party plugins filter the arra.
359
    $replace_array = apply_filters( 'wpinv_email_format_text', $replace_array, $content, $invoice );
360
361
    foreach ( $replace_array as $key => $value ) {
362
        $content = str_replace( $key, $value, $content );
363
    }
364
365
    return apply_filters( 'wpinv_email_content_replace', $content );
366
}
367
368
369
function wpinv_email_wrap_message( $message ) {
370
    // Buffer
371
    ob_start();
372
373
    do_action( 'wpinv_email_header' );
374
375
    echo wpautop( wptexturize( $message ) );
376
377
    do_action( 'wpinv_email_footer' );
378
379
    // Get contents
380
    $message = ob_get_clean();
381
382
    return $message;
383
}
384
385
386
387
function wpinv_send_customer_invoice( $data = array() ) {
388
    $invoice_id = !empty( $data['invoice_id'] ) ? absint( $data['invoice_id'] ) : NULL;
389
390
    if ( empty( $invoice_id ) ) {
391
        return;
392
    }
393
394
    if ( !wpinv_current_user_can_manage_invoicing() ) {
395
        wp_die( __( 'You do not have permission to send invoice notification', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
396
    }
397
    
398
    $sent = wpinv_user_invoice_notification( $invoice_id );
0 ignored issues
show
Deprecated Code introduced by
The function wpinv_user_invoice_notification() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

398
    $sent = /** @scrutinizer ignore-deprecated */ wpinv_user_invoice_notification( $invoice_id );
Loading history...
Unused Code introduced by
The call to wpinv_user_invoice_notification() has too many arguments starting with $invoice_id. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

398
    $sent = /** @scrutinizer ignore-call */ wpinv_user_invoice_notification( $invoice_id );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
Are you sure the assignment to $sent is correct as wpinv_user_invoice_notification($invoice_id) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
399
400
    if ( -1 === $sent ) {
0 ignored issues
show
introduced by
The condition -1 === $sent is always false.
Loading history...
401
        $status = 'email_disabled';
402
    } elseif ( $sent ) {
0 ignored issues
show
introduced by
$sent is defined implicitly as null, thus it is always evaluated to false.
Loading history...
403
        $status = 'email_sent';
404
    } else {
405
        $status = 'email_fail';
406
    }
407
408
    $redirect = add_query_arg( array( 'wpinv-message' => $status, 'wpi_action' => false, 'invoice_id' => false ) );
409
    wp_redirect( $redirect );
410
    exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
411
}
412
add_action( 'wpinv_send_invoice', 'wpinv_send_customer_invoice' );
413
414
function wpinv_send_overdue_reminder( $data = array() ) {
415
    $invoice_id = !empty( $data['invoice_id'] ) ? absint( $data['invoice_id'] ) : NULL;
416
417
    if ( empty( $invoice_id ) ) {
418
        return;
419
    }
420
421
    if ( !wpinv_current_user_can_manage_invoicing() ) {
422
        wp_die( __( 'You do not have permission to send reminder notification', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) );
423
    }
424
425
    $sent = wpinv_send_payment_reminder_notification( $invoice_id );
426
    
427
    $status = $sent ? 'email_sent' : 'email_fail';
428
429
    $redirect = add_query_arg( array( 'wpinv-message' => $status, 'wpi_action' => false, 'invoice_id' => false ) );
430
    wp_redirect( $redirect );
431
    exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
432
}
433
add_action( 'wpinv_send_reminder', 'wpinv_send_overdue_reminder' );
434
435
/**
436
 * @deprecated
437
 */
438
function wpinv_send_customer_note_email() {}
439
440
function wpinv_add_notes_to_invoice_email( $invoice, $email_type, $sent_to_admin ) {
0 ignored issues
show
Unused Code introduced by
The parameter $sent_to_admin is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

440
function wpinv_add_notes_to_invoice_email( $invoice, $email_type, /** @scrutinizer ignore-unused */ $sent_to_admin ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
441
    if ( !empty( $invoice ) && $email_type == 'user_invoice' && $invoice_notes = wpinv_get_invoice_notes( $invoice->ID, true ) ) {
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $type of wpinv_get_invoice_notes(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

441
    if ( !empty( $invoice ) && $email_type == 'user_invoice' && $invoice_notes = wpinv_get_invoice_notes( $invoice->ID, /** @scrutinizer ignore-type */ true ) ) {
Loading history...
442
        $date_format = get_option( 'date_format' );
443
        $time_format = get_option( 'time_format' );
444
        ?>
445
        <div id="wpinv-email-notes">
446
            <h3 class="wpinv-notes-t"><?php echo apply_filters( 'wpinv_email_invoice_notes_title', __( 'Invoice Notes', 'invoicing' ) ); ?></h3>
447
            <ol class="wpinv-notes-lists">
448
        <?php
449
        foreach ( $invoice_notes as $note ) {
450
            $note_time = strtotime( $note->comment_date );
451
            ?>
452
            <li class="comment wpinv-note">
453
            <p class="wpinv-note-date meta"><?php printf( __( '%2$s at %3$s', 'invoicing' ), $note->comment_author, date_i18n( $date_format, $note_time ), date_i18n( $time_format, $note_time ), $note_time ); ?></p>
0 ignored issues
show
Bug introduced by
It seems like $date_format can also be of type false; however, parameter $format of date_i18n() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

453
            <p class="wpinv-note-date meta"><?php printf( __( '%2$s at %3$s', 'invoicing' ), $note->comment_author, date_i18n( /** @scrutinizer ignore-type */ $date_format, $note_time ), date_i18n( $time_format, $note_time ), $note_time ); ?></p>
Loading history...
454
            <div class="wpinv-note-desc description"><?php echo wpautop( wptexturize( $note->comment_content ) ); ?></div>
455
            </li>
456
            <?php
457
        }
458
        ?>  </ol>
459
        </div>
460
        <?php
461
    }
462
}
463
add_action( 'wpinv_email_billing_details', 'wpinv_add_notes_to_invoice_email', 10, 3 );
464
465
/**
466
 * Sends renewal reminders.
467
 */
468
function wpinv_email_renewal_reminders() {
469
    global $wpdb;
470
471
    if ( ! wpinv_get_option( 'email_pre_payment_active' ) ) {
472
        return;
473
    }
474
475
    $reminder_days = wpinv_get_option( 'email_pre_payment_reminder_days' );
476
477
    if ( empty( $reminder_days ) ) {
478
        return;
479
    }
480
481
    // How many days before renewal should we send this email?
482
    $reminder_days = array_unique( array_map( 'absint', array_filter( wpinv_parse_list( $reminder_days ) ) ) );
483
    if ( empty( $reminder_days ) ) {
484
        return;
485
    }
486
487
    if ( 1 == count( $reminder_days ) ) {
488
        $days  = $reminder_days[0];
489
        $date  = date( 'Y-m-d', strtotime( "+$days days", current_time( 'timestamp' ) ) );
490
        $where = $wpdb->prepare( "DATE(expiration)=%s", $date );
491
    } else {
492
        $in    = array();
493
494
        foreach ( $reminder_days as $days ) {
495
            $date  = date( 'Y-m-d', strtotime( "+$days days", current_time( 'timestamp' ) ) );
496
            $in[]  = $wpdb->prepare( "%s", $date );
497
        }
498
499
        $in    = implode( ',', $in );
500
        $where = "DATE(expiration) IN ($in)";
501
    }
502
503
    // Fetch subscriptions to send out reminders for.
504
    $table = $wpdb->prefix . 'wpinv_subscriptions';
505
506
    // Fetch invoices.
507
	$subscriptions  = $wpdb->get_results(
508
		"SELECT parent_payment_id, product_id, expiration FROM $table
509
		WHERE
510
            $where
511
            AND status IN ( 'trialling', 'active' )");
512
513
    foreach ( $subscriptions as $subscription ) {
514
515
        // Skip packages.
516
        if ( get_post_meta( $subscription->product_id, '_wpinv_type', true ) == 'package' ) {
517
            continue;
518
        }
519
520
        wpinv_send_pre_payment_reminder_notification( $subscription->parent_payment_id, $subscription->expiration );
521
    }
522
523
}
524
525
function wpinv_email_payment_reminders() {
526
    global $wpi_auto_reminder, $wpdb;
527
528
    if ( ! wpinv_get_option( 'email_overdue_active' ) ) {
529
        return;
530
    }
531
532
    if ( $reminder_days = wpinv_get_option( 'email_due_reminder_days' ) ) {
533
534
        // Get a list of all reminder dates.
535
        $reminder_days  = is_array( $reminder_days ) ? array_values( $reminder_days ) : array();
0 ignored issues
show
introduced by
The condition is_array($reminder_days) is always true.
Loading history...
536
537
        // Ensure we have integers.
538
        $reminder_days  = array_unique( array_map( 'absint', $reminder_days ) );
539
540
        // Abort if non is selected.
541
        if ( empty( $reminder_days ) ) {
542
            return;
543
        }
544
545
        // Fetch the max reminder day.
546
        $max_date = max( $reminder_days );
547
548
        // Todays date.
549
        $today = date( 'Y-m-d', current_time( 'timestamp' ) );
550
551
        if ( empty( $max_date ) ) {
552
            $where = $wpdb->prepare( "DATE(invoices.due_date)=%s", $today );
553
        } else if ( 1 == count( $reminder_days ) ) {
554
            $days  = $reminder_days[0];
555
            $date  = date( 'Y-m-d', strtotime( "-$days days", current_time( 'timestamp' ) ) );
556
            $where = $wpdb->prepare( "DATE(invoices.due_date)=%s", $date );
557
        } else {
558
            $in    = array();
559
560
            foreach ( $reminder_days as $days ) {
561
                $date  = date( 'Y-m-d', strtotime( "-$days days", current_time( 'timestamp' ) ) );
562
                $in[]  = $wpdb->prepare( "%s", $date );
563
            }
564
565
            $in    = implode( ',', $in );
566
            $where = "DATE(invoices.due_date) IN ($in)";
567
        }
568
569
        // Invoices table.
570
        $table = $wpdb->prefix . 'getpaid_invoices';
571
572
        // Fetch invoices.
573
		$invoices  = $wpdb->get_col(
574
			"SELECT posts.ID FROM $wpdb->posts as posts
575
			LEFT JOIN $table as invoices ON invoices.post_id = posts.ID
576
			WHERE
577
                $where 
578
				AND posts.post_type = 'wpi_invoice'
579
                AND posts.post_status = 'wpi-pending'");
580
581
        $wpi_auto_reminder  = true;
582
583
        foreach ( $invoices as $invoice ) {
584
585
            if ( 'payment_form' != get_post_meta( $invoice, 'wpinv_created_via', true ) ) {
586
                do_action( 'wpinv_send_payment_reminder_notification', $invoice );
587
            }
588
589
        }
590
591
        $wpi_auto_reminder  = false;
592
    }
593
}
594
595
/**
596
 * Sends an upcoming renewal notification.
597
 */
598
function wpinv_send_pre_payment_reminder_notification( $invoice_id, $renewal_date ) {
599
600
    $email_type = 'pre_payment';
601
    if ( ! wpinv_email_is_enabled( $email_type ) ) {
602
        return false;
603
    }
604
605
    $invoice    = wpinv_get_invoice( $invoice_id );
606
    if ( empty( $invoice ) ) {
607
        return false;
608
    }
609
610
    $recipient  = wpinv_email_get_recipient( $email_type, $invoice_id, $invoice );
611
    if ( ! is_email( $recipient ) ) {
612
        return false;
613
    }
614
615
    $subject        = wpinv_email_get_subject( $email_type, $invoice_id, $invoice );
616
    $email_heading  = wpinv_email_get_heading( $email_type, $invoice_id, $invoice );
617
    $headers        = wpinv_email_get_headers( $email_type, $invoice_id, $invoice );
618
    $message_body   = wpinv_email_get_content( $email_type, $invoice_id, $invoice );
619
    $attachments    = wpinv_email_get_attachments( $email_type, $invoice_id, $invoice );
620
621
    $renewal_date = date_i18n( 'Y-m-d', strtotime( $renewal_date ) );
622
    $content        = wpinv_get_template_html( 'emails/wpinv-email-' . $email_type . '.php', array(
623
            'invoice'       => $invoice,
624
            'email_type'    => $email_type,
625
            'email_heading' => str_replace( '{subscription_renewal_date}', $renewal_date, $email_heading ),
626
            'sent_to_admin' => false,
627
            'plain_text'    => false,
628
            'message_body'  => str_replace( '{subscription_renewal_date}', $renewal_date, $message_body )
629
        ) );
630
631
    $content        = wpinv_email_format_text( $content, $invoice );
632
633
    $sent = wpinv_mail_send( $recipient, $subject, $content, $headers, $attachments );
634
635
    if ( wpinv_mail_admin_bcc_active( $email_type ) ) {
636
        $recipient  = wpinv_get_admin_email();
637
        $subject    .= ' - ADMIN BCC COPY';
638
        wpinv_mail_send( $recipient, $subject, $content, $headers, $attachments );
639
    }
640
641
    return $sent;
642
643
}
644
645
function wpinv_send_payment_reminder_notification( $invoice_id ) {
646
    $email_type = 'overdue';
647
    if ( !wpinv_email_is_enabled( $email_type ) ) {
648
        return false;
649
    }
650
651
    $invoice    = wpinv_get_invoice( $invoice_id );
652
    if ( empty( $invoice ) ) {
653
        return false;
654
    }
655
656
    if ( !$invoice->needs_payment() ) {
657
        return false;
658
    }
659
660
    $recipient  = wpinv_email_get_recipient( $email_type, $invoice_id, $invoice );
661
    if ( !is_email( $recipient ) ) {
662
        return false;
663
    }
664
665
    do_action( 'wpinv_pre_send_invoice_notification', $invoice, $email_type );
666
667
    $subject        = wpinv_email_get_subject( $email_type, $invoice_id, $invoice );
668
    $email_heading  = wpinv_email_get_heading( $email_type, $invoice_id, $invoice );
669
    $headers        = wpinv_email_get_headers( $email_type, $invoice_id, $invoice );
670
    $message_body   = wpinv_email_get_content( $email_type, $invoice_id, $invoice );
671
    $attachments    = wpinv_email_get_attachments( $email_type, $invoice_id, $invoice );
672
673
    $content        = wpinv_get_template_html( 'emails/wpinv-email-' . $email_type . '.php', array(
674
            'invoice'       => $invoice,
675
            'email_type'    => $email_type,
676
            'email_heading' => $email_heading,
677
            'sent_to_admin' => false,
678
            'plain_text'    => false,
679
            'message_body'  => $message_body
680
        ) );
681
682
    $content        = wpinv_email_format_text( $content, $invoice );
683
684
    $sent = wpinv_mail_send( $recipient, $subject, $content, $headers, $attachments );
685
    if ( $sent ) {
686
        do_action( 'wpinv_payment_reminder_sent', $invoice_id, $invoice );
687
    }
688
689
    if ( wpinv_mail_admin_bcc_active( $email_type ) ) {
690
        $recipient  = wpinv_get_admin_email();
691
        $subject    .= ' - ADMIN BCC COPY';
692
        wpinv_mail_send( $recipient, $subject, $content, $headers, $attachments );
693
    }
694
695
    do_action( 'wpinv_post_send_invoice_notification', $invoice, $email_type );
696
697
    return $sent;
698
}
699
add_action( 'wpinv_send_payment_reminder_notification', 'wpinv_send_payment_reminder_notification', 10, 1 );
700
701
function wpinv_payment_reminder_sent( $invoice_id, $invoice ) {
702
    global $wpi_auto_reminder;
703
704
    $sent = get_post_meta( $invoice_id, '_wpinv_reminder_sent', true );
705
706
    if ( empty( $sent ) ) {
707
        $sent = array();
708
    }
709
    $sent[] = date_i18n( 'Y-m-d' );
710
711
    update_post_meta( $invoice_id, '_wpinv_reminder_sent', $sent );
712
713
    if ( $wpi_auto_reminder ) { // Auto reminder note.
714
        $note = __( 'Automated reminder sent to the user.', 'invoicing' );
715
        $invoice->add_note( $note, false, false, true );
716
    } else { // Menual reminder note.
717
        $note = __( 'Manual reminder sent to the user.', 'invoicing' );
718
        $invoice->add_note( $note );
719
    }
720
}
721
add_action( 'wpinv_payment_reminder_sent', 'wpinv_payment_reminder_sent', 10, 2 );
722