<?php
 namespace App\Http\Controllers\Store; use App\Http\Controllers\Controller; use App\Http\Requests\Store\KbVoteRequest; use App\Models\KbArticle; use App\Models\KbVote; use App\Models\Post; use App\Models\Tag; use App\Services\LocaleOverrideService; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\View\View; class KnowledgebaseController extends Controller { public function index(Request $request): View { $tagSlug = $request->query('tag'); $search = $request->query('q'); $query = KbArticle::query() ->where('status', 'published') ->where(fn ($q) => $q->whereNull('published_at')->orWhere('published_at', '<=', now())) ->with('tags') ->withCount([ 'votes as helpful_count' => fn ($q) => $q->where('vote', 'helpful'), 'votes as not_helpful_count' => fn ($q) => $q->where('vote', 'not_helpful'), ]) ->orderBy('view_count', 'desc'); if ($tagSlug) { $query->whereHas('tags', fn ($q) => $q->where('slug', $tagSlug)); } if ($search) { $query->where('title', 'LIKE', '%' . $search . '%'); } $articles = $query->paginate(20)->withQueryString(); $tags = Tag::whereHas('articles')->orderBy('slug')->get(); app(\App\Core\Hook\HookBridge::class)->fireAction('ClientAreaPageKnowledgebase', []); return view('knowledgebase.index', compact('articles', 'tags', 'tagSlug', 'search')); } public function show(string $slug, Request $request, LocaleOverrideService $localeService): View { $result = Post::findBySlugInAnyLocale($slug, 'kb_article', app()->getLocale()); if (! $result) { abort(404); } $article = $result['post']; $matchedLocale = $result['matched_locale']; if ($matchedLocale && $matchedLocale !== app()->getLocale()) { $localeService->resolveFromSlug($matchedLocale, $request); } $article->increment('view_count'); $article->loadCount([ 'votes as helpful_count' => fn ($q) => $q->where('vote', 'helpful'), 'votes as not_helpful_count' => fn ($q) => $q->where('vote', 'not_helpful'), ]); $tagIds = $article->tags->pluck('id'); $related = KbArticle::query() ->where('id', '!=', $article->id) ->where('status', 'published') ->when($tagIds->isNotEmpty(), fn ($q) => $q->whereHas('tags', fn ($qq) => $qq->whereIn('tags.id', $tagIds))) ->orderBy('view_count', 'desc') ->limit(5) ->get(); app(\App\Core\Hook\HookBridge::class)->fireAction('ClientAreaPageKnowledgebase', [ 'article' => $article, 'articleid' => $article->id, 'article_id' => $article->id, ]); return view('knowledgebase.show', compact('article', 'related')); } public function vote(string $slug, KbVoteRequest $request): RedirectResponse { $result = Post::findBySlugInAnyLocale($slug, 'kb_article', app()->getLocale()); if (! $result) { abort(404); } $article = $result['post']; $clientId = Auth::guard('client')->id(); $ip = $request->ip(); $attrs = $clientId ? ['post_id' => $article->id, 'client_id' => $clientId] : ['post_id' => $article->id, 'client_id' => null, 'ip_address' => $ip]; KbVote::updateOrCreate($attrs, ['vote' => $request->validated('vote')]); return redirect()->back()->with('success', __('store.kb_vote_recorded')); } } 