TextRepository gains findByUser; JsonTextRepository and the fake implement filtering by stored userId. TextController splits the list endpoint into getMyTexts (own) and getAllTexts (admin), and getText now requires the session user, returning 403 to non-owners while admins bypass.
152 lines
3.1 KiB
PHP
152 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Text;
|
|
|
|
use App\Text\Text;
|
|
use App\Text\CreateTextDto;
|
|
use App\Text\TextRepository;
|
|
use App\User\User;
|
|
use App\User\UserRepository;
|
|
use DomainException;
|
|
|
|
class JsonTextRepository implements TextRepository
|
|
{
|
|
private string $filePath;
|
|
|
|
public function __construct(
|
|
private UserRepository $userRepo,
|
|
) {
|
|
$this->filePath = __DIR__ . '/../../data/texts.json';
|
|
}
|
|
|
|
public function create(CreateTextDto $dto): Text
|
|
{
|
|
$texts = $this->readTexts();
|
|
$id = $this->getNextId($texts);
|
|
|
|
$text = new Text(
|
|
id: $id,
|
|
name: $dto->name,
|
|
user: $dto->user,
|
|
);
|
|
$texts[] = [
|
|
'id' => $id,
|
|
'name' => $dto->name,
|
|
'userId' => $dto->user->getId(),
|
|
];
|
|
|
|
$this->writeTexts($texts);
|
|
|
|
return $text;
|
|
}
|
|
|
|
public function find(int $id): ?Text
|
|
{
|
|
$texts = $this->readTexts();
|
|
|
|
foreach ($texts as $data) {
|
|
if ($data['id'] === $id) {
|
|
return $this->hydrate($data);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return Text[]
|
|
*/
|
|
public function getAll(): array
|
|
{
|
|
$texts = $this->readTexts();
|
|
|
|
return array_map(
|
|
function (array $data) {
|
|
return $this->hydrate($data);
|
|
},
|
|
$texts
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return Text[]
|
|
*/
|
|
public function findByUser(User $user): array
|
|
{
|
|
$texts = $this->readTexts();
|
|
$userId = $user->getId();
|
|
$owned = array_filter(
|
|
$texts,
|
|
function (array $data) use ($userId) {
|
|
return $data['userId'] === $userId;
|
|
}
|
|
);
|
|
|
|
return array_map(
|
|
function (array $data) {
|
|
return $this->hydrate($data);
|
|
},
|
|
array_values($owned)
|
|
);
|
|
}
|
|
|
|
private function hydrate(array $data): Text
|
|
{
|
|
$user = $this->userRepo->find($data['userId']);
|
|
if ($user === null) {
|
|
throw new DomainException(
|
|
"User with id: {$data['userId']} doesnt exist"
|
|
);
|
|
}
|
|
|
|
return new Text(
|
|
id: $data['id'],
|
|
name: $data['name'],
|
|
user: $user,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
private function readTexts(): array
|
|
{
|
|
if (!file_exists($this->filePath)) {
|
|
return [];
|
|
}
|
|
|
|
$content = file_get_contents($this->filePath);
|
|
|
|
return json_decode($content, true) ?? [];
|
|
}
|
|
|
|
/**
|
|
* @param array $texts
|
|
*/
|
|
private function writeTexts(array $texts): void
|
|
{
|
|
file_put_contents(
|
|
$this->filePath,
|
|
json_encode($texts, JSON_PRETTY_PRINT)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $texts
|
|
*/
|
|
private function getNextId(array $texts): int
|
|
{
|
|
if (empty($texts)) {
|
|
return 1;
|
|
}
|
|
|
|
$maxId = 0;
|
|
foreach ($texts as $text) {
|
|
if ($text['id'] > $maxId) {
|
|
$maxId = $text['id'];
|
|
}
|
|
}
|
|
|
|
return $maxId + 1;
|
|
}
|
|
}
|