Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions app/Http/Controllers/Api/V1/Article/GetCommentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,29 @@ public function __invoke(GetCommentsRequest $request, Article $article): JsonRes
$params = $request->withDefaults();

try {
$parentId = $params['parent_id'] !== null ? (int) $params['parent_id'] : null;
/** @var mixed $parentIdInput */
$parentIdInput = $request->input('parent_id');
/** @var mixed $commentIdInput */
$commentIdInput = $request->input('comment_id');
/** @var mixed $userIdInput */
$userIdInput = $request->input('user_id');
$parentId = is_numeric($parentIdInput) ? (int) $parentIdInput : null;
$commentId = is_numeric($commentIdInput) ? (int) $commentIdInput : null;
$userId = is_numeric($userIdInput) ? (int) $userIdInput : null;

/** @var mixed $perPageParam */
$perPageParam = $params['per_page'] ?? 10;
/** @var mixed $pageParam */
$pageParam = $params['page'] ?? 1;
$perPage = (int) $perPageParam;
$page = (int) $pageParam;
$commentsDataResponse = CommentResource::collection($this->articleService->getArticleComments(
$article->id,
$parentId,
(int) $params['per_page'],
(int) $params['page']
$perPage,
$page
));
/** @var array{data: array, meta: array} $commentsData */
/** @var array{data: array<int, mixed>, meta: array<string, mixed>} $commentsData */
$commentsData = $commentsDataResponse->response()->getData(true);

return response()->apiSuccess(
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Middleware/OptionalSanctumAuthenticate.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function handle(Request $request, Closure $next): mixed
$token = $request->bearerToken();
if (is_string($token) && $token !== '') {
$accessToken = PersonalAccessToken::findToken($token);
if ($accessToken !== null) {
if ($accessToken !== null && $accessToken instanceof PersonalAccessToken) {
$tokenable = $accessToken->tokenable;
// Check for 'access-api' ability
if ($tokenable instanceof User && $accessToken->can('access-api')) {
Expand Down
6 changes: 3 additions & 3 deletions app/Http/Resources/V1/Article/ArticleResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ public function toArray(Request $request): array
'content_markdown' => $this->content_markdown,
'featured_image' => $this->featured_image,
'status' => $this->status,
'published_at' => $this->published_at?->toISOString(),
'published_at' => ($this->published_at instanceof \DateTimeInterface ? $this->published_at->toISOString() : $this->published_at),
'meta_title' => $this->meta_title,
'meta_description' => $this->meta_description,
'created_at' => $this->created_at?->toISOString(),
'updated_at' => $this->updated_at?->toISOString(),
'created_at' => ($this->created_at instanceof \DateTimeInterface ? $this->created_at->toISOString() : $this->created_at),
'updated_at' => ($this->updated_at instanceof \DateTimeInterface ? $this->updated_at->toISOString() : $this->updated_at),

// Relationships
// Original Author
Expand Down
17 changes: 14 additions & 3 deletions app/Http/Resources/V1/Auth/UserResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public function toArray(Request $request): array
$roles = $this->resource->roles;

foreach ($roles as $role) {
/** @var \App\Models\Role $role */
foreach ($role->permissions as $permission) {
/** @var \App\Models\Permission $permission */
$permissionSlugs[] = $permission->slug;
Expand All @@ -54,11 +53,23 @@ public function toArray(Request $request): array
fn () => [
'access_token' => $this->resource->getAttributes()['access_token'],
'refresh_token' => $this->resource->getAttributes()['refresh_token'] ?? null,
'access_token_expires_at' => optional($this->resource->getAttributes()['access_token_expires_at'] ?? null)?->toISOString(),
'refresh_token_expires_at' => optional($this->resource->getAttributes()['refresh_token_expires_at'] ?? null)?->toISOString(),
'access_token_expires_at' => $this->formatDateTime($this->resource->getAttributes()['access_token_expires_at'] ?? null),
'refresh_token_expires_at' => $this->formatDateTime($this->resource->getAttributes()['refresh_token_expires_at'] ?? null),
'token_type' => 'Bearer',
]
),
];
}

/**
* Format a datetime value to ISO string if it's a DateTimeInterface.
*/
private function formatDateTime(mixed $value): mixed
{
if ($value instanceof \DateTimeInterface) {
return $value->format('Y-m-d\TH:i:s.v\Z');
}

return $value;
}
}
51 changes: 36 additions & 15 deletions app/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
*
* @mixin \Eloquent
*
* @use HasFactory<Article>
* @phpstan-use \Illuminate\Database\Eloquent\Factories\HasFactory<self>
*/
final class Article extends Model
{
Expand All @@ -52,58 +52,79 @@ protected function casts(): array
}

/**
* @return BelongsTo<User,Article>
* @return BelongsTo<User, Article>
*/
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
/** @var BelongsTo<User, Article> $relation */
$relation = $this->belongsTo(User::class, 'created_by');

return $relation;
}

/**
* @return BelongsTo<User,Article>
* @return BelongsTo<User, Article>
*/
public function approver(): BelongsTo
{
return $this->belongsTo(User::class, 'approved_by');
/** @var BelongsTo<User, Article> $relation */
$relation = $this->belongsTo(User::class, 'approved_by');

return $relation;
}

/**
* @return BelongsTo<User,Article>
* @return BelongsTo<User, Article>
*/
public function updater(): BelongsTo
{
return $this->belongsTo(User::class, 'updated_by');
/** @var BelongsTo<User, Article> $relation */
$relation = $this->belongsTo(User::class, 'updated_by');

return $relation;
}

/**
* @return HasMany<Comment,Article>
* @return HasMany<Comment, Article>
*/
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
/** @var HasMany<Comment, Article> $relation */
$relation = $this->hasMany(Comment::class);

return $relation;
}

/**
* @return BelongsToMany<Category,Article>
* @return BelongsToMany<Category, Article, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'>
*/
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class, 'article_categories');
/** @var BelongsToMany<Category, Article, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'> $relation */
$relation = $this->belongsToMany(Category::class, 'article_categories');

return $relation;
}

