first commit

This commit is contained in:
2026-02-18 19:54:52 +07:00
commit 8e070562cb
101 changed files with 13462 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
namespace App\Services;
use App\Contracts\QueryFilterPipelineInterface;
use App\Contracts\RequestFilterInterface;
use App\Contracts\TaskServiceInterface;
use App\Models\Tag;
use App\Models\Task;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\DB;
final readonly class TaskService implements TaskServiceInterface
{
public function __construct(
private QueryFilterPipelineInterface $pipeline
) {
}
/**
* @inheritDoc
*/
public function list(RequestFilterInterface $filters): LengthAwarePaginator
{
$builder = Task::query()
->with('tags');
return $this->pipeline->applyFilters($builder, $filters);
}
/**
* @inheritDoc
*/
public function create(array $data): Task
{
return DB::transaction(function () use ($data) {
$tags = $data['tags'] ?? [];
unset($data['tags']);
$task = Task::create($data);
if (!empty($tags)) {
$this->syncTags($task, $tags);
}
return $task->load('tags');
});
}
public function show(Task $task): Task
{
return $task->load('tags');
}
/**
* @inheritDoc
*/
public function update(Task $task, array $data): Task
{
return DB::transaction(function () use ($task, $data) {
$tags = $data['tags'] ?? null;
unset($data['tags']);
$task->update($data);
if (is_array($tags)) {
$this->syncTags($task, $tags);
}
return $task->load('tags');
});
}
public function delete(Task $task): void
{
$task->delete();
}
private function syncTags(Task $task, array $tagNames): void
{
$tagIds = collect($tagNames)
->filter()
->unique()
->map(function (string $name) {
try {
return Tag::firstOrCreate([
'name' => $name,
])->id;
} catch (QueryException) {
return Tag::where('name', $name)->value('id');
}
})
->all();
$task->tags()->sync($tagIds);
}
}