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
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
namespace App\Athenia\Contracts\Repositories\Statistic;

use App\Athenia\Contracts\Repositories\BaseRepositoryContract;
use Illuminate\Support\Collection;

/**
* Interface StatisticRepositoryContract
*/
interface StatisticRepositoryContract extends BaseRepositoryContract
{
/**
* Get all statistics for a given model
*
* @param string $model
* @return Collection
*/
public function findAllForModel(string $model): Collection;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace App\Athenia\Contracts\Repositories\User;

use App\Athenia\Contracts\Repositories\BaseRepositoryContract;

/**
* Interface ArticleNoteRepositoryContract
* @package App\Athenia\Contracts\Repositories\User
*/
interface ArticleNoteRepositoryContract extends BaseRepositoryContract
{}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@
namespace App\Athenia\Contracts\Repositories\Wiki;

use App\Athenia\Contracts\Repositories\BaseRepositoryContract;
use App\Models\User\User;
use App\Models\Wiki\Article;

/**
* Interface ArticleRepositoryContract
* @package App\Contracts\Repositories\Wiki
*/
interface ArticleRepositoryContract extends BaseRepositoryContract
{}
{
/**
* Selects an article for a user based on their note completion status and article statistics
*
* @param User $user
* @return Article|null
*/
public function selectArticleForUser(User $user): ?Article;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php
declare(strict_types=1);

namespace App\Athenia\Http\Core\Controllers\User;

use App\Athenia\Contracts\Repositories\User\ArticleNoteRepositoryContract;
use App\Athenia\Contracts\Repositories\Wiki\ArticleRepositoryContract;
use App\Athenia\Http\Core\Controllers\BaseControllerAbstract;
use App\Athenia\Http\Core\Controllers\Traits\HasIndexRequests;
use App\Athenia\Models\BaseModelAbstract;
use App\Http\Core\Requests;
use App\Models\User\ArticleNote;
use App\Models\User\User;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\JsonResponse;

/**
* Class ArticleNoteControllerAbstract
* @package App\Athenia\Http\Core\Controllers\User
*/
abstract class ArticleNoteControllerAbstract extends BaseControllerAbstract
{
use HasIndexRequests;

/**
* @var ArticleNoteRepositoryContract
*/
private ArticleNoteRepositoryContract $repository;

/**
* @var ArticleRepositoryContract
*/
private ArticleRepositoryContract $articleRepository;

/**
* ArticleNoteController constructor.
* @param ArticleNoteRepositoryContract $repository
* @param ArticleRepositoryContract $articleRepository
*/
public function __construct(ArticleNoteRepositoryContract $repository, ArticleRepositoryContract $articleRepository)
{
$this->repository = $repository;
$this->articleRepository = $articleRepository;
}

/**
* @param Requests\User\ArticleNote\IndexRequest $request
* @param User $user
* @return LengthAwarePaginator
*/
public function index(Requests\User\ArticleNote\IndexRequest $request, User $user): LengthAwarePaginator
{
return $this->repository->findAll(
$this->filter($request),
$this->search($request),
$this->order($request),
$this->expand($request),
$this->limit($request),
[$user],
(int)$request->input('page', 1)
);
}

/**
* @param Requests\User\ArticleNote\StoreRequest $request
* @param User $user
* @return JsonResponse
*/
public function store(Requests\User\ArticleNote\StoreRequest $request, User $user): JsonResponse
{
$data = $request->json()->all();
$data['user_id'] = $user->id;

/** @var ArticleNote $model */
$model = $this->repository->create($data);

return new JsonResponse($model, 201);
}

/**
* @param Requests\User\ArticleNote\ViewRequest $request
* @param User $user
* @param ArticleNote $articleNote
* @return ArticleNote
*/
public function show(Requests\User\ArticleNote\ViewRequest $request, User $user, ArticleNote $articleNote): ArticleNote
{
return $articleNote;
}

/**
* @param Requests\User\ArticleNote\UpdateRequest $request
* @param User $user
* @param ArticleNote $articleNote
* @return BaseModelAbstract
*/
public function update(Requests\User\ArticleNote\UpdateRequest $request, User $user, ArticleNote $articleNote): BaseModelAbstract
{
$data = $request->json()->all();

return $this->repository->update($articleNote, $data);
}

/**
* @param Requests\User\ArticleNote\DeleteRequest $request
* @param User $user
* @param ArticleNote $articleNote
* @return JsonResponse
*/
public function destroy(Requests\User\ArticleNote\DeleteRequest $request, User $user, ArticleNote $articleNote): JsonResponse
{
$this->repository->delete($articleNote);

return new JsonResponse(null, 204);
}

/**
* Selects a random article for the user and creates or retrieves an article note
*
* @param Requests\User\ArticleNote\RandomArticleRequest $request
* @param User $user
* @return JsonResponse
*/
public function randomArticle(Requests\User\ArticleNote\RandomArticleRequest $request, User $user): JsonResponse
{
$article = $this->articleRepository->selectArticleForUser($user);

if (!$article) {
return new JsonResponse([
'message' => 'No available articles found.'
], 404);
}

// Check if a note already exists for this article
$existingNote = ArticleNote::where('user_id', $user->id)
->where('article_id', $article->id)
->first();

if ($existingNote) {
$existingNote->load('article');
return new JsonResponse($existingNote, 200);
}

/** @var ArticleNote $articleNote */
$articleNote = $this->repository->create([
'user_id' => $user->id,
'article_id' => $article->id,
]);

$articleNote->load('article');

return new JsonResponse($articleNote, 201);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);

namespace App\Athenia\Http\Core\Requests\User\ArticleNote;

use App\Athenia\Http\Core\Requests\BaseAuthenticatedRequestAbstract;
use App\Athenia\Http\Core\Requests\Traits\HasNoExpands;
use App\Athenia\Http\Core\Requests\Traits\HasNoRules;
use App\Models\User\ArticleNote;
use App\Policies\User\ArticleNotePolicy;

/**
* Class DeleteRequest
* @package App\Athenia\Http\Core\Requests\User\ArticleNote
*/
class DeleteRequest extends BaseAuthenticatedRequestAbstract
{
use HasNoRules, HasNoExpands;

/**
* Get the policy action for the guard
*
* @return string
*/
protected function getPolicyAction(): string
{
return ArticleNotePolicy::ACTION_DELETE;
}

/**
* @inheritDoc
*/
protected function getPolicyModel(): string
{
return ArticleNote::class;
}

/**
* @return array
*/
protected function getPolicyParameters(): array
{
return [
$this->route('user'),
$this->route('article_note'),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);

namespace App\Athenia\Http\Core\Requests\User\ArticleNote;

use App\Athenia\Http\Core\Requests\BaseAuthenticatedRequestAbstract;
use App\Athenia\Http\Core\Requests\Traits\HasNoRules;
use App\Models\User\ArticleNote;
use App\Policies\User\ArticleNotePolicy;

/**
* Class IndexRequest
* @package App\Athenia\Http\Core\Requests\User\ArticleNote
*/
class IndexRequest extends BaseAuthenticatedRequestAbstract
{
use HasNoRules;

/**
* Get the policy action for the guard
*
* @return string
*/
protected function getPolicyAction(): string
{
return ArticleNotePolicy::ACTION_LIST;
}

/**
* Get the class name of the policy that this request utilizes
*
* @return string
*/
protected function getPolicyModel(): string
{
return ArticleNote::class;
}

/**
* Gets any additional parameters needed for the policy function
*
* @return array
*/
protected function getPolicyParameters(): array
{
return [
$this->route('user'),
];
}

/**
* All expands that are allowed for this request
*
* @return array
*/
public function allowedExpands(): array
{
return [
'user',
'article',
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);

namespace App\Athenia\Http\Core\Requests\User\ArticleNote;

use App\Athenia\Http\Core\Requests\BaseAuthenticatedRequestAbstract;
use App\Athenia\Http\Core\Requests\Traits\HasNoExpands;
use App\Athenia\Http\Core\Requests\Traits\HasNoRules;
use App\Models\User\ArticleNote;
use App\Policies\User\ArticleNotePolicy;

/**
* Class RandomArticleRequest
* @package App\Athenia\Http\Core\Requests\User\ArticleNote
*/
class RandomArticleRequest extends BaseAuthenticatedRequestAbstract
{
use HasNoExpands, HasNoRules;

/**
* Get the policy action for the guard
*
* @return string
*/
protected function getPolicyAction(): string
{
return ArticleNotePolicy::ACTION_CREATE;
}

/**
* Get the class name of the policy that this request utilizes
*
* @return string
*/
protected function getPolicyModel(): string
{
return ArticleNote::class;
}

/**
* Gets any additional parameters needed for the policy function
*
* @return array
*/
protected function getPolicyParameters(): array
{
return [
$this->route('user'),
];
}
}
Loading