feat(124): sms templates CRUD + order picker
- Nowa tabela sms_templates (name + body + is_active) + minimalny CRUD.
- /settings/sms-templates: lista + formularz z paleta zmiennych (pill chips).
- Wydzielono Sms\SmsVariableResolver ze wspolna logika placeholderow;
Email\VariableResolver staje sie cienka fasada — EmailSendingService bez zmian.
- Dropdown "Wybierz szablon" w zakladce SMS na /orders/{id} z fetch
GET /orders/{id}/sms/template + OrderProAlerts.confirm przy nadpisaniu.
- Stopka SMSPLANET dalej doklejana wylacznie przez SmsConversationService
(Phase 122 contract preserved).
- Sidebar Ustawien: nowy link "Szablony SMS".
Migration: 20260512_000112_create_sms_templates.sql (CREATE TABLE).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
121
src/Modules/Sms/SmsTemplateRepository.php
Normal file
121
src/Modules/Sms/SmsTemplateRepository.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Sms;
|
||||
|
||||
use App\Core\Http\ToggleableRepositoryTrait;
|
||||
use PDO;
|
||||
use RuntimeException;
|
||||
|
||||
final class SmsTemplateRepository
|
||||
{
|
||||
use ToggleableRepositoryTrait;
|
||||
|
||||
public function __construct(
|
||||
private readonly PDO $pdo
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
public function listAll(): array
|
||||
{
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT id, name, body, is_active, created_at, updated_at
|
||||
FROM sms_templates
|
||||
ORDER BY name ASC'
|
||||
);
|
||||
$statement->execute();
|
||||
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
return is_array($rows) ? $rows : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
public function listActive(): array
|
||||
{
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT id, name, body
|
||||
FROM sms_templates
|
||||
WHERE is_active = 1
|
||||
ORDER BY name ASC'
|
||||
);
|
||||
$statement->execute();
|
||||
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
return is_array($rows) ? $rows : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
public function findById(int $id): ?array
|
||||
{
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT id, name, body, is_active, created_at, updated_at
|
||||
FROM sms_templates
|
||||
WHERE id = :id'
|
||||
);
|
||||
$statement->execute(['id' => $id]);
|
||||
$row = $statement->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
return is_array($row) ? $row : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function save(array $data): int
|
||||
{
|
||||
$name = trim((string) ($data['name'] ?? ''));
|
||||
$body = (string) ($data['body'] ?? '');
|
||||
if ($name === '') {
|
||||
throw new RuntimeException('Nazwa szablonu jest wymagana.');
|
||||
}
|
||||
if (trim($body) === '') {
|
||||
throw new RuntimeException('Tresc szablonu jest wymagana.');
|
||||
}
|
||||
|
||||
$id = isset($data['id']) && $data['id'] !== '' ? (int) $data['id'] : null;
|
||||
$params = [
|
||||
'name' => $name,
|
||||
'body' => $body,
|
||||
'is_active' => isset($data['is_active']) && $data['is_active'] ? 1 : 0,
|
||||
];
|
||||
|
||||
if ($id !== null) {
|
||||
$params['id'] = $id;
|
||||
$statement = $this->pdo->prepare(
|
||||
'UPDATE sms_templates
|
||||
SET name = :name, body = :body, is_active = :is_active
|
||||
WHERE id = :id'
|
||||
);
|
||||
$statement->execute($params);
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
$statement = $this->pdo->prepare(
|
||||
'INSERT INTO sms_templates (name, body, is_active)
|
||||
VALUES (:name, :body, :is_active)'
|
||||
);
|
||||
$statement->execute($params);
|
||||
|
||||
return (int) $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
public function delete(int $id): void
|
||||
{
|
||||
$statement = $this->pdo->prepare('DELETE FROM sms_templates WHERE id = :id');
|
||||
$statement->execute(['id' => $id]);
|
||||
}
|
||||
|
||||
public function toggleStatus(int $id): void
|
||||
{
|
||||
$this->toggleActive('sms_templates', $id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user