diff --git a/application/admin/command/Addon.php b/application/admin/command/Addon.php
index 7bca186e..c738c6a0 100644
--- a/application/admin/command/Addon.php
+++ b/application/admin/command/Addon.php
@@ -201,16 +201,20 @@ class Addon extends Command
new \RecursiveDirectoryIterator($addonDir), \RecursiveIteratorIterator::LEAVES_ONLY
);
+ $addonDir = str_replace(DS, '/', $addonDir);
+ $excludeDirRegex = "/\/(\.git|\.svn|\.vscode|\.idea|unpackage)\//i";
foreach ($files as $name => $file) {
- if (!$file->isDir()) {
- $filePath = $file->getRealPath();
- $relativePath = str_replace(DS, '/', substr($filePath, strlen($addonDir)));
- if (!in_array($file->getFilename(), ['.git', '.DS_Store', 'Thumbs.db'])) {
- $zip->addFile($filePath, $relativePath);
- }
+ $filePath = str_replace(DS, '/', $file->getPathname());
+ if ($file->isDir() || preg_match($excludeDirRegex, $filePath))
+ continue;
+ $relativePath = substr($filePath, strlen($addonDir));
+ if (!in_array($file->getFilename(), ['.DS_Store', 'Thumbs.db'])) {
+ $zip->addFile($filePath, $relativePath);
}
}
+
$zip->close();
+ $output->info("Package Resource Path:" . $addonFile);
$output->info("Package Successed!");
break;
case 'move':
diff --git a/application/admin/command/Crud.php b/application/admin/command/Crud.php
index b55f338a..3c54d39f 100755
--- a/application/admin/command/Crud.php
+++ b/application/admin/command/Crud.php
@@ -920,6 +920,7 @@ class Crud extends Command
$replace = '\'{"custom[type]":"' . $table . '"}\'';
} elseif ($selectpageController == 'admin') {
$attrArr['data-source'] = 'auth/admin/selectpage';
+ $attrArr['data-field'] = 'nickname';
} elseif ($selectpageController == 'user') {
$attrArr['data-source'] = 'user/user/index';
$attrArr['data-field'] = 'nickname';
diff --git a/application/admin/command/Crud/stubs/mixins/checkbox.stub b/application/admin/command/Crud/stubs/mixins/checkbox.stub
index d5f7b664..ba87ac81 100644
--- a/application/admin/command/Crud/stubs/mixins/checkbox.stub
+++ b/application/admin/command/Crud/stubs/mixins/checkbox.stub
@@ -1,7 +1,7 @@
public function {%methodName%}($value, $data)
{
- $value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
+ $value = $value ?: ($data['{%field%}'] ?? '');
$valueArr = explode(',', $value);
$list = $this->{%listMethodName%}();
return implode(',', array_intersect_key($list, array_flip($valueArr)));
diff --git a/application/admin/command/Crud/stubs/mixins/datetime.stub b/application/admin/command/Crud/stubs/mixins/datetime.stub
index 591dd4dd..60044487 100644
--- a/application/admin/command/Crud/stubs/mixins/datetime.stub
+++ b/application/admin/command/Crud/stubs/mixins/datetime.stub
@@ -1,6 +1,6 @@
public function {%methodName%}($value, $data)
{
- $value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
+ $value = $value ?: ($data['{%field%}'] ?? '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}
\ No newline at end of file
diff --git a/application/admin/command/Crud/stubs/mixins/radio.stub b/application/admin/command/Crud/stubs/mixins/radio.stub
index 71234a63..030d373d 100644
--- a/application/admin/command/Crud/stubs/mixins/radio.stub
+++ b/application/admin/command/Crud/stubs/mixins/radio.stub
@@ -1,7 +1,7 @@
public function {%methodName%}($value, $data)
{
- $value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
+ $value = $value ?: ($data['{%field%}'] ?? '');
$list = $this->{%listMethodName%}();
- return isset($list[$value]) ? $list[$value] : '';
+ return $list[$value] ?? '';
}
\ No newline at end of file
diff --git a/application/admin/command/Crud/stubs/mixins/select.stub b/application/admin/command/Crud/stubs/mixins/select.stub
index 71234a63..030d373d 100644
--- a/application/admin/command/Crud/stubs/mixins/select.stub
+++ b/application/admin/command/Crud/stubs/mixins/select.stub
@@ -1,7 +1,7 @@
public function {%methodName%}($value, $data)
{
- $value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
+ $value = $value ?: ($data['{%field%}'] ?? '');
$list = $this->{%listMethodName%}();
- return isset($list[$value]) ? $list[$value] : '';
+ return $list[$value] ?? '';
}
\ No newline at end of file
diff --git a/application/admin/command/Install.php b/application/admin/command/Install.php
index 572cc979..c4330599 100644
--- a/application/admin/command/Install.php
+++ b/application/admin/command/Install.php
@@ -214,22 +214,27 @@ class Install extends Command
$adminFile = ROOT_PATH . 'public' . DS . 'admin.php';
// 数据库配置文件
- $dbConfigFile = APP_PATH . 'database.php';
- $dbConfigText = @file_get_contents($dbConfigFile);
+ $envSampleFile = ROOT_PATH . '.env.sample';
+ $envFile = ROOT_PATH . '.env';
+ if (!file_exists($envFile)) {
+ if (!copy($envSampleFile, $envFile)) {
+ throw new Exception(__('Failed to copy %s to %s', '.env.sample', '.env'));
+ }
+ }
+
+ $envText = @file_get_contents($envFile);
+
$callback = function ($matches) use ($mysqlHostname, $mysqlHostport, $mysqlUsername, $mysqlPassword, $mysqlDatabase, $mysqlPrefix) {
$field = "mysql" . ucfirst($matches[1]);
$replace = $$field;
- if ($matches[1] == 'hostport' && $mysqlHostport == 3306) {
- $replace = '';
- }
- return "'{$matches[1]}'{$matches[2]}=>{$matches[3]}Env::get('database.{$matches[1]}', '{$replace}'),";
+ return "{$matches[1]} = {$replace}";
};
- $dbConfigText = preg_replace_callback("/'(hostname|database|username|password|hostport|prefix)'(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $dbConfigText);
+ $envText = preg_replace_callback("/(hostname|database|username|password|hostport|prefix)\s*=\s*(.*)/", $callback, $envText);
// 检测能否成功写入数据库配置
- $result = @file_put_contents($dbConfigFile, $dbConfigText);
+ $result = @file_put_contents($envFile, $envText);
if (!$result) {
- throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/database.php'));
+ throw new Exception(__('The current permissions are insufficient to write the file %s', '.env'));
}
// 设置新的Token随机密钥key
@@ -244,7 +249,7 @@ class Install extends Command
throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/config.php'));
}
- $avatar = request()->domain() . '/assets/img/avatar.png';
+ $avatar = '/assets/img/avatar.png';
// 变更默认管理员密码
$adminPassword = $adminPassword ? $adminPassword : Random::alnum(8);
$adminEmail = $adminEmail ? $adminEmail : "admin@admin.com";
diff --git a/application/admin/controller/Ajax.php b/application/admin/controller/Ajax.php
index 32748b01..4fd33e1f 100644
--- a/application/admin/controller/Ajax.php
+++ b/application/admin/controller/Ajax.php
@@ -21,7 +21,6 @@ use think\Validate;
*/
class Ajax extends Backend
{
-
protected $noNeedLogin = ['lang'];
protected $noNeedRight = ['*'];
protected $layout = '';
@@ -207,7 +206,6 @@ class Ajax extends Backend
$type = $this->request->request("type");
switch ($type) {
case 'all':
- // no break
case 'content':
//内容缓存
rmdirs(CACHE_PATH, false);
@@ -215,18 +213,21 @@ class Ajax extends Backend
if ($type == 'content') {
break;
}
+ // no break
case 'template':
// 模板缓存
rmdirs(TEMP_PATH, false);
if ($type == 'template') {
break;
}
+ // no break
case 'addons':
// 插件缓存
Service::refresh();
if ($type == 'addons') {
break;
}
+ // no break
case 'browser':
// 浏览器缓存
// 只有生产环境下才修改
@@ -323,5 +324,4 @@ class Ajax extends Backend
$response = Response::create($data, '', 200, $header);
return $response;
}
-
}
diff --git a/application/admin/lang/zh-cn.php b/application/admin/lang/zh-cn.php
index f7420df2..f0e1bc49 100755
--- a/application/admin/lang/zh-cn.php
+++ b/application/admin/lang/zh-cn.php
@@ -7,6 +7,7 @@ return [
'Mobile' => '手机',
'Email' => '邮箱',
'Password' => '密码',
+ 'Mobile' => '手机号',
'Sign up' => '注 册',
'Sign in' => '登 录',
'Sign out' => '退 出',
diff --git a/application/admin/lang/zh-cn/index.php b/application/admin/lang/zh-cn/index.php
index 3bde7d59..dcb72058 100644
--- a/application/admin/lang/zh-cn/index.php
+++ b/application/admin/lang/zh-cn/index.php
@@ -30,6 +30,7 @@ return [
'You\'ve logged in, do not login again' => '你已经登录,无需重复登录',
'Username or password can not be empty' => '用户名密码不能为空',
'Username or password is incorrect' => '用户名或密码不正确',
+ 'Username must be 3 to 30 characters' => '用户名只能由3-30位数字、字母、下划线组合',
'Username is incorrect' => '用户名不正确',
'Password is incorrect' => '密码不正确',
'Admin is forbidden' => '管理员已经被禁止登录',
diff --git a/application/admin/view/common/script.html b/application/admin/view/common/script.html
index 01c615e3..04d1e80f 100644
--- a/application/admin/view/common/script.html
+++ b/application/admin/view/common/script.html
@@ -1 +1 @@
-
\ No newline at end of file
+
diff --git a/application/admin/view/general/attachment/add.html b/application/admin/view/general/attachment/add.html
index 829adc45..f535e16a 100644
--- a/application/admin/view/general/attachment/add.html
+++ b/application/admin/view/general/attachment/add.html
@@ -46,9 +46,9 @@
{/foreach}
-
+
{if $config.upload.chunking}
-
+
{/if}
diff --git a/application/common/library/Log.php b/application/common/library/Log.php
index c6192ca8..d9aff8df 100644
--- a/application/common/library/Log.php
+++ b/application/common/library/Log.php
@@ -19,10 +19,8 @@ class Log extends AbstractLogger
* @param array $context
*
* @return void
- *
- * @throws \Psr\Log\InvalidArgumentException
*/
- public function log($level, $message, array $context = array())
+ public function log($level, $message, array $context = [])
{
\think\Log::write($message);
}
diff --git a/application/common/model/Config.php b/application/common/model/Config.php
index d3f49ad1..d0904923 100644
--- a/application/common/model/Config.php
+++ b/application/common/model/Config.php
@@ -219,7 +219,7 @@ class Config extends Model
}
file_put_contents(
CONF_PATH . 'extra' . DS . 'site.php',
- ' false,
+ /**
+ * 上传超时时长,这里仅用于JS上传超时控制
+ */
+ 'timeout' => 60000,
/**
* 是否支持分片上传
*/
diff --git a/extend/fast/Http.php b/extend/fast/Http.php
index b3bb31f7..0af26dc4 100644
--- a/extend/fast/Http.php
+++ b/extend/fast/Http.php
@@ -11,11 +11,11 @@ class Http
/**
* 发送一个POST请求
* @param string $url 请求URL
- * @param array $params 请求参数
- * @param array $options 扩展参数
+ * @param array $params 请求参数
+ * @param array $options 扩展参数
* @return mixed|string
*/
- public static function post($url, $params = [], $options = [])
+ public static function post(string $url, array $params = [], array $options = [])
{
$req = self::sendRequest($url, $params, 'POST', $options);
return $req['ret'] ? $req['msg'] : '';
@@ -24,11 +24,11 @@ class Http
/**
* 发送一个GET请求
* @param string $url 请求URL
- * @param array $params 请求参数
- * @param array $options 扩展参数
+ * @param array $params 请求参数
+ * @param array $options 扩展参数
* @return mixed|string
*/
- public static function get($url, $params = [], $options = [])
+ public static function get(string $url, array $params = [], array $options = [])
{
$req = self::sendRequest($url, $params, 'GET', $options);
return $req['ret'] ? $req['msg'] : '';
@@ -42,7 +42,7 @@ class Http
* @param mixed $options CURL的参数
* @return array
*/
- public static function sendRequest($url, $params = [], $method = 'POST', $options = [])
+ public static function sendRequest(string $url, $params = [], string $method = 'POST', $options = []): array
{
$method = strtoupper($method);
$protocol = substr($url, 0, 5);
@@ -108,7 +108,7 @@ class Http
* @param string $method 请求的方法
* @return boolean TRUE
*/
- public static function sendAsyncRequest($url, $params = [], $method = 'POST')
+ public static function sendAsyncRequest(string $url, $params = [], string $method = 'POST'): bool
{
$method = strtoupper($method);
$method = $method == 'POST' ? 'POST' : 'GET';
@@ -157,10 +157,10 @@ class Http
/**
* 发送文件到客户端
* @param string $file
- * @param bool $delaftersend
- * @param bool $exitaftersend
+ * @param bool $deleteAfterSend
+ * @param bool $exitAfterSend
*/
- public static function sendToBrowser($file, $delaftersend = true, $exitaftersend = true)
+ public static function sendToBrowser(string $file, bool $deleteAfterSend = true, bool $exitAfterSend = true)
{
if (file_exists($file) && is_readable($file)) {
header('Content-Description: File Transfer');
@@ -174,10 +174,10 @@ class Http
ob_clean();
flush();
readfile($file);
- if ($delaftersend) {
+ if ($deleteAfterSend) {
unlink($file);
}
- if ($exitaftersend) {
+ if ($exitAfterSend) {
exit;
}
}
diff --git a/extend/fast/Random.php b/extend/fast/Random.php
index 88109171..db1f6f9a 100644
--- a/extend/fast/Random.php
+++ b/extend/fast/Random.php
@@ -14,7 +14,7 @@ class Random
* @param int $len 长度
* @return string
*/
- public static function alnum($len = 6)
+ public static function alnum(int $len = 6): string
{
return self::build('alnum', $len);
}
@@ -25,7 +25,7 @@ class Random
* @param int $len 长度
* @return string
*/
- public static function alpha($len = 6)
+ public static function alpha(int $len = 6): string
{
return self::build('alpha', $len);
}
@@ -36,7 +36,7 @@ class Random
* @param int $len 长度
* @return string
*/
- public static function numeric($len = 4)
+ public static function numeric(int $len = 4): string
{
return self::build('numeric', $len);
}
@@ -47,7 +47,7 @@ class Random
* @param int $len 长度
* @return string
*/
- public static function nozero($len = 4)
+ public static function nozero(int $len = 4): string
{
return self::build('nozero', $len);
}
@@ -58,7 +58,7 @@ class Random
* @param int $len 长度
* @return string
*/
- public static function build($type = 'alnum', $len = 8)
+ public static function build(string $type = 'alnum', int $len = 8): string
{
switch ($type) {
case 'alpha':
@@ -93,7 +93,7 @@ class Random
* 获取全球唯一标识
* @return string
*/
- public static function uuid()
+ public static function uuid(): string
{
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
diff --git a/extend/fast/Tree.php b/extend/fast/Tree.php
index 2c1997c2..1f9e97fc 100644
--- a/extend/fast/Tree.php
+++ b/extend/fast/Tree.php
@@ -325,7 +325,7 @@ class Tree
'@url' => $childdata || !isset($value['@url']) ? "javascript:;" : $value['@url'],
'@addtabs' => $childdata || !isset($value['@url']) ? "" : (stripos($value['@url'], "?") !== false ? "&" : "?") . "ref=addtabs",
'@caret' => ($childdata && (!isset($value['@badge']) || !$value['@badge']) ? '' : ''),
- '@badge' => isset($value['@badge']) ? $value['@badge'] : '',
+ '@badge' => $value['@badge'] ?? '',
'@class' => ($selected ? ' active' : '') . ($disabled ? ' disabled' : '') . ($childdata ? ' treeview' . (config('fastadmin.show_submenu') ? ' treeview-open' : '') : ''),
);
$str .= strtr($nstr, $value);
@@ -422,7 +422,7 @@ class Tree
{
$arr = [];
foreach ($data as $k => $v) {
- $childlist = isset($v['childlist']) ? $v['childlist'] : [];
+ $childlist = $v['childlist'] ?? [];
unset($v['childlist']);
$v[$field] = $v['spacer'] . ' ' . $v[$field];
$v['haschild'] = $childlist ? 1 : 0;
diff --git a/public/assets/js/backend/addon.js b/public/assets/js/backend/addon.js
index 42eb9d22..defe5b52 100644
--- a/public/assets/js/backend/addon.js
+++ b/public/assets/js/backend/addon.js
@@ -165,7 +165,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template', 'cookie']
title: __('Operate'),
table: table,
formatter: Controller.api.formatter.operate,
- align: 'right'
+ align: 'right',
+ cellStyle: function (value, row, index) {
+ return {css: {'min-width': '158px'}};
+ }
},
]
],
@@ -238,6 +241,27 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template', 'cookie']
Layer.close(index);
});
return false;
+ } else if (ret && ret.code === -3) {
+ //插件目录发现影响全局的文件
+ Layer.open({
+ content: Template("conflicttpl", ret.data),
+ shade: 0.8,
+ area: area,
+ title: __('Warning'),
+ btn: [__('Continue install'), __('Cancel')],
+ end: function () {
+
+ },
+ yes: function (index) {
+ up.removeFile(file);
+ file.force = true;
+ up.uploadFile(file);
+ Layer.close(index);
+ }
+ });
+
+ } else {
+ Layer.alert(ret.msg, {title: __('Warning'), icon: 0});
}
});
diff --git a/public/assets/js/backend/auth/rule.js b/public/assets/js/backend/auth/rule.js
index f88928c5..77477b1d 100755
--- a/public/assets/js/backend/auth/rule.js
+++ b/public/assets/js/backend/auth/rule.js
@@ -180,7 +180,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
var iconfunc = function () {
Layer.open({
type: 1,
- area: ['99%', '98%'], //宽高
+ area: ['80%', '80%'], //宽高
content: Template('chooseicontpl', {iconlist: iconlist})
});
};
@@ -192,8 +192,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
$(document).on('click', ".btn-search-icon", function () {
if (iconlist.length == 0) {
- $.get(Config.site.cdnurl + "/assets/libs/font-awesome/less/variables.less", function (ret) {
- var exp = /fa-var-(.*):/ig;
+ $.get(Config.site.cdnurl + "/assets/libs/font-awesome/css/font-awesome.css", function (ret) {
+ var exp = /fa-(.*):before/ig;
var result;
while ((result = exp.exec(ret)) != null) {
iconlist.push(result[1]);
diff --git a/public/assets/js/backend/general/attachment.js b/public/assets/js/backend/general/attachment.js
index 23202114..53c8680a 100644
--- a/public/assets/js/backend/general/attachment.js
+++ b/public/assets/js/backend/general/attachment.js
@@ -167,7 +167,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
{
field: 'operate', title: __('Operate'), width: 85, events: {
'click .btn-chooseone': function (e, value, row, index) {
- Fast.api.close({url: row.url, multiple: multiple});
+ Fast.api.close($.extend({multiple: multiple}, row));
},
}, formatter: function () {
return ' ' + __('Choose') + '';
diff --git a/public/assets/js/bootstrap-table-commonsearch.js b/public/assets/js/bootstrap-table-commonsearch.js
index bb1f9ebb..a6c20457 100644
--- a/public/assets/js/bootstrap-table-commonsearch.js
+++ b/public/assets/js/bootstrap-table-commonsearch.js
@@ -208,7 +208,7 @@
} else {
value = process ? process(obj.val()) : obj.val();
}
- if (removeempty && (value == '' || value == null || ($.isArray(value) && value.length == 0)) && !sym.match(/null/i)) {
+ if (removeempty && (value === '' || value == null || ($.isArray(value) && value.length === 0)) && !sym.match(/null/i)) {
return true;
}
@@ -268,7 +268,7 @@
return "Common search";
},
formatCommonSubmitButton: function () {
- return "Submit";
+ return "Search";
},
formatCommonResetButton: function () {
return "Reset";
diff --git a/public/assets/js/require-form.js b/public/assets/js/require-form.js
index fcdcc6f3..f327febc 100755
--- a/public/assets/js/require-form.js
+++ b/public/assets/js/require-form.js
@@ -102,6 +102,7 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
//绑定select元素事件
if ($(".selectpicker", form).length > 0) {
require(['bootstrap-select', 'bootstrap-select-lang'], function () {
+ $.fn.selectpicker.Constructor.BootstrapVersion = '3';
$('.selectpicker', form).selectpicker();
$(form).on("reset", function () {
setTimeout(function () {
@@ -294,6 +295,9 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
var url = Config.upload.fullmode ? Fast.api.cdnurl(data.url) : data.url;
$("#" + input_id).val(url).trigger("change").trigger("validate");
}
+
+ // 触发选择文件自定义事件
+ button.trigger("fa.event.selectedfile", data);
}
});
return false;
@@ -567,7 +571,9 @@ define(['jquery', 'bootstrap', 'upload', 'validator', 'validator-lang'], functio
}
};
// @formatter:on
+ var $disabledElements = form.find(':disabled').removeAttr('disabled');
var dataArr = form.serializeArray(), dataObj = {}, fieldName, fieldValue;
+ $disabledElements.attr('disabled', 'disabled');
$(dataArr).each(function (i, field) {
fieldName = field.name;
fieldValue = field.value;