diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 3f8917b65427..a55188338073 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -1301,4 +1301,29 @@ class AccountController extends BaseController return Redirect::to("/settings/$section/", 301); } + + public function previewEmail(\App\Services\TemplateService $templateService) + { + $template = Input::get('template'); + $invoice = Invoice::scope()->first(); + $account = Auth::user()->account; + + // replace the variables with sample data + $data = [ + 'account' => $account, + 'invoice' => $invoice, + 'invitation' => $invoice->invitations->first(), + 'client' => $invoice->client, + 'amount' => $invoice->amount + ]; + + // create the email view + $view = 'emails.' . $account->getTemplateView() . '_html'; + $data = array_merge($data, [ + 'body' => $templateService->processVariables($template, $data), + 'entityType' => ENTITY_INVOICE, + ]); + + return Response::view($view, $data); + } } diff --git a/app/Http/routes.php b/app/Http/routes.php index df1f1add4bb8..c1162db275c1 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -208,6 +208,7 @@ Route::group([ Route::resource('tax_rates', 'TaxRateController'); Route::post('tax_rates/bulk', 'TaxRateController@bulk'); + Route::get('settings/email_preview', 'AccountController@previewEmail'); Route::get('company/{section}/{subSection?}', 'AccountController@redirectLegacy'); Route::get('settings/data_visualizations', 'ReportController@d3'); Route::get('settings/charts_and_reports', 'ReportController@showReports'); diff --git a/app/Models/Account.php b/app/Models/Account.php index 5814ec76423a..92e2a623ff7b 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -1169,6 +1169,11 @@ class Account extends Eloquent return str_replace('/>', ' />', $template); } + public function getTemplateView($view = '') + { + return $this->getEmailDesignId() == EMAIL_DESIGN_PLAIN ? $view : 'design' . $this->getEmailDesignId(); + } + public function getEmailFooter() { if ($this->email_footer) { diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php index 4b176628ebf0..fbebd0c5fdfd 100644 --- a/app/Ninja/Mailers/ContactMailer.php +++ b/app/Ninja/Mailers/ContactMailer.php @@ -1,17 +1,13 @@ templateService = $templateService; + } + public function sendInvoice(Invoice $invoice, $reminder = false, $pdfString = false) { $invoice->load('invitations', 'client.language', 'account'); @@ -144,7 +145,7 @@ class ContactMailer extends Mailer } $data = [ - 'body' => $this->processVariables($body, $variables), + 'body' => $this->templateService->processVariables($body, $variables), 'link' => $invitation->getLink(), 'entityType' => $invoice->getEntityType(), 'invoiceId' => $invoice->id, @@ -160,14 +161,9 @@ class ContactMailer extends Mailer $data['pdfFileName'] = $invoice->getFileName(); } - $subject = $this->processVariables($subject, $variables); + $subject = $this->templateService->processVariables($subject, $variables); $fromEmail = $user->email; - - if ($account->getEmailDesignId() == EMAIL_DESIGN_PLAIN) { - $view = ENTITY_INVOICE; - } else { - $view = 'design' . ($account->getEmailDesignId() - 1); - } + $view = $account->getTemplateView(ENTITY_INVOICE); $response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, $view, $data); @@ -230,7 +226,7 @@ class ContactMailer extends Mailer ]; $data = [ - 'body' => $this->processVariables($emailTemplate, $variables), + 'body' => $this->templateService->processVariables($emailTemplate, $variables), 'link' => $invitation->getLink(), 'invoice' => $invoice, 'client' => $client, @@ -244,14 +240,10 @@ class ContactMailer extends Mailer $data['pdfFileName'] = $invoice->getFileName(); } - $subject = $this->processVariables($emailSubject, $variables); + $subject = $this->templateService->processVariables($emailSubject, $variables); $data['invoice_id'] = $payment->invoice->id; - if ($account->getEmailDesignId() == EMAIL_DESIGN_PLAIN) { - $view = 'payment_confirmation'; - } else { - $view = 'design' . ($account->getEmailDesignId() - 1); - } + $view = $account->getTemplateView('payment_confirmation'); if ($user->email && $contact->email) { $this->sendTo($contact->email, $user->email, $accountName, $subject, $view, $data); @@ -281,75 +273,4 @@ class ContactMailer extends Mailer $this->sendTo($email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); } - - private function processVariables($template, $data) - { - $account = $data['account']; - $client = $data['client']; - $invitation = $data['invitation']; - $invoice = $invitation->invoice; - $passwordHTML = isset($data['password'])?'

'.trans('texts.password').': '.$data['password'].'

':false; - $documentsHTML = ''; - - if($account->hasFeature(FEATURE_DOCUMENTS) && $invoice->hasDocuments()){ - $documentsHTML .= trans('texts.email_documents_header').'

'; - } - - $variables = [ - '$footer' => $account->getEmailFooter(), - '$client' => $client->getDisplayName(), - '$account' => $account->getDisplayName(), - '$dueDate' => $account->formatDate($invoice->due_date), - '$invoiceDate' => $account->formatDate($invoice->invoice_date), - '$contact' => $invitation->contact->getDisplayName(), - '$firstName' => $invitation->contact->first_name, - '$amount' => $account->formatMoney($data['amount'], $client), - '$invoice' => $invoice->invoice_number, - '$quote' => $invoice->invoice_number, - '$link' => $invitation->getLink(), - '$password' => $passwordHTML, - '$viewLink' => $invitation->getLink().'$password', - '$viewButton' => Form::emailViewButton($invitation->getLink(), $invoice->getEntityType()).'$password', - '$paymentLink' => $invitation->getLink('payment').'$password', - '$paymentButton' => Form::emailPaymentButton($invitation->getLink('payment')).'$password', - '$customClient1' => $account->custom_client_label1, - '$customClient2' => $account->custom_client_label2, - '$customInvoice1' => $account->custom_invoice_text_label1, - '$customInvoice2' => $account->custom_invoice_text_label2, - '$documents' => $documentsHTML, - ]; - - // Add variables for available payment types - foreach (Gateway::$paymentTypes as $type) { - $camelType = Gateway::getPaymentTypeName($type); - $type = Utils::toSnakeCase($camelType); - $variables["\${$camelType}Link"] = $invitation->getLink('payment') . "/{$type}"; - $variables["\${$camelType}Button"] = Form::emailPaymentButton($invitation->getLink('payment') . "/{$type}"); - } - - $includesPasswordPlaceholder = strpos($template, '$password') !== false; - - $str = str_replace(array_keys($variables), array_values($variables), $template); - - if(!$includesPasswordPlaceholder && $passwordHTML){ - $pos = strrpos($str, '$password'); - if($pos !== false) - { - $str = substr_replace($str, $passwordHTML, $pos, 9/* length of "$password" */); - } - } - $str = str_replace('$password', '', $str); - $str = autolink($str, 100); - - return $str; - } } diff --git a/app/Services/TemplateService.php b/app/Services/TemplateService.php new file mode 100644 index 000000000000..5a41c705352d --- /dev/null +++ b/app/Services/TemplateService.php @@ -0,0 +1,80 @@ +invoice; + $passwordHTML = isset($data['password'])?'

'.trans('texts.password').': '.$data['password'].'

':false; + $documentsHTML = ''; + + if ($account->hasFeature(FEATURE_DOCUMENTS) && $invoice->hasDocuments()) { + $documentsHTML .= trans('texts.email_documents_header').'

'; + } + + $variables = [ + '$footer' => $account->getEmailFooter(), + '$client' => $client->getDisplayName(), + '$account' => $account->getDisplayName(), + '$dueDate' => $account->formatDate($invoice->due_date), + '$invoiceDate' => $account->formatDate($invoice->invoice_date), + '$contact' => $invitation->contact->getDisplayName(), + '$firstName' => $invitation->contact->first_name, + '$amount' => $account->formatMoney($data['amount'], $client), + '$invoice' => $invoice->invoice_number, + '$quote' => $invoice->invoice_number, + '$link' => $invitation->getLink(), + '$password' => $passwordHTML, + '$viewLink' => $invitation->getLink().'$password', + '$viewButton' => Form::emailViewButton($invitation->getLink(), $invoice->getEntityType()).'$password', + '$paymentLink' => $invitation->getLink('payment').'$password', + '$paymentButton' => Form::emailPaymentButton($invitation->getLink('payment')).'$password', + '$customClient1' => $account->custom_client_label1, + '$customClient2' => $account->custom_client_label2, + '$customInvoice1' => $account->custom_invoice_text_label1, + '$customInvoice2' => $account->custom_invoice_text_label2, + '$documents' => $documentsHTML, + ]; + + // Add variables for available payment types + foreach (Gateway::$paymentTypes as $type) { + $camelType = Gateway::getPaymentTypeName($type); + $type = Utils::toSnakeCase($camelType); + $variables["\${$camelType}Link"] = $invitation->getLink('payment') . "/{$type}"; + $variables["\${$camelType}Button"] = Form::emailPaymentButton($invitation->getLink('payment') . "/{$type}"); + } + + $includesPasswordPlaceholder = strpos($template, '$password') !== false; + + $str = str_replace(array_keys($variables), array_values($variables), $template); + + if (!$includesPasswordPlaceholder && $passwordHTML) { + $pos = strrpos($str, '$password'); + if ($pos !== false) + { + $str = substr_replace($str, $passwordHTML, $pos, 9/* length of "$password" */); + } + } + $str = str_replace('$password', '', $str); + $str = autolink($str, 100); + + return $str; + } +} \ No newline at end of file diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index f101c79564e7..6d6f3229b059 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1176,6 +1176,7 @@ $LANG = array( 'page_size' => 'Page Size', 'live_preview_disabled' => 'Live preview has been disabled to support selected font', 'invoice_number_padding' => 'Padding', + 'preview' => 'Preview', ); diff --git a/resources/views/accounts/template.blade.php b/resources/views/accounts/template.blade.php index 0d4294af5b6f..68279299f607 100644 --- a/resources/views/accounts/template.blade.php +++ b/resources/views/accounts/template.blade.php @@ -62,11 +62,14 @@
+

 

-
-

 

+

@include('partials/quill_toolbar', ['name' => $field])
+
+ {!! Button::primary(trans('texts.preview'))->withAttributes(['onclick' => 'serverPreview("'.$field.'")'])->small() !!} +
diff --git a/resources/views/accounts/templates_and_reminders.blade.php b/resources/views/accounts/templates_and_reminders.blade.php index 067433a21763..d8032f352a92 100644 --- a/resources/views/accounts/templates_and_reminders.blade.php +++ b/resources/views/accounts/templates_and_reminders.blade.php @@ -80,6 +80,26 @@ + + +