Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New updates #18

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/filament-email-templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@

//These will be included in the language picker when editing an email template
'languages' => [
'ar' => ['display' => 'العربية', 'flag-icon' => 'sa'],
'en_GB' => ['display' => 'British', 'flag-icon' => 'gb'],
'en_US' => ['display' => 'USA', 'flag-icon' => 'us'],
'es' => ['display' => 'Español', 'flag-icon' => 'es'],
Expand Down
3 changes: 2 additions & 1 deletion resources/lang/ar.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"Email Templates": "قوالب البريد الإلكتروني",
"Email Template Themes": "ثيمات قالب البريد الإلكتروني"
"Email Template Themes": "ثيمات قالب البريد الإلكتروني",
"Preview Email": "مشاهدة البريد الإلكتروني"
}
2 changes: 1 addition & 1 deletion resources/views/email/parts/_content.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: {{config('filament-email-templates.content_width')}}px; margin-bottom: 30px" >
<!-- COPY -->
<tr>
<td bgcolor="{{$data['theme']["content_bg_color"]}}" align="left" style="padding: 20px 30px 40px 30px; color: {{$data['theme']["body_color"]}}; font-family: 'Lato',
<td bgcolor="{{$data['theme']["content_bg_color"]}}" align="{{$data['language']==='ar'?'right':'left'}}" style="padding: 20px 30px 40px 30px; color: {{$data['theme']["body_color"]}}; font-family: 'Lato',
Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 1.8;" >

{!! $data['content']??'' !!}
Expand Down
4 changes: 2 additions & 2 deletions resources/views/email/parts/_footer.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: {{config('filament-email-templates.content_width')}}px;">
<!-- NAVIGATION -->
<tr>
<td bgcolor="{{$data['theme']["body_bg_color"]}}" align="left" style="padding: 30px; color: {{$data['theme']["body_color"]}}; border-radius: 4px 4px 4px 4px;
<td bgcolor="{{$data['theme']["body_bg_color"]}}" align="{{$data['language']==='ar'?'right':'left'}}" style="padding: 30px; color: {{$data['theme']["body_color"]}}; border-radius: 4px 4px 4px 4px;
font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 400; line-height: 18px;">
<p style="margin: 0;">
@foreach(config('filament-email-templates.links') as $link)
Expand All @@ -26,7 +26,7 @@

<!-- ADDRESS -->
<tr>
<td bgcolor="{{$data['theme']["body_bg_color"]}}" align="left"
<td bgcolor="{{$data['theme']["body_bg_color"]}}" align="{{$data['language']==='ar'?'right':'left'}}"
style="padding: 30px; color: {{$data['theme']["body_color"]}}; border-radius: 4px 4px 4px 4px; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 14px;
font-weight: 400; line-height: 18px;">
<p style="margin: 0;"> &copy; <?= date('Y'); ?> {{config('app.name')}}. {{__('vb-email-templates::email-templates.general-labels.all-rights-reserved')}}.</p>
Expand Down
4 changes: 2 additions & 2 deletions resources/views/email/parts/_head.blade.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<html dir="{{$data['language']==='ar'?'rtl':'ltr'}}" style="direction: {{$data['language']==='ar'?'rtl':'ltr'}}">
<head lang="{{$data['language']}}">
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
Expand Down
52 changes: 34 additions & 18 deletions src/DefaultTokenHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

use Illuminate\Support\Facades\View;
use Visualbuilder\EmailTemplates\Contracts\TokenReplacementInterface;
use Visualbuilder\EmailTemplates\Models\EmailTemplate;


