Laravel.io
//Так выглядит "клиенский" код
$emailTemplate = TransactionEmailFactory::make($transaction, 'client')->render();
//Фабрика для определения того, какой емейл темплейт должен быть заюзан
abstract class TransactionEmailFactory
{
public static function make($transaction, $target)
{
switch ($transaction->trans_class) {
case 'car':
return new CarEmail($transaction, $target);
case 'hotel':
return new HotelEmail($transaction, $target);
}
}
}
//Емейл букинга машины
class CarEmail extends TransactionEmail
{
public $vehicleType;
public function __construct($transaction, $target)
{
parent::__construct($transaction, $target);
$this->vehicleType = $this->json_notes->vehicle;
}
}
//Емейл букинга отеля
class HotelEmail extends TransactionEmail
{
public $guestsInfo;
public function __construct($transaction, $target)
{
parent::__construct($transaction, $targeta);
$this->guestsInfo = $this->json_notes->guests_info;
}
}
//Мейлабл класс для всех транзакционных емейлов
class TransactionEmail extends Mailable
{
public $transaction;
public $type;
public $target;
public $json_notes;
public function __construct($transaction, $target)
{
$this->transaction = $transaction;
$this->type = strtolower($transaction->trans_class);
$this->target = $target;
$this->json_notes = json_decode($this->transaction->notes);
}
public function build()
{
$target = $this->getTarget();
$type = $this->getType();
return $this->view("emails.transactionEmails.{$target}.{$type}");
}
}
// ----------------------------------------------------------------------------------------------
// Дальше идут варианты реализации кастомных емейлов для определнных партнеров
class PartnerACustomization extends TransactionEmailCustomization
{
public function getTemplate()
{
if ($this->type == 'car') {
return "emails.transactionEmails.custom.partnerA.car";
}
return parent::getTemplate();
}
}
class TransactionEmailCustomization
{
public $type;
public $target;
public function __construct($type, $target)
{
$this->type = $type;
$this->target = $target;
}
public function getType()
{
return $this->type;
}
public function getTarget()
{
return $this->target;
}
public function getTemplate()
{
return "emails.transactionEmails.{$target}.{$type}";
}
}
interface TransactionEmailsCustomizationInterface
{
public function getType();
public function getTarget();
public function getTemplate();
}
//Тогда, теоретически, класс по отправке емейлов будет выглядеть так:
class TransactionEmail extends Mailable
{
...
public $customization;
public function __construct($transaction, $target, TransactionEmailsCustomizationInterface $customization)
{
...
$this->customization = $customization;
}
public function build()
{
return $this->view($this->customization->getTemplate());
}
}
//Ну и мы будем должны передать этот кастомизейшн класс по цепочке емейлФактори->карЕмейл->транзакшнЕмейл
abstract class TransactionEmailFactory
{
public static function make($transaction, $target)
{
$customizationClass = $transaction->partner->getTransactionCustomizationClass();
switch ($transaction->trans_class) {
case 'car':
return new CarEmail($transaction, $target, $customizationClass);
case 'hotel':
return new HotelEmail($transaction, $target, $customizationClass);
}
}
}
//Емейл букинга машины
class CarEmail extends TransactionEmail
{
public $vehicleType;
public function __construct($transaction, $target, $customizationClass)
{
parent::__construct($transaction, $target, $customizationClass);
$this->vehicleType = $this->json_notes->vehicle;
}
}
//Емейл букинга отеля
class HotelEmail extends TransactionEmail
{
public $guestsInfo;
public function __construct($transaction, $target, $customizationClass)
{
parent::__construct($transaction, $targeta, $customizationClass);
$this->guestsInfo = $this->json_notes->guests_info;
}
}
//И в итоге мне совсем не нравится то, что получилось :(