extend Post entity with feature slot
Adds nullable feature_slot column (unique) plus repo findByFeatureSlot/findFeatured/update methods so admins can pin a post into one of two slots.
This commit is contained in:
parent
64a334c63e
commit
f73e5a1af5
6 changed files with 160 additions and 4 deletions
|
|
@ -4,6 +4,7 @@ namespace App\Post;
|
|||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use RuntimeException;
|
||||
|
||||
class EloquentPostRepository implements PostRepository
|
||||
{
|
||||
|
|
@ -65,6 +66,53 @@ class EloquentPostRepository implements PostRepository
|
|||
PostModel::query()->where('id', $id)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function update(Post $post): Post
|
||||
{
|
||||
$model = PostModel::find($post->getId());
|
||||
if ($model === null) {
|
||||
throw new RuntimeException(
|
||||
"Post with id: {$post->getId()} does not exist"
|
||||
);
|
||||
}
|
||||
$model->user_id = $post->getUserId();
|
||||
$model->title = $post->getTitle();
|
||||
$model->body = $post->getBody();
|
||||
$model->created_at = $post->getCreatedAt();
|
||||
$model->feature_slot = $post->getFeatureSlot();
|
||||
$model->save();
|
||||
|
||||
return $this->toDomain($model);
|
||||
}
|
||||
|
||||
public function findByFeatureSlot(int $slot): ?Post
|
||||
{
|
||||
$model = PostModel::query()
|
||||
->where('feature_slot', $slot)
|
||||
->first();
|
||||
|
||||
return $model === null ? null : $this->toDomain($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Post[]
|
||||
*/
|
||||
public function findFeatured(): array
|
||||
{
|
||||
$models = PostModel::query()
|
||||
->whereNotNull('feature_slot')
|
||||
->orderBy('feature_slot', 'asc')
|
||||
->get();
|
||||
|
||||
return $models->map(
|
||||
function (PostModel $model) {
|
||||
return $this->toDomain($model);
|
||||
},
|
||||
)->all();
|
||||
}
|
||||
|
||||
private function toDomain(PostModel $model): Post
|
||||
{
|
||||
$utc = new DateTimeZone('UTC');
|
||||
|
|
@ -78,6 +126,7 @@ class EloquentPostRepository implements PostRepository
|
|||
$model->created_at->toDateTimeString(),
|
||||
$utc,
|
||||
),
|
||||
featureSlot: $model->feature_slot,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class Post
|
|||
private string $title,
|
||||
private string $body,
|
||||
private DateTimeImmutable $createdAt,
|
||||
private ?int $featureSlot,
|
||||
) {}
|
||||
|
||||
public function getId(): int
|
||||
|
|
@ -38,4 +39,14 @@ class Post
|
|||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
public function getFeatureSlot(): ?int
|
||||
{
|
||||
return $this->featureSlot;
|
||||
}
|
||||
|
||||
public function isFeatured(): bool
|
||||
{
|
||||
return $this->featureSlot !== null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@
|
|||
|
||||
namespace App\Post;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $user_id
|
||||
* @property string $title
|
||||
* @property string $body
|
||||
* @property Carbon $created_at
|
||||
* @property DateTimeImmutable $created_at
|
||||
* @property ?int $feature_slot
|
||||
*
|
||||
* @method static Builder<static>|PostModel newModelQuery()
|
||||
* @method static Builder<static>|PostModel newQuery()
|
||||
* @method static Builder<static>|PostModel query()
|
||||
* @method static Builder<static>|PostModel whereId($value)
|
||||
* @method static Builder<static>|PostModel whereUserId($value)
|
||||
* @method static Builder<static>|PostModel whereTitle($value)
|
||||
* @method static Builder<static>|PostModel whereBody($value)
|
||||
* @method static Builder<static>|PostModel whereCreatedAt($value)
|
||||
* @method static Builder<static>|PostModel whereFeatureSlot($value)
|
||||
*
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
|
|
@ -32,9 +37,11 @@ class PostModel extends Model
|
|||
'title',
|
||||
'body',
|
||||
'created_at',
|
||||
'feature_slot',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'created_at' => 'datetime',
|
||||
'created_at' => 'immutable_datetime',
|
||||
'feature_slot' => 'integer',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Post;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
interface PostRepository
|
||||
{
|
||||
public function create(CreatePostDto $dto): Post;
|
||||
|
|
@ -19,4 +21,16 @@ interface PostRepository
|
|||
public function findRecent(int $limit): array;
|
||||
|
||||
public function delete(int $id): void;
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function update(Post $post): Post;
|
||||
|
||||
public function findByFeatureSlot(int $slot): ?Post;
|
||||
|
||||
/**
|
||||
* @return Post[]
|
||||
*/
|
||||
public function findFeatured(): array;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue