diff --git a/application/admin/controller/Action.php b/application/admin/controller/Action.php index e492247f..50f7c381 100644 --- a/application/admin/controller/Action.php +++ b/application/admin/controller/Action.php @@ -42,8 +42,8 @@ class Action extends Admin { $model = model('Action'); if(IS_POST){ $data = input('post.'); - $result = $model->save(); - if ($result) { + $result = $model->save($data); + if (false != $result) { action_log('add_action', 'Action', $result, session('user_auth.uid')); return $this->success('添加成功!',url('index')); }else{ diff --git a/application/admin/controller/Ad.php b/application/admin/controller/Ad.php index 945a5b60..04e7970b 100644 --- a/application/admin/controller/Ad.php +++ b/application/admin/controller/Ad.php @@ -43,8 +43,7 @@ class Ad extends Admin { public function add(){ $place = model('AdPlace'); if (IS_POST) { - $data = input('post.'); - $result = $place->save($data); + $result = $place->change(); if (false !== false) { return $this->success("添加成功!"); }else{ @@ -63,14 +62,9 @@ class Ad extends Admin { public function edit($id = null){ $place = model('AdPlace'); if (IS_POST) { - $data = $this->request->post(); - if ($data) { - $result = $place->save($data,array('id'=>$data['id'])); - if ($result) { - return $this->success("修改成功!", url('admin/ad/index')); - }else{ - return $this->error($this->adplace->getError()); - } + $result = $place->change(); + if ($result) { + return $this->success("修改成功!", url('admin/ad/index')); }else{ return $this->error($this->adplace->getError()); } @@ -122,14 +116,9 @@ class Ad extends Admin { public function addad($id){ $ad = model('ad'); if (IS_POST) { - $data = $this->request->post(); - if ($data) { - $result = $ad->save($data); - if ($result) { - return $this->success("添加成功!", url('admin/ad/lists',array('id'=>$data['place_id']))); - }else{ - return $this->error($ad->getError()); - } + $result = $ad->change(); + if ($result) { + return $this->success("添加成功!", url('admin/ad/lists',array('id'=>$data['place_id']))); }else{ return $this->error($ad->getError()); } @@ -148,14 +137,9 @@ class Ad extends Admin { public function editad($id = null){ $ad = model('ad'); if (IS_POST) { - $data = $this->request->post(); - if ($data) { - $result = $ad->save($data,array('id'=>$data['id'])); - if ($result) { - return $this->success("修改成功!", url('admin/ad/lists',array('id'=>$data['place_id']))); - }else{ - return $this->error($ad->getError()); - } + $result = $ad->change(); + if ($result) { + return $this->success("修改成功!", url('admin/ad/lists',array('id'=>$data['place_id']))); }else{ return $this->error($ad->getError()); } diff --git a/application/admin/controller/Addons.php b/application/admin/controller/Addons.php index 915dc7d3..47777b6f 100644 --- a/application/admin/controller/Addons.php +++ b/application/admin/controller/Addons.php @@ -24,28 +24,17 @@ class Addons extends Admin { /** * 插件列表 */ - public function index(){ - $row = $this->addons->getList(); - foreach($row as $key => $value){ - $value['status_text'] = ''; - if($value['uninstall'] == 1){ - $value['uninstall_text'] = '未安装'; - }else{ - $value['uninstall_text'] = '已安装'; - if($value['status'] == 0){ - $value['status_text'] = '禁用'; - }else{ - $value['status_text'] = '启用'; - } - } - $list[] = $value; + public function index($refresh = 0){ + if ($refresh) { + $this->addons->refresh(); } + $list = $this->addons->order('id desc')->paginate(25); // 记录当前列表页的cookie Cookie('__forward__',$_SERVER['REQUEST_URI']); $data = array( 'list' => $list, - //'page' => $page->show() + 'page' => $list->render() ); $this->setMeta("插件管理"); $this->assign($data); diff --git a/application/admin/controller/Attribute.php b/application/admin/controller/Attribute.php index 95b616ae..5dcfaaae 100644 --- a/application/admin/controller/Attribute.php +++ b/application/admin/controller/Attribute.php @@ -75,7 +75,7 @@ class Attribute extends Admin { if ($result) { return $this->success("创建成功!",url('Attribute/index',array('model_id'=>$model_id))); }else{ - return $this->error($this->model->getError(),''); + return $this->error($this->model->getError()); } }else{ if (!$model_id) { diff --git a/application/admin/controller/Content.php b/application/admin/controller/Content.php index ee198fa5..04480f3f 100644 --- a/application/admin/controller/Content.php +++ b/application/admin/controller/Content.php @@ -82,9 +82,9 @@ class Content extends Admin{ if (IS_POST) { $result = $this->model->change(); if ($result) { - return $this->success("添加成功!",url('admin/content/index',array('model_id'=>$this->modelInfo['id']))); + return $this->success("添加成功!", url('admin/content/index',array('model_id'=>$this->modelInfo['id']))); }else{ - return $this->error($this->model->getError(),''); + return $this->error($this->model->getError(), url('admin/content/add',array('model_id'=>$this->modelInfo['id']))); } }else{ $info = array( @@ -109,16 +109,15 @@ class Content extends Admin{ * 内容修改 * @author molong */ - public function edit(){ + public function edit($id){ if (IS_POST) { $result = $this->model->change(); if ($result !== false) { return $this->success("更新成功!",url('admin/content/index',array('model_id'=>$this->modelInfo['id']))); }else{ - return $this->error($this->model->getError(),''); + return $this->error($this->model->getError(), url('admin/content/edit',array('model_id'=>$this->modelInfo['id'],'id'=>$id))); } }else{ - $id = input('id','','trim,intval'); if (!$id) { return $this->error("非法操作!"); } diff --git a/application/admin/view/addons/index.html b/application/admin/view/addons/index.html index 575e0079..1a95b2e8 100644 --- a/application/admin/view/addons/index.html +++ b/application/admin/view/addons/index.html @@ -57,6 +57,7 @@ {/volist} + {$page} diff --git a/application/common.php b/application/common.php index 695bc1e6..7fa6a06d 100644 --- a/application/common.php +++ b/application/common.php @@ -983,26 +983,6 @@ function get_category_child($id){ return array_unique($ids); } -function getContentNav($type, $info){ - $data = array(); - - $map['model_id'] = $info['model_id']; - $map['category_id'] = $info['category_id']; - if ($type == 'prev') { - $map['id'] = array('gt',$info['id']); - $data = db('Document')->where($map)->order('id desc')->find(); - }elseif ($type == 'next') { - $map['id'] = array('lt',$info['id']); - $data = db('Document')->where($map)->order('id asc')->find(); - } - if (!empty($data)) { - $html = '' . $data['title'] . ''; - }else{ - $html = '没有了……'; - } - return $html; -} - function send_email($to, $subject, $message){ $config = array( 'protocol' => 'smtp', @@ -1018,4 +998,56 @@ function send_email($to, $subject, $message){ $email->message($message); return $email->send(); +} + +//php获取中文字符拼音首字母 +function getFirstCharter($s0){ + $fchar = ord($s0{0}); + if($fchar >= ord("A") and $fchar <= ord("z") )return strtoupper($s0{0}); + $s1 = \iconv("UTF-8","gb2312", $s0); + $s2 = \iconv("gb2312","UTF-8", $s1); + if($s2 == $s0){$s = $s1;}else{$s = $s0;} + $asc = ord($s{0}) * 256 + ord($s{1}) - 65536; + if($asc >= -20319 and $asc <= -20284) return "A"; + if($asc >= -20283 and $asc <= -19776) return "B"; + if($asc >= -19775 and $asc <= -19219) return "C"; + if($asc >= -19218 and $asc <= -18711) return "D"; + if($asc >= -18710 and $asc <= -18527) return "E"; + if($asc >= -18526 and $asc <= -18240) return "F"; + if($asc >= -18239 and $asc <= -17923) return "G"; + if($asc >= -17922 and $asc <= -17418) return "H"; + if($asc >= -17417 and $asc <= -16475) return "J"; + if($asc >= -16474 and $asc <= -16213) return "K"; + if($asc >= -16212 and $asc <= -15641) return "L"; + if($asc >= -15640 and $asc <= -15166) return "M"; + if($asc >= -15165 and $asc <= -14923) return "N"; + if($asc >= -14922 and $asc <= -14915) return "O"; + if($asc >= -14914 and $asc <= -14631) return "P"; + if($asc >= -14630 and $asc <= -14150) return "Q"; + if($asc >= -14149 and $asc <= -14091) return "R"; + if($asc >= -14090 and $asc <= -13319) return "S"; + if($asc >= -13318 and $asc <= -12839) return "T"; + if($asc >= -12838 and $asc <= -12557) return "W"; + if($asc >= -12556 and $asc <= -11848) return "X"; + if($asc >= -11847 and $asc <= -11056) return "Y"; + if($asc >= -11055 and $asc <= -10247) return "Z"; + return null; +} + +function PyFirst($zh){ + $ret = ""; + $s1 = \iconv("UTF-8","gb2312", $zh); + $s2 = \iconv("gb2312","UTF-8", $s1); + if($s2 == $zh){$zh = $s1;} + for($i = 0; $i < strlen($zh); $i++){ + $s1 = substr($zh,$i,1); + $p = ord($s1); + if($p > 160){ + $s2 = substr($zh,$i++,2); + $ret .= getFirstCharter($s2); + }else{ + $ret .= $s1; + } + } + return $ret; } \ No newline at end of file diff --git a/application/common/controller/Base.php b/application/common/controller/Base.php index 70849c6e..f093749c 100644 --- a/application/common/controller/Base.php +++ b/application/common/controller/Base.php @@ -79,7 +79,7 @@ class Base extends \think\Controller{ return $ret; } - protected function setSeo($title = null,$keywords = null,$description = null){ + protected function setSeo($title = '', $keywords = '', $description = ''){ $seo = array( 'title' => $title, 'keywords' => $keywords, @@ -87,14 +87,11 @@ class Base extends \think\Controller{ ); //获取还没有经过变量替换的META信息 $meta = model('SeoRule')->getMetaOfCurrentPage($seo); - foreach ($seo as $key => $value) { - if (is_array($value)) { - foreach ($value as $k => $v) { - $meta[$key] = str_replace("[".$k."]", $v . '|', $meta[$key]); - } - }else{ - $meta[$key] = str_replace("[".$key."]", $value . '|', $meta[$key]); + foreach ($seo as $key => $item) { + if (is_array($item)) { + $item = implode(',', $item); } + $meta[$key] = str_replace("[".$key."]", $item . '|', $meta[$key]); } $data = array( diff --git a/application/common/model/Addons.php b/application/common/model/Addons.php index 45a76e51..13c45486 100644 --- a/application/common/model/Addons.php +++ b/application/common/model/Addons.php @@ -19,15 +19,27 @@ class Addons extends \app\common\model\Base { protected $auto = array('status'); protected $insert = array('create_time'); - protected function setStatusAttr(){ + protected function setStatusAttr($value){ return 1; } + protected function setIsinstallAttr($value){ + return 0; + } + + protected function getStatusTextAttr($value, $data){ + return $data['status'] ? "启用" : "禁用"; + } + + protected function getUninstallAttr($value, $data){ + return 0; + } + /** - * 获取插件列表 + * 更新插件列表 * @param string $addon_dir */ - public function getList($addon_dir = ''){ + public function refresh($addon_dir = ''){ if(!$addon_dir){ $addon_dir = SENT_ADDON_PATH; } @@ -36,13 +48,9 @@ class Addons extends \app\common\model\Base { $this->error = '插件目录不可读或者不存在'; return FALSE; } - $addons = array(); $where['name'] = array('in',$dirs); - $list = db('Addons')->where($where)->field(true)->select(); - foreach($list as $addon){ - $addon['uninstall'] = 0; - $addons[$addon['name']] = $addon; - } + $addons = $this->where($where)->select(); + foreach ($dirs as $value) { $value = ucfirst($value); if(!isset($addons[$value])){ @@ -61,9 +69,6 @@ class Addons extends \app\common\model\Base { } } } - int_to_string($addons, array('status'=>array(-1=>'损坏', 0=>'禁用', 1=>'启用', null=>'未安装'))); - $addons = list_sort_by($addons,'uninstall','desc'); - return $addons; } /** diff --git a/application/common/model/Attribute.php b/application/common/model/Attribute.php index d668e220..531a010a 100644 --- a/application/common/model/Attribute.php +++ b/application/common/model/Attribute.php @@ -43,27 +43,24 @@ class Attribute extends Base{ } public function change(){ - $data = input('post.'); + $data = \think\Request::instance()->post(); - if (!empty($data)) { + if ($data['id']) { + $status = $this->validate('attribute.edit')->save($data, array('id'=>$data['id'])); + }else{ + $status = $this->validate('attribute.add')->save($data); + } + + if (false !== $status) { //在数据库内添加字段 $result = $this->checkTableField($data); if (!$result) { $this->error = "字段创建失败!"; return false; } - if ($data['id']) { - $status = $this->save($data, array('id'=>$data['id'])); - }else{ - $status = $this->save($data); - } - - if (false !== $status) { - return $status; - }else{ - $this->error = "添加失败!"; - return false; - } + return $status; + }else{ + return false; } } diff --git a/application/common/model/Document.php b/application/common/model/Document.php index 3cf0dd39..5ff930f5 100644 --- a/application/common/model/Document.php +++ b/application/common/model/Document.php @@ -85,17 +85,15 @@ class Document extends \think\model\Merge{ /* 添加或新增基础内容 */ if(empty($data['id'])){ //新增数据 unset($data['id']); - $id = $this->save($data); //添加基础内容 + $id = $this->validate('document.edit')->save($data); //添加基础内容 if(!$id){ - $this->error = '添加基础内容出错!'; return false; } $data['id'] = $id; } else { //更新数据 - $status = $this->save($data, array('id'=>$data['id'])); //更新基础内容 + $status = $this->validate('document.edit')->save($data, array('id'=>$data['id'])); //更新基础内容 if(false === $status){ - $this->error = '更新基础内容出错!'; return false; } } diff --git a/application/common/validate/Attribute.php b/application/common/validate/Attribute.php new file mode 100644 index 00000000..2cb7f346 --- /dev/null +++ b/application/common/validate/Attribute.php @@ -0,0 +1,38 @@ + +// +---------------------------------------------------------------------- + +namespace app\common\validate; + +/** +* 设置模型 +*/ +class Attribute extends Base{ + + protected $rule = array( + 'name' => 'require|/^[a-zA-Z]\w{0,39}$/', + 'title' => 'require', + 'type' => 'require', + 'length' => 'requireIn:type,textarea,editor|integer', + 'remark' => 'require', + ); + + protected $message = array( + 'length.requireIn' => '字段长度必须!', + 'length.integer' => '字段必须为整形', + 'name.require' => '字段名不能为空!', + 'title.require' => '字段标题不能为空!', + 'type.require' => '类型不能为空!', + 'remark.require' => '描述不能为空!', + ); + + protected $scene = array( + 'add' => 'name,title,type,remark,length', + 'edit' => 'name,title,type,remark,length' + ); +} \ No newline at end of file diff --git a/application/common/validate/Base.php b/application/common/validate/Base.php new file mode 100644 index 00000000..3af8bdcf --- /dev/null +++ b/application/common/validate/Base.php @@ -0,0 +1,32 @@ + +// +---------------------------------------------------------------------- + +namespace app\common\validate; + +/** +* 设置模型 +*/ +class Base extends \think\Validate{ + + + protected function requireIn($value, $rule, $data){ + if (is_string($rule)) { + $rule = explode(',', $rule); + }else{ + return true; + } + $field = array_shift($rule); + $val = $this->getDataValue($data, $field); + if (!in_array($val, $rule) && $value == '') { + return false; + } else { + return true; + } + } +} \ No newline at end of file diff --git a/application/common/validate/Config.php b/application/common/validate/Config.php index 5933a064..152d3df0 100644 --- a/application/common/validate/Config.php +++ b/application/common/validate/Config.php @@ -12,7 +12,7 @@ namespace app\common\validate; /** * 设置模型 */ -class Config extends \think\Validate{ +class Config extends Base{ protected $rule = array( 'name' => 'require|unique', diff --git a/application/common/validate/Document.php b/application/common/validate/Document.php new file mode 100644 index 00000000..788b04d2 --- /dev/null +++ b/application/common/validate/Document.php @@ -0,0 +1,29 @@ + +// +---------------------------------------------------------------------- + +namespace app\common\validate; + +/** +* 设置模型 +*/ +class Document extends Base{ + + protected $rule = array( + 'title' => 'require', + ); + + protected $message = array( + 'title.require' => '字段标题不能为空!', + ); + + protected $scene = array( + 'add' => 'title', + 'edit' => 'title' + ); +} \ No newline at end of file diff --git a/application/common/validate/Member.php b/application/common/validate/Member.php index 1e83efa3..85587a8f 100644 --- a/application/common/validate/Member.php +++ b/application/common/validate/Member.php @@ -12,7 +12,7 @@ namespace app\common\validate; /** * 设置模型 */ -class Member extends \think\Validate{ +class Member extends Base{ protected $rule = array( 'username' => 'require|unique:member|/^[a-zA-Z]\w{0,39}$/', diff --git a/application/common/validate/Model.php b/application/common/validate/Model.php index 05ab08fe..ec9bb246 100644 --- a/application/common/validate/Model.php +++ b/application/common/validate/Model.php @@ -12,7 +12,7 @@ namespace app\common\validate; /** * 设置模型 */ -class Model extends \think\Validate{ +class Model extends Base{ protected $rule = array( 'name' => 'require|unique:model|/^[a-zA-Z]\w{0,39}$/', diff --git a/application/index/controller/Content.php b/application/index/controller/Content.php index 354085aa..f77b7c73 100644 --- a/application/index/controller/Content.php +++ b/application/index/controller/Content.php @@ -96,7 +96,10 @@ class Content extends Fornt{ } $cate = $this->getCategory($id); - $map = array(); + $category = get_category_child($id); + $map = array( + 'category_id' => array('IN', $category) + ); $order = "id desc"; $list = model('Document')->where($map)->order($order)->paginate(15); diff --git a/core/convention.php b/core/convention.php index 87fe69eb..1dcf80dc 100644 --- a/core/convention.php +++ b/core/convention.php @@ -77,8 +77,6 @@ return [ 'url_html_suffix' => 'html', // URL普通方式参数 用于自动生成 'url_common_param' => false, - //url禁止访问的后缀 - 'url_deny_suffix' => 'ico|png|gif|jpg', // URL参数方式 0 按名称成对解析 1 按顺序解析 'url_param_type' => 0, // 是否开启路由 diff --git a/core/extend/com/Sent.php b/core/extend/com/Sent.php index 56d19c44..b7f94155 100644 --- a/core/extend/com/Sent.php +++ b/core/extend/com/Sent.php @@ -139,26 +139,24 @@ class Sent extends Taglib{ $cate = !empty($tag['cate']) ? $tag['cate'] : ''; $model_id = !empty($tag['model']) ? $tag['model'] : ''; - $map = "category_id = ".$cate." and model_id=".$model_id." and id < ".$id; - $parse = 'where("' . $map . '")->order(\'id asc\')->find();'; + $parse .= '$map = "category_id=" . ' . $cate . ' . " and model_id=" . ' . $model_id . ' . " and id>".' . $id . ';'; + $parse .= '$prev = db(\'Document\')->where($map)->order(\'id asc\')->find();if(!empty($prev)){ ?>'; $parse .= $content; - $parse .= '}?>'; + $parse .= ''; return $parse; } public function tagnext($tag, $content){ - $id = !empty($tag['id']) ? $tag['id'] : ''; + $id = !empty($tag['id']) ? ($tag['id']) : ''; $cate = !empty($tag['cate']) ? $tag['cate'] : ''; - $model_id = !empty($tag['model']) ? $tag['model'] : ''; - - $map = "category_id = ".$cate." and model_id=".$model_id." and id < ".$id; + $model_id = !empty($tag['model']) ? $tag['model'] : ''; $parse = 'where("' . $map . '")->order(\'id asc\')->find();'; + $parse .= '$map = "category_id=" . ' . $cate . ' . " and model_id=" . ' . $model_id . ' . " and id<".' . $id . ';'; + $parse .= '$next = db(\'Document\')->where($map)->order(\'id desc\')->find();if(!empty($next)){ ?>'; $parse .= $content; - $parse .= '}?>'; + $parse .= ''; return $parse; } } \ No newline at end of file diff --git a/core/library/think/App.php b/core/library/think/App.php index 4b26992f..24163372 100644 --- a/core/library/think/App.php +++ b/core/library/think/App.php @@ -77,6 +77,10 @@ class App { is_null($request) && $request = Request::instance(); + if ('ico' == $request->ext()) { + throw new HttpException(404, 'ico file not exists'); + } + $config = self::initCommon(); try { @@ -461,11 +465,6 @@ class App */ public static function routeCheck($request, array $config) { - // 检测URL禁用后缀 - if ($config['url_deny_suffix'] && preg_match('/\.(' . $config['url_deny_suffix'] . ')$/i', $request->pathinfo())) { - throw new Exception('url suffix deny:' . $request->ext()); - } - $path = $request->path(); $depr = $config['pathinfo_depr']; $result = false; diff --git a/core/library/think/File.php b/core/library/think/File.php index d9d03325..54c2b138 100644 --- a/core/library/think/File.php +++ b/core/library/think/File.php @@ -25,6 +25,8 @@ class File extends SplFileObject protected $filename; // 文件上传命名规则 protected $rule = 'date'; + // 文件上传验证规则 + protected $validate = []; // 单元测试 protected $isTest; // 上传文件信息 @@ -108,6 +110,17 @@ class File extends SplFileObject return $this; } + /** + * 设置上传文件的验证规则 + * @param array $rule 验证规则 + * @return $this + */ + public function validate($rule = []) + { + $this->validate = $rule; + return $this; + } + /** * 检测是否合法的上传文件 * @return bool @@ -120,6 +133,106 @@ class File extends SplFileObject return is_uploaded_file($this->filename); } + /** + * 检测上传文件 + * @param array $rule 验证规则 + * @return bool + */ + public function check($rule = []) + { + $rule = $rule ?: $this->validate; + + /* 检查文件大小 */ + if (isset($rule['size']) && !$this->checkSize($rule['size'])) { + $this->error = '上传文件大小不符!'; + return false; + } + + /* 检查文件Mime类型 */ + if (isset($rule['type']) && !$this->checkMime($rule['type'])) { + $this->error = '上传文件MIME类型不允许!'; + return false; + } + + /* 检查文件后缀 */ + if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) { + $this->error = '上传文件后缀不允许'; + return false; + } + + /* 检查图像文件 */ + if (!$this->checkImg()) { + $this->error = '非法图像文件!'; + return false; + } + + return true; + } + + /** + * 检测上传文件后缀 + * @param array|string $ext 允许后缀 + * @return bool + */ + public function checkExt($ext) + { + if (is_string($ext)) { + $ext = explode(',', $ext); + } + $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); + if (!in_array($extension, $ext)) { + return false; + } + + return true; + } + + /** + * 检测图像文件 + * @return bool + */ + public function checkImg() + { + $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); + /* 对图像文件进行严格检测 */ + if (in_array($extension, array('gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'))) { + $imginfo = getimagesize($this->filename); + if (empty($imginfo) || ('gif' == $extension && empty($imginfo['bits']))) { + return false; + } + } + return true; + } + + /** + * 检测上传文件大小 + * @param integer $size 最大大小 + * @return bool + */ + public function checkSize($size) + { + if ($this->getSize() > $size) { + return false; + } + return true; + } + + /** + * 检测上传文件类型 + * @param array|string $mime 允许类型 + * @return bool + */ + public function checkMime($mime) + { + if (is_string($mime)) { + $mime = explode(',', $mime); + } + if (!in_array(strtolower($this->getMime()), $mime)) { + return false; + } + return true; + } + /** * 移动文件 * @param string $path 保存路径 @@ -135,6 +248,10 @@ class File extends SplFileObject return false; } + // 验证上传 + if (!$this->check()) { + return false; + } $path = rtrim($path, DS) . DS; // 文件保存命名规则 $savename = $this->getSaveName($savename); @@ -189,12 +306,12 @@ class File extends SplFileObject $savename = call_user_func($this->rule); } } - if (!strpos($savename, '.')) { - $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION); - } } elseif ('' === $savename) { $savename = $this->getInfo('name'); } + if (!strpos($savename, '.')) { + $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION); + } return $savename; } diff --git a/core/library/think/Request.php b/core/library/think/Request.php index 41b079c4..798575d9 100644 --- a/core/library/think/Request.php +++ b/core/library/think/Request.php @@ -623,6 +623,12 @@ class Request // 当前请求参数和URL地址中的参数合并 $this->param = array_merge($this->route(false), $this->get(false), $vars); } + if (true === $name) { + // 获取包含文件上传信息的数组 + $file = $this->file(); + $data = array_merge($this->param, $file); + return $this->input($data, '', $default, $filter); + } return $this->input($this->param, $name, $default, $filter); } @@ -934,6 +940,9 @@ class Request return $default; } } + if (is_object($data)) { + return $data; + } } // 解析过滤器 @@ -986,7 +995,7 @@ class Request if (is_callable($filter)) { // 调用函数或者方法过滤 $value = call_user_func($filter, $value); - } else { + } elseif (is_scalar($value)) { if (strpos($filter, '/')) { // 正则过滤 if (!preg_match($filter, $value)) { diff --git a/core/library/think/Route.php b/core/library/think/Route.php index 55fde12c..ad3b603b 100644 --- a/core/library/think/Route.php +++ b/core/library/think/Route.php @@ -745,7 +745,7 @@ class Route continue; } if ($group) { - $rule = $group . '/' . ltrim($rule, '/'); + $rule = $group . ($rule ? '/' . ltrim($rule, '/') : ''); } $result = self::checkRule($rule, $route, $url, $pattern, $option); if (false !== $result) { @@ -916,7 +916,8 @@ class Route // 请求类型检测 if ((isset($option['method']) && false === stripos($option['method'], $request->method())) || (isset($option['ext']) && false === stripos($option['ext'], $request->ext())) // 伪静态后缀检测 - || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测 + || (isset($option['deny_ext']) && false !== stripos($option['deny_ext'], $request->ext())) + || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测 || (!empty($option['https']) && !$request->isSsl()) // https检测 || (!empty($option['before_behavior']) && false === Hook::exec($option['before_behavior'], '', $url)) // 行为检测 || (!empty($option['callback']) && is_callable($option['callback']) && false === call_user_func($option['callback'])) // 自定义检测 diff --git a/core/library/think/Validate.php b/core/library/think/Validate.php index 552494d0..1c43f80c 100644 --- a/core/library/think/Validate.php +++ b/core/library/think/Validate.php @@ -11,7 +11,6 @@ namespace think; -use think\Exception; use think\Request; class Validate @@ -35,51 +34,53 @@ class Validate // 验证规则默认提示信息 protected static $typeMsg = [ - 'require' => ':attribute不能为空', - 'number' => ':attribute必须是数字', - 'float' => ':attribute必须是浮点数', - 'boolean' => ':attribute必须是布尔值', - 'email' => ':attribute格式不符', - 'array' => ':attribute必须是数组', - 'accepted' => ':attribute必须是yes、on或者1', - 'date' => ':attribute格式不符合', - 'file' => ':attribute不是有效的上传文件', - 'alpha' => ':attribute只能是字母', - 'alphaNum' => ':attribute只能是字母和数字', - 'alphaDash' => ':attribute只能是字母、数字和下划线_及破折号-', - 'activeUrl' => ':attribute不是有效的域名或者IP', - 'chs' => ':attribute只能是汉字', - 'chsAlpha' => ':attribute只能是汉字、字母', - 'chsAlphaNum'=> ':attribute只能是汉字、字母和数字', - 'chsDash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', - 'url' => ':attribute不是有效的URL地址', - 'ip' => ':attribute不是有效的IP地址', - 'dateFormat' => ':attribute必须使用日期格式 :rule', - 'in' => ':attribute必须在 :rule 范围内', - 'notIn' => ':attribute不能在 :rule 范围内', - 'between' => ':attribute只能在 :1 - :2 之间', - 'notBetween' => ':attribute不能在 :1 - :2 之间', - 'length' => ':attribute长度不符合要求 :rule', - 'max' => ':attribute长度不能超过 :rule', - 'min' => ':attribute长度不能小于 :rule', - 'after' => ':attribute日期不能小于 :rule', - 'before' => ':attribute日期不能超过 :rule', - 'expire' => '不在有效期内 :rule', - 'allowIp' => '不允许的IP访问', - 'denyIp' => '禁止的IP访问', - 'confirm' => ':attribute和字段 :rule 不一致', - 'egt' => ':attribute必须大于等于 :rule', - 'gt' => ':attribute必须大于 :rule', - 'elt' => ':attribute必须小于等于 :rule', - 'lt' => ':attribute必须小于 :rule', - 'eq' => ':attribute必须等于 :rule', - 'unique' => ':attribute已存在', - 'regex' => ':attribute不符合指定规则', - 'method' => '无效的请求类型', - 'token' => '令牌数据无效', - 'fileSize' => '上传文件大小不符', - 'fileExt' => '上传文件后缀不符', - 'fileMime' => '上传文件类型不符', + 'require' => ':attribute不能为空', + 'number' => ':attribute必须是数字', + 'float' => ':attribute必须是浮点数', + 'boolean' => ':attribute必须是布尔值', + 'email' => ':attribute格式不符', + 'array' => ':attribute必须是数组', + 'accepted' => ':attribute必须是yes、on或者1', + 'date' => ':attribute格式不符合', + 'file' => ':attribute不是有效的上传文件', + 'image' => ':attribute不是有效的图像文件', + 'alpha' => ':attribute只能是字母', + 'alphaNum' => ':attribute只能是字母和数字', + 'alphaDash' => ':attribute只能是字母、数字和下划线_及破折号-', + 'activeUrl' => ':attribute不是有效的域名或者IP', + 'chs' => ':attribute只能是汉字', + 'chsAlpha' => ':attribute只能是汉字、字母', + 'chsAlphaNum' => ':attribute只能是汉字、字母和数字', + 'chsDash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', + 'url' => ':attribute不是有效的URL地址', + 'ip' => ':attribute不是有效的IP地址', + 'dateFormat' => ':attribute必须使用日期格式 :rule', + 'in' => ':attribute必须在 :rule 范围内', + 'notIn' => ':attribute不能在 :rule 范围内', + 'between' => ':attribute只能在 :1 - :2 之间', + 'notBetween' => ':attribute不能在 :1 - :2 之间', + 'length' => ':attribute长度不符合要求 :rule', + 'max' => ':attribute长度不能超过 :rule', + 'min' => ':attribute长度不能小于 :rule', + 'after' => ':attribute日期不能小于 :rule', + 'before' => ':attribute日期不能超过 :rule', + 'expire' => '不在有效期内 :rule', + 'allowIp' => '不允许的IP访问', + 'denyIp' => '禁止的IP访问', + 'confirm' => ':attribute和字段 :rule 不一致', + 'egt' => ':attribute必须大于等于 :rule', + 'gt' => ':attribute必须大于 :rule', + 'elt' => ':attribute必须小于等于 :rule', + 'lt' => ':attribute必须小于 :rule', + 'eq' => ':attribute必须等于 :rule', + 'unique' => ':attribute已存在', + 'regex' => ':attribute不符合指定规则', + 'method' => '无效的请求类型', + 'token' => '令牌数据无效', + 'fileSize' => '上传文件大小不符', + 'fileExt' => '上传文件后缀不符', + 'fileMime' => '上传文件类型不符', + ]; // 当前验证场景 @@ -386,33 +387,6 @@ class Validate return true !== $result ? $result : true; } - /** - * 验证表单令牌(需要配置令牌生成行为) - * @access protected - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @return bool - */ - protected function token($value, $rule, $data) - { - if (!isset($data[$rule]) || !isset($_SESSION[$rule])) { - // 令牌数据无效 - return false; - } - - // 令牌验证 - list($key, $value) = explode('_', $data[$rule]); - if (isset($_SESSION[$rule][$key]) && $value && $_SESSION[$rule][$key] === $value) { - // 防止重复提交 - unset($_SESSION[$rule][$key]); // 验证完成销毁session - return true; - } - // 开启TOKEN重置 - unset($_SESSION[$rule][$key]); - return false; - } - /** * 验证是否和某个字段的值一致 * @access protected @@ -570,8 +544,10 @@ class Validate $result = is_array($value); break; case 'file': - $file = Request::instance()->file($value); - $result = !empty($file); + $result = $value instanceof \think\File; + break; + case 'image': + $result = $value instanceof \think\File && in_array(exif_imagetype($value->getRealPath()), [1, 2, 3, 6]); break; default: if (isset(self::$type[$rule])) { @@ -615,14 +591,13 @@ class Validate /** * 验证上传文件后缀 * @access protected - * @param mixed $value 字段值 + * @param mixed $file 上传文件 * @param mixed $rule 验证规则 * @return bool */ - protected function fileExt($value, $rule) + protected function fileExt($file, $rule) { - $file = Request::instance()->file($value); - if (empty($file)) { + if (!($file instanceof \think\File)) { return false; } if (is_string($rule)) { @@ -630,27 +605,26 @@ class Validate } if (is_array($file)) { foreach ($file as $item) { - if (!in_array(strtolower($item->getExtension()), $rule)) { + if (!$item->checkExt($rule)) { return false; } } return true; } else { - return in_array(strtolower($file->getExtension()), $rule); + return $file->checkExt($rule); } } /** * 验证上传文件类型 * @access protected - * @param mixed $value 字段值 + * @param mixed $file 上传文件 * @param mixed $rule 验证规则 * @return bool */ - protected function fileMime($value, $rule) + protected function fileMime($file, $rule) { - $file = Request::instance()->file($value); - if (empty($file)) { + if (!($file instanceof \think\File)) { return false; } if (is_string($rule)) { @@ -658,44 +632,67 @@ class Validate } if (is_array($file)) { foreach ($file as $item) { - if (!in_array(strtolower($item->getMime()), $rule)) { + if (!$item->checkMime($rule)) { return false; } } return true; } else { - return in_array(strtolower($file->getMime()), $rule); + return $file->checkMime($rule); } } /** * 验证上传文件大小 * @access protected - * @param mixed $value 字段值 + * @param mixed $file 上传文件 * @param mixed $rule 验证规则 * @return bool */ - protected function fileSize($value, $rule) + protected function fileSize($file, $rule) { - $file = Request::instance()->file($value); - if (empty($file)) { + if (!($file instanceof \think\File)) { return false; } - if (is_string($rule)) { - $rule = explode(',', $rule); - } if (is_array($file)) { foreach ($file as $item) { - if ($item->getSize() > $rule) { + if (!$item->checkSize($rule)) { return false; } } return true; } else { - return $file->getSize() <= $rule; + return $file->checkSize($rule); } } + /** + * 验证图片的宽高及类型 + * @access protected + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function image($file, $rule) + { + if (!($file instanceof \think\File)) { + return false; + } + $rule = explode(',', $rule); + list($width, $height, $type) = getimagesize($file->getRealPath()); + if (isset($rule[2])) { + $imageType = strtolower($rule[2]); + if ('jpeg' == $imageType) { + $imageType = 'jpg'; + } + if (image_type_to_extension($type) != $imageType) { + return false; + } + } + list($w, $h) = $rule; + return $w == $width && $h == $height; + } + /** * 验证请求类型 * @access protected @@ -915,7 +912,14 @@ class Validate */ protected function length($value, $rule) { - $length = strlen((string) $value); // 当前数据长度 + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof \think\File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } + if (strpos($rule, ',')) { // 长度区间 list($min, $max) = explode(',', $rule); @@ -935,7 +939,13 @@ class Validate */ protected function max($value, $rule) { - $length = strlen((string) $value); + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof \think\File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } return $length <= $rule; } @@ -948,7 +958,13 @@ class Validate */ protected function min($value, $rule) { - $length = strlen((string) $value); + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof \think\File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } return $length >= $rule; } diff --git a/core/library/think/view/driver/Php.php b/core/library/think/view/driver/Php.php index 13820baa..a7e72e9e 100644 --- a/core/library/think/view/driver/Php.php +++ b/core/library/think/view/driver/Php.php @@ -67,8 +67,14 @@ class Php } // 记录视图信息 App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info'); - extract($data, EXTR_OVERWRITE); - include $template; + if (isset($data['template'])) { + $__template__ = $template; + extract($data, EXTR_OVERWRITE); + include $__template__; + } else { + extract($data, EXTR_OVERWRITE); + include $template; + } } /** @@ -80,8 +86,14 @@ class Php */ public function display($content, $data = []) { - extract($data, EXTR_OVERWRITE); - eval('?>' . $content); + if (isset($data['content'])) { + $__content__ = $content; + extract($data, EXTR_OVERWRITE); + eval('?>' . $__content__); + } else { + extract($data, EXTR_OVERWRITE); + eval('?>' . $content); + } } /**