Proje dosyaları eklendi
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\ProjectStatus;
|
||||
use App\Http\Requests\StoreProjectRequest;
|
||||
use App\Http\Requests\UpdateProjectRequest;
|
||||
use App\Models\Project;
|
||||
use App\Services\ProjectUrlNormalizer;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ProjectController extends Controller
|
||||
{
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$this->authorize('viewAny', Project::class);
|
||||
$archived = $request->string('filter')->toString() === 'archived';
|
||||
$projects = $request->user()->projects()
|
||||
->where('status', $archived ? ProjectStatus::Archived : ProjectStatus::Active)
|
||||
->withCount(['keywords' => fn ($query) => $query->active()])
|
||||
->orderByDesc('id')->paginate(15)->withQueryString();
|
||||
return view('projects.index', compact('projects', 'archived'));
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
$this->authorize('create', Project::class);
|
||||
return view('projects.create');
|
||||
}
|
||||
|
||||
public function store(StoreProjectRequest $request, ProjectUrlNormalizer $normalizer): RedirectResponse
|
||||
{
|
||||
$normalized = $normalizer->normalize($request->string('website_url')->toString());
|
||||
try {
|
||||
$project = $request->user()->projects()->create([
|
||||
'name' => $request->string('name')->trim()->toString(),
|
||||
'domain' => $normalized->domain,
|
||||
'url' => $normalized->url,
|
||||
]);
|
||||
} catch (QueryException $exception) {
|
||||
$this->throwDuplicateValidation($exception);
|
||||
}
|
||||
return redirect()->route('projects.show', $project)->with('status', 'Proje oluşturuldu.');
|
||||
}
|
||||
|
||||
public function show(Project $customerProject): View
|
||||
{
|
||||
$this->authorize('view', $customerProject);
|
||||
$customerProject->load(['keywords' => fn ($q) => $q->active()->orderBy('phrase'), 'keywords.serpChecks' => fn ($q) => $q->where('status', 'completed')->latest('checked_at')->with(['results' => fn ($r) => $r->where('is_project_domain', true)->orderBy('position')])]);
|
||||
$rows = $customerProject->keywords->map(function ($keyword) { $checks=$keyword->serpChecks->filter(fn($c)=>$c->results->isNotEmpty())->values();$current=$checks->get(0);$previous=$checks->get(1);$rank=$current?->results->min('position');$prior=$previous?->results->min('position');return ['current'=>$rank,'change'=>($rank&&$prior)?$prior-$rank:null,'checked_at'=>$current?->checked_at]; });
|
||||
$measured=$rows->whereNotNull('current');
|
||||
return view('projects.show', ['project'=>$customerProject,'summary'=>['keywords'=>$customerProject->keywords->count(),'last_check'=>$rows->max('checked_at'),'average'=>$measured->isNotEmpty()?round($measured->avg('current'),1):null,'top10'=>$measured->where('current','<=',10)->count(),'winners'=>$rows->where('change','>',0)->count(),'losers'=>$rows->where('change','<',0)->count()]]);
|
||||
}
|
||||
|
||||
public function edit(Project $customerProject): View
|
||||
{
|
||||
$this->authorize('update', $customerProject);
|
||||
return view('projects.edit', ['project' => $customerProject]);
|
||||
}
|
||||
|
||||
public function update(UpdateProjectRequest $request, Project $customerProject, ProjectUrlNormalizer $normalizer): RedirectResponse
|
||||
{
|
||||
$normalized = $normalizer->normalize($request->string('website_url')->toString());
|
||||
try {
|
||||
$customerProject->update([
|
||||
'name' => $request->string('name')->trim()->toString(),
|
||||
'domain' => $normalized->domain,
|
||||
'url' => $normalized->url,
|
||||
]);
|
||||
} catch (QueryException $exception) {
|
||||
$this->throwDuplicateValidation($exception);
|
||||
}
|
||||
return redirect()->route('projects.show', $customerProject)->with('status', 'Proje güncellendi.');
|
||||
}
|
||||
|
||||
public function archive(Project $customerProject): RedirectResponse
|
||||
{
|
||||
$this->authorize('archive', $customerProject);
|
||||
$customerProject->archive();
|
||||
return redirect()->route('projects.index')->with('status', 'Proje arşivlendi.');
|
||||
}
|
||||
|
||||
public function restore(Project $customerProject): RedirectResponse
|
||||
{
|
||||
$this->authorize('restore', $customerProject);
|
||||
$customerProject->restoreProject();
|
||||
return redirect()->route('projects.show', $customerProject)->with('status', 'Proje yeniden etkinleştirildi.');
|
||||
}
|
||||
|
||||
private function throwDuplicateValidation(QueryException $exception): never
|
||||
{
|
||||
if (! in_array((string) $exception->getCode(), ['23000', '19'], true)) throw $exception;
|
||||
throw ValidationException::withMessages(['website_url' => 'Bu alan adı hesabınızda zaten kayıtlı.']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user