/**
* @return BelongsToMany<Tag,Article>
* @return BelongsToMany<Tag, Article, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'>
*/
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class, 'article_tags');
/** @var BelongsToMany<Tag, Article, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'> $relation */
$relation = $this->belongsToMany(Tag::class, 'article_tags');

return $relation;
}

/**
* @return BelongsToMany<User,Article>
* @return BelongsToMany<User, Article, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'>
*/
public function authors(): BelongsToMany
{
return $this->belongsToMany(User::class, 'article_authors')->withPivot('role');
/** @var BelongsToMany<User, Article, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'> $relation */
$relation = $this->belongsToMany(User::class, 'article_authors')->withPivot('role');

return $relation;
}
}
18 changes: 11 additions & 7 deletions app/Models/ArticleAuthor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
*
* @mixin \Eloquent
*
* @use HasFactory<ArticleAuthor>
*
* @phpstan-use HasFactory<ArticleAuthor>
* @phpstan-use \Illuminate\Database\Eloquent\Factories\HasFactory<self>
*/
final class ArticleAuthor extends Model
{
Expand All @@ -41,18 +39,24 @@ protected function casts(): array
}

/**
* @return BelongsTo<Article,ArticleAuthor>
* @return BelongsTo<Article, ArticleAuthor>
*/
public function article(): BelongsTo
{
return $this->belongsTo(Article::class);
/** @var BelongsTo<Article, ArticleAuthor> $relation */
$relation = $this->belongsTo(Article::class);

return $relation;
}

/**
* @return BelongsTo<User,ArticleAuthor>
* @return BelongsTo<User, ArticleAuthor>
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
/** @var BelongsTo<User, ArticleAuthor> $relation */
$relation = $this->belongsTo(User::class);

return $relation;
}
}
18 changes: 11 additions & 7 deletions app/Models/ArticleCategory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*
* @mixin \Eloquent
*
* @use HasFactory<ArticleCategory>
*
* @phpstan-use HasFactory<ArticleCategory>
* @phpstan-use \Illuminate\Database\Eloquent\Factories\HasFactory<self>
*/
final class ArticleCategory extends Model
{
Expand All @@ -37,18 +35,24 @@ protected function casts(): array
}

