diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index 28f0a536..1c8c189f 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -26,54 +26,71 @@ class AdminController extends Controller
{
$form->text('home_pic_url', '首页图片地址')->hint('相对于首页的路径或者完整的 URL');
- $form->select('copyright_prefer', '程序版权信息', function($options) {
- $options->add('0', 'Powered with ❤ by Blessing Skin Server.');
- $options->add('1', 'Powered by Blessing Skin Server.');
- $options->add('2', '由 Blessing Skin Server 强力驱动.');
- $options->add('3', '自豪地采用 Blessing Skin Server.');
- })->setSelected(Option::get('copyright_prefer', 0, false));
+ $form->select('copyright_prefer', '程序版权信息')
+ ->option('0', 'Powered with ❤ by Blessing Skin Server.')
+ ->option('1', 'Powered by Blessing Skin Server.')
+ ->option('2', '由 Blessing Skin Server 强力驱动.')
+ ->option('3', '自豪地采用 Blessing Skin Server.');
- $form->textarea('copyright_text', '自定义版权文字', function($textarea) {
- $textarea->setRows(6);
- $textarea->setDescription('自定义版权文字内可使用占位符,{site_name}
将会被自动替换为站点名称,{site_url}
会被替换为站点地址。');
- });
+ $form->textarea('copyright_text', '自定义版权文字')->rows(6)
+ ->description('自定义版权文字内可使用占位符,{site_name}
将会被自动替换为站点名称,{site_url}
会被替换为站点地址。');
})->handle();
- return view('admin.customize', compact('homepage'));
+ $customJsCss = Option::form('customJsCss', '自定义 CSS/JavaScript', function($form)
+ {
+ $form->textarea('custom_css', 'CSS')->rows(6);
+ $form->textarea('custom_js', 'JavaScript')->rows(6);
+ })->addMessage('
+ 内容将会被追加至每个页面的 <style> 和 <script> 标签中。
+ - 这里有一些有用的示例:「自定义 CSS JavaScript」功能的一些实例@GitHub WiKi
+ ')->handle();
+
+ return view('admin.customize', ['forms' => compact('homepage', 'customJsCss')]);
}
public function score()
{
$rate = Option::form('rate', '积分换算', function($form)
{
- $form->group('score_per_storage', '存储', function($group) {
- $group->text('score_per_storage');
- $group->addon('积分 = 1 KB');
- });
+ $form->group('score_per_storage', '存储')->text('score_per_storage')->addon('积分 = 1 KB');
- $form->group('private_score_per_storage', '私密材质存储', function($group) {
- $group->text('private_score_per_storage');
- $group->addon('积分 = 1 KB');
- })->hint('上传私密材质将消耗更多积分');
+ $form->group('private_score_per_storage', '私密材质存储')
+ ->text('private_score_per_storage')->addon('积分 = 1 KB')
+ ->hint('上传私密材质将消耗更多积分');
- $form->group('score_per_closet_item', '收藏消耗积分', function($group) {
- $group->text('score_per_closet_item');
- $group->addon('积分 = 一个衣柜物品');
- });
+ $form->group('score_per_closet_item', '收藏消耗积分')
+ ->text('score_per_closet_item')->addon('积分 = 一个衣柜物品');
- $form->checkbox('return_score', '积分返还', '用户删除角色/材质/收藏时返还积分');
+ $form->checkbox('return_score', '积分返还')->label('用户删除角色/材质/收藏时返还积分');
- $form->group('score_per_player', '角色', function($group) {
- $group->text('score_per_player');
- $group->addon('积分 = 一个角色');
- });
+ $form->group('score_per_player', '角色')->text('score_per_player')->addon('积分 = 一个角色');
$form->text('user_initial_score', '新用户默认积分');
})->handle();
- return view('admin.score', compact('rate'));
+ $signIn = Option::form('sign_in', '签到配置', function($form)
+ {
+ $form->group('sign_score', '签到获得积分')
+ ->text('sign_score_from')->addon('积分 ~ ')->text('sign_score_to')->addon('积分');
+
+ $form->group('sign_gap_time', '签到间隔时间')->text('sign_gap_time')->addon('小时');
+
+ $form->checkbox('sign_after_zero', '签到时间')->label('每天零点后可签到')
+ ->hint('勾选后将无视上一条,每天零时后均可签到');
+ })->handle(function() {
+ $sign_score = $_POST['sign_score_from'].','.$_POST['sign_score_to'];
+ Option::set('sign_score', $sign_score);
+
+ unset($_POST['sign_score_from']);
+ unset($_POST['sign_score_to']);
+ })->with([
+ 'sign_score_from' => @explode(',', option('sign_score'))[0],
+ 'sign_score_to' => @explode(',', option('sign_score'))[1]
+ ]);
+
+ return view('admin.score', ['forms' => compact('rate', 'signIn')]);
}
public function options()
diff --git a/app/Services/OptionForm.php b/app/Services/OptionForm.php
index 978a91d4..10f0aef8 100644
--- a/app/Services/OptionForm.php
+++ b/app/Services/OptionForm.php
@@ -3,8 +3,10 @@
namespace App\Services;
use Option;
+use ReflectionClass;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
+use BadMethodCallException;
class OptionForm
{
@@ -12,11 +14,12 @@ class OptionForm
protected $title;
protected $hint;
- protected $type = 'primary';
- protected $items;
+ protected $type = 'primary';
+ protected $items = [];
- protected $values;
+ protected $values = [];
+ protected $buttons = [];
protected $messages = [];
protected $alwaysCallback = null;
@@ -24,26 +27,48 @@ class OptionForm
protected $renderWithOutTable = false;
protected $renderInputTagsOnly = false;
+ /**
+ * Create a new option form instance.
+ *
+ * @param string $id
+ * @param string $title
+ * @return void
+ */
public function __construct($id, $title)
{
$this->id = $id;
$this->title = $title;
}
- public function __call($name, $arguments)
+ /**
+ * Add option item to the form dynamically.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return OptionItem
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __call($method, $parameters)
{
- if (!in_array($name, ['text', 'checkbox', 'textarea', 'select', 'group'])) {
- throw new \InvalidArgumentException("No such item for option form.", 1);
+ if (!in_array($method, ['text', 'checkbox', 'textarea', 'select', 'group'])) {
+ throw new BadMethodCallException("Method [$method] does not exist on option form.");
}
- $class = new \ReflectionClass('App\Services\OptionForm'.Str::title($name));
+ $class = new ReflectionClass('App\Services\OptionForm'.Str::title($method));
// use ReflectionClass to create a new OptionFormItem instance
- $item = $class->newInstanceArgs($arguments);
+ $item = $class->newInstanceArgs($parameters);
$this->items[] = $item;
return $item;
}
+ /**
+ * Set the box type of option form.
+ *
+ * @param string $type
+ * @return $this
+ */
public function type($type)
{
$this->type = $type;
@@ -51,17 +76,30 @@ class OptionForm
return $this;
}
- public function hint($hint_content)
+ /**
+ * Add a hint to option form.
+ *
+ * @param array $info
+ * @return $this
+ */
+ public function hint($hintContent)
{
- $this->hint = view('vendor.option-form.hint')->with('hint', $hint_content)->render();
+ $this->hint = view('vendor.option-form.hint')->with('hint', $hintContent)->render();
return $this;
}
+ /**
+ * Add a piece of data to the option form.
+ *
+ * @param string|array $key
+ * @param mixed $value
+ * @return $this
+ */
public function with($key, $value = null)
{
if (is_array($key)) {
- $this->values = array_merge($this->values, $values);
+ $this->values = array_merge($this->values, $key);
} else {
$this->values[$key] = $value;
}
@@ -69,22 +107,69 @@ class OptionForm
return $this;
}
- public function addMessage($msg, $type = "info")
+ /**
+ * Add a button at the footer of option form.
+ *
+ * @param array $info
+ * @return $this
+ */
+ public function addButton(array $info)
{
- $this->messages[] = "
$msg
";
+ $info = array_merge([
+ 'style' => 'default',
+ 'class' => [],
+ 'href' => '',
+ 'text' => 'BUTTON',
+ 'type' => 'button',
+ 'name' => ''
+ ], $info);
+
+ $classes = "btn btn-{$info['style']} ".implode(' ', (array) Arr::get($info, 'class'));
+
+ if ($info['href']) {
+ $this->buttons[] = "{$info['text']}";
+ } else {
+ $this->buttons[] = "";
+ }
+
+ return $this;
}
- public function always($callback)
+ /**
+ * Add a message to the top of option form.
+ *
+ * @param string $msg
+ * @param string $style
+ * @return $this
+ */
+ public function addMessage($msg, $style = "info")
+ {
+ $this->messages[] = "$msg
";
+
+ return $this;
+ }
+
+ /**
+ * Add callback which will be always executed.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function always(callable $callback)
{
$this->alwaysCallback = $callback;
return $this;
}
+ /**
+ * Parse id formatted as *[*]. Return id & offset when succeed.
+ *
+ * @param string $id
+ * @return bool|array
+ */
protected function parseIdWithOffset($id)
{
- // detect if id is formatted as *[*]
- // array option is stored as unserialized string
preg_match('/(.*)\[(.*)\]/', $id, $matches);
if (isset($matches[2])) {
@@ -97,34 +182,54 @@ class OptionForm
return false;
}
- public function handle($callback = null)
+ /**
+ * Handle the HTTP post request and update modified options.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function handle(callable $callback = null)
{
if (Arr::get($_POST, 'option') == $this->id) {
if (!is_null($callback)) {
call_user_func($callback, $this);
}
- $arrayOptionCache = [];
+ $postOptionQueue = [];
+ $arrayOptionQueue = [];
foreach ($this->items as $item) {
+ if ($item instanceof OptionFormGroup) {
+ foreach ($item->items as $innerItem) {
+ if ($innerItem['type'] == "text") {
+ $postOptionQueue[] = new OptionFormText($innerItem['id']);
+ }
+ }
+ continue;
+ }
+ // push item to the queue
+ $postOptionQueue[] = $item;
+ }
+
+ foreach ($postOptionQueue as $item) {
if ($item instanceof OptionFormCheckbox && !isset($_POST[$item->id])) {
// preset value for checkboxes which are not checked
- $_POST[$item->id] = "0";
+ $_POST[$item->id] = "false";
}
// Str::is('*[*]', $item->id)
if (false !== ($result = $this->parseIdWithOffset($item->id))) {
// push array option value to cache
- $arrayOptionCache[$result['id']][$result['offset']] = $_POST[$item->id];
+ $arrayOptionQueue[$result['id']][$result['offset']] = $_POST[$item->id];
continue;
}
- if ($_POST[$item->id] != option($item->id, null, false)) {
- Option::set($item->id, $_POST[$item->id]);
+ if (($data = Arr::get($_POST, $item->id)) != option($item->id, null, false)) {
+ Option::set($item->id, $data);
}
}
- foreach ($arrayOptionCache as $key => $value) {
+ foreach ($arrayOptionQueue as $key => $value) {
Option::set($key, serialize($value));
}
@@ -135,7 +240,7 @@ class OptionForm
}
/**
- * Load value from $this->values & options.
+ * Load value from $this->values & options by given id.
*
* @param string $id
* @return mixed
@@ -143,7 +248,7 @@ class OptionForm
protected function getValueById($id)
{
if (false === ($result = $this->parseIdWithOffset($id))) {
- return option($id);
+ return Arr::get($this->values, $id, option($id, null, false));
} else {
$option = Arr::get(
$this->values,
@@ -156,6 +261,11 @@ class OptionForm
}
}
+ /**
+ * Assign value for option items whose value haven't been set.
+ *
+ * @return void
+ */
protected function assignValues()
{
if (!is_null($this->alwaysCallback)) {
@@ -165,7 +275,7 @@ class OptionForm
// load values for items if not set manually
foreach ($this->items as $item) {
if ($item instanceof OptionFormGroup) {
- foreach ($item->items as $groupItem) {
+ foreach ($item->items as &$groupItem) {
if ($groupItem['id'] && is_null($groupItem['value'])) {
$groupItem['value'] = $this->getValueById($groupItem['id']);
}
@@ -193,12 +303,27 @@ class OptionForm
return $this;
}
+ /**
+ * Get the string contents of the option form.
+ *
+ * @return string
+ */
public function render()
{
$this->assignValues();
return view('vendor.option-form.main')->with(array_merge(get_object_vars($this)))->render();
}
+
+ /**
+ * Get the string contents of the option form.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
}
class OptionFormItem
diff --git a/app/helpers.php b/app/helpers.php
index dcadb863..c17d4c0a 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -221,7 +221,15 @@ if (! function_exists('bs_nickname')) {
}
if (! function_exists('option')) {
-
+ /**
+ * Get / set the specified option value.
+ *
+ * If an array is passed as the key, we will assume you want to set an array of values.
+ *
+ * @param array|string $key
+ * @param mixed $default
+ * @return mixed
+ */
function option($key = null, $default = null, $bool = true)
{
$options = app('options');
diff --git a/resources/views/admin/customize.tpl b/resources/views/admin/customize.tpl
index c38b017e..479bd6b5 100644
--- a/resources/views/admin/customize.tpl
+++ b/resources/views/admin/customize.tpl
@@ -86,55 +86,12 @@
-
- {!! $homepage->render() !!}
+ {!! $forms['homepage']->render() !!}
-
-
-
-
+ {!! $forms['customJsCss']->render() !!}
diff --git a/resources/views/admin/score.tpl b/resources/views/admin/score.tpl
index 610f1160..9cd34b06 100644
--- a/resources/views/admin/score.tpl
+++ b/resources/views/admin/score.tpl
@@ -18,69 +18,11 @@
- {!! $rate->render() !!}
+ {!! $forms['rate']->render() !!}
-
-
-
-
-
-
+ {!! $forms['signIn']->render() !!}
diff --git a/resources/views/vendor/option-form/checkbox.tpl b/resources/views/vendor/option-form/checkbox.tpl
index 07068495..ba91f33d 100644
--- a/resources/views/vendor/option-form/checkbox.tpl
+++ b/resources/views/vendor/option-form/checkbox.tpl
@@ -1,3 +1,3 @@
diff --git a/resources/views/vendor/option-form/item.tpl b/resources/views/vendor/option-form/item.tpl
new file mode 100644
index 00000000..c7c678fd
--- /dev/null
+++ b/resources/views/vendor/option-form/item.tpl
@@ -0,0 +1,5 @@
+{!! $item->render() !!}
+
+@if ($item->description)
+{!! $item->description !!}
+@endif
diff --git a/resources/views/vendor/option-form/main.tpl b/resources/views/vendor/option-form/main.tpl
index 960f5c9d..98bf181b 100644
--- a/resources/views/vendor/option-form/main.tpl
+++ b/resources/views/vendor/option-form/main.tpl
@@ -6,43 +6,37 @@
- @if (!empty($messages))
- @foreach($messages as $msg)
- {!! $msg !!}
- @endforeach
- @endif
+ @foreach($messages as $msg)
+ {!! $msg !!}
+ @endforeach
+ @if ($renderWithOutTable)
+ @each('vendor.option-form.item', $items, 'item')
+ @else
@foreach($items as $item)
-
-
- @unless ($renderWithOutTable)
@unless ($renderInputTagsOnly)
{{ $item->name }} {!! $item->hint or '' !!} |
@endunless
- @endunless
-
- {!! $item->render() !!}
-
- @if ($item->description)
- {!! $item->description !!}
- @endif
-
- @unless ($renderWithOutTable)
+ @include('vendor.option-form.item', compact('item'))
|
- @endunless
-
@endforeach
+ @endif
+