522 lines
17 KiB
PHP
522 lines
17 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\GetApiRequest;
|
|
use App\Models\Art;
|
|
use App\Models\Book;
|
|
use App\Models\Branch;
|
|
use App\Models\Category;
|
|
use App\Models\Chapter;
|
|
use App\Models\Division;
|
|
use App\Models\Gate;
|
|
use App\Models\Law;
|
|
use App\Models\LikeArt;
|
|
use App\Models\Note;
|
|
use App\Models\Part;
|
|
use App\Models\Section;
|
|
use App\Models\Volum;
|
|
use App\Traits\BaseApiResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class ArtController extends Controller
|
|
{
|
|
use BaseApiResponse;
|
|
|
|
public function index(GetApiRequest $request)
|
|
{
|
|
$book = Book::find($request->book_id);
|
|
$law = Law::find($book?->law_id);
|
|
|
|
if ($this->isLockedForCurrentUser($law)) {
|
|
return $this->failed([], ['title' => 'Subscription Required', 'message' => 'This content requires an active subscription.'], 403);
|
|
}
|
|
|
|
$arts = Art::with(['chapter', 'part', 'volum', 'law', 'book', 'section', 'gate'])->where('book_id', $request->book_id)->orderBy('number')->get();
|
|
|
|
$arts = $arts->map(function ($art) {
|
|
return [
|
|
'id' => $art->id,
|
|
'text' => $art->text,
|
|
'number' => $art->number,
|
|
'chapter' => $art->chapter != null ? [
|
|
'id' => $art->chapter->id,
|
|
'title' => $art->chapter->title,
|
|
'number' => $art->chapter->number,
|
|
] : null,
|
|
'part' => $art->part != null ? [
|
|
'id' => $art->part->id,
|
|
'title' => $art->part->title,
|
|
'number' => $art->part->number,
|
|
] : null,
|
|
'volum' => $art->volum != null ? [
|
|
'id' => $art->volum->id,
|
|
'title' => $art->volum->title,
|
|
'number' => $art->volum->number,
|
|
] : null,
|
|
'law' => $art->law != null ? [
|
|
'id' => $art->law->id,
|
|
'title' => $art->law->title,
|
|
'number' => $art->law->number,
|
|
] : null,
|
|
'book' => $art->book != null ? [
|
|
'id' => $art->book->id,
|
|
'title' => $art->book->title,
|
|
'number' => $art->book->number,
|
|
] : null,
|
|
'section' => $art->section != null ? [
|
|
'id' => $art->section->id,
|
|
'title' => $art->section->title,
|
|
'number' => $art->section->number,
|
|
] : null,
|
|
'gate' => $art->gate != null ? [
|
|
'id' => $art->gate->id,
|
|
'title' => $art->gate->title,
|
|
'number' => $art->gate->number,
|
|
] : null,
|
|
];
|
|
});
|
|
|
|
return response()->json(['arts' => $arts]);
|
|
}
|
|
|
|
public function single($id)
|
|
{
|
|
$art = Art::select('id', 'title', 'number', 'text', 'law_id')->find($id);
|
|
|
|
if (!$art) {
|
|
return $this->failed([], 'Art not found');
|
|
}
|
|
|
|
$law = Law::find($art?->law_id);
|
|
|
|
if ($this->isLockedForCurrentUser($law)) {
|
|
return $this->failed([], ['title' => 'Subscription Required', 'message' => 'This content requires an active subscription.'], 403);
|
|
}
|
|
|
|
$art->is_like = $this->isLiked($art->id);
|
|
$art->note = Note::select('id', 'note', 'color_code','created_at')->where('user_id', auth()->user()->id)->where('art_id', $id)->get();
|
|
$art->category = $law?->category?->name;
|
|
$art->route = array_values($this->route(Art::class, $art));
|
|
|
|
$previousArt = Art::select('id', 'title', 'number', 'text', 'law_id')
|
|
->where('law_id',$art->law_id)
|
|
->where('number', '<', $art->number)
|
|
->orderBy('number', 'desc')
|
|
->first();
|
|
|
|
if ($previousArt) {
|
|
$previousLaw = Law::find($previousArt->law_id);
|
|
$previousArt->is_like = $this->isLiked($previousArt->id);
|
|
$previousArt->note = Note::select('id', 'note', 'color_code')->where('user_id', auth()->user()->id)->where('art_id', $previousArt->id)->get();
|
|
$previousArt->category = $previousLaw?->category?->name;
|
|
$previousArt->route = array_values($this->route(Art::class, $previousArt));
|
|
}
|
|
|
|
$nextArt = Art::select('id', 'title', 'number', 'text', 'law_id')
|
|
->where('law_id',$art->law_id)
|
|
->where('number', '>', $art->number)
|
|
->orderBy('number')
|
|
->first();
|
|
|
|
if ($nextArt) {
|
|
$nextLaw = Law::find($nextArt->law_id);
|
|
$nextArt->is_like = $this->isLiked($nextArt->id);
|
|
$nextArt->note = Note::select('id', 'note', 'color_code')->where('user_id', auth()->user()->id)->where('art_id', $nextArt->id)->get();
|
|
$nextArt->category = $nextLaw?->category?->name;
|
|
$nextArt->route = array_values($this->route(Art::class, $nextArt));
|
|
}
|
|
|
|
$results = array_values(array_filter([$previousArt, $art, $nextArt]));
|
|
|
|
return $this->success($results);
|
|
}
|
|
|
|
public function like(Art $art)
|
|
{
|
|
$userId = auth()->id();
|
|
|
|
$existingLike = LikeArt::query()->where('art_id', $art->id)
|
|
->where('user_id', $userId)
|
|
->first();
|
|
|
|
if ($existingLike) {
|
|
$existingLike->delete();
|
|
|
|
return $this->success(null, 'Success', 'Art unliked successfully');
|
|
}
|
|
|
|
LikeArt::create([
|
|
'art_id' => $art->id,
|
|
'user_id' => $userId,
|
|
]);
|
|
|
|
return $this->success(null, 'Success', 'Art liked successfully');
|
|
}
|
|
|
|
|
|
private function isLiked($art_id): bool
|
|
{
|
|
return LikeArt::query()->where('art_id', $art_id)
|
|
->where('user_id', auth()->user()->id)
|
|
->exists();
|
|
}
|
|
|
|
private function isLockedForCurrentUser(?Law $law): bool
|
|
{
|
|
return !auth()->user()->isSubscriber() && (bool) $law?->is_locked;
|
|
}
|
|
|
|
public function likes()
|
|
{
|
|
$likes = LikeArt::query()->where('user_id', auth()->user()->id)
|
|
->with('art.law')
|
|
->get()
|
|
->map(function ($q) {
|
|
$isLocked = $this->isLockedForCurrentUser($q->art?->law);
|
|
|
|
return [
|
|
'id' => $q->art->id,
|
|
'title' => $q->art->title,
|
|
'text' => $isLocked ? null : $q->art->text
|
|
];
|
|
});
|
|
|
|
return $this->success($likes);
|
|
}
|
|
|
|
|
|
public function search(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'book_id' => 'nullable|array',
|
|
'volume_id' => 'nullable|array',
|
|
'division_id' => 'nullable|array',
|
|
'section_id' => 'nullable|array',
|
|
'part_id' => 'nullable|array',
|
|
'gate_id' => 'nullable|array',
|
|
'law_id' => 'nullable|array',
|
|
'chapter_id' => 'nullable|array',
|
|
'branch_id' => 'nullable|array',
|
|
'category_id' => 'nullable|int',
|
|
'per_page' => 'nullable|integer',
|
|
'search' => 'nullable|string'
|
|
]);
|
|
|
|
$models = [
|
|
Law::class,
|
|
Volum::class,
|
|
Book::class,
|
|
Division::class,
|
|
Section::class,
|
|
Chapter::class,
|
|
Part::class,
|
|
Gate::class,
|
|
Branch::class,
|
|
Art::class
|
|
];
|
|
|
|
$results = [];
|
|
|
|
foreach ($models as $modelClass) {
|
|
$results = array_merge($results, $this->searchModel($modelClass, $validated));
|
|
}
|
|
|
|
return $this->success($results);
|
|
}
|
|
|
|
private function searchModel($modelClass, $validated)
|
|
{
|
|
$query = $modelClass::query();
|
|
|
|
$filters = [
|
|
'law_id',
|
|
'volume_id',
|
|
'division_id',
|
|
'section_id',
|
|
'part_id',
|
|
'gate_id',
|
|
'chapter_id',
|
|
'branch_id'
|
|
];
|
|
|
|
$model = new $modelClass;
|
|
if ($model->getTable() == 'art') {
|
|
$query->where(function ($query) use ($validated, $filters) {
|
|
if (!empty($validated['search'])) {
|
|
$query->where(function ($q) use ($validated) {
|
|
$q->where('title', 'LIKE', "%{$validated['search']}%")
|
|
->orWhere('text', 'LIKE', "%{$validated['search']}%");
|
|
});
|
|
}
|
|
|
|
foreach ($filters as $filter) {
|
|
if (!empty($validated[$filter])) {
|
|
$query->whereIn($filter, $validated[$filter]);
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
if (!empty($validated['category_id'])) {
|
|
$query->whereIn('law_id', Category::where('type', $this->convertValueTo($validated['category_id']))->get()->pluck('id'));
|
|
}
|
|
|
|
$items = $query->paginate($validated['per_page'] ?? 10);
|
|
|
|
return $items->map(function ($item) use ($validated, $modelClass) {
|
|
$text = $item->text ?? '';
|
|
$search = preg_quote($validated['search'] ?? '', '/');
|
|
if (!empty($text) && preg_match('/\b(.{0,50})\b(' . $search . ')\b(.{0,50})\b/i', $text, $matches)) {
|
|
$context = trim($matches[1] ?? '') . ' ' . $matches[2] . ' ' . trim($matches[3] ?? '');
|
|
} else {
|
|
$context = $text;
|
|
}
|
|
|
|
$law = Law::find($item->law_id);
|
|
$isLocked = $this->isLockedForCurrentUser($law);
|
|
|
|
return [
|
|
'id' => $item->id,
|
|
'title' => $item->title,
|
|
'text' => $isLocked ? null : $context,
|
|
'is_locked' => $isLocked,
|
|
'type' => 'art',
|
|
'route' => array_values($this->route($modelClass, $item)),
|
|
'category' => optional($law->category)->name,
|
|
'law' => $law?->title,
|
|
'count_art' => $law->arts->count(),
|
|
'count_volums' => $law->volums->count(),
|
|
'price' => $law->price,
|
|
'image' => $law->image
|
|
];
|
|
})->toArray();
|
|
} else {
|
|
$query = $query->where('title', 'LIKE', '%' . ($validated['search'] ?? '') . '%');
|
|
}
|
|
|
|
$items = $query->paginate($validated['per_page'] ?? 10);
|
|
|
|
return $items->map(function ($item) use ($modelClass) {
|
|
$law = Law::find($item?->law_id ?? $item->id);
|
|
if ((new $modelClass)->getTable() == 'laws') {
|
|
return [
|
|
'id' => $item->id,
|
|
'title' => $item->title,
|
|
'number' => $item->number,
|
|
'type' => (new $modelClass)->getTable(),
|
|
'is_locked' => auth()->user()->isSubscriber() !== false ? false : optional($law)->is_locked,
|
|
'route' => array_values($this->route($modelClass, $item)),
|
|
'category' => optional($law?->category)?->name ?? '',
|
|
'image' => $law->image
|
|
];
|
|
} else if ((new $modelClass)->getTable() == 'art') {
|
|
return [
|
|
'id' => $item->id,
|
|
'title' => $item->title,
|
|
'number' => $item->number,
|
|
'type' => (new $modelClass)->getTable(),
|
|
'is_locked' => auth()->user()->isSubscriber() !== false ? false : optional($law)->is_locked,
|
|
'route' => array_values($this->route($modelClass, $item)),
|
|
'law' => $law?->title ?? '',
|
|
'image' => $law->image
|
|
];
|
|
} else {
|
|
return [
|
|
'id' => $item->id,
|
|
'title' => $item->title,
|
|
'number' => $item->number,
|
|
'type' => (new $modelClass)->getTable(),
|
|
'is_locked' => auth()->user()->isSubscriber() !== false ? false : optional($law)->is_locked,
|
|
'route' => array_values($this->route($modelClass, $item)),
|
|
'law' => $law?->title ?? '',
|
|
];
|
|
}
|
|
})->toArray();
|
|
}
|
|
|
|
|
|
|
|
private function route($modelClass, $query)
|
|
{
|
|
if ((new $modelClass)->getTable() == 'art') {
|
|
$route = array_filter([
|
|
Law::find($query->law_id)?->title,
|
|
Volum::find($query->volum_id)?->title,
|
|
Book::find($query->book_id)?->title,
|
|
Division::find($query->division_id)?->title,
|
|
Section::find($query->section_id)?->title,
|
|
Chapter::find($query->chapter_id)?->title,
|
|
Part::find($query->part_id)?->title,
|
|
Gate::find($query->gate_id)?->title,
|
|
Branch::find($query->branch_id)?->title
|
|
]);
|
|
|
|
$route = array_values($route);
|
|
return $route;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
public function fash_search(Request $request)
|
|
{
|
|
$search = $request->input('search');
|
|
|
|
$models = [
|
|
Law::class,
|
|
Art::class
|
|
];
|
|
|
|
$results = [];
|
|
|
|
foreach ($models as $modelClass) {
|
|
$results = array_merge($results, $this->searchModelFastSearch($modelClass, $search));
|
|
}
|
|
|
|
|
|
$models_other = [
|
|
Volum::class,
|
|
Book::class,
|
|
Division::class,
|
|
Section::class,
|
|
Chapter::class,
|
|
Part::class,
|
|
Gate::class,
|
|
Branch::class,
|
|
];
|
|
|
|
$found = false;
|
|
foreach ($models_other as $modelClass) {
|
|
if (count($this->searchModelFastSearch($modelClass, $search)) > 0 && !$found) {
|
|
$results = array_merge($results, $this->searchModelFastSearch($modelClass, $search));
|
|
$found = true;
|
|
}
|
|
}
|
|
|
|
|
|
$models = [
|
|
Law::class,
|
|
Volum::class,
|
|
Book::class,
|
|
Division::class,
|
|
Section::class,
|
|
Chapter::class,
|
|
Part::class,
|
|
Gate::class,
|
|
Branch::class,
|
|
Art::class
|
|
];
|
|
|
|
$count_all = 0;
|
|
|
|
foreach ($models as $modelClass) {
|
|
$count_all += count($this->searchModel($modelClass, $search));
|
|
}
|
|
|
|
|
|
return $this->success(['items' => $results, 'count' => $count_all]);
|
|
}
|
|
|
|
private function searchModelFastSearch($modelClass, $search)
|
|
{
|
|
$results = $modelClass::searchLimit($search);
|
|
|
|
return $results->map(function ($q) use ($modelClass, $search) {
|
|
$instance = new $modelClass;
|
|
$table = $instance->getTable();
|
|
|
|
if ($table === 'art') {
|
|
return $this->formatArtResult($q, $search);
|
|
}
|
|
|
|
return $this->formatGenericResult($q, $table);
|
|
})->toArray();
|
|
}
|
|
|
|
private function formatGenericResult($q, $table)
|
|
{
|
|
$category = null;
|
|
if ($table === 'laws') {
|
|
$category = Law::where('id', $q->id)->first()?->category?->name;
|
|
} else {
|
|
$category = Law::where('id', $q->law_id)->first()?->category?->name;
|
|
}
|
|
|
|
if ($table !== 'laws') {
|
|
return [
|
|
'id' => $q->id,
|
|
'title' => $q->title,
|
|
'type' => $table === 'section' ? 'sections' : $table,
|
|
'category' => $category,
|
|
'law' => Law::where('id', $q->law_id)->first()?->title
|
|
];
|
|
}
|
|
|
|
return [
|
|
'id' => $q->id,
|
|
'title' => $q->title,
|
|
'type' => $table === 'section' ? 'sections' : $table,
|
|
'category' => $category,
|
|
'image' => Law::where('id', $q->id)->first()?->image
|
|
];
|
|
}
|
|
|
|
private function formatArtResult($q, $search)
|
|
{
|
|
$law = Law::where('id', $q->law_id)->first();
|
|
$route = array_filter([
|
|
$law?->title,
|
|
Volum::find($q->volum_id)?->title,
|
|
Book::find($q->book_id)?->title,
|
|
Division::find($q->division_id)?->title,
|
|
Section::find($q->section_id)?->title,
|
|
Chapter::find($q->chapter_id)?->title,
|
|
Part::find($q->part_id)?->title,
|
|
Gate::find($q->gate_id)?->title,
|
|
Branch::find($q->branch_id)?->title
|
|
]);
|
|
|
|
$text = $q->text;
|
|
$search = preg_quote($search, '/');
|
|
if (preg_match('/\b(.{0,50})\b(' . $search . ')\b(.{0,50})\b/i', $text, $matches)) {
|
|
$context = trim($matches[1]) . ' ' . $matches[2] . ' ' . trim($matches[3]);
|
|
} else {
|
|
$context = $text;
|
|
}
|
|
|
|
$isLocked = $this->isLockedForCurrentUser($law);
|
|
|
|
return [
|
|
'id' => $q->id,
|
|
'title' => $q->title,
|
|
'text' => $isLocked ? null : $context,
|
|
'is_locked' => $isLocked,
|
|
'type' => 'art',
|
|
'route' => $route,
|
|
'category' => $law?->category?->name,
|
|
'law' => $law?->title,
|
|
'count_art' => $law->arts->count(),
|
|
'count_volum' => $law->volums->count(),
|
|
'price' => $law->price,
|
|
'image' => $law->image
|
|
];
|
|
}
|
|
|
|
private function convertValueTo($var)
|
|
{
|
|
switch ($var) {
|
|
case 1:
|
|
return 'hagigi';
|
|
break;
|
|
case 2:
|
|
return 'kifari';
|
|
break;
|
|
|
|
default:
|
|
return 'kifari';
|
|
break;
|
|
}
|
|
}
|
|
}
|