/**
* @return BelongsTo<Article,ArticleCategory>
* @return BelongsTo<Article, ArticleCategory>
*/
public function article(): BelongsTo
{
return $this->belongsTo(Article::class);
/** @var BelongsTo<Article, ArticleCategory> $relation */
$relation = $this->belongsTo(Article::class);

return $relation;
}

/**
* @return BelongsTo<Category,ArticleCategory>
* @return BelongsTo<Category, ArticleCategory>
*/
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
/** @var BelongsTo<Category, ArticleCategory> $relation */
$relation = $this->belongsTo(Category::class);

return $relation;
}
}
18 changes: 11 additions & 7 deletions app/Models/ArticleTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
*
* @mixin \Eloquent
*
* @use HasFactory<ArticleTag>
*
* @phpstan-use HasFactory<ArticleTag>
* @phpstan-use \Illuminate\Database\Eloquent\Factories\HasFactory<self>
*/
final class ArticleTag extends Model
{
Expand All @@ -37,18 +35,24 @@ protected function casts(): array
}

/**
* @return BelongsTo<Article,ArticleTag>
* @return BelongsTo<Article, ArticleTag>
*/
public function article(): BelongsTo
{
return $this->belongsTo(Article::class);
/** @var BelongsTo<Article, ArticleTag> $relation */
$relation = $this->belongsTo(Article::class);

return $relation;
}

/**
* @return BelongsTo<Tag,ArticleTag>
* @return BelongsTo<Tag, ArticleTag>
*/
public function tag(): BelongsTo
{
return $this->belongsTo(Tag::class);
/** @var BelongsTo<Tag, ArticleTag> $relation */
$relation = $this->belongsTo(Tag::class);

return $relation;
}
}
9 changes: 6 additions & 3 deletions app/Models/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* @mixin \Eloquent
*
* @phpstan-use HasFactory<Category>
* @phpstan-use \Illuminate\Database\Eloquent\Factories\HasFactory<self>
*/
final class Category extends Model
{
Expand All @@ -34,10 +34,13 @@ protected function casts(): array
}

/**
* @return BelongsToMany<Article,Category>
* @return BelongsToMany<Article, Category, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'>
*/
public function articles(): BelongsToMany
{
return $this->belongsToMany(Article::class, 'article_categories');
/** @var BelongsToMany<Article, Category, \Illuminate\Database\Eloquent\Relations\Pivot, 'pivot'> $relation */
$relation = $this->belongsToMany(Article::class, 'article_categories');

return $relation;
}
}
25 changes: 16 additions & 9 deletions app/Models/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
*
* @mixin \Eloquent
*
* @use HasFactory<Comment>
*
* @phpstan-use HasFactory<Comment>
* @phpstan-use \Illuminate\Database\Eloquent\Factories\HasFactory<self>
*/
final class Comment extends Model
{
Expand All @@ -40,28 +38,37 @@ protected function casts(): array
}

/**
* @return BelongsTo<Article,Comment>
* @return BelongsTo<Article, Comment>
*/
public function article(): BelongsTo
{
return $this->belongsTo(Article::class);
/** @var BelongsTo<Article, Comment> $relation */
$relation = $this->belongsTo(Article::class);

return $relation;
}

/**
* @return BelongsTo<User,Comment>
* @return BelongsTo<User, Comment>
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
/** @var BelongsTo<User, Comment> $relation */
$relation = $this->belongsTo(User::class);

return $relation;
}

/**
* Get the replies (child comments) for this comment.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Comment, Comment>
* @return \Illuminate\Database\Eloquent\Relations\HasMany<Comment, Comment>
*/
public function replies(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(Comment::class, 'parent_comment_id');
/** @var \Illuminate\Database\Eloquent\Relations\HasMany<Comment, Comment> $relation */
$relation = $this->hasMany(Comment::class, 'parent_comment_id');

return $relation;
}
}
Loading