diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index 772a0dfd..2e65bc4a 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use View;
use Utils;
+use Option;
use App\Models\User;
use App\Models\Player;
use App\Models\Texture;
@@ -31,7 +32,53 @@ class AdminController extends Controller
public function options()
{
- return view('admin.options');
+ $general = Option::form('general', '常规选项', function($form)
+ {
+ $form->text('site_name', '站点标题');
+ $form->text('site_description', '站点描述');
+ $form->text('site_url', '站点地址(URL)')->hint('以 http(s):// 开头,不要以 / 结尾');
+
+ $form->checkbox('user_can_register', '开放注册', '任何人都可以注册');
+
+ $form->text('regs_per_ip', '每个 IP 限制注册数');
+
+ $form->group('max_upload_file_size', '最大允许上传大小', function($group) {
+ // main textbox
+ $group->text('max_upload_file_size', option('max_upload_file_size'));
+ $group->addon('KB');
+ })->hint('PHP 限制:'.ini_get('post_max_size').',定义在 php.ini 中。');
+
+ $form->checkbox('allow_chinese_playername', '角色名', '允许中文角色名');
+
+ $form->select('api_type', '首选 JSON API', function($options) {
+ $options->add('0', 'CustomSkinLoader API');
+ $options->add('1', 'UniversalSkinAPI');
+
+ $options->setSelected(option('api_type'));
+ });
+
+ $form->checkbox('auto_del_invalid_texture', '失效材质', '自动删除失效材质')->hint('自动从皮肤库中删除文件不存在的材质记录');
+
+ $form->textarea('comment_script', '评论代码', option('comment_script'), function($textarea) {
+ $textarea->setRows(6);
+ $textarea->setDescription('评论代码内可使用占位符,{tid} 将会被自动替换为材质的 id,{name} 会被替换为材质名称,{url} 会被替换为当前页面地址。');
+ });
+ })->handle(function() {
+ if (substr($_POST['site_url'], -1) == "/")
+ $_POST['site_url'] = substr($_POST['site_url'], 0, -1);
+ });
+
+ $cache = Option::form('cache', '缓存相关配置', function($form)
+ {
+ $form->checkbox('avatar_query_string', '头像缓存', '为头像添加 Query String');
+ $form->checkbox('auto_detect_asset_url', '资源地址', '自动判断资源文件地址')->hint('根据当前 URL 自动加载资源文件。如果出现 CDN 回源问题请关闭');
+ $form->checkbox('return_200_when_notfound', 'HTTP 响应码', '请求不存在的角色时返回 200 而不是 404');
+
+ $form->text('cache_expire_time', '缓存失效时间')->hint('秒数,86400 = 一天,31536000 = 一年');
+
+ })->hint('如果启用了 CDN 缓存请适当修改这些配置')->handle();
+
+ return view('admin.options')->with('forms', compact('general', 'cache'));
}
/**
diff --git a/app/Services/Facades/Option.php b/app/Services/Facades/Option.php
index 02c522a8..51d7267c 100644
--- a/app/Services/Facades/Option.php
+++ b/app/Services/Facades/Option.php
@@ -2,7 +2,8 @@
namespace App\Services\Facades;
-use \Illuminate\Support\Facades\Facade;
+use App\Services\OptionForm;
+use Illuminate\Support\Facades\Facade;
class Option extends Facade
{
@@ -15,4 +16,13 @@ class Option extends Facade
{
return 'option';
}
+
+ public static function form($id, $title, $callback)
+ {
+ $form = new OptionForm($id, $title);
+
+ call_user_func($callback, $form);
+
+ return $form;
+ }
}
diff --git a/app/Services/OptionForm.php b/app/Services/OptionForm.php
new file mode 100644
index 00000000..caa1e2e0
--- /dev/null
+++ b/app/Services/OptionForm.php
@@ -0,0 +1,304 @@
+id = $id;
+ $this->title = $title;
+ }
+
+ public function text($id, $name, $value = null)
+ {
+ return $this->addItem('text', $id, $name);
+ }
+
+ public function checkbox($id, $name, $label, $checked = null)
+ {
+ $checkbox = $this->addItem('checkbox', $id, $name);
+
+ $checkbox->set('label', $label);
+
+ return $checkbox;
+ }
+
+ public function select($id, $name, $callback)
+ {
+ $item = $this->addItem('select', $id, $name);
+
+ $select = new OptionFormSelect($id);
+
+ call_user_func($callback, $select);
+
+ $item->set('view', $select->render());
+
+ return $select;
+ }
+
+ public function textarea($id, $name, $value, $callback)
+ {
+ $item = $this->addItem('textarea', $id, $name);
+
+ $textarea = new OptionFormTextarea($id, $value);
+
+ call_user_func($callback, $textarea);
+
+ $item->set('view', $textarea->render());
+
+ return $textarea;
+ }
+
+ public function group($id, $name, $callback)
+ {
+ $item = $this->addItem('group', $id, $name);
+
+ $group = new OptionFormGroup($id);
+
+ call_user_func($callback, $group);
+
+ $item->set('view', $group->render());
+
+ return $item;
+ }
+
+ public function addItem($type, $id, $name)
+ {
+ $item = new OptionFormItem($id, $name, $type);
+
+ $this->items[] = $item;
+
+ return $item;
+ }
+
+ public function hint($hint_content)
+ {
+ $this->hint = view('vendor.option-form.hint')->with('hint', $hint_content)->render();
+
+ return $this;
+ }
+
+ public function handle($callback = null)
+ {
+ if (Arr::get($_POST, 'option') == $this->id) {
+ if (!is_null($callback)) {
+ call_user_func($callback);
+ }
+
+ foreach ($this->items as $item) {
+ if ($item->type == "checkbox" && !isset($_POST[$item->id])) {
+ $_POST[$item->id] = "0";
+ }
+
+ if ($_POST[$item->id] != option($item->id)) {
+ Option::set($item->id, $_POST[$item->id]);
+ }
+ }
+
+ $this->success = true;
+ }
+
+ return $this;
+ }
+
+ public function render()
+ {
+ foreach ($this->items as $item) {
+ $id = $item->id;
+ $value = Option::get($item->id);
+
+ switch ($item->type) {
+ case 'text':
+ $view = view('vendor.option-form.text')->with(compact('id', 'value'));
+ break;
+
+ case 'checkbox':
+ $view = view('vendor.option-form.checkbox')->with([
+ 'id' => $id,
+ 'label' => $item->get('label'),
+ 'checked' => (bool) $value
+ ]);
+ break;
+
+ case 'select':
+ case 'textarea':
+ case 'group':
+ $view = $item->get('view');
+ break;
+ }
+
+ $item->setContent($view->render());
+ }
+
+
+ return view('vendor.option-form.main')->with([
+ 'title' => $this->title,
+ 'id' => $this->id,
+ 'hint' => $this->hint,
+ 'items' => $this->items,
+ 'success' => $this->success
+ ])->render();
+ }
+}
+
+class OptionFormItem
+{
+ public $id;
+ public $type;
+ public $title;
+
+ protected $data;
+
+ protected $hint;
+ protected $content;
+
+ public function __construct($id, $title, $type = "")
+ {
+ $this->id = $id;
+ $this->type = $type;
+ $this->title = $title;
+ }
+
+ public function hint($hint_content)
+ {
+ $this->hint = view('vendor.option-form.hint')->with('hint', $hint_content)->render();
+
+ return $this;
+ }
+
+ public function setContent($content)
+ {
+ $this->content = $content;
+
+ return $this;
+ }
+
+ public function set($key, $value)
+ {
+ $this->data[$key] = $value;
+ }
+
+ public function get($key)
+ {
+ return Arr::get($this->data, $key);
+ }
+
+ public function render()
+ {
+ return view('vendor.option-form.item')->with([
+ 'title' => $this->title,
+ 'content' => $this->content,
+ 'hint' => $this->hint
+ ]);
+ }
+
+}
+
+class OptionFormSelect
+{
+ protected $id;
+
+ protected $items;
+
+ protected $selected;
+
+ public function __construct($id)
+ {
+ $this->id = $id;
+ }
+
+ public function add($id, $name)
+ {
+ $this->items[] = [$id, $name];
+ }
+
+ public function setSelected($id)
+ {
+ $this->selected = $id;
+ }
+
+ public function render()
+ {
+ return view('vendor.option-form.select')->with([
+ 'id' => $this->id,
+ 'items' => $this->items,
+ 'selected' => $this->selected
+ ]);
+ }
+}
+
+class OptionFormTextarea
+{
+ protected $id;
+
+ protected $value;
+
+ protected $rows = 3;
+
+ protected $description = "";
+
+ public function __construct($id, $value)
+ {
+ $this->id = $id;
+ $this->value = $value;
+ }
+
+ public function setRows($rows)
+ {
+ $this->rows = $rows;
+ }
+
+ public function setDescription($description)
+ {
+ $this->description = $description;
+ }
+
+ public function render()
+ {
+ return view('vendor.option-form.textarea')->with([
+ 'rows' => $this->rows,
+ 'id' => $this->id,
+ 'value' => $this->value,
+ 'description' => $this->description
+ ]);
+ }
+}
+
+class OptionFormGroup
+{
+ protected $id;
+
+ protected $items = [];
+
+ public function __construct($id)
+ {
+ $this->id = $id;
+ }
+
+ public function text($id, $value)
+ {
+ $this->items[] = view('vendor.option-form.text')->withId($id)->withValue($value);
+ }
+
+ public function addon($value)
+ {
+ $this->items[] = view('vendor.option-form.addon')->withValue($value);
+ }
+
+ public function render()
+ {
+ return view('vendor.option-form.group')->with('items', $this->items);
+ }
+}
diff --git a/resources/views/admin/options.tpl b/resources/views/admin/options.tpl
index a705587e..e587c6ac 100644
--- a/resources/views/admin/options.tpl
+++ b/resources/views/admin/options.tpl
@@ -2,13 +2,6 @@
@section('title', trans('general.options'))
-@section('style')
-
-@endsection
-
@section('content')
@@ -26,134 +19,7 @@
{!! $description !!}
+@endif