Skip to content

Commit

Permalink
翻译 URL 标示
Browse files Browse the repository at this point in the history
  • Loading branch information
summerblue committed Sep 20, 2019
1 parent 0bfee57 commit d7f9c70
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

BAIDU_TRANSLATE_APPID=
BAIDU_TRANSLATE_KEY=
75 changes: 75 additions & 0 deletions app/Handlers/SlugTranslateHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace App\Handlers;

use GuzzleHttp\Client;
use Overtrue\Pinyin\Pinyin;

class SlugTranslateHandler
{
public function translate($text)
{
// 实例化 HTTP 客户端
$http = new Client;

// 初始化配置信息
$api = 'http://api.fanyi.baidu.com/api/trans/vip/translate?';
$appid = config('services.baidu_translate.appid');
$key = config('services.baidu_translate.key');
$salt = time();

// 如果没有配置百度翻译,自动使用兼容的拼音方案
if (empty($appid) || empty($key)) {
return $this->pinyin($text);
}

// 根据文档,生成 sign
// http://api.fanyi.baidu.com/api/trans/product/apidoc
// appid+q+salt+密钥 的MD5值
$sign = md5($appid. $text . $salt . $key);

// 构建请求参数
$query = http_build_query([
"q" => $text,
"from" => "zh",
"to" => "en",
"appid" => $appid,
"salt" => $salt,
"sign" => $sign,
]);

// 发送 HTTP Get 请求
$response = $http->get($api.$query);

$result = json_decode($response->getBody(), true);

/**
获取结果,如果请求成功,dd($result) 结果如下:
array:3 [▼
"from" => "zh"
"to" => "en"
"trans_result" => array:1 [▼
0 => array:2 [▼
"src" => "XSS 安全漏洞"
"dst" => "XSS security vulnerability"
]
]
]
**/

// 尝试获取获取翻译结果
if (isset($result['trans_result'][0]['dst'])) {
return str_slug($result['trans_result'][0]['dst']);
} else {
// 如果百度翻译没有结果,使用拼音作为后备计划。
return $this->pinyin($text);
}
}

public function pinyin($text)
{
return str_slug(app(Pinyin::class)->permalink($text));
}
}
11 changes: 8 additions & 3 deletions app/Http/Controllers/TopicsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ public function index(Request $request, Topic $topic)
return view('topics.index', compact('topics'));
}

public function show(Topic $topic)
public function show(Request $request, Topic $topic)
{
// URL 矫正
if ( ! empty($topic->slug) && $topic->slug != $request->slug) {
return redirect($topic->link(), 301);
}

return view('topics.show', compact('topic'));
}

Expand All @@ -40,7 +45,7 @@ public function store(TopicRequest $request, Topic $topic)
$topic->user_id = Auth::id();
$topic->save();

return redirect()->route('topics.show', $topic->id)->with('success', '帖子创建成功');
return redirect()->to($topic->link())->with('success', '成功创建话题');
}

public function edit(Topic $topic)
Expand All @@ -55,7 +60,7 @@ public function update(TopicRequest $request, Topic $topic)
$this->authorize('update', $topic);
$topic->update($request->all());

return redirect()->route('topics.show', $topic->id)->with('success', '更新成功!');
return redirect()->to($topic->link())->with('success', '更新成功!');
}

public function destroy(Topic $topic)
Expand Down
5 changes: 5 additions & 0 deletions app/Models/Topic.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ public function scopeRecent($query)
// 按照创建时间排序
return $query->orderBy('created_at', 'desc');
}

public function link($params = [])
{
return route('topics.show', array_merge([$this->id, $this->slug], $params));
}
}
8 changes: 8 additions & 0 deletions app/Observers/TopicObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Observers;

use App\Models\Topic;
use App\Handlers\SlugTranslateHandler;

// creating, created, updating, updated, saving,
// saved, deleting, deleted, restoring, restored
Expand All @@ -11,8 +12,15 @@ class TopicObserver
{
public function saving(Topic $topic)
{
// XSS 过滤
$topic->body = clean($topic->body, 'user_topic_body');

// 生成话题摘录
$topic->excerpt = make_excerpt($topic->body);

// 如 slug 字段无内容,即使用翻译器对 title 进行翻译
if ( ! $topic->slug) {
$topic->slug = app(SlugTranslateHandler::class)->translate($topic->title);
}
}
}
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
"require": {
"php": "^7.2",
"fideloper/proxy": "^4.0",
"guzzlehttp/guzzle": "~6.3",
"intervention/image": "^2.5",
"laravel/framework": "^6.0",
"laravel/tinker": "^1.0",
"mews/captcha": "~3.0",
"mews/purifier": "~3.0",
"overtrue/laravel-lang": "~3.0",
"overtrue/pinyin": "~4.0",
"summerblue/laravel-active": "6.*"
},
"require-dev": {
Expand Down
184 changes: 183 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],

'baidu_translate' => [
'appid' => env('BAIDU_TRANSLATE_APPID'),
'key' => env('BAIDU_TRANSLATE_KEY'),
],
];
4 changes: 2 additions & 2 deletions resources/views/topics/_topic_list.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
<div class="media-body">

<div class="media-heading mt-0 mb-1">
<a href="{{ route('topics.show', [$topic->id]) }}" title="{{ $topic->title }}">
<a href="{{ $topic->link() }}" title="{{ $topic->title }}">
{{ $topic->title }}
</a>
<a class="float-right" href="{{ route('topics.show', [$topic->id]) }}">
<a class="float-right" href="{{ $topic->link() }}">
<span class="badge badge-secondary badge-pill"> {{ $topic->reply_count }} </span>
</a>
</div>
Expand Down
Loading

0 comments on commit d7f9c70

Please sign in to comment.