Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 470
0.00% covered (danger)
0.00%
0 / 18
CRAP
n/a
0 / 0
zeroBSCRM_mailTemplate_processEmailHTML
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
zeroBSCRM_mailTemplate_emailPreview
0.00% covered (danger)
0.00%
0 / 96
0.00% covered (danger)
0.00%
0 / 1
182
zeroBSCRM_preview_email_template
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
42
zeroBSCRM_mail_retrieveDefaultBodyTemplate
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
zeroBSCRM_quote_generateNotificationHTML
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 1
182
zeroBSCRM_quote_generateAcceptNotifHTML
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 1
110
zeroBSCRM_invoice_generateNotificationHTML
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
30
zeroBSCRM_statement_generateNotificationHTML
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
20
zeroBSCRM_Portal_generateNotificationHTML
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
30
zeroBSCRM_Portal_generatePWresetNotificationHTML
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
20
jpcrm_task_generate_notification_html
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 1
72
jpcrm_mailTemplates_single_send_templated
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
jpcrm_mailTemplates_generic_msg
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
zeroBSCRM_mailDelivery_generateTestHTML
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
12
zeroBSCRM_mailTemplate_poweredByHTML
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
zeroBSCRM_mailTemplate_getHeaders
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
zeroBSCRM_mailTemplate_emailSafeButton
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
zeroBSCRM_mailTemplate_genericReplaces
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/*
3 * Jetpack CRM
4 * https://jetpackcrm.com
5 * V1.2.5
6 *
7 * Copyright 2020 Automattic
8 *
9 * Date: 09/01/2017
10 */
11
12defined( 'ZEROBSCRM_PATH' ) || exit( 0 );
13
14function zeroBSCRM_mailTemplate_processEmailHTML( $content ) {
15    global $zbs;
16    // acceptable html here is a bit flawed as it needs to be specifically done otherwise it will strip a <b>
17    // inside a <p> if not defined carefully, better to just do wp_kses_post()
18    // https://codex.wordpress.org/Function_Reference/wp_kses_post also sanitizes.
19    $content = wp_kses_post( $content );
20    return $content;
21}
22
23function zeroBSCRM_mailTemplate_emailPreview( $templateID = -1 ) {
24
25    global $zbs;
26
27    $html     = '';
28    $bodyHTML = '';
29
30    if ( $templateID > 0 ) {
31
32        // retrieve template
33        $html            = jpcrm_retrieve_template( 'emails/default-email.html', false );
34        $message_content = zeroBSCRM_mailTemplate_get( $templateID );
35        if ( isset( $message_content->zbsmail_body ) ) {
36            $bodyHTML = $message_content->zbsmail_body;
37        }
38
39        // load templater
40        $placeholder_templating = $zbs->get_templating();
41
42        // build replacements array
43        // ... start with generic replaces (e.g. loginlink, loginbutton)
44        $replacements = $placeholder_templating->get_generic_replacements();
45
46        if ( isset( $message_content->zbsmail_body ) ) {
47            $bodyHTML = $message_content->zbsmail_body;
48        }
49
50        // preview sublne
51        $subLine = __( 'This is a <b>Jetpack CRM email template preview</b><br/><em>This footer text is not shown in live emails</em>.', 'zero-bs-crm' );
52        $html    = $placeholder_templating->replace_single_placeholder( 'msg-content', $bodyHTML, $html );
53
54        $replacements['unsub-line']      = $subLine;
55        $replacements['powered-by']      = zeroBSCRM_mailTemplate_poweredByHTML();
56        $replacements['email-from-name'] = zeroBSCRM_mailDelivery_defaultFromname();
57
58        // process the template specific ##PLACEHOLDER## to actual viewable stuff...
59        if ( $templateID == 1 ) {
60
61            // client portal
62
63            // Replace some common ones with generic examples too:
64            $replacements['email']     = 'your.user@email.com';
65            $replacements['login-url'] = site_url( 'clients/login' );
66
67            // replace vars
68            $html = $placeholder_templating->replace_placeholders( array( 'global', 'contact' ), $html, $replacements );
69
70        }
71
72        if ( $templateID == 2 ) {
73
74            // quote accepted
75            $replacements['quote-title']    = __( 'Example Quotation #101', 'zero-bs-crm' );
76            $replacements['quote-url']      = site_url( 'clients/login' );
77            $replacements['quote-edit-url'] = admin_url();
78
79            // replace vars
80            $html = $placeholder_templating->replace_placeholders( array( 'global', 'quote', 'contact' ), $html, $replacements );
81
82        }
83
84        if ( $templateID == 3 ) {
85
86            // invoice template
87
88            $i = 0;
89
90            $logo_url = '';
91            ##WLREMOVE
92            $logo_url = $zbs->urls['crm-logo'];
93            ##/WLREMOVE
94
95            $lineitems = array(
96                array(
97                    'title'    => __( 'Your Invoice Item', 'zero-bs-crm' ),
98                    'desc'     => __( 'Your invoice item description goes here', 'zero-bs-crm' ),
99                    'quantity' => 5,
100                    'price'    => 20,
101                    'net'      => 100,
102                ),
103                array(
104                    'title'    => __( 'Another Item', 'zero-bs-crm' ),
105                    'desc'     => __( 'Some other description', 'zero-bs-crm' ),
106                    'quantity' => 3,
107                    'price'    => 17,
108                    'net'      => 51,
109                ),
110            );
111
112            $lineitems_header_html = zeroBSCRM_invoicing_generateInvPart_tableHeaders( 1 );
113            $lineitem_html         = zeroBSCRM_invoicing_generateInvPart_lineitems( $lineitems );
114
115            $replacements['title']         = __( 'Invoice Template', 'zero-bs-crm' );
116            $replacements['invoice-title'] = __( 'Invoice', 'zero-bs-crm' );
117            $replacements['logo-url']      = esc_url( $logo_url );
118
119            $inv_number   = '2468';
120            $inv_date_str = jpcrm_uts_to_date_str( 1931212800, false, true );
121            $ref          = '920592qz-42';
122
123            $totals_table = '';
124
125            $biz_info_table = '';
126            ##WLREMOVE
127            $biz_info_table = '<div style="text-align:right"><b>John Doe</b><br/>' . __( 'This is replaced<br>with the contacts details<br>from their profile.', 'zero-bs-crm' ) . '</div>'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase    
128            ##/WLREMOVE
129
130            $replacements['invoice-number']        = $inv_number;
131            $replacements['invoice-date']          = $inv_date_str;
132            $replacements['invoice-ref']           = $ref;
133            $replacements['invoice-due-date']      = $inv_date_str;
134            $replacements['invoice-table-headers'] = $lineitems_header_html;
135            $replacements['invoice-line-items']    = $lineitem_html;
136            $replacements['invoice-totals-table']  = $totals_table;
137            $replacements['biz-info']              = $biz_info_table;
138
139            $viewInPortal = '';
140            $invoiceID    = '';
141
142            // got portal?
143            // if (isset($invsettings['feat_portal']) && !empty($invsettings['feat_portal'])){
144            if ( zeroBSCRM_isExtensionInstalled( 'portal' ) ) {
145
146                // view on portal (hashed?)
147                $viewInPortalURL = zeroBSCRM_portal_linkObj( $invoiceID, ZBS_TYPE_INVOICE ); // zeroBS_portal_link('invoices',$invoiceID);
148
149                // if viewing in portal?
150                $viewInPortal = '<div style="text-align:center;margin:1em;margin-top:2em">' . zeroBSCRM_mailTemplate_emailSafeButton( $viewInPortalURL, __( 'View Invoice', 'zero-bs-crm' ) ) . '</div>';
151
152            }
153
154            // view in portal?
155            $replacements['portal-view-button'] = $viewInPortal;
156
157            // replace vars
158            $html = $placeholder_templating->replace_placeholders( array( 'global', 'invoice', 'contact', 'company' ), $html, $replacements );
159
160        }
161
162        // new proposal
163        if ( $templateID == 4 ) {
164
165            $replacements['quote-title'] = __( 'Example Quotation #101', 'zero-bs-crm' );
166            $replacements['quote-url']   = site_url( 'clients/login' );
167
168            $viewInPortal = '';
169            $quoteID      = '';
170
171            // got portal?
172            // if (isset($invsettings['feat_portal']) && !empty($invsettings['feat_portal'])){
173            if ( zeroBSCRM_isExtensionInstalled( 'portal' ) ) {
174
175                // view on portal (hashed?)
176                $viewInPortalURL = zeroBSCRM_portal_linkObj( $quoteID, ZBS_TYPE_QUOTE );
177
178                // if viewing in portal?
179                $viewInPortal = '<div style="text-align:center;margin:1em;margin-top:2em">' . zeroBSCRM_mailTemplate_emailSafeButton( $viewInPortalURL, __( 'View Proposal', 'zero-bs-crm' ) ) . '</div>';
180
181            }
182
183            // view in portal?
184            $replacements['portal-view-button'] = $viewInPortal;
185
186            // replace vars
187            $html = $placeholder_templating->replace_placeholders( array( 'global', 'quote', 'contact' ), $html, $replacements );
188        }
189
190        // task
191        if ( $templateID == 5 ) {
192
193            $replacements['task-title']       = __( 'Example Task #101', 'zero-bs-crm' );
194            $replacements['task-link']        = '<div style="text-align:center;margin:1em;margin-top:2em">' . zeroBSCRM_mailTemplate_emailSafeButton( admin_url(), __( 'View Task', 'zero-bs-crm' ) ) . '</div>';
195            $replacements['contact-fname']    = __( 'First-Name', 'zero-bs-crm' );
196            $replacements['contact-lname']    = __( 'Last-Name', 'zero-bs-crm' );
197            $replacements['contact-fullname'] = __( 'Full-Name', 'zero-bs-crm' );
198
199            // replace vars
200            $html = $placeholder_templating->replace_placeholders( array( 'global', 'event' ), $html, $replacements );
201
202        }
203
204        // Your Client Portal Password
205        if ( $templateID == 6 ) {
206
207            $replacements['password'] = '********';
208            $replacements['email']    = 'your.user@email.com';
209
210            // replace vars
211            $html = $placeholder_templating->replace_placeholders( array( 'global' ), $html, $replacements );
212
213        }
214
215        // Your Statement
216        if ( $templateID == 7 ) {
217
218            // replace vars
219            $html = $placeholder_templating->replace_placeholders( array( 'global' ), $html, $replacements );
220
221        }
222    }
223
224    return $html;
225}
226
227// Check if attempting to preview email template
228function zeroBSCRM_preview_email_template() {
229
230    global $zbs;
231
232    // if trying to preview
233    if ( isset( $_GET['zbsmail-template-preview'] ) && $_GET['zbsmail-template-preview'] == 1 ) {
234
235        // if rights
236        if ( current_user_can( 'admin_zerobs_manage_options' ) ) {
237
238            $html = '';
239
240            if ( isset( $_GET['template_id'] ) && ! empty( $_GET['template_id'] ) ) {
241
242                $templateID = (int) sanitize_text_field( $_GET['template_id'] );
243                echo zeroBSCRM_mailTemplate_emailPreview( $templateID );
244
245            } else {
246
247                // load templater
248                $placeholder_templating = $zbs->get_templating();
249
250                // retrieve template
251                $html = jpcrm_retrieve_template( 'emails/default-email.html', false );
252
253                $message_content = '';
254                $unsub_line      = '';
255
256                ##WLREMOVE##
257                $message_content = "<h3 style='text-align:center;text-transform:uppercase'>Welcome to Jetpack CRM Email Templates</h3>";
258                $unsub_line      = __( 'Thanks for using Jetpack CRM', 'zero-bs-crm' );
259                ##/WLREMOVE##
260
261                $message_content .= "<div style='text-align:center'>" . __( 'This is example content for the email template preview. <p>This content will be replaced by what you have in your system email templates</p>', 'zero-bs-crm' ) . '</div>';
262
263                // replacements
264                echo $placeholder_templating->replace_placeholders(
265                    array( 'global', 'invoice' ),
266                    $html,
267                    array(
268
269                        'title'           => esc_html__( 'Template Preview', 'zero-bs-crm' ),
270                        'msg-content'     => $message_content,
271                        'unsub-line'      => esc_html( $unsub_line ),
272                        'powered-by'      => zeroBSCRM_mailTemplate_poweredByHTML(),
273                        'email-from-name' => esc_html( zeroBSCRM_mailDelivery_defaultFromname() ),
274
275                    )
276                );
277
278            }
279
280            die( 0 );
281
282        }
283    }
284} add_action( 'init', 'zeroBSCRM_preview_email_template' );
285
286/*
287===========================================================
288    ZBS Templating - Load Default Templates / Restore Default
289    ==========================================================
290    Noting here that although zeroBSCRM_mail_retrieveWrapTemplate has been deprecated (4.5.0),
291    This one is not, the thinking being these are used to load specific email bodies which (as of now)
292    are loaded into the DB via zeroBSCRM_populateEmailTemplateList() and then edited via UI
293    ...so there is probably no need to move these out of UI into templated files.
294 */
295function zeroBSCRM_mail_retrieveDefaultBodyTemplate( $template = 'maintemplate' ) {
296
297    $templatedHTML = '';
298
299    if ( function_exists( 'file_get_contents' ) ) {
300
301        #} templates
302        $acceptableTemplates = array( 'maintemplate', 'clientportal', 'invoicesent', 'quoteaccepted', 'quotesent', 'tasknotification', 'clientportalpwreset', 'invoicestatementsent' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
303
304        if ( in_array( $template, $acceptableTemplates ) ) {
305
306                // 2.98.6+ translated. maintemplate was a misnomer
307            if ( $template == 'maintemplate' ) {
308                $template = 'email-body';
309            }
310
311            try {
312
313                #} Build from default template - see the useful - http://www.leemunroe.com/responsive-html-email-template/
314                $templatedHTML = file_get_contents( ZEROBSCRM_PATH . 'html/templates/' . $template . '.html' );
315
316            } catch ( Exception $e ) {
317
318                #} Nada
319
320            }
321        }
322    }
323
324    return $templatedHTML;
325}
326
327/*
328======================================================
329    / ZBS Templating - Load Initial HTML
330    ====================================================== */
331
332/*
333======================================================
334    ZBS Quotes - Generate HTML (notification emails)
335    ====================================================== */
336
337function zeroBSCRM_quote_generateNotificationHTML( $quoteID = -1, $return = true ) {
338
339    global $zbs;
340
341    if ( ! empty( $quoteID ) ) {
342        $quote_contact_id = $zbs->DAL->quotes->getQuoteContactID( $quoteID );
343        $quote_contact    = $zbs->DAL->contacts->getContact( $quote_contact_id );
344        $html             = '';
345        $pWrap            = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
346
347        // retrieve template
348        $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
349
350        // Act
351        if ( ! empty( $templatedHTML ) ) {
352
353            // Actual body:
354            $bodyHTML = '';
355
356            // load templater
357            $placeholder_templating = $zbs->get_templating();
358
359            // get initial replacements arr
360            $replacements = $placeholder_templating->get_generic_replacements();
361
362            // Retrieve quote (for title + URL)
363            $quote = zeroBS_getQuote( $quoteID, true );
364
365            if ( isset( $quote ) && is_array( $quote ) ) {
366
367                $proposalTitle = '';
368                if ( ! empty( $quote['title'] ) ) {
369                    $proposalTitle = $quote['title'];
370                }
371
372                // vars
373                $zbs_biz_name       = zeroBSCRM_getSetting( 'businessname' );
374                $zbs_biz_yourname   = zeroBSCRM_getSetting( 'businessyourname' );
375                $zbs_biz_extra      = zeroBSCRM_getSetting( 'businessextra' );
376                $zbs_biz_youremail  = zeroBSCRM_getSetting( 'businessyouremail' );
377                $zbs_biz_yoururl    = zeroBSCRM_getSetting( 'businessyoururl' );
378                $zbs_settings_slug  = admin_url( 'admin.php?page=' . $zbs->slugs['settings'] ) . '&tab=quotes';
379                $quote_url          = zeroBSCRM_portal_linkObj( $quoteID, ZBS_TYPE_QUOTE );
380                $proposalEmailTitle = __( 'Proposal Notification', 'zero-bs-crm' );
381
382                // build content
383                $message_content = zeroBSCRM_mailTemplate_get( ZBSEMAIL_NEWQUOTE );
384                $bodyHTML        = $message_content->zbsmail_body;
385
386                // replacements $bodyHTML
387                $replacements['quote-url']   = $quote_url;
388                $replacements['quote-title'] = $proposalTitle;
389                $replacements['quote-value'] = $quote['value'] ? zeroBSCRM_formatCurrency( $quote['value'] ) : '';
390
391                $viewInPortal = '';
392                $quoteID      = '';
393                // got portal?
394                if ( zeroBSCRM_isExtensionInstalled( 'portal' ) ) {
395                    // view on portal (hashed?)
396                    $viewInPortalURL = zeroBSCRM_portal_linkObj( $quoteID, ZBS_TYPE_QUOTE );
397                    // if viewing in portal?
398                    $viewInPortal = '<div style="text-align:center;margin:1em;margin-top:2em">' . zeroBSCRM_mailTemplate_emailSafeButton( $viewInPortalURL, __( 'View Proposal', 'zero-bs-crm' ) ) . '</div>';
399                }
400                // view in portal?
401                $replacements['portal-view-button'] = $viewInPortal;
402
403                // build msg-content html
404                $bodyHTML = $placeholder_templating->replace_placeholders(
405                    array( 'global', 'quote', 'contact' ),
406                    $bodyHTML,
407                    $replacements,
408                    array(
409                        ZBS_TYPE_QUOTE   => $quote,
410                        ZBS_TYPE_CONTACT => $quote_contact,
411                    )
412                );
413
414                // For now, use this, ripped from invoices:
415                // (We need to centralise)
416                $bizInfoTable  = '<table class="table zbs-table" style="width:100%;">';
417                $bizInfoTable .= '<tbody>';
418                $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;"><strong>' . $zbs_biz_name . '</strong></td></tr>';
419                $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;">' . $zbs_biz_yourname . '</td></tr>';
420                $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;">' . $zbs_biz_extra . '</td></tr>';
421                $bizInfoTable .= '</tbody>';
422                $bizInfoTable .= '</table>';
423
424                // phony - needs unsub
425                $unsub_line = __( 'You have received this notification because a proposal has been sent to you', 'zero-bs-crm' );
426                if ( isset( $zbs_biz_name ) && ! empty( $zbs_biz_name ) ) {
427                    $unsub_line .= ' by ' . $zbs_biz_name;
428                }
429                $unsub_line .= '. ' . __( 'If you believe this was sent in error, please reply and let us know.', 'zero-bs-crm' );
430
431                // build body html
432                $replacements                = $placeholder_templating->get_generic_replacements();
433                $replacements['title']       = $proposalEmailTitle;
434                $replacements['msg-content'] = $bodyHTML;
435                $replacements['unsub-line']  = $unsub_line;
436                $replacements['biz-info']    = $bizInfoTable;
437
438                $settings = $zbs->settings->getAll();
439                if ( $settings['currency'] && $settings['currency']['strval'] ) {
440                    $replacements['quote-currency'] = $settings['currency']['strval'];
441                }
442                $html = $placeholder_templating->replace_placeholders( array( 'global', 'quote' ), $templatedHTML, $replacements );
443
444            }
445
446            // return
447            if ( ! $return ) {
448
449                echo $html;
450                exit( 0 );
451
452            }
453        }
454
455        return $html;
456
457    }
458    // FAIL
459    return;
460}
461
462#} sent to quote creator
463function zeroBSCRM_quote_generateAcceptNotifHTML( $quoteID = -1, $quoteSignedBy = '', $return = true ) {
464
465    global $zbs;
466
467    if ( ! empty( $quoteID ) ) {
468        $quote_contact_id = $zbs->DAL->quotes->getQuoteContactID( $quoteID );
469        $quote_contact    = $zbs->DAL->contacts->getContact( $quote_contact_id );
470
471        $html  = '';
472        $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
473
474        // retrieve template
475        $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
476
477        // load templater
478        $placeholder_templating = $zbs->get_templating();
479
480        // get initial replacements arr
481        $replacements = $placeholder_templating->get_generic_replacements();
482
483        // Act
484        if ( ! empty( $templatedHTML ) ) {
485
486            // Actual body:
487            $bodyHTML = '';
488
489            // Retrieve quote (for title + URL)
490            $quote = zeroBS_getQuote( $quoteID, true );
491
492            if ( isset( $quote ) && is_array( $quote ) ) {
493
494                $proposalTitle = '';
495                if ( ! empty( $quote['title'] ) ) {
496                    $proposalTitle = $quote['title'];
497                }
498
499                $message_content    = zeroBSCRM_mailTemplate_get( ZBSEMAIL_QUOTEACCEPTED );
500                $bodyHTML           = $message_content->zbsmail_body;
501                $proposalEmailTitle = __( 'Proposal Notification', 'zero-bs-crm' );
502                $zbs_biz_name       = zeroBSCRM_getSetting( 'businessname' );
503                $zbs_biz_yourname   = zeroBSCRM_getSetting( 'businessyourname' );
504                $zbs_biz_extra      = zeroBSCRM_getSetting( 'businessextra' );
505                $zbs_biz_youremail  = zeroBSCRM_getSetting( 'businessyouremail' );
506                $zbs_biz_yoururl    = zeroBSCRM_getSetting( 'businessyoururl' );
507
508                // build msg-content html
509                $bodyHTML = $placeholder_templating->replace_placeholders(
510                    array( 'global', 'quote', 'contact' ),
511                    $bodyHTML,
512                    $replacements,
513                    array(
514                        ZBS_TYPE_QUOTE   => $quote,
515                        ZBS_TYPE_CONTACT => $quote_contact,
516                    )
517                );
518
519                // For now, use this, ripped from invoices:
520                // (We need to centralise)
521                $bizInfoTable  = '<table class="table zbs-table" style="width:100%;">';
522                $bizInfoTable .= '<tbody>';
523                $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;"><strong>' . $zbs_biz_name . '</strong></td></tr>';
524                $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;">' . $zbs_biz_yourname . '</td></tr>';
525                $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;">' . $zbs_biz_extra . '</td></tr>';
526                // $bizInfoTable .= '<tr class="top-pad"><td>'.$zbs_biz_youremail.'</td></tr>';
527                // $bizInfoTable .= '<tr><td>'.$zbs_biz_yoururl.'</td></tr>';
528                $bizInfoTable .= '</tbody>';
529                $bizInfoTable .= '</table>';
530
531                // unsub line
532                $unsub_line = __( 'You have received this notification because your proposal has been accepted in CRM', 'zero-bs-crm' );
533                ##WLREMOVE
534                $unsub_line = __( 'You have received this notification because your proposal has been accepted in Jetpack CRM', 'zero-bs-crm' );
535                ##/WLREMOVE
536                $unsub_line .= __( '. If you believe this was sent in error, please reply and let us know.', 'zero-bs-crm' );
537
538                // build body html
539                $replacements                   = $placeholder_templating->get_generic_replacements();
540                $replacements['title']          = $proposalEmailTitle;
541                $replacements['msg-content']    = $bodyHTML;
542                $replacements['unsub-line']     = $unsub_line;
543                $replacements['biz-info']       = $bizInfoTable;
544                $replacements['quote-url']      = zeroBSCRM_portal_linkObj( $quoteID, ZBS_TYPE_QUOTE ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
545                $replacements['quote-edit-url'] = jpcrm_esc_link( 'edit', $quoteID, 'zerobs_quote' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
546                $replacements['quote-value']    = $quote['value'] ? zeroBSCRM_formatCurrency( $quote['value'] ) : '';
547
548                $settings = $zbs->settings->getAll();
549                if ( $settings['currency'] && $settings['currency']['strval'] ) {
550                    $replacements['quote-currency'] = $settings['currency']['strval'];
551                }
552                $html = $placeholder_templating->replace_placeholders( array( 'global', 'quote' ), $templatedHTML, $replacements );
553
554            }
555
556            // return
557            if ( ! $return ) {
558
559                echo $html;
560                exit( 0 );
561
562            }
563        }
564
565        return $html;
566
567    }
568
569    // FAIL
570    return;
571}
572
573/*
574======================================================
575    / ZBS Quotes - Generate HTML (notification email)
576    ====================================================== */
577
578/*
579======================================================
580    ZBS Invoices - Generate HTML (notification emails)
581    ====================================================== */
582
583function zeroBSCRM_invoice_generateNotificationHTML( $invoiceID = -1, $return = true ) {
584
585    if ( ! empty( $invoiceID ) && $invoiceID > 0 ) {
586
587        global $zbs;
588        $invoice = $zbs->DAL->invoices->getInvoice( $invoiceID );
589
590        // load templater
591        $placeholder_templating = $zbs->get_templating();
592
593        // body template
594        $mailTemplate = zeroBSCRM_mailTemplate_get( ZBSEMAIL_EMAILINVOICE );
595        $bodyHTML     = $mailTemplate->zbsmail_body;
596
597        // html template
598        $html = jpcrm_retrieve_template( 'emails/default-email.html', false );
599        $html = $placeholder_templating->replace_single_placeholder( 'msg-content', $bodyHTML, $html );
600
601        // Act
602        if ( ! empty( $html ) ) {
603
604            // this was refactored as was duplicate code.
605            // now all wired through zeroBSCRM_invoicing_generateInvoiceHTML
606            $html = zeroBSCRM_invoicing_generateInvoiceHTML( $invoiceID, 'notification', $html );
607
608            // get generics
609            $replacements = $placeholder_templating->get_generic_replacements();
610
611            // replacements
612            $html = $placeholder_templating->replace_placeholders( array( 'global', 'invoice' ), $html, $replacements, array( ZBS_TYPE_INVOICE => $invoice ) );
613
614            // return
615            if ( ! $return ) {
616
617                echo $html;
618                exit( 0 );
619
620            }
621        }
622
623        return $html;
624
625    }
626
627    // FAIL
628    return;
629}
630
631// generates statement email html based on template in sys mail
632function zeroBSCRM_statement_generateNotificationHTML( $contact_id = -1, $return = true ) {
633
634    global $zbs;
635
636    if ( ! empty( $contact_id ) ) {
637        $contact = $zbs->DAL->contacts->getContact( $contact_id );
638
639        $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
640
641        // load templater
642        $placeholder_templating = $zbs->get_templating();
643
644        // Get templated notify email
645
646        // body template
647        $mailTemplate = zeroBSCRM_mailTemplate_get( ZBSEMAIL_STATEMENT );
648        $bodyHTML     = $mailTemplate->zbsmail_body;
649
650        // html template
651        $html = jpcrm_retrieve_template( 'emails/default-email.html', false );
652        $html = $placeholder_templating->replace_single_placeholder( 'msg-content', $bodyHTML, $html );
653
654        // Act
655        if ( ! empty( $html ) ) {
656
657            // the business info from the settings
658            $zbs_biz_name     = zeroBSCRM_getSetting( 'businessname' );
659            $zbs_biz_yourname = zeroBSCRM_getSetting( 'businessyourname' );
660            $zbs_biz_extra    = zeroBSCRM_getSetting( 'businessextra' );
661
662            // For now, use this, ripped from invoices:
663            // (We need to centralise)
664            $bizInfoTable  = '<table class="table zbs-table" style="width:100%;">';
665            $bizInfoTable .= '<tbody>';
666            $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;"><strong>' . $zbs_biz_name . '</strong></td></tr>';
667            $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;">' . $zbs_biz_yourname . '</td></tr>';
668            $bizInfoTable .= '<tr><td style="font-family:sans-serif;font-size:14px;vertical-align:top;padding-bottom:5px;">' . $zbs_biz_extra . '</td></tr>';
669            $bizInfoTable .= '</tbody>';
670            $bizInfoTable .= '</table>';
671
672                    // get generics
673            $replacements = $placeholder_templating->get_generic_replacements();
674
675            // view in portal?
676            $replacements['title']    = __( 'Statement', 'zero-bs-crm' );
677            $replacements['biz-info'] = $bizInfoTable;
678
679            // replacements
680            $html = $placeholder_templating->replace_placeholders( array( 'global', 'contact' ), $html, $replacements, array( ZBS_TYPE_CONTACT => $contact ) );
681
682            // return
683            if ( ! $return ) {
684
685                echo $html;
686                exit( 0 );
687
688            }
689        }
690
691        return $html;
692
693    }
694    // FAIL
695    return;
696}
697/*
698======================================================
699    / ZBS Invoices - Generate HTML (notification email)
700    ====================================================== */
701
702/*
703======================================================
704    ZBS Portal - Generate HTML (notification emails)
705    ====================================================== */
706
707function zeroBSCRM_Portal_generateNotificationHTML( $pwd = -1, $return = true, $email = null, $contact_id = false ) {
708
709    global $zbs;
710
711    if ( ! empty( $pwd ) ) {
712
713        $html  = '';
714        $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
715
716        // Get templated notify email
717        $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
718
719        // load templater
720        $placeholder_templating = $zbs->get_templating();
721
722        // Act
723        if ( ! empty( $templatedHTML ) ) {
724
725            // body
726            $message_content = zeroBSCRM_mailTemplate_get( ZBSEMAIL_CLIENTPORTALWELCOME );
727            $bodyHTML        = $message_content->zbsmail_body;
728            $html            = $placeholder_templating->replace_single_placeholder( 'msg-content', $bodyHTML, $templatedHTML );
729
730            // get replacements
731            $replacements = $placeholder_templating->get_generic_replacements();
732
733            // replacements
734            $replacements['title'] = __( 'Welcome to your Client Portal', 'zero-bs-crm' );
735            $replacements['email'] = $email;
736
737            // if got contact_id (DAL3+) pass the contact object (so user can use ##ASSIGNED-TO-NAME##)
738            $replacement_objects = array();
739            if ( $contact_id > 0 ) {
740                $replacement_objects[ ZBS_TYPE_CONTACT ] = zeroBS_getCustomer( $contact_id );
741            }
742
743            // replacements
744            $html = $placeholder_templating->replace_placeholders( array( 'global', 'contact' ), $html, $replacements, $replacement_objects );
745
746            // return
747            if ( ! $return ) {
748
749                echo $html;
750                exit( 0 );
751
752            }
753        }
754
755        return $html;
756
757    }
758
759    // FAIL
760    return;
761}
762
763#} adapted from above. pw reset email
764function zeroBSCRM_Portal_generatePWresetNotificationHTML( $pwd, $return, $contact ) {
765
766    global $zbs;
767
768    if ( ! empty( $pwd ) ) {
769
770        $html  = '';
771        $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
772
773        // Get templated notify email
774        $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
775
776        // load templater
777        $placeholder_templating = $zbs->get_templating();
778
779        // Act
780        if ( ! empty( $templatedHTML ) ) {
781
782            $message_content = zeroBSCRM_mailTemplate_get( ZBSEMAIL_CLIENTPORTALPWREST );
783            $bodyHTML        = $message_content->zbsmail_body;
784            $html            = $placeholder_templating->replace_single_placeholder( 'msg-content', $bodyHTML, $templatedHTML );
785
786            // get replacements
787            $replacements = $placeholder_templating->get_generic_replacements();
788
789            // replacements
790            $replacements['title']    = __( 'Your Client Portal Password has been reset', 'zero-bs-crm' );
791            $replacements['email']    = $contact['email'];
792            $replacements['password'] = $pwd;
793
794            // replacements
795            $html = $placeholder_templating->replace_placeholders( array( 'global', 'contact' ), $html, $replacements, array( ZBS_TYPE_CONTACT => $contact ) );
796
797            // return
798            if ( ! $return ) {
799
800                echo $html;
801                exit( 0 );
802
803            }
804        }
805
806        return $html;
807
808    }
809
810    // FAIL
811    return;
812}
813
814function jpcrm_task_generate_notification_html( $return = true, $email = false, $task_id = -1, $task = false ) {
815
816    global $zbs;
817
818    // checks
819    if ( ! zeroBSCRM_validateEmail( $email ) || $task_id < 1 ) {
820        return false;
821    }
822
823    // Get templated notify email
824    $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
825
826    // prep
827    $html  = '';
828    $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
829
830    // load templater
831    $placeholder_templating = $zbs->get_templating();
832
833    // Act
834    if ( ! empty( $templatedHTML ) ) {
835
836        // retrieve task notification
837        $message_content = zeroBSCRM_mailTemplate_get( ZBSEMAIL_TASK_NOTIFICATION );
838        $bodyHTML        = $message_content->zbsmail_body;
839        $html            = $placeholder_templating->replace_single_placeholder( 'msg-content', $bodyHTML, $templatedHTML );
840
841        // get replacements
842        $replacements = $placeholder_templating->get_generic_replacements();
843
844        // retrieve task (if not passed)
845        if ( ! is_array( $task ) ) {
846
847            $task = $zbs->DAL->events->getEvent( $task_id );
848
849        }
850
851        // vars / html gen
852        $task_url   = jpcrm_esc_link( 'edit', $task['id'], ZBS_TYPE_TASK );
853        $task_html  = '<p>' . nl2br( $task['desc'] ) . '</p>';
854        $task_html .= '<hr /><p style="text-align:center">';
855        $task_html .= __( 'Your task starts at ', 'zero-bs-crm' ) . '<strong>' . $task['start_date'] . '</strong><br/>'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
856        // $task_html .= __( 'to: ', 'zero-bs-crm' ) . $task['end_date'];
857        $task_html .= '</p><hr />';
858
859        // replacements
860        $replacements['title']            = __( 'Your Task is starting soon', 'zero-bs-crm' );
861        $replacements['task-title']       = '<h2>' . $task['title'] . '</h2>';
862        $replacements['task-body']        = $task_html; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
863        $replacements['task-link-button'] = '<div style="text-align:center;margin:1em;margin-top:2em">' . __( 'You can view your task at the following URL: ', 'zero-bs-crm' ) . '<br />' . zeroBSCRM_mailTemplate_emailSafeButton( $task_url, __( 'View Task', 'zero-bs-crm' ) ) . '</div>'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
864
865        // replacements
866        $html = $placeholder_templating->replace_placeholders(
867            array(
868                'global',
869                'event',
870                'contact',
871                'company',
872            ),
873            $html,
874            $replacements,
875            array(
876                ZBS_TYPE_TASK    => $task,
877                ZBS_TYPE_CONTACT => isset( $task['contact'] ) ? $task['contact'][0] : null,
878                ZBS_TYPE_COMPANY => isset( $task['company'] ) ? $task['company'][0] : null,
879            )
880        );
881
882        // return
883        if ( ! $return ) {
884
885            echo $html;
886            exit( 0 );
887
888        }
889    }
890
891    return $html;
892}
893
894/*
895======================================================
896    / ZBS Invoices - Generate HTML (notification emails)
897    ====================================================== */
898
899/*
900======================================================
901    ZBS Single Send Emails - Generate HTML
902    ====================================================== */
903
904/**
905 * Creates the html of a single send email based on passed details
906 * Note this diverges from jpcrm_mailTemplates_generic_msg because it takes in $contact_object
907 * ... and makes sense to have it's own abstraction in any case (as later we can apply specific theming etc.)
908 * Replaces zeroBSCRM_mailTemplates_directMsg
909 */
910function jpcrm_mailTemplates_single_send_templated( $return = true, $content = '', $title = '', $contact_object = false ) {
911
912    global $zbs;
913
914    $html  = '';
915    $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
916
917    // load templater
918    $placeholder_templating = $zbs->get_templating();
919
920    // Get templated notify email
921    $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
922
923    // Act
924    if ( ! empty( $templatedHTML ) ) {
925
926        // replacements (initial templating)
927        $html = $placeholder_templating->replace_single_placeholder( 'msg-content', $content, $templatedHTML );
928
929        // get replacements
930        $replacements          = $placeholder_templating->get_generic_replacements();
931        $replacements['title'] = $title;
932
933        // enact replacements
934        $html = $placeholder_templating->replace_placeholders( array( 'global', 'contact', 'company' ), $html, $replacements, array( ZBS_TYPE_CONTACT => $contact_object ) );
935
936        // return
937        if ( ! $return ) {
938            echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
939            exit( 0 );
940        }
941    }
942    return $html;
943}
944/*
945======================================================
946    / ZBS Single Send Emails - Generate HTML
947    ====================================================== */
948
949/*
950======================================================
951    ZBS Generic Emails - Generate HTML
952    ====================================================== */
953function jpcrm_mailTemplates_generic_msg( $return = true, $content = '', $title = '' ) {
954
955    global $zbs;
956
957    $html  = '';
958    $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
959
960    // load templater
961    $placeholder_templating = $zbs->get_templating();
962
963    // Get templated notify email
964    $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
965
966    // Act
967    if ( ! empty( $templatedHTML ) ) {
968
969        // replacements (initial templating)
970        $html = $placeholder_templating->replace_single_placeholder( 'msg-content', $content, $templatedHTML );
971
972        // get replacements
973        $replacements          = $placeholder_templating->get_generic_replacements();
974        $replacements['title'] = $title;
975
976        // replacements
977        $html = $placeholder_templating->replace_placeholders( array( 'global', 'contact', 'company' ), $html, $replacements );
978
979        // return
980        if ( ! $return ) {
981            echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
982            exit( 0 );
983        }
984    }
985    return $html;
986}
987/*
988======================================================
989    / ZBS Generic Emails - Generate HTML
990    ====================================================== */
991
992/*
993======================================================
994    ZBS Mail Delivery Tests
995    ====================================================== */
996
997function zeroBSCRM_mailDelivery_generateTestHTML( $return = true ) {
998
999    global $zbs;
1000
1001    $html  = '';
1002    $pWrap = '<p style="font-family:sans-serif;font-size:14px;font-weight:normal;margin:0;Margin-bottom:15px;">';
1003
1004    // load templater
1005    $placeholder_templating = $zbs->get_templating();
1006
1007    // Get templated notify email
1008    $templatedHTML = jpcrm_retrieve_template( 'emails/default-email.html', false );
1009
1010    #} Act
1011    if ( ! empty( $templatedHTML ) ) {
1012
1013            #} Actual body:
1014            $bodyHTML = '';
1015
1016            $bodyHTML  = "<div style='text-align:center'><h1>" . __( 'Testing Mail Delivery Option', 'zero-bs-crm' ) . '</h1>';
1017            $bodyHTML .= '<p>' . __( "This is a test email, sent to you by Jetpack CRM. If you're receiving this loud and clear, it means your mail delivery setup has been successful, congratulations!", 'zero-bs-crm' ) . '</p>';
1018
1019            ##WLREMOVE
1020            $bodyHTML .= '<p>' . __( 'Why not follow us on twitter to celebrate?', 'zero-bs-crm' ) . '</p>';
1021            $bodyHTML .= '<p><a href="https://twitter.com/jetpackcrm">@jetpackcrm</a></p>';
1022            ##/WLREMOVE
1023
1024            $bodyHTML .= '</div>';
1025
1026            // replacements (initial templating)
1027            $html = $placeholder_templating->replace_single_placeholder( 'msg-content', $bodyHTML, $templatedHTML );
1028
1029            // get replacements
1030            $replacements               = $placeholder_templating->get_generic_replacements();
1031            $replacements['title']      = __( 'Testing Mail Delivery Option', 'zero-bs-crm' );
1032            $replacements['biz-info']   = '<p>' . __( 'Sent from your friendly neighbourhood CRM.', 'zero-bs-crm' ) . '</p>';
1033            $replacements['unsub-line'] = '<p>' . __( 'Have a great day.', 'zero-bs-crm' ) . '</p>';
1034
1035            // replacements
1036            $html = $placeholder_templating->replace_placeholders( array( 'global', 'contact', 'company' ), $html, $replacements );
1037
1038        // return
1039        if ( ! $return ) {
1040            echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1041            exit( 0 );
1042        }
1043    }
1044    return $html;
1045}
1046
1047/*
1048======================================================
1049    / ZBS Mail Delivery Tests
1050    ====================================================== */
1051
1052/*
1053======================================================
1054    ZBS Mail Templating General
1055    ====================================================== */
1056
1057function zeroBSCRM_mailTemplate_poweredByHTML( $type = 'html' ) {
1058
1059    ##WLREMOVE
1060    global $zbs;
1061    $showpoweredby_public = $zbs->settings->get( 'showpoweredby_public' ) === 1 ? true : false;
1062
1063    if ( $showpoweredby_public ) {
1064
1065        if ( $type == 'html' ) {
1066            global $zbs;
1067            return sprintf( __( 'Powered by <a href="%s">Jetpack CRM</a>', 'zero-bs-crm' ), $zbs->urls['home'] );
1068
1069        } elseif ( $type == 'text' ) {
1070
1071            return __( 'Powered by Jetpack CRM', 'zero-bs-crm' );
1072
1073        }
1074    }
1075
1076    ##/WLREMOVE
1077    return '';
1078}
1079
1080function zeroBSCRM_mailTemplate_getHeaders( $templateID = -1 ) {
1081
1082    if ( $templateID > 0 ) {
1083
1084        $mailTemplate = zeroBSCRM_mailTemplate_get( $templateID );
1085
1086        // headers being set...
1087        $headers = array( 'Content-Type: text/html; charset=UTF-8' );
1088
1089        // extra header settings..
1090        // We don't use these now, as mail is sent out properly via Mail Delivery
1091        // $headers[]  = 'From: '. esc_html($mailTemplate->zbsmail_fromname).' <'.sanitize_email($mailTemplate->zbsmail_fromaddress).'>';
1092        // $headers[]  = 'Reply-To: ' . sanitize_email($mailTemplate->zbsmail_replyto);
1093        // but we use this :)
1094        if ( isset( $mailTemplate->zbsmail_bccto ) && ! empty( $mailTemplate->zbsmail_bccto ) ) {
1095            $headers[] = 'Bcc: ' . sanitize_email( $mailTemplate->zbsmail_bccto );
1096        }
1097    } else {
1098        $headers = array( 'Content-Type: text/html; charset=UTF-8' );
1099    }
1100
1101    return $headers;
1102}
1103
1104// adapted from https://buttons.cm/
1105function zeroBSCRM_mailTemplate_emailSafeButton( $url = '', $str = '' ) {
1106
1107    return '<div><!--[if mso]>
1108    <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="' . $url . '" style="height:53px;v-text-anchor:middle;width:200px;" arcsize="8%" stroke="f" fillcolor="#49a9ce">
1109        <w:anchorlock/>
1110        <center>
1111    <![endif]-->
1112        <a href="' . $url . '"
1113    style="background-color:#49a9ce;border-radius:4px;color:#ffffff;display:inline-block;font-family:sans-serif;font-size:13px;font-weight:700;line-height:53px;text-align:center;text-decoration:none;width:200px;-webkit-text-size-adjust:none;">' . $str . '</a>
1114    <!--[if mso]>
1115        </center>
1116    </v:roundrect>
1117    <![endif]--></div>';
1118}
1119
1120// replaces generic attrs in one place, e.g. loginlink, loginurl
1121// note as placeholder templates hard-override empty placeholders not passed,
1122// here we pass true as the forth variable to leave existing ##PLACEHOLDERS## intact
1123// (if leave_existing_placeholders = true)
1124//
1125// TL;DR; Phase out using this function, instead get the replacements for use with 'replace_placeholders'
1126// ... from ->get_generic_replacements()
1127function zeroBSCRM_mailTemplate_genericReplaces( $html = '', $leave_existing_placeholders = true ) {
1128
1129    global $zbs;
1130
1131    // load templater
1132    $placeholder_templating = $zbs->get_templating();
1133
1134    // get replacements
1135    $replacements = $placeholder_templating->get_generic_replacements();
1136
1137    // replace
1138    return $placeholder_templating->replace_placeholders( array( 'global' ), $html, $replacements, $leave_existing_placeholders );
1139}
1140
1141/*
1142======================================================
1143    / ZBS Mail Templating General
1144    ====================================================== */