Files

176 lines
5.3 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers;
use App\Models\Question;
use App\Models\Tag;
use App\Models\Category;
use Illuminate\Http\Request;
class QuestionController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$query = Question::with(['tags', 'category']);
// تابع برای نرمال‌سازی رشته فارسی
$normalize = function ($string) {
// تبدیل نیم‌فاصله به فاصله معمولی
$string = str_replace('', ' ', $string);
// حذف فاصله‌های اضافی
$string = preg_replace('/\s+/', ' ', $string);
return trim($string);
};
if ($request->has('tag')) {
$tag = $normalize($request->tag);
$query->whereHas('tags', function ($q) use ($tag) {
$q->whereRaw("REPLACE(name, '', ' ') LIKE ?", ["%{$tag}%"]);
});
}
if ($request->has('category')) {
$category = $normalize($request->category);
$query->whereHas('category', function ($q) use ($category) {
$q->whereRaw("REPLACE(name, '', ' ') LIKE ?", ["%{$category}%"]);
});
}
return response()->json(
$query->get()->map(fn ($q) => $this->formatQuestion($q))->values()
);
}
/**
* Shape a question into the legacy (old Flutter) response: category_id and
* category are always present and non-null, tags is always an array, and
* timestamps are always ISO strings — so the old client never hits a null.
*/
private function formatQuestion(Question $question): array
{
$question->loadMissing(['tags', 'category']);
$createdAt = optional($question->created_at)->toIso8601String();
$updatedAt = optional($question->updated_at)->toIso8601String();
$categoryId = $question->category_id ?? 0;
$category = $question->category;
$categoryPayload = $category
? [
'id' => $category->id,
'name' => $category->name ?? '',
'created_at' => optional($category->created_at)->toIso8601String() ?? $createdAt,
'updated_at' => optional($category->updated_at)->toIso8601String() ?? $updatedAt,
]
: [
'id' => $categoryId,
'name' => '',
'created_at' => $createdAt,
'updated_at' => $updatedAt,
];
return [
'id' => $question->id,
'title' => $question->title ?? '',
'category_id' => $categoryId,
'created_at' => $createdAt,
'updated_at' => $updatedAt,
'tags' => $question->tags->values(),
'category' => $categoryPayload,
];
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required|string',
'category' => 'nullable|string',
'tags' => 'nullable|array',
'tags.*' => 'string'
]);
$category = null;
if (!empty($data['category'])) {
$category = Category::firstOrCreate(['name' => $data['category']]);
}
$question = Question::create([
'title' => $data['title'],
'category_id' => $category?->id
]);
if (!empty($data['tags'])) {
$tagIds = [];
foreach ($data['tags'] as $tagName) {
$tag = Tag::firstOrCreate(['name' => $tagName]);
$tagIds[] = $tag->id;
}
$question->tags()->sync($tagIds);
}
return response()->json($this->formatQuestion($question), 201);
}
/**
* Display the specified resource.
*/
public function show(Question $question)
{
return response()->json($this->formatQuestion($question));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Question $question)
{
$data = $request->validate([
'title' => 'sometimes|string',
'category' => 'nullable|string',
'tags' => 'nullable|array',
'tags.*' => 'string'
]);
if (isset($data['title'])) {
$question->update(['title' => $data['title']]);
}
if (array_key_exists('category', $data)) {
if ($data['category']) {
$category = Category::firstOrCreate(['name' => $data['category']]);
$question->update(['category_id' => $category->id]);
} else {
$question->update(['category_id' => null]);
}
}
if (isset($data['tags'])) {
$tagIds = [];
foreach ($data['tags'] as $tagName) {
$tag = Tag::firstOrCreate(['name' => $tagName]);
$tagIds[] = $tag->id;
}
$question->tags()->sync($tagIds);
}
return response()->json($this->formatQuestion($question->fresh()));
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Question $question)
{
$question->delete();
return response()->json(['message' => 'سوال حذف شد']);
}
}