class DefaultTokenHelper implements TokenReplacementInterface
{

/**
* Replace tokens in the content with actual values from the models.
*
* @param string $content The content with tokens to be replaced
* @param array $models The models containing the values for the tokens
* @param string $content The content with tokens to be replaced
* @param array $models The models containing the values for the tokens
*
* @return string The content with replaced tokens
*/
Expand All @@ -25,26 +25,25 @@ public function replaceTokens(string $content, $models): string
* Replace singular tokens for password reset and validations
* Add custom tokens in the config
*/
foreach (config('filament-email-templates.known_tokens') as $key){
foreach (config('filament-email-templates.known_tokens') as $key) {
if (isset($models->{$key})) {
$content = str_replace("##$key##", $models->{$key}, $content);
}
}

/**
* Replace model-attribute tokens.
* Will look for pattern ##model.attribute## and replace the value if found.
* Replace model-attribute and template attribute tokens.
* Will look for pattern ##model.attribute## or ##attribute## and replace the value if found.
* Eg ##user.name## or create your own accessors in a model
*/
preg_match_all('/##(.*?)\.(.*?)##/', $content, $matches);
preg_match_all('/##(.*?)##/', $content, $matches);

if (count($matches) > 0 && count($matches[0]) > 0) {
for ($i = 0; $i < count($matches[0]); $i++) {
$modelKey = $matches[1][$i];
$attributeKey = $matches[2][$i];
$replacement = (isset($models->$modelKey) && isset($models->$modelKey->$attributeKey))?$models->$modelKey->$attributeKey:"";
$content = str_replace($matches[0][$i], $replacement, $content);
if (count($matches) > 0 && count($matches[1]) > 0) {

for ($i = 0; $i < count($matches[1]); $i++) {
$attributes = explode('.', $matches[1][$i]);
$replacement = $this->getObjectAttribute($models, $attributes);
$content = str_replace($matches[0][$i], $replacement, $content);
}
}

Expand All @@ -68,7 +67,7 @@ public function replaceTokens(string $content, $models): string
}


if(isset($models->emailTemplate)){
if (isset($models->emailTemplate)) {
$button = $this->buildEmailButton($content, $models->emailTemplate);
$content = self::replaceButtonToken($content, $button);
}
Expand All @@ -77,15 +76,32 @@ public function replaceTokens(string $content, $models): string
return $content;
}

/**
* @Access model attribute using attribute path
*/
public function getObjectAttribute($object, $path)
{
foreach ($path as $key) {
if (is_object($object) && isset($object->$key)) {
$object = $object->$key; // Move to the next level in the object
} elseif (is_array($object) && isset($object[$key])) {
$object = $object[$key]; // Move to the next level in the array
} else {
return null; // Return null if the path is invalid
}
}
return $object; // Return the final value
}

private function buildEmailButton($content, $emailTemplate)
{
$title = $url = '';
if (preg_match('/(?<=##button).*?(?=#)/', $content, $matches)) {
if ($check1 = preg_match("/(?<=url=').*?(?='\s)/", $matches[ 0 ], $url)) {
$url = $url[ 0 ];
if ($check1 = preg_match("/(?<=url=').*?(?='\s)/", $matches[0], $url)) {
$url = $url[0];
}
if ($check2 = preg_match("/(?<=title=').*?(?=')/", $matches[ 0 ], $title)) {
$title = $title[ 0 ];
if ($check2 = preg_match("/(?<=title=').*?(?=')/", $matches[0], $title)) {
$title = $title[0];
}
if ($check1 && $check2) {

Expand Down
67 changes: 36 additions & 31 deletions src/Models/EmailTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,6 @@ public function __construct(array $attributes = [])
$this->setTableFromConfig();
}

protected static function boot()
{
parent::boot();

// When an email template is updated
static::updated(function ($template) {
self::clearEmailTemplateCache($template->key, $template->language);
});

// When an email template is deleted
static::deleted(function ($template) {
self::clearEmailTemplateCache($template->key, $template->language);
});
}

public function setTableFromConfig()
{
$this->table = config('filament-email-templates.table_name');
Expand All @@ -114,12 +99,6 @@ public static function findEmailByKey($key, $language = null)
});
}

public static function clearEmailTemplateCache($key, $language)
{
$cacheKey = "email_by_key_{$key}_{$language}";
Cache::forget($cacheKey);
}

/**
* @return \Illuminate\Support\Collection
*/
Expand All @@ -128,6 +107,27 @@ public static function getSendToSelectOptions()
return collect(config('emailTemplate.recipients'));
}

protected static function boot()
{
parent::boot();

// When an email template is updated
static::updated(function ($template) {
self::clearEmailTemplateCache($template->key, $template->language);
});

// When an email template is deleted
static::deleted(function ($template) {
self::clearEmailTemplateCache($template->key, $template->language);
});
}

public static function clearEmailTemplateCache($key, $language)
{
$cacheKey = "email_by_key_{$key}_{$language}";
Cache::forget($cacheKey);
}

/**
* @return EmailTemplateFactory
*/
Expand Down Expand Up @@ -181,16 +181,7 @@ public function getBase64EmailPreviewData()
public function getEmailPreviewData()
{
$models = self::createEmailPreviewData();

return [
'user' => $models->user,
'content' => TokenHelper::replace($this->content ?? '', $models),
'subject' => TokenHelper::replace($this->subject ?? '', $models),
'preHeaderText' => TokenHelper::replace($this->preheader ?? '', $models),
'title' => TokenHelper::replace($this->title ?? '', $models),
'theme' => $this->theme->colours,
'logo' => $this->logo,
];
return self::getEmailData($this, $models);
}

/**
Expand All @@ -212,6 +203,20 @@ public static function createEmailPreviewData()
return $models;
}

public static function getEmailData($template, $model)
{
return [
'user' => $model->user,
'content' => TokenHelper::replace($template->content ?? '', $model),
'subject' => TokenHelper::replace($template->subject ?? '', $model),
'preHeaderText' => TokenHelper::replace($template->preheader ?? '', $model),
'title' => TokenHelper::replace($template->title ?? '', $model),
'theme' => $template->theme->colours,
'logo' => $template->logo,
'language' => $template->language,
];
}

/**
* Efficient method to return requested template locale or default language template in one query
*
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/EmailTemplateResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public static function table(Table $table): Table
'vb-email-templates::forms.components.iframe',
['record' => $record],
))->form(null)
->modalHeading(fn(EmailTemplate $record): string => 'Preview Email: ' . $record->name)
->modalHeading(fn(EmailTemplate $record): string => __('Preview Email').': ' . $record->name)
->modalSubmitAction(false)
->modalCancelAction(false)
->slideOver(),
Expand Down
26 changes: 10 additions & 16 deletions src/Traits/BuildGenericEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,20 @@ public function build()

if ($this->attachment ?? false) {
$this->attach(
$this->attachment->getPath(),
[
'as' => $this->attachment->filename,
'mime' => $this->attachment->mime_type,
]
$this->attachment->getPath(),
[
'as' => $this->attachment->filename,
'mime' => $this->attachment->mime_type,
]
);
}

$data = [
'content' => TokenHelper::replace($this->emailTemplate->content, $this),
'preHeaderText' => TokenHelper::replace($this->emailTemplate->preheader, $this),
'title' => TokenHelper::replace($this->emailTemplate->title, $this),
'theme' => $this->emailTemplate->theme->colours,
'logo' => $this->emailTemplate->logo,
];
$data = EmailTemplate::getEmailData($this->emailTemplate, $this);

return $this->from($this->emailTemplate->from['email'], $this->emailTemplate->from['name'])
->view($this->emailTemplate->view_path)
->subject(TokenHelper::replace($this->emailTemplate->subject, $this))
->to($this->sendTo)
->with(['data' => $data]);
->view($this->emailTemplate->view_path)
->subject(TokenHelper::replace($this->emailTemplate->subject, $this))
->to($this->sendTo)
->with(['data' => $data]);
}
}