100 lines
4.5 KiB
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);
|
|
}
|
|
}
|