Migrate backend to Porto architecture and fix minor bugs
- Fully transitioned the backend to the Porto architectural pattern - Improved code organization and maintainability - Fixed minor bugs and inconsistencies
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\Loaders;
|
||||
|
||||
class AliasesLoader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $aliases = [];
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\Loaders;
|
||||
|
||||
class MiddlewareLoader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $middleware = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $middlewareGroups = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $routeMiddleware = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $middlewarePriority = [];
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\Loaders;
|
||||
|
||||
class ProvidersLoader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $providers = [];
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\Models;
|
||||
|
||||
use App\Ship\Contracts\SeoDescriptionInterface;
|
||||
use App\Ship\Models\Model;
|
||||
use App\Ship\Traits\HasSeo;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class AcademicJournal extends Model implements SeoDescriptionInterface
|
||||
{
|
||||
use HasFactory, HasSeo;
|
||||
|
||||
protected $guarded = false;
|
||||
|
||||
protected $casts = [
|
||||
'main_info' => 'array',
|
||||
'chief_editor' => 'array',
|
||||
'editors' => 'array',
|
||||
'for_authors' => 'array',
|
||||
];
|
||||
|
||||
public function journals(): HasMany
|
||||
{
|
||||
return $this->hasMany(JournalIssue::class);
|
||||
}
|
||||
|
||||
public function getSeoDescription(): array
|
||||
{
|
||||
return $this->main_info;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\Models;
|
||||
|
||||
use App\Ship\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class JournalIssue extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = false;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\Policies;
|
||||
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Containers\Science\Models\AcademicJournal;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class AcademicJournalPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('view_any_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, AcademicJournal $academicJournal): bool
|
||||
{
|
||||
return $user->can('view_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('create_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, AcademicJournal $academicJournal): bool
|
||||
{
|
||||
return $user->can('update_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, AcademicJournal $academicJournal): bool
|
||||
{
|
||||
return $user->can('delete_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('delete_any_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, AcademicJournal $academicJournal): bool
|
||||
{
|
||||
return $user->can('force_delete_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('force_delete_any_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, AcademicJournal $academicJournal): bool
|
||||
{
|
||||
return $user->can('restore_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
{
|
||||
return $user->can('restore_any_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, AcademicJournal $academicJournal): bool
|
||||
{
|
||||
return $user->can('replicate_academic::journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_academic::journal');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\Policies;
|
||||
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Containers\Science\Models\JournalIssue;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class JournalIssuePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('view_any_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, JournalIssue $journalIssue): bool
|
||||
{
|
||||
return $user->can('view_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('create_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, JournalIssue $journalIssue): bool
|
||||
{
|
||||
return $user->can('update_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, JournalIssue $journalIssue): bool
|
||||
{
|
||||
return $user->can('delete_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('delete_any_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, JournalIssue $journalIssue): bool
|
||||
{
|
||||
return $user->can('force_delete_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('force_delete_any_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, JournalIssue $journalIssue): bool
|
||||
{
|
||||
return $user->can('restore_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
{
|
||||
return $user->can('restore_any_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, JournalIssue $journalIssue): bool
|
||||
{
|
||||
return $user->can('replicate_journal::issue');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_journal::issue');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\UI\WEB\Controllers;
|
||||
|
||||
use App\Containers\Science\Models\AcademicJournal;
|
||||
use App\Containers\Science\Models\JournalIssue;
|
||||
use App\Containers\Science\UI\WEB\Transformers\AcademicJournalResource;
|
||||
use App\Ship\Contracts\SeoServiceInterface;
|
||||
use App\Ship\Controllers\Controller;
|
||||
use App\Ship\Enums\CacheKeys;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientAcademicJournalController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoServiceInterface $seoPageProvider){}
|
||||
|
||||
public function index(): \Inertia\Response
|
||||
{
|
||||
$journals = Cache::remember(
|
||||
CacheKeys::ACADEMIC_JOURNALS_PREFIX->value . 'list',
|
||||
now()->addWeek(),
|
||||
function () {
|
||||
return AcademicJournalResource::collection(
|
||||
AcademicJournal::query()->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$seo = $this->seoPageProvider->getSeoForCurrentPage();
|
||||
|
||||
return Inertia::render('Client/AcademicJournals/Index', compact('journals', 'seo'));
|
||||
}
|
||||
|
||||
public function show(string $slug): \Inertia\Response
|
||||
{
|
||||
$journalData = Cache::remember(
|
||||
CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . $slug,
|
||||
now()->addWeek(),
|
||||
function () use ($slug) {
|
||||
return AcademicJournal::query()
|
||||
->where('slug', $slug)
|
||||
->firstOrFail();
|
||||
}
|
||||
);
|
||||
|
||||
$seo = Cache::remember(
|
||||
CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . 'seo_' . $slug,
|
||||
now()->addWeek(),
|
||||
function () use ($journalData) {
|
||||
return $this->seoPageProvider->getSeoForModel($journalData);
|
||||
}
|
||||
);
|
||||
|
||||
$journal = new AcademicJournalResource($journalData);
|
||||
|
||||
|
||||
|
||||
// Кешируем выпуски журнала, сгруппированные по годам
|
||||
$journals = Cache::remember(
|
||||
CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . 'issues_' . $slug,
|
||||
now()->addWeek(),
|
||||
function () use ($journal) {
|
||||
$journalIssues = JournalIssue::where('academic_journal_id', $journal->id)
|
||||
->get()
|
||||
->groupBy('year_publication');
|
||||
|
||||
$groupedIssues = [];
|
||||
foreach ($journalIssues as $year => $journalGroup) {
|
||||
$groupedIssues[] = [
|
||||
'year_publication' => $year,
|
||||
'journalIssues' => $journalGroup
|
||||
];
|
||||
}
|
||||
|
||||
return $groupedIssues;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
return Inertia::render('Client/AcademicJournals/Show', compact('journal', 'journals', 'seo'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use App\Containers\Science\UI\WEB\Controllers\ClientAcademicJournalController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
||||
Route::middleware('access-check')->group(function () {
|
||||
Route::get('/academic-journals/', [ClientAcademicJournalController::class, 'index'])->name('client.academicJournals.index');
|
||||
Route::get('/academic-journals/{slug}', [ClientAcademicJournalController::class, 'show'])->name('client.academicJournals.show');
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Science\UI\WEB\Transformers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AcademicJournalResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user