File: /home/xedaptot/ai.naniguide.com/app/Services/TemplateService.php
<?php
namespace App\Services;
use App\Library\Contracts\TemplateSubjectInterface;
use App\Model\Email;
use App\Model\Template;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Schema;
use InvalidArgumentException;
class TemplateService
{
private Model $subject;
private function __construct(TemplateSubjectInterface $subject)
{
if (!$subject instanceof Model) {
throw new InvalidArgumentException('TemplateService subjects must be Eloquent models');
}
$relation = $subject->template();
if (!$relation instanceof BelongsTo) {
throw new InvalidArgumentException('TemplateService requires a belongsTo template() relation');
}
if ($relation->getForeignKeyName() !== 'template_id') {
throw new InvalidArgumentException('TemplateService requires template() to use template_id as the foreign key');
}
$this->subject = $subject;
}
public static function for(TemplateSubjectInterface $subject): self
{
return new self($subject);
}
public function setTemplate(Template $template, string $name): Template
{
$this->propagateNameToSubject($name);
$copy = $template->copyAsPrivate([
'name' => $name,
'customer_id' => $this->subject->getAttribute('customer_id'),
]);
return $this->replaceWithTemplate($copy);
}
public function replaceWithTemplate(Template $template): Template
{
$currentTemplate = $this->subject->template;
$this->subject->template()->associate($template);
$this->subject->save();
$this->subject->refresh();
if ($currentTemplate && !$currentTemplate->is($template)) {
$currentTemplate->deleteAndCleanup();
}
return $this->subject->template;
}
public function setCustomHtml(string $html, string $name): Template
{
$this->propagateNameToSubject($name);
$template = Template::makeUploaded(name: $name, html: $html);
$template->save();
return $this->replaceWithTemplate($template);
}
/**
* Write $name to the subject's `name` column if it has one. Email uses `subject`
* for its label, so we skip it; MailListTemplate has no name column either.
*/
private function propagateNameToSubject(string $name): void
{
static $cache = [];
$class = get_class($this->subject);
$cache[$class] ??= Schema::hasColumn($this->subject->getTable(), 'name');
if ($cache[$class]) {
$this->subject->setAttribute('name', $name);
}
}
public function removeTemplate(): void
{
$currentTemplate = $this->subject->template;
if (!$currentTemplate) {
return;
}
$this->subject->template()->dissociate();
$this->subject->save();
$this->subject->unsetRelation('template');
$currentTemplate->deleteAndCleanup();
$this->subject->refresh();
}
public function deleteSubjectAndTemplate(): void
{
$currentTemplate = $this->subject->template;
if ($currentTemplate) {
$currentTemplate->deleteAndCleanup();
}
if ($this->subject->getKey() && $this->subject->newQuery()->whereKey($this->subject->getKey())->exists()) {
$this->subject->delete();
}
}
}