fn_b/app/Http/Controllers/Web/ArticlesController.php

100 lines
4.5 KiB
PHP

<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Services\ArticlesService;
use Illuminate\Http\Request;
use App\Models\Articles;
class ArticlesController extends Controller
{
protected $oArticlesService;
public function __construct(ArticlesService $oService)
{
$this->oArticlesService = $oService;
}
public function search(Request $oRequest, string $sKeyword)
{
$page = \App\Services\Seo::page($oRequest);
$data = $this->oArticlesService->search($sKeyword, 'view');
$data['seo'] = \App\Services\Seo::listMeta('搜索:'.$data['sKeywords'], '本站文章搜索结果', '/search/'.rawurlencode($data['sKeywords']), $page, false);
return $this->listing($oRequest, $data);
}
public function like(int $iArticleId, Request $oRequest)
{
// 1. 获取/生成指纹
$sFingerprint = $oRequest->cookie('visitor_token')
?? md5($oRequest->ip() . $oRequest->userAgent());
// 2. 调用 Service
$aResult = $this->oArticlesService->like($iArticleId, $oRequest->ip(), $sFingerprint);
if (!$aResult['status']) {
return response()->json($aResult);
}
// 3. 成功后下发持久 Cookie
return response()->json($aResult)
->withCookie(cookie()->forever('visitor_token', $sFingerprint));
}
public function listByTag(Request $oRequest, string $sSlug)
{
$page = \App\Services\Seo::page($oRequest);
$data = $this->oArticlesService->getTagArticles($sSlug, 'view');
$data['seo'] = \App\Services\Seo::listMeta($data['oTag']->sName.'相关文章', '按标签浏览本站内容', '/tag/'.$sSlug, $page, false);
return $this->listing($oRequest, $data);
}
public function home(Request $oRequest)
{
if ($oRequest->filled('s')) {
abort_unless(is_string($oRequest->query('s')),404);
return redirect(\App\Services\Seo::url('/search/'.rawurlencode(trim($oRequest->query('s')))),301);
}
$page = \App\Services\Seo::page($oRequest);
if ($oRequest->has('page')) return redirect(\App\Services\Seo::url($page>1?'/freenode':'/', $page),301);
$slug = $this->oArticlesService->getLatestFreeNodeSlug();
if (!$slug) return response()->view('pages.articles.default.unavailable', [], 503)->header('Retry-After','3600');
$data = $this->articleData($slug, $oRequest);
$data['bIsHome'] = true;
$data['seo'] = \App\Services\Seo::articleMeta($data['oArticle'], true);
return view('pages.articles.default.show', $data);
}
public function list(Request $oRequest, string $sSlug1, ?string $sSlug2 = null)
{
$page = \App\Services\Seo::page($oRequest);
$data = $this->oArticlesService->getCategoryArticles($sSlug2 ?? $sSlug1, 'view');
$category = $data['oCategory'];
$path = \App\Services\Seo::categoryPath($category);
if ($sSlug2) abort_unless($path === '/'.$sSlug1.'/'.$sSlug2, 404);
$heading = $category->sSlug === 'freenode' ? '免费节点更新记录' : \App\Services\Seo::categoryName($category);
$desc = $category->sSlug === 'freenode' ? '按发布时间查看免费节点历史记录;获取当前订阅请访问首页。' : ($category->sDescription ?: $heading.'相关文章与使用说明');
$data['seo'] = \App\Services\Seo::listMeta($heading, $desc, $path, $page, $data['oArticles']->total()>0);
if ('/'.$sSlug1 !== $path && !$sSlug2) return redirect(\App\Services\Seo::url($path,$page),301);
return $this->listing($oRequest, $data);
}
private function listing(Request $request, array $data)
{
$page = \App\Services\Seo::page($request);
abort_if($page > $data['oArticles']->lastPage(),404);
if ($request->has('page') && $page === 1) return redirect($data['seo']['canonical'],301);
$data['oArticles']->withPath(strtok($data['seo']['canonical'],'?'));
return view('pages.articles.default.index', $data);
}
private function articleData(string $slug, Request $request): array
{
return $this->oArticlesService->getArticle($slug, $request->ip(), $request->cookie('visitor_token') ?? md5($request->ip().$request->userAgent()));
}
public function show(string $sArticleSlug, Request $oRequest)
{
$data = $this->articleData($sArticleSlug,$oRequest);
$data['seo'] = \App\Services\Seo::articleMeta($data['oArticle']);
return view('pages.articles.default.show',$data);
}
}