217 lines
7.8 KiB
PHP
217 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\LegalOpinion;
|
|
use App\Models\LegalOpinionCategory;
|
|
use App\Traits\BaseApiResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class LegalOpinionApiController extends Controller
|
|
{
|
|
use BaseApiResponse;
|
|
|
|
public function categories()
|
|
{
|
|
$categories = LegalOpinionCategory::all()->map(function ($category) {
|
|
return [
|
|
'id' => $category->id,
|
|
'name' => $category->name,
|
|
];
|
|
});
|
|
|
|
return $this->success($categories, 'Success', 'Categories List');
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$request->validate([
|
|
'category_id' => 'nullable|exists:legal_opinion_categories,id',
|
|
'sort_by' => 'nullable|in:date,number',
|
|
'sort' => 'nullable|in:asc,desc',
|
|
'per_page' => 'nullable|integer|min:1|max:100',
|
|
]);
|
|
|
|
$query = LegalOpinion::query();
|
|
|
|
if ($request->filled('category_id')) {
|
|
$query->where('category_id', $request->category_id);
|
|
}
|
|
|
|
$sortBy = $request->input('sort_by', 'date');
|
|
$sortOrder = $request->input('sort', 'desc');
|
|
$sortColumn = $sortBy === 'number' ? 'opinion_number' : 'opinion_date';
|
|
|
|
if ($sortBy === 'number') {
|
|
$query->orderByRaw("LENGTH({$sortColumn}) {$sortOrder}")->orderBy($sortColumn, $sortOrder);
|
|
} else {
|
|
$query->orderBy($sortColumn, $sortOrder);
|
|
}
|
|
|
|
$perPage = min(max((int) $request->input('per_page', 15), 10), 100);
|
|
$paginator = $query->paginate($perPage);
|
|
|
|
$items = collect($paginator->items())->map(function ($item) {
|
|
return $this->formatItem($item);
|
|
});
|
|
|
|
$responseData = [
|
|
'items' => $items,
|
|
'current_page' => $paginator->currentPage(),
|
|
'last_page' => $paginator->lastPage(),
|
|
'per_page' => $paginator->perPage(),
|
|
'total' => $paginator->total(),
|
|
];
|
|
|
|
return $this->success($responseData, 'Success', 'Legal Opinions Fetched');
|
|
}
|
|
|
|
public function search(Request $request)
|
|
{
|
|
$request->validate([
|
|
'search' => 'nullable|string',
|
|
'sort_by' => 'nullable|in:date,number',
|
|
'sort' => 'nullable|in:asc,desc',
|
|
'per_page' => 'nullable|integer|min:1|max:100',
|
|
]);
|
|
|
|
$query = LegalOpinion::query();
|
|
|
|
if ($request->filled('search')) {
|
|
$searchTerm = $request->input('search');
|
|
|
|
$query->where(function ($q) use ($searchTerm) {
|
|
$q->where('opinion_number', 'LIKE', "%{$searchTerm}%")
|
|
->orWhere('subject', 'LIKE', "%{$searchTerm}%")
|
|
->orWhere('full_text', 'LIKE', "%{$searchTerm}%")
|
|
->orWhere('issuing_authority', 'LIKE', "%{$searchTerm}%");
|
|
});
|
|
}
|
|
|
|
$sortBy = $request->input('sort_by', 'date');
|
|
$sortOrder = $request->input('sort', 'desc');
|
|
$sortColumn = $sortBy === 'number' ? 'opinion_number' : 'opinion_date';
|
|
|
|
if ($sortBy === 'number') {
|
|
$query->orderByRaw("LENGTH({$sortColumn}) {$sortOrder}")->orderBy($sortColumn, $sortOrder);
|
|
} else {
|
|
$query->orderBy($sortColumn, $sortOrder);
|
|
}
|
|
|
|
$perPage = min(max((int) $request->input('per_page', 15), 10), 100);
|
|
$paginator = $query->paginate($perPage);
|
|
|
|
$items = collect($paginator->items())->map(function ($item) {
|
|
return $this->formatItem($item);
|
|
});
|
|
|
|
$responseData = [
|
|
'items' => $items,
|
|
'current_page' => $paginator->currentPage(),
|
|
'last_page' => $paginator->lastPage(),
|
|
'per_page' => $paginator->perPage(),
|
|
'total' => $paginator->total(),
|
|
];
|
|
|
|
return $this->success($responseData, 'Success', 'Search Results Fetched');
|
|
}
|
|
|
|
public function fast_search(Request $request)
|
|
{
|
|
$searchTerm = $request->input('search');
|
|
$query = LegalOpinion::query();
|
|
|
|
if ($request->filled('search')) {
|
|
$query->where(function ($q) use ($searchTerm) {
|
|
$q->where('opinion_number', 'LIKE', "%{$searchTerm}%")
|
|
->orWhere('subject', 'LIKE', "%{$searchTerm}%")
|
|
->orWhere('full_text', 'LIKE', "%{$searchTerm}%")
|
|
->orWhere('issuing_authority', 'LIKE', "%{$searchTerm}%");
|
|
});
|
|
}
|
|
|
|
$count = $query->count();
|
|
$items = $query->orderBy('opinion_date', 'desc')->take(5)->get()->map(function ($item) {
|
|
return $this->formatItem($item);
|
|
});
|
|
|
|
return $this->success([
|
|
'items' => $items,
|
|
'count' => $count
|
|
], 'Success', 'Fast Search Results');
|
|
}
|
|
|
|
public function pager($id)
|
|
{
|
|
$current = LegalOpinion::find($id);
|
|
|
|
if (!$current) {
|
|
return $this->failed([], ['title' => 'خطا', 'message' => 'نظریه قانونی مورد نظر یافت نشد.'], 404);
|
|
}
|
|
|
|
$previousItem = LegalOpinion::where(function ($query) use ($current) {
|
|
if ($current->opinion_date) {
|
|
$query->where('opinion_date', '<', $current->opinion_date)->orWhere(function ($subQuery) use ($current) {
|
|
$subQuery->where('opinion_date', '=', $current->opinion_date)->where('id', '<', $current->id);
|
|
});
|
|
} else {
|
|
$query->whereNull('opinion_date')->where('id', '<', $current->id);
|
|
}
|
|
})->orderBy('opinion_date', 'desc')->orderBy('id', 'desc')->first();
|
|
|
|
$nextItem = LegalOpinion::where(function ($query) use ($current) {
|
|
if ($current->opinion_date) {
|
|
$query->where('opinion_date', '>', $current->opinion_date)->orWhere(function ($subQuery) use ($current) {
|
|
$subQuery->where('opinion_date', '=', $current->opinion_date)->where('id', '>', $current->id);
|
|
});
|
|
} else {
|
|
$query->whereNotNull('opinion_date')->orWhere(function ($subQuery) use ($current) {
|
|
$subQuery->whereNull('opinion_date')->where('id', '>', $current->id);
|
|
});
|
|
}
|
|
})->orderBy('opinion_date', 'asc')->orderBy('id', 'asc')->first();
|
|
|
|
// Apply format and add Notes
|
|
$formatWithNote = function($item) {
|
|
if (!$item) return null;
|
|
$formatted = $this->formatItem($item);
|
|
$formatted['note'] = \App\Models\LegalOpinionNote::select('id', 'note', 'color_code', 'created_at')
|
|
->where('user_id', auth()->user()->id)
|
|
->where('legal_opinion_id', $item->id)
|
|
->get();
|
|
return $formatted;
|
|
};
|
|
|
|
$results = array_values(array_filter([
|
|
$previousItem ? $formatWithNote($previousItem) : null,
|
|
$formatWithNote($current),
|
|
$nextItem ? $formatWithNote($nextItem) : null
|
|
]));
|
|
|
|
return $this->success($results, 'Success', 'Pager Window Details');
|
|
}
|
|
|
|
private function isLockedForCurrentUser($item): bool
|
|
{
|
|
return ! auth()->user()->isSubscriber() && (bool) ($item->is_locked ?? false);
|
|
}
|
|
|
|
private function formatItem($item)
|
|
{
|
|
$isLocked = $this->isLockedForCurrentUser($item);
|
|
|
|
return [
|
|
'id' => $item->id,
|
|
'opinion_number' => $item->opinion_number,
|
|
'opinion_date' => $item->opinion_date,
|
|
'subject' => $item->subject,
|
|
'full_text' => $isLocked ? null : $item->full_text,
|
|
'issuing_authority' => $item->issuing_authority,
|
|
'category_id' => $item->category_id,
|
|
'category_name' => optional($item->category)->name,
|
|
'is_locked' => $isLocked,
|
|
];
|
|
}
|
|
}
|