diff --git a/.htaccess b/.htaccess
new file mode 100644
index 00000000..cbc78689
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,8 @@
+
+ Options +FollowSymlinks -Multiviews
+ RewriteEngine On
+
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
+
diff --git a/README.md b/README.md
index 4ff8281c..0ede4302 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,40 @@
-# Cloudreve
-A project helps you build your own cloud in minutes.
+
+
+Cloudreve - Make the cloud easy for everyone
+=========================
+[]()
+[](https://opensource.org/licenses/GPL-3.0/)
+
+基于ThinkPHP构建的网盘系统,能够助您以较低成本快速搭建起公私兼备的网盘。
+
+
+
+目前已经实现的特性:
+
+* 快速对接多家云存储,支持七牛、又拍云、阿里云OSS、AWS S3,当然,还有本地存储
+* 可限制单文件最大大小、MMMEType、文件后缀、用户可用容量
+* 图片、音频、视频、文本、Markdown、Ofiice文档 在线预览
+* 移动端全站响应式布局
+* 文件、目录分享系统,可创建私有分享或公开分享链接
+* 用户个人主页,可查看用户所有分享
+* 多用户系统、用户组支持
+* 初步完善的后台,方便管理
+* 拖拽上传、分片上传、断点续传、下载限速(*实验性功能)
+* 多上传策略,可为不同用户组分配不同策略
+* 用户组基础权限设置
+* WebDAV协议支持
+
+安装需求
+------------
+* LNMP/LAMP With PHP5.6+
+* curl、fileinfo、gd扩展
+* Composer
+
+简要安装说明
+------------
+
+Coming Soon...
+
+许可证
+------------
+GPLV3
\ No newline at end of file
diff --git a/application/.htaccess b/application/.htaccess
new file mode 100644
index 00000000..3418e55a
--- /dev/null
+++ b/application/.htaccess
@@ -0,0 +1 @@
+deny from all
\ No newline at end of file
diff --git a/application/command.php b/application/command.php
new file mode 100644
index 00000000..826bb2b2
--- /dev/null
+++ b/application/command.php
@@ -0,0 +1,12 @@
+
+// +----------------------------------------------------------------------
+
+return [];
diff --git a/application/common.php b/application/common.php
new file mode 100644
index 00000000..fb70d169
--- /dev/null
+++ b/application/common.php
@@ -0,0 +1,41 @@
+
+// +----------------------------------------------------------------------
+
+// 应用公共文件
+function array_column_fix($array,$key){
+ if(count($array) == count($array,1)){
+ return array(0 =>$array[$key]);
+ }else{
+ return array_column($array,$key);
+ }
+}
+function getAllowedExt($ext){
+ $returnValue = "";
+ foreach (json_decode($ext,true) as $key => $value) {
+ $returnValue .= $value["ext"].",";
+ }
+ return rtrim($returnValue, ",");
+}
+function getDirName($name){
+ $explode = explode("/", $name);
+ return end($explode);
+}
+function getSize($bit,$array=false){
+ $type = array('Bytes','KB','MB','GB','TB');
+ $box = array('1','1024','1048576','1073741824','TB');
+ for($i = 0; $bit >= 1024; $i++) {
+ $bit/=1024;
+ }
+ if($array){
+ return [(floor($bit*100)/100),$box[$i]];
+ }
+ return (floor($bit*100)/100).$type[$i];
+}
\ No newline at end of file
diff --git a/application/config.php b/application/config.php
new file mode 100644
index 00000000..a7d2ce8a
--- /dev/null
+++ b/application/config.php
@@ -0,0 +1,270 @@
+
+// +----------------------------------------------------------------------
+
+return [
+ // +----------------------------------------------------------------------
+ // | 应用设置
+ // +----------------------------------------------------------------------
+ //密码加盐
+ 'salt' => 'sdshare',
+ // 应用命名空间
+ 'app_namespace' => 'app',
+ // 应用调试模式
+ 'app_debug' => false,
+ // 应用Trace
+ 'app_trace' => false,
+ // 应用模式状态
+ 'app_status' => '',
+ // 是否支持多模块
+ 'app_multi_module' => true,
+ // 入口自动绑定模块
+ 'auto_bind_module' => false,
+ // 注册的根命名空间
+ 'root_namespace' => [],
+ // 扩展函数文件
+ 'extra_file_list' => [THINK_PATH . 'helper' . EXT],
+ // 默认输出类型
+ 'default_return_type' => 'html',
+ // 默认AJAX 数据返回格式,可选json xml ...
+ 'default_ajax_return' => 'json',
+ // 默认JSONP格式返回的处理方法
+ 'default_jsonp_handler' => 'jsonpReturn',
+ // 默认JSONP处理方法
+ 'var_jsonp_handler' => 'callback',
+ // 默认时区
+ 'default_timezone' => 'PRC',
+ // 是否开启多语言
+ 'lang_switch_on' => false,
+ // 默认全局过滤方法 用逗号分隔多个
+ 'default_filter' => '',
+ // 默认语言
+ 'default_lang' => 'zh-cn',
+ // 应用类库后缀
+ 'class_suffix' => false,
+ // 控制器类后缀
+ 'controller_suffix' => false,
+
+ // +----------------------------------------------------------------------
+ // | 模块设置
+ // +----------------------------------------------------------------------
+
+ // 默认模块名
+ 'default_module' => 'index',
+ // 禁止访问模块
+ 'deny_module_list' => ['common'],
+ // 默认控制器名
+ 'default_controller' => 'Index',
+ // 默认操作名
+ 'default_action' => 'index',
+ // 默认验证器
+ 'default_validate' => '',
+ // 默认的空控制器名
+ 'empty_controller' => 'Error',
+ // 操作方法后缀
+ 'action_suffix' => '',
+ // 自动搜索控制器
+ 'controller_auto_search' => false,
+
+ // +----------------------------------------------------------------------
+ // | URL设置
+ // +----------------------------------------------------------------------
+
+ // PATHINFO变量名 用于兼容模式
+ 'var_pathinfo' => 's',
+'url_convert' => false,
+ // 兼容PATH_INFO获取
+ 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
+ // pathinfo分隔符
+ 'pathinfo_depr' => '/',
+ // URL伪静态后缀
+ 'url_html_suffix' => '',
+ // URL普通方式参数 用于自动生成
+ 'url_common_param' => false,
+ // URL参数方式 0 按名称成对解析 1 按顺序解析
+ 'url_param_type' => 0,
+ // 是否开启路由
+ 'url_route_on' => true,
+ // 路由使用完整匹配
+ 'route_complete_match' => false,
+ // 路由配置文件(支持配置多个)
+ 'route_config_file' => ['route'],
+ // 是否强制使用路由
+ 'url_route_must' => false,
+ // 域名部署
+ 'url_domain_deploy' => false,
+ // 域名根,如thinkphp.cn
+ 'url_domain_root' => '',
+ // 是否自动转换URL中的控制器和操作名
+ 'url_convert' => false,
+ // 默认的访问控制器层
+ 'url_controller_layer' => 'controller',
+ // 表单请求类型伪装变量
+ 'var_method' => '_method',
+ // 表单ajax伪装变量
+ 'var_ajax' => '_ajax',
+ // 表单pjax伪装变量
+ 'var_pjax' => '_pjax',
+ // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
+ 'request_cache' => false,
+ // 请求缓存有效期
+ 'request_cache_expire' => null,
+ // 全局请求缓存排除规则
+ 'request_cache_except' => [],
+
+ // +----------------------------------------------------------------------
+ // | 模板设置
+ // +----------------------------------------------------------------------
+
+ 'template' => [
+ // 模板引擎类型 支持 php think 支持扩展
+ 'type' => 'Think',
+ // 模板路径
+ 'view_path' => '',
+ // 模板后缀
+ 'view_suffix' => 'html',
+ // 模板文件名分隔符
+ 'view_depr' => DS,
+ // 模板引擎普通标签开始标记
+ 'tpl_begin' => '{',
+ // 模板引擎普通标签结束标记
+ 'tpl_end' => '}',
+ // 标签库标签开始标记
+ 'taglib_begin' => '{',
+ // 标签库标签结束标记
+ 'taglib_end' => '}',
+ ],
+
+ // 视图输出字符串内容替换
+ 'view_replace_str' => [],
+ // 默认跳转页面对应的模板文件
+ 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
+ 'dispatch_error_tmpl' => "application/index/view/error.html",
+
+ // +----------------------------------------------------------------------
+ // | 异常及错误设置
+ // +----------------------------------------------------------------------
+
+ // 异常页面的模板文件
+ 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',
+
+ // 错误显示信息,非调试模式有效
+ 'error_message' => '页面错误!请稍后再试~',
+ // 显示错误信息
+ 'show_error_msg' => false,
+ // 异常处理handle类 留空使用 \think\exception\Handle
+ 'exception_handle' => '',
+
+ // +----------------------------------------------------------------------
+ // | 日志设置
+ // +----------------------------------------------------------------------
+
+ 'log' => [
+ // 日志记录方式,内置 file socket 支持扩展
+ 'type' => 'File',
+ // 日志保存目录
+ 'path' => LOG_PATH,
+ // 日志记录级别
+ 'level' => ["error"],
+ ],
+
+ // +----------------------------------------------------------------------
+ // | Trace设置 开启 app_trace 后 有效
+ // +----------------------------------------------------------------------
+ 'trace' => [
+ // 内置Html Console 支持扩展
+ 'type' => 'Html',
+ ],
+
+ // +----------------------------------------------------------------------
+ // | 缓存设置
+ // +----------------------------------------------------------------------
+
+ 'cache' => [
+ // 驱动方式
+ 'type' => 'File',
+ // 缓存保存目录
+ 'path' => CACHE_PATH,
+ // 缓存前缀
+ 'prefix' => '',
+ // 缓存有效期 0表示永久缓存
+ 'expire' => 0,
+ ],
+
+ // +----------------------------------------------------------------------
+ // | 会话设置
+ // +----------------------------------------------------------------------
+
+ 'session' => [
+ 'id' => '',
+ // SESSION_ID的提交变量,解决flash上传跨域
+ 'var_session_id' => '',
+ // SESSION 前缀
+ 'prefix' => 'sd',
+ // 驱动方式 支持redis memcache memcached
+ 'type' => '',
+ // 是否自动开启 SESSION
+ 'auto_start' => true,
+ ],
+
+ // +----------------------------------------------------------------------
+ // | Cookie设置
+ // +----------------------------------------------------------------------
+ 'cookie' => [
+ // cookie 名称前缀
+ 'prefix' => '',
+ // cookie 保存时间
+ 'expire' => 0,
+ // cookie 保存路径
+ 'path' => '/',
+ // cookie 有效域名
+ 'domain' => '',
+ // cookie 启用安全传输
+ 'secure' => false,
+ // httponly设置
+ 'httponly' => '',
+ // 是否使用 setcookie
+ 'setcookie' => true,
+ ],
+
+ //分页配置
+ 'paginate' => [
+ 'type' => 'bootstrap',
+ 'var_page' => 'page',
+ 'list_rows' => 15,
+ ],
+ // +----------------------------------------------------------------------
+ // | 验证码设置
+ // +----------------------------------------------------------------------
+ 'captcha'=>[
+ 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
+ // 验证码字符集合
+ 'expire' => 1800,
+ // 验证码过期时间(s)
+ 'useZh' => false,
+ // 使用背景图片
+ 'fontSize' => 25,
+ // 验证码字体大小(px)
+ 'useCurve' => true,
+ // 是否画混淆曲线
+ 'useNoise' => true,
+ // 是否添加杂点
+ 'imageH' => 0,
+ // 验证码图片高度
+ 'imageW' => 0,
+ // 验证码图片宽度
+ 'length' => 4,
+ // 验证码位数
+ 'fontttf' => '',
+ // 验证码字体,不设置随机获取
+ 'bg' => [243, 251, 254],
+ // 背景颜色
+ 'reset' => true],
+];
diff --git a/application/database.lock b/application/database.lock
new file mode 100644
index 00000000..e69de29b
diff --git a/application/database.php b/application/database.php
new file mode 100644
index 00000000..192c8c30
--- /dev/null
+++ b/application/database.php
@@ -0,0 +1,53 @@
+
+// +----------------------------------------------------------------------
+
+return [
+ // 数据库类型
+ 'type' => 'mysql',
+ // 服务器地址
+ 'hostname' => '127.0.0.1',
+ // 数据库名
+ 'database' => 'lite',
+ // 用户名
+ 'username' => 'root',
+ // 密码
+ 'password' => 'root',
+ // 端口
+ 'hostport' => '3306',
+ // 连接dsn
+ 'dsn' => '',
+ // 数据库连接参数
+ 'params' => [],
+ // 数据库编码默认采用utf8
+ 'charset' => 'utf8',
+ // 数据库表前缀
+ 'prefix' => 'sd_',
+ // 数据库调试模式
+ 'debug' => true,
+ // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+ 'deploy' => 0,
+ // 数据库读写是否分离 主从式有效
+ 'rw_separate' => false,
+ // 读写分离后 主服务器数量
+ 'master_num' => 1,
+ // 指定从服务器序号
+ 'slave_no' => '',
+ // 是否严格检查字段是否存在
+ 'fields_strict' => true,
+ // 数据集返回类型
+ 'resultset_type' => 'array',
+ // 自动写入时间戳字段
+ 'auto_timestamp' => false,
+ // 时间字段取出后的默认时间格式
+ 'datetime_format' => 'Y-m-d H:i:s',
+ // 是否需要进行SQL性能分析
+ 'sql_explain' => false,
+];
diff --git a/application/database_sample.php b/application/database_sample.php
new file mode 100644
index 00000000..47841bd6
--- /dev/null
+++ b/application/database_sample.php
@@ -0,0 +1,53 @@
+
+// +----------------------------------------------------------------------
+
+return [
+ // 数据库类型
+ 'type' => 'mysql',
+ // 服务器地址
+ 'hostname' => '127.0.0.1',
+ // 数据库名
+ 'database' => 'tp',
+ // 用户名
+ 'username' => 'root',
+ // 密码
+ 'password' => 'root',
+ // 端口
+ 'hostport' => '3306',
+ // 连接dsn
+ 'dsn' => '',
+ // 数据库连接参数
+ 'params' => [],
+ // 数据库编码默认采用utf8
+ 'charset' => 'utf8',
+ // 数据库表前缀
+ 'prefix' => 'sd_',
+ // 数据库调试模式
+ 'debug' => true,
+ // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+ 'deploy' => 0,
+ // 数据库读写是否分离 主从式有效
+ 'rw_separate' => false,
+ // 读写分离后 主服务器数量
+ 'master_num' => 1,
+ // 指定从服务器序号
+ 'slave_no' => '',
+ // 是否严格检查字段是否存在
+ 'fields_strict' => true,
+ // 数据集返回类型
+ 'resultset_type' => 'array',
+ // 自动写入时间戳字段
+ 'auto_timestamp' => false,
+ // 时间字段取出后的默认时间格式
+ 'datetime_format' => 'Y-m-d H:i:s',
+ // 是否需要进行SQL性能分析
+ 'sql_explain' => false,
+];
diff --git a/application/index/autoload.php b/application/index/autoload.php
new file mode 100644
index 00000000..4379b91d
--- /dev/null
+++ b/application/index/autoload.php
@@ -0,0 +1,14 @@
+= 1024; $i++) {
+ $bit/=1024;
+ }
+ if($array){
+ return [(floor($bit*100)/100),$box[$i]];
+ }
+ return (floor($bit*100)/100).$type[$i];
+}
+
+function isPreview($fileName){
+ $allowedSuffix=["jpg","jpeg","gif","bmp","png","svg","mp4","mp3","ogg"];
+ $suffix = explode(".",$fileName);
+ if(in_array(end($suffix),$allowedSuffix)){
+ return "yes";
+ }
+ return "no";
+}
+function getDay($sec){
+ return floor($sec/86400);
+}
+?>
\ No newline at end of file
diff --git a/application/index/controller/Admin.php b/application/index/controller/Admin.php
new file mode 100644
index 00000000..00bceabe
--- /dev/null
+++ b/application/index/controller/Admin.php
@@ -0,0 +1,448 @@
+siteOptions = Option::getValues(["basic","admin"]);
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ if(!$this->userObj->loginStatus){
+ $this->redirect(url('/Login','',''));
+ exit();
+ }
+ if($this->userObj->groupData["id"] != 1){
+ $this->error('你无权访问此页面',403,$this->siteOptions);
+ }
+ $this->adminObj = new AdminHandler($this->siteOptions);
+ }
+
+ public function index(){
+ return view('admin_index', [
+ 'options' => $this->siteOptions,
+ 'statics' => $this->adminObj->getStatics(),
+ ]);
+ }
+
+ public function Setting(){
+ return view('basic_setting', [
+ 'options' => $this->siteOptions,
+ ]);
+ }
+
+ public function Config(){
+ $configType=input("?param.type") ? input("param.type") : "common";
+ $configFile = $this->adminObj->getConfigFile($configType);
+ return view('config_file', [
+ 'options' => $this->siteOptions,
+ 'type' => $configType,
+ 'content' => $configFile[0],
+ 'path' => $configFile[1],
+ ]);
+ }
+
+ public function SaveConfigFile(){
+ return $this->adminObj->saveConfigFile(input('post.'));
+ }
+
+ public function SettingReg(){
+ return view('reg_setting', [
+ 'options' => $this->siteOptions,
+ 'optionsForSet' => Option::getValues(["login","register"]),
+ 'groups' => $this->adminObj->getAvaliableGroup(),
+ ]);
+ }
+
+ public function Theme(){
+ $fileName=input("?param.name") ? input("param.name") : "error";
+ $dir = ROOT_PATH."application/index/view/";
+ if(!function_exists("scandir")){
+ return "scandir被禁用";
+ }
+ $fileList=[];
+ $fileList=$fileList+scandir($dir);
+ $pathList=["/"=>$fileList];
+ foreach (["admin","explore","file","home","index","member","profile","share"] as $key => $value) {
+ $childPath = scandir($dir.$value."/");
+ $fileList=array_merge($fileList,$childPath);
+ $pathList = array_merge($pathList,[$value => $childPath]);
+ }
+ foreach ($fileList as $key => $value) {
+ if(substr_compare($value, ".html", -strlen(".html")) != 0){
+ unset($fileList[$key]);
+ }
+ }
+ foreach($pathList as $key=>$val){
+ if(in_array($fileName.".html",$val)){
+ $parentPath = $key;
+ break;
+ }
+ }
+ $fileContent = file_get_contents($dir.rtrim($parentPath,"/")."/".$fileName.".html");
+ return view('theme', [
+ 'options' => $this->siteOptions,
+ 'list' => $fileList,
+ 'content' => $fileContent,
+ 'path' => $parentPath,
+ 'name' => $fileName,
+ ]);
+ }
+
+ public function SaveThemeFile(){
+ return $this->adminObj->saveThemeFile(input('post.'));
+ }
+
+ public function SettingMail(){
+ return view('mail_setting', [
+ 'options' => $this->siteOptions,
+ 'optionsForSet' => Option::getValues(["mail_template","mail"]),
+ ]);
+ }
+
+ public function SettingPay(){
+ return view('pay_setting', [
+ 'options' => $this->siteOptions,
+ 'optionsForSet' => Option::getValues(["payment"]),
+ ]);
+ }
+
+ public function SettingOther(){
+ return view('other_setting', [
+ 'options' => $this->siteOptions,
+ 'optionsForSet' => Option::getValues(["file_edit","share","avatar","admin","storage_policy"]),
+ ]);
+ }
+
+ public function Files(){
+ $this->adminObj->listFile();
+ return view('file_list', [
+ 'options' => $this->siteOptions,
+ 'groups' => $this->adminObj->getAvaliableGroup(),
+ 'list' => $this->adminObj->pageData,
+ 'originList' => $this->adminObj->listData,
+ 'pageNow' => $this->adminObj->pageNow,
+ 'pageTotal' => $this->adminObj->pageTotal,
+ 'dataTotal' => $this->adminObj->dataTotal,
+ 'policy' => $this->adminObj->getAvaliablePolicy(),
+ ]);
+ }
+
+ Public function Users(){
+ $this->adminObj->listUser();
+ $group = $this->adminObj->getAvaliableGroup();
+ return view('user_list', [
+ 'options' => $this->siteOptions,
+ 'group' => $group,
+ 'groups' => $group,
+ 'list' => $this->adminObj->pageData,
+ 'originList' => $this->adminObj->listData,
+ 'pageNow' => $this->adminObj->pageNow,
+ 'pageTotal' => $this->adminObj->pageTotal,
+ 'dataTotal' => $this->adminObj->dataTotal,
+ 'policy' => $this->adminObj->getAvaliablePolicy(),
+ ]);
+ }
+
+ public function Shares(){
+ $this->adminObj->listShare();
+ return view('share_list', [
+ 'options' => $this->siteOptions,
+ 'groups' => $this->adminObj->getAvaliableGroup(),
+ 'list' => $this->adminObj->pageData,
+ 'originList' => $this->adminObj->listData,
+ 'pageNow' => $this->adminObj->pageNow,
+ 'pageTotal' => $this->adminObj->pageTotal,
+ 'dataTotal' => $this->adminObj->dataTotal,
+ ]);
+ }
+
+ public function PolicyList(){
+ $this->adminObj->listPolicy();
+ return view('policy_list', [
+ 'options' => $this->siteOptions,
+ 'groups' => $this->adminObj->getAvaliableGroup(),
+ 'list' => $this->adminObj->pageData,
+ 'originList' => $this->adminObj->listData,
+ 'pageNow' => $this->adminObj->pageNow,
+ 'pageTotal' => $this->adminObj->pageTotal,
+ 'dataTotal' => $this->adminObj->dataTotal,
+ ]);
+ }
+
+ public function GroupList(){
+ $this->adminObj->listGroup();
+ return view('group_list', [
+ 'options' => $this->siteOptions,
+ 'list' => $this->adminObj->pageData,
+ 'originList' => $this->adminObj->listData,
+ 'pageNow' => $this->adminObj->pageNow,
+ 'pageTotal' => $this->adminObj->pageTotal,
+ 'dataTotal' => $this->adminObj->dataTotal,
+ ]);
+ }
+
+ public function OrderList(){
+ $this->adminObj->listOrder();
+ return view('order_list', [
+ 'options' => $this->siteOptions,
+ 'list' => $this->adminObj->pageData,
+ 'originList' => $this->adminObj->listData,
+ 'pageNow' => $this->adminObj->pageNow,
+ 'pageTotal' => $this->adminObj->pageTotal,
+ 'dataTotal' => $this->adminObj->dataTotal,
+ ]);
+ }
+
+ public function SaveBasicSetting(){
+ return $this->adminObj->saveBasicSetting(input('post.'));
+ }
+
+ public function SaveRegSetting(){
+ return $this->adminObj->saveRegSetting(input('post.'));
+ }
+
+ public function SaveMailSetting(){
+ return $this->adminObj->saveMailSetting(input('post.'));
+ }
+
+ public function SendTestMail(){
+ return $this->adminObj->sendTestMail(input('post.'));
+ }
+
+ public function SaveMailTemplate(){
+ return $this->adminObj->saveMailTemplate(input('post.'));
+ }
+
+ public function GetFileInfo(){
+ return $this->adminObj->getFileInfo(input('post.id'));
+ }
+
+ public function GetUserInfo(){
+ return $this->adminObj->getUserInfo(input('post.id'));
+ }
+
+ public function savePolicy(){
+ return $this->adminObj->addPolicy(input('post.'));
+ }
+
+ public function SaveEditPolicy(){
+ return $this->adminObj->editPolicy(input('post.'));
+ }
+
+ public function SaveGroup(){
+ return $this->adminObj->saveGroup(input('post.'));
+ }
+
+ public function AddPack(){
+ return $this->adminObj->addPack(input('post.'));
+ }
+
+ public function AddGroupPurchase(){
+ return $this->adminObj->addGroupPurchase(input('post.'));
+ }
+
+ public function SaveCron(){
+ $this->adminObj->saveCron(input('post.'));
+ $this->redirect("/Admin/Cron",302);
+ }
+
+ public function SaveUser(){
+ return $this->adminObj->saveUser(input('post.'));
+ }
+
+ public function BanUser(){
+ return $this->adminObj->banUser(input('post.id'),$this->userObj->uid);
+ }
+
+ public function AddUser(){
+ return $this->adminObj->addUser(input('post.'));
+ }
+
+ public function Preview(){
+ $fileId = input('param.id');
+ $fileRecord = Db::name("files")->where("id",$fileId)->find();
+ $fileObj = new FileManage(rtrim($fileRecord["dir"],"/")."/".$fileRecord["orign_name"],$fileRecord["upload_user"]);
+ $previewHandler = $fileObj->PreviewHandler(true);
+ if($previewHandler[0]){
+ $this->redirect($previewHandler[1],302);
+ }
+ }
+
+ public function Download(){
+ $fileId = input('param.id');
+ $fileRecord = Db::name("files")->where("id",$fileId)->find();
+ $fileObj = new FileManage(rtrim($fileRecord["dir"],"/")."/".$fileRecord["orign_name"],$fileRecord["upload_user"]);
+ $FileHandler = $fileObj->Download(true);
+ if($FileHandler[0]){
+ $this->redirect($FileHandler[1],302);
+ }
+ }
+
+ public function Delete(){
+ return $this->adminObj->deleteSingle(input('post.id'));
+ }
+
+ public function DeleteShare(){
+ return $this->adminObj->deleteShare([0=>input('post.id')]);
+ }
+
+ public function DeleteShareMultiple(){
+ return $this->adminObj->deleteShare(json_decode(input('post.id'),true));
+ }
+
+ public function DeleteMultiple(){
+ return $this->adminObj->deleteMultiple(input('post.id'));
+ }
+
+ public function DeletePolicy(){
+ return $this->adminObj->deletePolicy(input('post.id'));
+ }
+
+ public function DeleteGroup(){
+ return $this->adminObj->deleteGroup(input('post.id'));
+ }
+
+ public function DeleteOrder(){
+ return $this->adminObj->deleteOrder(input('post.id'));
+ }
+
+ public function ChangeShareType(){
+ return $this->adminObj->changeShareType(input('post.id'));
+ }
+
+ public function DeletePack(){
+ return $this->adminObj->deletePack(input('post.id'));
+ }
+
+ public function DeleteGroupPurchase(){
+ return $this->adminObj->deleteGroupPurchase(input('post.id'));
+ }
+
+ public function DeleteUser(){
+ return $this->adminObj->deleteUser(input('post.id'),$this->userObj->uid);
+ }
+
+ public function DeleteUsers(){
+ $uidGroup = json_decode(input('post.id'),true);
+ foreach ($uidGroup as $key => $value) {
+ $this->adminObj->deleteUser($value,$this->userObj->uid);
+ }
+ return ["error"=>false,"msg"=>"删除成功"];
+ }
+
+ public function SwitchColor(){
+ $colorNow = Option::getValues(["admin"]);
+ if($colorNow["admin_color_body"] == "fixed-nav sticky-footer bg-light"){
+ $colorNew = [
+ "admin_color_body" => "fixed-nav sticky-footer bg-dark",
+ "admin_color_nav" => "navbar navbar-expand-lg fixed-top navbar-dark bg-dark",
+ ];
+ }else{
+ $colorNew = [
+ "admin_color_body" => "fixed-nav sticky-footer bg-light",
+ "admin_color_nav" => "navbar navbar-expand-lg fixed-top navbar-light bg-light",
+ ];
+ }
+ foreach ($colorNew as $key => $value) {
+ Db::name("options")->where("option_name",$key)->update(["option_value" => $value]);
+ }
+ }
+
+ public function EditPolicy(){
+ $policyId = input('param.id');
+ $policyRecord = Db::name("policy")->where("id",$policyId)->find();
+ return view('edit_policy', [
+ 'options' => $this->siteOptions,
+ 'policy' => $policyRecord,
+ ]);
+ }
+
+ public function EditGroup(){
+ $groupId = input('param.id');
+ $groupRecord = Db::name("groups")->where("id",$groupId)->find();
+ return view('edit_group', [
+ 'options' => $this->siteOptions,
+ 'group' => $groupRecord,
+ 'policy' => $this->adminObj->getAvaliablePolicy(),
+ ]);
+ }
+
+ public function AddGroup(){
+ return $this->adminObj->addGroup(input('post.'));
+ }
+
+ public function PolicyAdd(){
+ return view('add_policy', [
+ 'options' => $this->siteOptions,
+ ]);
+ }
+
+ public function Cron(){
+ $cronData = Db::name("corn")->select();
+ $neverExcute = true;
+ foreach ($cronData as $key => $value) {
+ if($value["last_excute"] !=0){
+ $neverExcute = false;
+ }
+ }
+ return view('cron_list', [
+ 'options' => $this->siteOptions,
+ 'cron' => $cronData,
+ 'neverExcute' => $neverExcute,
+ ]);
+ }
+
+ public function PolicyAddS3(){
+ return view('add_policy_s3', [
+ 'options' => $this->siteOptions,
+ ]);
+ }
+
+ public function About(){
+ $verison = json_decode(file_get_contents(ROOT_PATH . "application/version.json"),true);
+ return view('about', [
+ 'options' => $this->siteOptions,
+ 'programVersion' => $verison,
+ "dbsVersion" => Option::getValue("database_version"),
+ ]);
+ }
+
+ public function Purchase(){
+ $packData = json_decode(Option::getValue("pack_data"),true);
+ return view('purchase', [
+ 'options' => $this->siteOptions,
+ 'pack' => $packData,
+ ]);
+ }
+
+ public function PurchaseGroup(){
+ $groupData = json_decode(Option::getValue("group_sell_data"),true);
+ foreach ($groupData as $key => $value) {
+ $groupData[$key]["group"] = Db::name("groups")->where("id",$value["goup_id"])->find();
+ }
+ return view('purchase_group', [
+ 'options' => $this->siteOptions,
+ 'group' => $groupData,
+ 'group_list' => $this->adminObj->getAvaliableGroup(),
+ ]);
+ }
+
+ public function GroupAdd(){
+ return view('add_group', [
+ 'options' => $this->siteOptions,
+ 'policy' => $this->adminObj->getAvaliablePolicy(),
+ ]);
+ }
+
+}
diff --git a/application/index/controller/Callback.php b/application/index/controller/Callback.php
new file mode 100644
index 00000000..c8f20563
--- /dev/null
+++ b/application/index/controller/Callback.php
@@ -0,0 +1,84 @@
+ qiniuHandler(Request::instance()->header('Authorization'));
+ }
+
+ public function Oss(){
+ ob_end_clean();
+ header('Content-Type: application/json');
+ $handllerObj = new CallbackHandler(file_get_contents("php://input"));
+ $handllerObj -> ossHandler(Request::instance()->header('Authorization'),Request::instance()->header('x-oss-pub-key-url'));
+ }
+
+ public function TmpPreview(){
+ $basicOptions = Option::getValues(['basic']);
+ $params = explode(":",input("param.key"));
+ $fileData = Db::name("files")->where("id",$params[0])->find();
+ if (empty($fileData)){
+ abort(404);
+ }
+ $userData = Db::name("users")->where("id",$fileData["upload_user"])->find();
+ if(md5($userData["user_pass"].$fileData["id"].$params[1].config("salt")) != $params[2] || time()<$params[0]){
+ abort(403);
+ }
+ $fileObj = new FileManage(rtrim($fileData["dir"],"/")."/".$fileData["orign_name"],$userData["id"]);
+ $Redirect = $fileObj->PreviewHandler();
+ }
+
+ public function Upyun(){
+ $signToken = Request::instance()->header('Authorization');
+ $reqDate = Request::instance()->header('Date');
+ $contentMd5 = Request::instance()->header('Content-MD5');
+ ob_end_clean();
+ header('Content-Type: application/json');
+ $callbackData = [
+ "code" => input("post.code"),
+ "file_size" => input("post.file_size"),
+ "url" => input("post.url"),
+ "image-width" => input("post.image-width"),
+ "image-height" => input("post.image-height"),
+ "ext-param" => json_decode(input("post.ext-param"),true),
+ ];
+ $handllerObj = new CallbackHandler($callbackData);
+ $handllerObj -> upyunHandler($signToken,$reqDate,$contentMd5);
+ }
+
+ public function S3(){
+ $request = Request::instance();
+ if($request->method() == "OPTIONS"){
+ ob_end_clean();
+ header("Access-Control-Allow-Origin: *");
+ exit();
+ }
+ ob_end_clean();
+ header("Access-Control-Allow-Origin: *");
+ $callbackKey = input("param.key");
+ $callbackData = [
+ "bucket" => input("get.bucket"),
+ "key" => input("get.key"),
+ ];
+ $handllerObj = new CallbackHandler($callbackData);
+ $handllerObj -> s3Handler($callbackKey);
+ }
+
+}
diff --git a/application/index/controller/Cron.php b/application/index/controller/Cron.php
new file mode 100644
index 00000000..d7c600eb
--- /dev/null
+++ b/application/index/controller/Cron.php
@@ -0,0 +1,17 @@
+Doit();
+ }
+
+}
diff --git a/application/index/controller/Explore.php b/application/index/controller/Explore.php
new file mode 100644
index 00000000..2b4b3321
--- /dev/null
+++ b/application/index/controller/Explore.php
@@ -0,0 +1,60 @@
+siteOptions = Option::getValues(["basic"]);
+ }
+
+ public function Search(){
+ $this->visitorObj = new User(cookie('user_id'),cookie('login_key'));
+ return view("search",[
+ "options" => $this->siteOptions,
+ 'loginStatus' => $this->visitorObj->loginStatus,
+ 'userData' => $this->visitorObj->userSQLData,
+ ]);
+ }
+
+ public function S(){
+ $this->visitorObj = new User(cookie('user_id'),cookie('login_key'));
+ $keyWords=input("param.key");
+ if(empty($keyWords)){
+ $this->redirect('/Explore/Search',302);
+ }
+ $list = Db::name('shares')
+ ->where('type',"public")
+ ->where('origin_name',"like","%".$keyWords."%")
+ ->order('id DESC')
+ ->paginate(10);
+ $listData = $list->all();
+ foreach ($listData as $key => $value) {
+ if($value["source_type"]=="file"){
+ $listData[$key]["fileData"] = $value["origin_name"];
+
+ }else{
+ $pathDir = explode("/",$value["source_name"]);
+ $listData[$key]["fileData"] = end($pathDir);
+ }
+ }
+ return view("result",[
+ "options" => $this->siteOptions,
+ 'loginStatus' => $this->visitorObj->loginStatus,
+ 'userData' => $this->visitorObj->userSQLData,
+ 'list' => $listData,
+ 'listOrigin' => $list,
+ 'keyWords' => $keyWords,
+ ]);
+ }
+
+}
diff --git a/application/index/controller/File.php b/application/index/controller/File.php
new file mode 100644
index 00000000..eb729005
--- /dev/null
+++ b/application/index/controller/File.php
@@ -0,0 +1,175 @@
+userObj = new User(cookie('user_id'),cookie('login_key'));
+ if(!$this->userObj->loginStatus){
+ echo "Bad request";
+ exit();
+ }
+ }
+
+ /**
+ * [index description]
+ * @Author Aaron
+ * @DateTime 2017-07-03
+ * @return [type] [description]
+ */
+ public function index(){
+ return "";
+ }
+
+ /**
+ * [List description]
+ * @Author Aaron
+ * @DateTime 2017-07-03
+ */
+ public function ListFile(){
+ $reqPath = stripslashes(json_decode(file_get_contents("php://input"),true)['path']);
+ return FileManage::ListFile($reqPath,$this->userObj->uid);
+ }
+
+ public function Delete(){
+ $reqPath = json_decode(file_get_contents("php://input"),true)['items'];
+ $dirPath = json_decode(file_get_contents("php://input"),true)['dirs'];
+ FileManage::DirDeleteHandler($dirPath,$this->userObj->uid);
+ return FileManage::DeleteHandler($reqPath,$this->userObj->uid);
+ }
+
+ public function Move(){
+ $reqPath = json_decode(file_get_contents("php://input"),true)['items'];
+ $dirPath = json_decode(file_get_contents("php://input"),true)['dirs'];
+ $newPath = json_decode(file_get_contents("php://input"),true)['newPath'];
+ return FileManage::MoveHandler($reqPath,$dirPath,$newPath,$this->userObj->uid);
+ }
+
+ public function Rename(){
+ $reqPath = json_decode(file_get_contents("php://input"),true)['item'];
+ $newPath = json_decode(file_get_contents("php://input"),true)['newItemPath'];
+ return FileManage::RenameHandler($reqPath,$newPath,$this->userObj->uid);
+ }
+
+ public function Preview(){
+ $reqPath = $_GET["path"];
+ $fileObj = new FileManage($reqPath,$this->userObj->uid);
+ $Redirect = $fileObj->PreviewHandler();
+ if($Redirect[0]){
+ $this->redirect($Redirect[1],302);
+ }
+ }
+
+ public function ListPic(){
+ $reqPath = $_GET["path"];
+ return FileManage::listPic($reqPath,$this->userObj->uid);
+ }
+
+ public function Download(){
+ $reqPath = $_GET["path"];
+ $fileObj = new FileManage($reqPath,$this->userObj->uid);
+ $FileHandler = $fileObj->Download();
+ if($FileHandler[0]){
+ $this->redirect($FileHandler[1],302);
+ }
+ }
+
+ public function Share(){
+ $reqPath = json_decode(file_get_contents("php://input"),true)['item'];
+ $shareType = json_decode(file_get_contents("php://input"),true)['shareType'];
+ ShareHandler::createShare($reqPath,$shareType,$this->userObj->getSQLData(),$this->userObj->getGroupData());
+ }
+
+ public function gerSource(){
+ $reqPath = $_POST["path"];
+ $fileObj = new FileManage($reqPath,$this->userObj->uid);
+ $FileHandler = $fileObj->Source();
+ }
+
+ public function Content(){
+ $reqPath = json_decode(file_get_contents("php://input"),true)['item'];
+ $fileObj = new FileManage($reqPath,$this->userObj->uid);
+ $FileHandler = $fileObj->getContent();
+ }
+
+ public function Edit(){
+ $reqPath = json_decode(file_get_contents("php://input"),true)['item'];
+ $fileContent = json_decode(file_get_contents("php://input"),true)['content'];
+ $fileObj = new FileManage($reqPath,$this->userObj->uid);
+ $FileHandler = $fileObj->saveContent($fileContent);
+ }
+
+ public function OssDownload(){
+ return view('oss_download', [
+ 'url' => urldecode(input("get.url")),
+ 'name' => urldecode(input("get.name")),
+ ]);
+ }
+
+ public function DocPreview(){
+ $filePath = input("get.path");
+ $fileObj = new FileManage($filePath,$this->userObj->uid);
+ $tmpUrl = $fileObj->signTmpUrl();
+ $this->redirect("http://view.officeapps.live.com/op/view.aspx?src=".urlencode($tmpUrl),302);
+ }
+
+ public function Thumb(){
+ $filePath = input("get.path");
+ if(input("get.isImg") != "true"){
+ return "";
+ }
+ $fileObj = new FileManage($filePath,$this->userObj->uid);
+ $Redirect = $fileObj->getThumb();
+ if($Redirect[0]){
+ $this->redirect($Redirect[1],302);
+ }
+ }
+
+ public function GoogleDocPreview(){
+ $filePath = input("get.path");
+ $fileObj = new FileManage($filePath,$this->userObj->uid);
+ $tmpUrl = $fileObj->signTmpUrl();
+ $this->redirect("https://docs.google.com/viewer?url=".urlencode($tmpUrl),302);
+ }
+
+ /**
+ * [createFolder description]
+ * @Author Aaron
+ * @DateTime 2017-07-03
+ * @return [type] [description]
+ */
+ public function createFolder(){
+ $reqPath = stripslashes(json_decode(file_get_contents("php://input"),true)['newPath']);
+ $pathSplit = explode("/",$reqPath);
+ $dirName = end($pathSplit);
+ $dirPosition="/";
+ foreach ($pathSplit as $key => $value) {
+ if (empty($value)){
+
+ }else if($key == (count($pathSplit)-2)){
+ $dirPosition = $dirPosition.$value;
+ }else if($key == (count($pathSplit)-1)){
+ }else{
+ $dirPosition = $dirPosition.$value."/";
+ }
+
+ }
+ return FileManage::createFolder($dirName,$dirPosition,$this->userObj->uid);
+ }
+}
\ No newline at end of file
diff --git a/application/index/controller/Home.php b/application/index/controller/Home.php
new file mode 100644
index 00000000..5f9f78c8
--- /dev/null
+++ b/application/index/controller/Home.php
@@ -0,0 +1,75 @@
+userObj = new User(cookie('user_id'),cookie('login_key'));
+ if(!$this->userObj->loginStatus){
+ $this->redirect(url('/Login','',''));
+ exit();
+ }
+ }
+
+ public function index(){
+ $userInfo = $this->userObj->getInfo();
+ $policyData = $this->userObj->getPolicy();
+ $groupData = $this->userObj->getGroupData();
+ $extJson = json_decode($policyData["filetype"],true);
+ $extLimit="";
+ foreach ($extJson as $key => $value) {
+ $extLimit.='{ title : "'.$value["title"].'", extensions : "'.$value["ext"].'" },';
+ }
+ $policyData["max_size"] = $policyData["max_size"]/(1024*1024);
+ return view('home', [
+ 'options' => Option::getValues(['basic','upload']),
+ 'userInfo' => $userInfo,
+ 'extLimit' => $extLimit,
+ 'policyData' => $policyData,
+ 'groupData' => $groupData,
+ ]);
+ }
+
+ public function Album(){
+ $userInfo = $this->userObj->getInfo();
+ $list = Db::name("files")->where("upload_user",$this->userObj->uid)
+ ->where(function ($query) {
+ $query->where('orign_name', "like","%jpg")
+ ->whereor('orign_name', "like","%png")
+ ->whereor('orign_name', "like","%gif")
+ ->whereor('orign_name', "like","%bmp");
+ })
+ ->order('id DESC')
+ ->paginate(9);
+ $pageCount = ceil(Db::name("files")->where("upload_user",$this->userObj->uid)
+ ->where(function ($query) {
+ $query->where('orign_name', "like","%jpg")
+ ->whereor('orign_name', "like","%png")
+ ->whereor('orign_name', "like","%gif")
+ ->whereor('orign_name', "like","%bmp");
+ })
+ ->order('id DESC')->count()/9);
+ $listData = $list->all();
+ $pageNow = input("?get.page")?input("get.page"):1;
+ if($pageNow>$pageCount){
+ $this->error('页面不存在',404,Option::getValues(['basic','group_sell']));
+ }
+ return view('album', [
+ 'options' => Option::getValues(['basic','group_sell']),
+ 'userInfo' => $userInfo,
+ 'list' => $listData,
+ 'listOrigin' => $list,
+ 'pageCount' => $pageCount,
+ 'page' => $pageNow,
+ ]);
+ }
+
+}
diff --git a/application/index/controller/Index.php b/application/index/controller/Index.php
new file mode 100644
index 00000000..ec35d4ea
--- /dev/null
+++ b/application/index/controller/Index.php
@@ -0,0 +1,23 @@
+userObj = new User(cookie('user_id'),cookie('login_key'));
+ $userInfo = $this->userObj->getInfo();
+ return view('index', [
+ 'options' => Option::getValues(['basic']),
+ 'userInfo' => $userInfo,
+ ]);
+ }
+
+}
diff --git a/application/index/controller/Member.php b/application/index/controller/Member.php
new file mode 100644
index 00000000..aa7e2398
--- /dev/null
+++ b/application/index/controller/Member.php
@@ -0,0 +1,300 @@
+ '200','message' => $regAction[1]]);
+ }else{
+ return json(['code' => '1','message' => $regAction[1]]);
+ }
+ }else{
+ return json(['code' => '1','message' => "信息不完整"]);
+ }
+ }
+
+ public function ForgetPwd(){
+ if(input('?post.regEmail') && input('?post.captchaCode') && !empty(input('post.captchaCode')) && !empty(input('post.regEmail'))){
+ $findAction = User::findPwd(input('post.regEmail'),input('post.captchaCode'));
+ if ($findAction[0]){
+ return json(['code' => '200','message' => $findAction[1]]);
+ }else{
+ return json(['code' => '1','message' => $findAction[1]]);
+ }
+ }else{
+ return json(['code' => '1','message' => "信息不完整"]);
+ }
+ }
+
+ /**
+ * [Login description]
+ */
+ public function Login(){
+ if(input('?post.userMail') && input('?post.userPass')){
+ $logAction = User::login(input('post.userMail'),input('post.userPass'),input('post.captchaCode'));
+ if ($logAction[0]){
+ return json(['code' => '200','message' => '登陆成功']);
+ }else{
+ return json(['code' => '1','message' => $logAction[1]]);
+ }
+ }else{
+ return json(['code' => '1','message' => "信息不完整"]);
+ }
+ }
+
+ /**
+ * [LogOut description]
+ */
+ public function LogOut(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->userObj->clear();
+ $this->redirect("/Login",302);
+
+ }
+
+ public function Memory(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->userObj->getMemory();
+ }
+
+ public function LoginForm(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->isLoginStatusCheck();
+ return view('login', [
+ 'options' => Option::getValues(['basic']),
+ 'RegOptions' => Option::getValues(['register','login']),
+ 'loginStatus' => $this->userObj->loginStatus,
+ ]);
+ }
+
+ public function TwoStepCheck(){
+ $checkCode = input("post.code");
+ if(empty($checkCode)){
+ return json(['code' => '1','message' => "验证码不能为空"]);
+ }
+ $userId = session("user_id_tmp");
+ $userData = Db::name('users')->where('id',$userId)->find();
+ $ga = new PHPGangsta_GoogleAuthenticator();
+ $checkResult = $ga->verifyCode($userData["two_step"], $checkCode, 2);
+ if($checkResult) {
+ cookie('user_id',session("user_id_tmp"),604800);
+ cookie('login_status',session("login_status_tmp"),604800);
+ cookie('login_key',session("login_key_tmp"),604800);
+ return json(['code' => '200','message' => '登陆成功']);
+ }else{
+ return json(['code' => '1','message' => "验证失败"]);
+ }
+ }
+
+ public function TwoStep(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->isLoginStatusCheck();
+ return view('two_step', [
+ 'options' => Option::getValues(['basic']),
+ 'RegOptions' => Option::getValues(['register','login']),
+ 'loginStatus' => $this->userObj->loginStatus,
+ ]);
+ }
+
+ public function setWebdavPwd(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->loginStatusCheck();
+ Db::name("users")->where("id",$this->userObj->uid)
+ ->update([
+ "webdav_key" => md5($this->userObj->userSQLData["user_email"].":CloudreveWebDav:".input("post.pwd")),
+ ]);
+ return json(['error' => '200','msg' => '设置成功']);
+ }
+
+ public function emailActivate(){
+ $activationKey = input('param.key');
+ $basicOptions = Option::getValues(['basic']);
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->isLoginStatusCheck();
+ $activeAction = User::activicateUser($activationKey);
+ if($activeAction[0]){
+ return view('active_user', [
+ 'options' => $basicOptions,
+ 'loginStatus' => $this->userObj->loginStatus,
+ ]);
+ }else{
+ $this->error($activeAction[1],403,$basicOptions);
+ }
+ }
+
+ public function resetPwd(){
+ $resetKey = input('param.key');
+ $userId = input('get.uid');
+ $basicOptions = Option::getValues(['basic']);
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->isLoginStatusCheck();
+ $resetAction = User::resetUser($resetKey,$userId);
+ if($resetAction[0]){
+ return view('reset_user', [
+ 'options' => $basicOptions,
+ 'loginStatus' => $this->userObj->loginStatus,
+ 'key' => $resetKey."_".$userId,
+ ]);
+ }else{
+ $this->error($resetAction[1],403,$basicOptions);
+ }
+ }
+
+ public function Reset(){
+ $newPwd = input('post.pwd');
+ $resetKey = input('post.key');
+ $resetAction = User::resetPwd($resetKey,$newPwd);
+ if($resetAction[0]){
+ return json(['code' => '200','message' => '重设成功,请前往登录页登录']);
+ }else{
+ return json(['code' => '1','message' => $resetAction[1]]);
+ }
+ }
+
+ public function Setting(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $userInfo = $this->userObj->getInfo();
+ $this->loginStatusCheck();
+ $policyList=[];
+ foreach (explode(",",$this->userObj->groupData["policy_list"]) as $key => $value) {
+ $policyList[$key] = $value;
+ }
+ $avaliablePolicy = Db::name("policy")->where("id","in",$policyList)->select();
+ $basicOptions = Option::getValues(['basic']);
+ return view('setting', [
+ 'options' => $basicOptions,
+ 'userInfo' => $userInfo,
+ 'userSQL' => $this->userObj->userSQLData,
+ 'groupData' => $this->userObj->groupData,
+ 'loginStatus' => $this->userObj->loginStatus,
+ 'avaliablePolicy' => $avaliablePolicy,
+ ]);
+ }
+
+ public function SaveAvatar(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $file = request()->file("avatar");
+ $avatarObj = new Avatar(true,$file);
+ if(!$avatarObj->SaveAvatar()){
+ return json_encode($avatarObj->errorMsg);
+ }else{
+ $avatarObj->bindUser($this->userObj->uid);
+ return json_encode(["result" => "success"]);
+ }
+ }
+
+ public function Avatar(){
+ if(!input("get.cache")=="no"){
+ header("Cache-Control: max-age=10800");
+ }
+ $userId = input("param.uid");
+ $avatarObj = new Avatar(false,$userId);
+ $avatarImg = $avatarObj->Out(input("param.size"));
+ $this->redirect($avatarImg,302);
+ }
+
+ public function SetGravatar(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $avatarObj = new Avatar(false,$this->userObj->uid);
+ $avatarObj->setGravatar();
+ }
+
+ public function Nick(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $userInfo = $this->userObj->getInfo();
+ $this->loginStatusCheck();
+ $saveAction = $this->userObj->changeNick(input("post.nick"));
+ if($saveAction[0]){
+ return json(['error' => '200','msg' => '设置成功']);
+ }else{
+ return json(['error' => '1','msg' => $saveAction[1]]);
+ }
+ }
+
+ public function HomePage(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $userInfo = $this->userObj->getInfo();
+ $this->loginStatusCheck();
+ $saveAction = $this->userObj->homePageToggle(input("post.status"));
+ if($saveAction[0]){
+ return json(['error' => '200','msg' => '设置成功']);
+ }else{
+ return json(['error' => '1','msg' => $saveAction[1]]);
+ }
+ }
+
+ public function EnableTwoFactor(){
+ $twoFactor = new TwoFactor();
+ $twoFactor->qrcodeRender();
+ }
+
+ public function TwoFactorConfirm(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $userInfo = $this->userObj->getInfo();
+ $this->loginStatusCheck();
+ $twoFactor = new TwoFactor();
+ $confirmResult = $twoFactor->confirmCode(session("two_factor_enable"),input("post.code"));
+ if($confirmResult[0]){
+ $twoFactor->bindUser($this->userObj->uid);
+ return json(['error' => '200','msg' => '设置成功']);
+ }else{
+ return json(['error' => '1','msg' => $confirmResult[1]]);
+ }
+ }
+
+ public function ChangePwd(){
+ $this->userObj = new User(cookie('user_id'),cookie('login_key'));
+ $userInfo = $this->userObj->getInfo();
+ $this->loginStatusCheck();
+ $changeAction = $this->userObj->changePwd(input("post.origin"),input("post.new"));
+ if($changeAction[0]){
+ return json(['error' => '200','msg' => '设置成功']);
+ }else{
+ return json(['error' => '1','msg' => $changeAction[1]]);
+ }
+ }
+
+ private function loginStatusCheck($login=true){
+ if(!$this->userObj->loginStatus){
+ if($login){
+ $this->redirect(url('/Login','',''));
+ }else{
+ $this->redirect(url('/Home','',''));
+ }
+ exit();
+ }
+ }
+
+ private function isLoginStatusCheck(){
+ if($this->userObj->loginStatus){
+ $this->redirect(url('/Home','',''));
+ exit();
+ }
+ }
+
+}
diff --git a/application/index/controller/Profile.php b/application/index/controller/Profile.php
new file mode 100644
index 00000000..4e2979db
--- /dev/null
+++ b/application/index/controller/Profile.php
@@ -0,0 +1,80 @@
+siteOptions = Option::getValues(["basic"]);
+ }
+
+ public function index(){
+ $this->visitorObj = new User(cookie('user_id'),cookie('login_key'));
+ $userId = (string)input("param.uid");
+ $userData = Db::name("users")->where("id",$userId)->find();
+ if (empty($userId) || empty($userData) || $userData["profile"] == 0){
+ $this->error('用户主页不存或者用户关闭了个人主页',404,$this->siteOptions);
+ }
+ $groupData = Db::name("groups")->where("id",$userData["user_group"])->find();
+ $shareCount = Db::name('shares')
+ ->where('owner',$userId)
+ ->where('type',"public")
+ ->count();
+ $regDays = (int)((time()-strtotime($userData["user_date"]))/86400);
+ switch (input("get.type")) {
+ case 'all':
+ $list = Db::name('shares')
+ ->where('owner',$userId)
+ ->where('type',"public")
+ ->order('id DESC')
+ ->paginate(10);
+ break;
+ case 'hot':
+ $num = Option::getValue("hot_share_num");
+ $list = Db::name('shares')
+ ->where('owner',$userId)
+ ->where('type',"public")
+ ->paginate($num);
+ break;
+ default:
+ $list = Db::name('shares')
+ ->where('owner',$userId)
+ ->where('type',"public")
+ ->order('id DESC')
+ ->paginate(10);
+ break;
+ }
+ $listData = $list->all();
+ foreach ($listData as $key => $value) {
+ if($value["source_type"]=="file"){
+ $listData[$key]["fileData"] = Db::name('files')->where('id',$value["source_name"])->find()["orign_name"];
+
+ }else{
+ $pathDir = explode("/",$value["source_name"]);
+ $listData[$key]["fileData"] = end($pathDir);
+ }
+ }
+ return view("profile",[
+ "options" => $this->siteOptions,
+ 'loginStatus' => $this->visitorObj->loginStatus,
+ 'userInfo' => $userData,
+ 'userData' => $this->visitorObj->userSQLData,
+ 'groupData' => $groupData,
+ 'list' => $listData,
+ 'listOrigin' => $list,
+ 'type' => input("get.type"),
+ 'shareCount' => $shareCount,
+ 'regDays' => $regDays,
+ ]);
+ }
+
+}
diff --git a/application/index/controller/Share.php b/application/index/controller/Share.php
new file mode 100644
index 00000000..67aa253b
--- /dev/null
+++ b/application/index/controller/Share.php
@@ -0,0 +1,185 @@
+userObj = new User(cookie('user_id'),cookie('login_key'));
+ $this->siteOptions = Option::getValues(["basic"]);
+ }
+
+ public function index(){
+ $shareKey = input('param.key');
+ $shareObj = new ShareHandler($shareKey);
+ if(!$shareObj->querryStatus){
+ header('HTTP/1.1 404 Not Found');
+ $this->error('当前分享不存在或者已经失效',404,$this->siteOptions);
+ }
+ if(!$shareObj->lockStatus){
+ $shareObj->numIncrease("view_num");
+ if($shareObj->shareData["source_type"] == "dir"){
+ return view('share_dir', [
+ 'options' => Option::getValues(['basic','share']),
+ 'userInfo' => $shareObj->shareOwner->userSQLData,
+ 'dirData' => $shareObj->dirData,
+ 'shareData' => $shareObj->shareData,
+ 'loginStatus' => $this->userObj->loginStatus,
+ 'userData' => $this->userObj->userSQLData,
+ 'groupData' => $shareObj->shareOwner->groupData,
+ 'allowPreview' => Option::getValue("allowdVisitorDownload"),
+ ]);
+ }else{
+ return view('share_single', [
+ 'options' => Option::getValues(['basic','share']),
+ 'userInfo' => $shareObj->shareOwner->userSQLData,
+ 'fileData' => $shareObj->fileData,
+ 'shareData' => $shareObj->shareData,
+ 'loginStatus' => $this->userObj->loginStatus,
+ 'userData' => $this->userObj->userSQLData,
+ 'allowPreview' => Option::getValue("allowdVisitorDownload"),
+ ]);
+ }
+ }else{
+ return view('share_lock', [
+ 'options' => Option::getValues(['basic','share']),
+ 'userInfo' => $shareObj->shareOwner->userSQLData,
+ 'fileData' => $shareObj->fileData,
+ 'shareData' => $shareObj->shareData,
+ 'loginStatus' => $this->userObj->loginStatus,
+ 'userData' => $this->userObj->userSQLData,
+ 'pwd' => input("?get.pwd") ? input("get.pwd") : "",
+ ]);
+ }
+ }
+
+ public function getDownloadUrl(){
+ $shareId = input('key');
+ $shareObj = new ShareHandler($shareId,false);
+ return $shareObj->getDownloadUrl($this->userObj);
+ }
+
+ public function Download(){
+ $shareId = input('param.key');
+ $filePath = input('get.path');
+ $shareObj = new ShareHandler($shareId,false);
+ if(empty($filePath)){
+ $DownloadHandler = $shareObj->Download($this->userObj);
+ }else{
+ $DownloadHandler = $shareObj->DownloadFolder($this->userObj,$filePath);
+ }
+ if($DownloadHandler[0]){
+ $this->redirect($DownloadHandler[1],302);
+ }else{
+ $this->error($DownloadHandler[1],404,$this->siteOptions);
+ }
+ }
+
+ public function chekPwd(){
+ $shareId = input('key');
+ $inputPwd = input('password');
+ $shareObj = new ShareHandler($shareId,false);
+ if(!$shareObj->querryStatus){
+ return array(
+ "error" => 1,
+ "msg" => "分享不存在"
+ );
+ }
+ return $shareObj->checkPwd($inputPwd);
+ }
+
+ public function Preview(){
+ $shareId = input('param.key');
+ $filePath = input('get.path');
+ $shareObj = new ShareHandler($shareId,false);
+ if(empty($filePath)){
+ $previewHandler = $shareObj->Preview($this->userObj);
+ }else{
+ if(!empty(input('get.folder'))){
+ $previewHandler = $shareObj->PreviewFolder($this->userObj,$filePath,true);
+ }else{
+ $previewHandler = $shareObj->PreviewFolder($this->userObj,$filePath);
+ }
+ }
+ if($previewHandler[0]){
+ $this->redirect($previewHandler[1],302);
+ }else{
+ $this->error($previewHandler[1],404,$this->siteOptions);
+ }
+ }
+
+ public function ListFile(){
+ $shareId = input('param.key');
+ $reqPathTo = stripslashes(json_decode(file_get_contents("php://input"),true)['path']);
+ $shareObj = new ShareHandler($shareId,false);
+ return $shareObj->ListFile($reqPathTo);
+ }
+
+ public function ListPic(){
+ $filePath = input('get.path');
+ $shareId = input('get.id');
+ $shareObj = new ShareHandler($shareId,false);
+ return $shareObj->listPic($shareId,$filePath);
+ }
+
+ public function Delete(){
+ $shareId = input('post.id');
+ $shareObj = new ShareHandler($shareId,false);
+ if(!$shareObj->querryStatus){
+ return array(
+ "error" => 1,
+ "msg" => "分享不存在"
+ );
+ }
+ return $shareObj->deleteShare($this->userObj->uid);
+ }
+
+ public function ChangePromission(){
+ $shareId = input('post.id');
+ $shareObj = new ShareHandler($shareId,false);
+ if(!$shareObj->querryStatus){
+ return array(
+ "error" => 1,
+ "msg" => "分享不存在"
+ );
+ }
+ return $shareObj->changePromission($this->userObj->uid);
+ }
+
+ public function My(){
+ if(!$this->userObj->loginStatus){
+ $this->redirect(url('/Login','',''));
+ exit();
+ }
+ $userInfo = $this->userObj->getInfo();
+ $groupData = $this->userObj->getGroupData();
+ $list = Db::name('shares')->where('owner',$this->userObj->uid)->paginate(10);
+ $listData = $list->all();
+ foreach ($listData as $key => $value) {
+ if($value["source_type"]=="file"){
+ $listData[$key]["fileData"] = Db::name('files')->where('id',$value["source_name"])->find()["orign_name"];
+
+ }else{
+ $listData[$key]["fileData"] = $value["source_name"];
+ }
+ }
+ return view('share_home', [
+ 'options' => Option::getValues(['basic','share']),
+ 'userInfo' => $userInfo,
+ 'groupData' => $groupData,
+ 'list' => $listData,
+ 'listOrigin' => $list
+ ]);
+ }
+
+}
diff --git a/application/index/controller/Upload.php b/application/index/controller/Upload.php
new file mode 100644
index 00000000..c8b307d4
--- /dev/null
+++ b/application/index/controller/Upload.php
@@ -0,0 +1,78 @@
+userObj = new User(cookie('user_id'),cookie('login_key'));
+ if(!$this->userObj->loginStatus){
+ echo "Bad request";
+ exit();
+ }
+ }
+
+ public function index(){
+ ob_end_clean();
+ $file = request()->file('file');
+ $fileInfo = Request::instance()->request();
+ $UploadHandler = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
+ return $UploadHandler->fileReceive($file,$fileInfo);
+ }
+
+ public function Token(){
+ $uploadObj = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
+ $upToken = $uploadObj->getToken();
+ if(!empty($uploadObj->upyunPolicy)){
+ return json([
+ "token" => $upToken,
+ "policy" => $uploadObj->upyunPolicy,
+ ]);
+ }
+ if(!empty($uploadObj->s3Policy)){
+ return json([
+ "policy" => $uploadObj->s3Policy,
+ "sign" => $uploadObj->s3Sign,
+ "key" => $uploadObj->dirName,
+ "credential" => $uploadObj->s3Credential,
+ "x_amz_date" => $uploadObj->x_amz_date,
+ "siteUrl"=>$uploadObj->siteUrl,
+ "callBackKey" => $uploadObj->callBackKey,
+ ]);
+ }
+ if(!$uploadObj->getToken()){
+ return json([
+ "uptoken" => $uploadObj->ossToken,
+ "sign" => $uploadObj->ossSign,
+ "id" => $uploadObj->ossAccessId,
+ "key" => $uploadObj->ossFileName,
+ "callback" => $uploadObj->ossCallBack,
+ ]);
+ }
+ return json(["uptoken" => $uploadObj->getToken()]);
+ }
+
+ public function chunk(){
+ $file = file_get_contents('php://input');
+ $uploadObj = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
+ $uploadObj->setChunk(input('param.chunk'),input('param.chunks'),$file);
+ }
+
+ public function mkFile(){
+ $ctx = file_get_contents('php://input');
+ $originName = UploadHandler::b64Decode(input('param.fname'));
+ $filePath = UploadHandler::b64Decode(input('param.path'));
+ $uploadObj = new UploadHandler($this->userObj->groupData['policy_name'],$this->userObj->uid);
+ $uploadObj->generateFile($ctx,$originName,$filePath);
+ }
+
+}
diff --git a/application/index/controller/WebDav.php b/application/index/controller/WebDav.php
new file mode 100644
index 00000000..19f6f01a
--- /dev/null
+++ b/application/index/controller/WebDav.php
@@ -0,0 +1,45 @@
+uid = input("param.uid");
+ $publicDir = new Directory($this->uid."/");
+
+ $server = new DAV\Server($publicDir);
+ $server->setBaseUri('/WebDav/Api/uid/'.$this->uid);
+ $lockBackend = new DAV\Locks\Backend\File(ROOT_PATH.'public/locks');
+ $lockPlugin = new DAV\Locks\Plugin($lockBackend);
+ $server->addPlugin($lockPlugin);
+ $check = new DavAuth($this->uid);
+ $callBack = new BasicCallBack($check);
+ $authPlugin = new Auth\Plugin($callBack);
+ $server->addPlugin($authPlugin);
+ $server->addPlugin(new DAV\Browser\Plugin());
+ $server->addPlugin(new \Sabre\DAV\Browser\GuessContentType());
+ ob_end_clean();
+ $server->exec();
+ }
+
+}
diff --git a/application/index/model/AdminHandler.php b/application/index/model/AdminHandler.php
new file mode 100644
index 00000000..92518f7b
--- /dev/null
+++ b/application/index/model/AdminHandler.php
@@ -0,0 +1,657 @@
+siteOptions = $options;
+ }
+
+ public function getStatics(){
+ $statics["fileNum"] = Db::name('files')->count();
+ $statics["privateShareNum"] = Db::name('shares')->where("type","private")->count();
+ $statics["publicShareNum"] = Db::name('shares')->where("type","public")->count();
+ $statics["userNum"] = Db::name('users')->where("user_status",0)->count();
+ if($statics["fileNum"]==0){
+ $statics["imgRate"] = 0;
+ $statics["audioRate"] = 0;
+ $statics["videoRate"] = 0;
+ $statics['otherRate'] = 0;
+ }else{
+ $statics["imgRate"] =floor(Db::name('files')
+ ->where('pic_info',"<>"," ")
+ ->where('pic_info',"<>","0,0")
+ ->where('pic_info',"<>","null,null")
+ ->count()/$statics["fileNum"]*10000)/100;
+ $statics["audioRate"] =floor(Db::name('files')
+ ->where(function ($query) {
+ $query->where('orign_name', "like","%mp3")
+ ->whereor('orign_name', "like","%flac")
+ ->whereor('orign_name', "like","%wma")
+ ->whereor('orign_name', "like","%aac")
+ ->whereor('orign_name', "like","%wav")
+ ->whereor('orign_name', "like","%ogg");
+ })
+ ->count()/$statics["fileNum"]*10000)/100;
+ $statics["videoRate"] =floor(Db::name('files')
+ ->where(function ($query) {
+ $query->where('orign_name', "like","%mp4")
+ ->whereor('orign_name', "like","%avi")
+ ->whereor('orign_name', "like","%rmvb")
+ ->whereor('orign_name', "like","%aac")
+ ->whereor('orign_name', "like","%wav")
+ ->whereor('orign_name', "like","%mkv");
+ })
+ ->count()/$statics["fileNum"]*10000)/100;
+ $statics['otherRate'] = 100-($statics["videoRate"]+$statics["audioRate"]+$statics["imgRate"]);
+ }
+ $timeNow=time();
+ $statics["trendFile"]="";
+ $statics["trendUser"]="";
+ $statics["trendDate"]="";
+ for ($i=0; $i < 13; $i++) {
+ $statics["trendFile"].= Db::name('files')->where('upload_date','between time',[date("Y-m-d",$timeNow-(12-$i)*3600*24),date("Y-m-d",$timeNow-(11-$i)*3600*24)])->count().",";
+ }
+ for ($i=0; $i < 13; $i++) {
+ $statics["trendUser"].= Db::name('users')->where('user_date','between time',[date("Y-m-d",$timeNow-(12-$i)*3600*24),date("Y-m-d",$timeNow-(11-$i)*3600*24)])->count().",";
+ }
+ for ($i=0; $i < 13; $i++) {
+ $statics["trendDate"].='"'.date("m月d日",$timeNow-(12-$i)*3600*24).'",';
+ }
+ $statics["trendFile"] = rtrim($statics["trendFile"],",");
+ $statics["trendDate"] = rtrim($statics["trendDate"],",");
+ $statics["trendUser"] = rtrim($statics["trendUser"],",");
+ return $statics;
+ }
+
+ public function saveBasicSetting($options){
+ $siteUrl = rtrim($options["siteURL"],"/")."/";
+ $options["siteURL"]=$siteUrl;
+ return $this->saveOptions($options);
+ }
+
+ public function saveRegSetting($options){
+ foreach(["email_active","login_captcha","reg_captcha","forget_captcha"] as $key){
+ $options[$key] = array_key_exists($key,$options) ? $options[$key] : 0;
+ }
+ return $this->saveOptions($options);
+ }
+
+ public function saveMailSetting($options){
+ return $this->saveOptions($options);
+ }
+
+ public function saveMailTemplate($options){
+ return $this->saveOptions($options);
+ }
+
+ public function AddGroup($options){
+ $options["max_storage"] = $options["max_storage"]*$options["sizeTimes"];
+ unset($options["sizeTimes"]);
+ $options["grade_policy"] = 0;
+ $options["policy_list"] = $options["policy_name"];
+ try {
+ Db::name("groups")->insert($options);
+ } catch (Exception $e) {
+ return ["error"=>1,"msg"=>$e->getMessage()];
+ }
+ return ["error"=>200,"msg"=>"设置已保存"];
+ }
+
+ public function addPolicy($options){
+ $options["max_size"] = $options["max_size"]*$options["sizeTimes"];
+ unset($options["sizeTimes"]);
+ $options["server"] = isset($options["server"]) ? $options["server"] : "/Upload";
+ foreach (["bucketname","bucket_private","bucketname","ak","sk","op_name","op_pwd","mimetype","namerule"] as $key => $value) {
+ $options[$value] = isset($options[$value]) ? $options[$value] : "0";
+ }
+ if(empty($options["filetype"])){
+ $options["filetype"]="[]";
+ }else{
+ $options["filetype"] = json_encode([0=>["ext"=>$options["filetype"],"title"=>"default"]]);
+ }
+ if($options["policy_type"] == "upyun"){
+ $options["server"] = "https://v0.api.upyun.com/".$options["bucketname"];
+ }
+ try {
+ Db::name("policy")->insert($options);
+ } catch (Exception $e) {
+ return ["error"=>1,"msg"=>$e->getMessage()];
+ }
+ return ["error"=>200,"msg"=>"设置已保存"];
+ }
+
+ public function editPolicy($options){
+ $policyId = $options["id"];
+ $options["max_size"] = $options["max_size"]*$options["sizeTimes"];
+ unset($options["sizeTimes"]);
+ unset($options["id"]);
+ if(empty($options["filetype"])){
+ $options["filetype"]="[]";
+ }else{
+ $options["filetype"] = json_encode([0=>["ext"=>$options["filetype"],"title"=>"default"]]);
+ }
+ try {
+ Db::name("policy")->where("id",$policyId)->update($options);
+ } catch (Exception $e) {
+ return ["error"=>1,"msg"=>$e->getMessage()];
+ }
+ return ["error"=>200,"msg"=>"设置已保存"];
+ }
+
+ public function saveGroup($options){
+ $groupId = $options["id"];
+ unset($options["id"]);
+ $options["max_storage"] = $options["max_storage"]*$options["sizeTimes"];
+ unset($options["sizeTimes"]);
+ try {
+ Db::name("groups")->where("id",$groupId)->update($options);
+ } catch (Exception $e) {
+ return ["error"=>1,"msg"=>$e->getMessage()];
+ }
+ return ["error"=>200,"msg"=>"设置已保存"];
+ }
+
+ public function saveOptions($options){
+ try {
+ foreach ($options as $key => $value) {
+ Db::name("options")->where("option_name",$key)->update(["option_value"=>$value]);
+ }
+ } catch (Exception $e) {
+ return ["error"=>1,"msg"=>$e->getMessage()];
+ }
+ return ["error"=>200,"msg"=>"设置已保存"];
+ }
+
+ public function getAvaliableGroup(){
+ $groupData = Db::name("groups")->where("id","neq",2)->select();
+ return $groupData;
+ }
+
+ public function saveCron($options){
+ $cronId = $options["id"];
+ unset($options["id"]);
+ Db::name("corn")->where("id",$cronId)->update($options);
+ }
+
+ public function getAvaliablePolicy(){
+ $policyData = Db::name("policy")->select();
+ return $policyData;
+ }
+
+ public function sendTestMail($options){
+ $mailObj = new Mail();
+ if(empty($options["receiveMail"])){
+ return ["error"=>1,"msg"=>"接收邮箱不能为空"];
+ }
+ $sendResult = $mailObj->Send($options["receiveMail"],"发信测试",$options["subject"],$options["content"]);
+ if($sendResult){
+ return ["error"=>200,"msg"=>"发送成功"];
+ }else{
+ return ["error"=>1,"msg"=>$mailObj->errorMsg];
+ }
+ }
+
+ public function deleteSingle($id){
+ $fileRecord = Db::name("files")->where("id",$id)->find();
+ return FileManage::DeleteHandler([0 => rtrim($fileRecord["dir"],"/")."/".$fileRecord["orign_name"]],$fileRecord["upload_user"]);
+ }
+
+ public function deletePolicy($id){
+ $groupData = Db::name("groups")->where("policy_name",$id)->select();
+ if(!empty($groupData)){
+ return ["error"=>true,"msg"=>"此上传策略正在被以下用户组使用:".join(",",array_column($groupData, "group_name"))];
+ }
+ Db::name("policy")->where("id",$id)->delete();
+ return ["error"=>false,"msg"=>"已删除"];
+ }
+
+ public function deleteGroup($id){
+ $userData = Db::name("users")->where("user_group",$id)->find();
+ if(!empty($userData)){
+ return ["error"=>true,"msg"=>"此用户组下仍有用户,请先删除这些用户"];
+ }
+ if($id == 1 || $id == 2){
+ return ["error"=>true,"msg"=>"系统保留用户组,无法删除"];
+ }
+ Db::name("groups")->where("id",$id)->delete();
+ return ["error"=>false,"msg"=>"已删除"];
+ }
+
+ public function getConfigFile($type){
+ switch ($type) {
+ case 'common':
+ $configPath = ROOT_PATH ."application/config.php";
+ $basicPath = "application/config.php";
+ break;
+ case 'database':
+ if(file_exists( ROOT_PATH ."application/database.lock")){
+ return ["出于安全考虑,默认禁止直接编辑数据库配置文件。如果需要开启编辑,请手动删除 application/database.lock 文件。","application/database.php"];
+ }
+ $configPath = ROOT_PATH ."application/database.php";
+ $basicPath = "application/database.php";
+ break;
+ case 'route':
+ $configPath = ROOT_PATH ."application/route.php";
+ $basicPath = "application/route.php";
+ break;
+ case 'tags':
+ $configPath = ROOT_PATH ."application/tags.php";
+ $basicPath = "application/tags.php";
+ break;
+ default:
+ die("");
+ break;
+ }
+ return [file_get_contents($configPath),$basicPath];
+ }
+
+ public function saveConfigFile($options){
+ switch ($options["type"]) {
+ case 'common':
+ file_put_contents(ROOT_PATH ."application/config.php",$options["content"]);
+ break;
+ case 'route':
+ file_put_contents(ROOT_PATH ."application/route.php",$options["content"]);
+ break;
+ case 'tags':
+ file_put_contents(ROOT_PATH ."application/tags.php",$options["content"]);
+ break;
+ case 'database':
+ if(file_exists( ROOT_PATH ."application/database.lock")){
+ return ["error"=>true,"msg"=>"出于安全考虑,默认禁止直接编辑数据库配置文件。如果需要开启编辑,请手动删除 application/database.lock 文件。"];
+ }
+ file_put_contents(ROOT_PATH ."application/database.php",$options["content"]);
+ break;
+ default:
+ # code...
+ break;
+ }
+ return ["error"=>false,"msg"=>""];
+ }
+
+ public function deleteMultiple($id){
+ $fileInfo = json_decode($id,true);
+ $pathGroup = [];
+ foreach ($fileInfo as $key => $value) {
+ $pathGroup[$value["uid"]] = isset($pathGroup[$value["uid"]]) ? $pathGroup[$value["uid"]] : [];
+ array_push($pathGroup[$value["uid"]], $value["path"]);
+ }
+ foreach ($pathGroup as $key => $value) {
+ FileManage::DeleteHandler($value,$key);
+ }
+ return ["error"=>200,"msg"=>"删除成功"];
+ }
+
+ public function deleteShare($ids){
+ Db::name("shares")->where("id","in",$ids)->delete();
+ return ["error"=>false,"msg"=>"删除成功"];
+ }
+
+ public function deleteOrder($id){
+ Db::name("order")->where("id",$id)->delete();
+ return ["error"=>false,"msg"=>"删除成功"];
+ }
+
+ public function deleteUser($id,$userNow){
+ if($userNow == $id){
+ return ["error"=>true,"msg"=>"我的老伙计,你可不能删除你自己"];
+ }
+ //删除用户所有文件及目录
+ FileManage::DirDeleteHandler([0 => "/"],$id);
+ //删除此用户所有分享
+ Db::name("shares")->where("owner",$id)->delete();
+ //删除此用户
+ Db::name("users")->where("id",$id)->delete();
+ return ["error"=>false,"msg"=>"删除成功"];
+ }
+
+ public function changeShareType($id){
+ $shareId = $id;
+ $shareObj = new ShareHandler($shareId,false);
+ if(!$shareObj->querryStatus){
+ return array(
+ "error" => 1,
+ "msg" => "分享不存在"
+ );
+ }
+ return $shareObj->changePromission(0,true);
+ }
+
+ public function getUserInfo($id){
+ $userData = Db::name("users")->where("id",$id)->find();
+ $userData["used_storage"] =getSize($userData["used_storage"]);
+ return $userData;
+ }
+
+ public function listFile(){
+ $pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
+ $orderType = empty(cookie('orderMethodFile')) ? "id DESC" : cookie('orderMethodFile');
+ $this->pageData = Db::name("files")
+ ->where(function ($query) {
+ if(!empty(cookie('fileSearch'))){
+ $query->where('orign_name', "like","%".cookie('fileSearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('filePolicy'))){
+ $query->where('policy_id', cookie('filePolicy'));
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('searchValue'))){
+ $query->where(cookie('searchCol'),"like", cookie('searchValue'));
+ }
+ })
+ ->order($orderType)
+ ->paginate($pageSize);
+ $this->dataTotal = Db::name("files")
+ ->where(function ($query) {
+ if(!empty(cookie('fileSearch'))){
+ $query->where('orign_name', "like","%".cookie('fileSearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('filePolicy'))){
+ $query->where('policy_id', cookie('filePolicy'));
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('searchValue'))){
+ $query->where(cookie('searchCol'),"like", cookie('searchValue'));
+ }
+ })
+ ->order($orderType)
+ ->count();
+ $this->pageTotal = ceil($this->dataTotal/$pageSize);
+ $this->listData = $this->pageData->all();
+ $userCache=[];
+ $userCacheList=[];
+ foreach ($this->listData as $key => $value) {
+ if(in_array($value["upload_user"], $userCacheList)){
+ $this->listData[$key]["user"] = $userCache[$value["upload_user"]];
+ }else{
+ $this->listData[$key]["user"] = Db::name("users")->where("id",$value["upload_user"])->find();
+ array_push($userCacheList,$value["upload_user"]);
+ $userCache[$value["upload_user"]] = $this->listData[$key]["user"];
+ }
+ }
+ $this->pageNow = input("?get.page")?input("get.page"):1;
+ }
+
+ public function listUser(){
+ $pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
+ $orderType = empty(cookie('orderMethodUser')) ? "id DESC" : cookie('orderMethodUser');
+ $this->pageData = Db::name("users")
+ ->where(function ($query) {
+ if(!empty(cookie('userStatus'))){
+ $query->where('user_status', cookie('userStatus')-1);
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('userSearch'))){
+ $query->where('user_nick', "like","%".cookie('userSearch')."%")
+ ->whereOr("id",cookie('userSearch'))
+ ->whereOr("user_email","like","%".cookie('userSearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('userGroup'))){
+ $query->where('user_group', cookie('userGroup'));
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('searchValueUser'))){
+ $query->where(cookie('searchColUser'),"like", cookie('searchValueUser'));
+ }
+ })
+ ->order($orderType)
+ ->paginate($pageSize);
+ $this->dataTotal = Db::name("users")
+ ->where(function ($query) {
+ if(!empty(cookie('userStatus'))){
+ $query->where('user_status', cookie('userStatus')-1);
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('userSearch'))){
+ $query->where('user_nick', "like","%".cookie('userSearch')."%")
+ ->whereOr("id",cookie('userSearch'))
+ ->whereOr("user_email","like","%".cookie('userSearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('userGroup'))){
+ $query->where('user_group', cookie('userGroup'));
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('searchValueUser'))){
+ $query->where(cookie('searchColUser'),"like", cookie('searchValueUser'));
+ }
+ })
+ ->order($orderType)
+ ->count();
+ $this->pageTotal = ceil($this->dataTotal/$pageSize);
+ $this->listData = $this->pageData->all();
+ $groupCache=[];
+ $groupCacheList=[];
+ foreach ($this->listData as $key => $value) {
+ if(in_array($value["user_group"], $groupCacheList)){
+ $this->listData[$key]["group"] = $groupCache[$value["user_group"]];
+ }else{
+ $this->listData[$key]["group"] = Db::name("groups")->where("id",$value["user_group"])->find();
+ array_push($groupCacheList,$value["user_group"]);
+ $groupCache[$value["user_group"]] = $this->listData[$key]["group"];
+ }
+ }
+ $this->pageNow = input("?get.page")?input("get.page"):1;
+ }
+
+ public function listShare(){
+ $pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
+ $orderType = empty(cookie('orderMethodShare')) ? "id DESC" : cookie('orderMethodShare');
+ $this->pageData = Db::name("shares")
+ ->where(function ($query) {
+ if(!empty(cookie('shareSearch'))){
+ $query->where('source_name', "like","%".cookie('shareSearch')."%")->whereOr('origin_name', "like","%".cookie('shareSearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('shareType'))){
+ $query->where('type', cookie('shareType'));
+ }
+ })
+ ->order($orderType)
+ ->paginate($pageSize);
+ $this->dataTotal = Db::name("shares")
+ ->where(function ($query) {
+ if(!empty(cookie('shareSearch'))){
+ $query->where('source_name', "like","%".cookie('shareSearch')."%")->whereOr('origin_name', "like","%".cookie('shareSearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('shareType'))){
+ $query->where('type', cookie('shareType'));
+ }
+ })
+ ->order($orderType)
+ ->count();
+ $this->pageTotal = ceil($this->dataTotal/$pageSize);
+ $this->listData = $this->pageData->all();
+ $userCache=[];
+ $userCacheList=[];
+ foreach ($this->listData as $key => $value) {
+ if(in_array($value["owner"], $userCacheList)){
+ $this->listData[$key]["user"] = $userCache[$value["owner"]];
+ }else{
+ $this->listData[$key]["user"] = Db::name("users")->where("id",$value["owner"])->find();
+ array_push($userCacheList,$value["owner"]);
+ $userCache[$value["owner"]] = $this->listData[$key]["user"];
+ }
+ }
+ $this->pageNow = input("?get.page")?input("get.page"):1;
+ }
+
+ public function listPolicy(){
+ $pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
+ $this->pageData = Db::name("policy")
+ ->where(function ($query) {
+ if(!empty(cookie('policySearch'))){
+ $query->where('policy_name', "like","%".cookie('policySearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('policyType'))){
+ $query->where('policy_type', cookie('policyType'));
+ }
+ })
+ ->order("id DESC")
+ ->paginate($pageSize);
+ $this->dataTotal = Db::name("policy")
+ ->where(function ($query) {
+ if(!empty(cookie('policySearch'))){
+ $query->where('policy_name', "like","%".cookie('policySearch')."%");
+ }
+ })
+ ->where(function ($query) {
+ if(!empty(cookie('policyType'))){
+ $query->where('policy_type', cookie('policyType'));
+ }
+ })
+ ->order("id DESC")
+ ->count();
+ $this->pageTotal = ceil($this->dataTotal/$pageSize);
+ $this->listData = $this->pageData->all();
+ $this->pageNow = input("?get.page")?input("get.page"):1;
+ foreach ($this->listData as $key => $value) {
+ $this->listData[$key]["file_num"] = Db::name("files")->where("policy_id",$value["id"])->count();
+ $this->listData[$key]["file_size"] = Db::name("files")->where("policy_id",$value["id"])->sum("size");
+ }
+ }
+
+ public function getFileInfo($id){
+ $fileRecord = Db::name("files")->where("id",$id)->find();
+ $policyRecord = Db::name("policy")->where("id",$fileRecord["policy_id"])->find();
+ $fileRecord["policy"] = $policyRecord;
+ return $fileRecord;
+ }
+
+ public function saveThemeFile($options){
+ $fileName=$options["name"];
+ $dir = ROOT_PATH."application/index/view/";
+ $fileList=[];
+ $fileList=$fileList+scandir($dir);
+ $pathList=["/"=>$fileList];
+ foreach (["admin","explore","file","home","index","member","profile","share"] as $key => $value) {
+ $childPath = scandir($dir.$value."/");
+ $fileList=array_merge($fileList,$childPath);
+ $pathList = array_merge($pathList,[$value => $childPath]);
+ }
+ foreach ($fileList as $key => $value) {
+ if(substr_compare($value, ".html", -strlen(".html")) != 0){
+ unset($fileList[$key]);
+ }
+ }
+ foreach($pathList as $key=>$val){
+ if(in_array($fileName.".html",$val)){
+ $parentPath = $key;
+ break;
+ }
+ }
+ file_put_contents($dir.rtrim($parentPath,"/")."/".$fileName.".html",$options["content"]);
+ return ["error"=>false,"msg"=>"成功"];
+ }
+
+ public function saveUser($options){
+ if(empty($options["user_pass"])){
+ unset($options["user_pass"]);
+ }else{
+ $options["user_pass"] = md5(config('salt').$options["user_pass"]);
+ }
+ $userId = $options["uid"];
+ unset($options["uid"]);
+ try {
+ Db::name("users")->where("id",$userId)->update($options);
+ } catch (Exception $e) {
+ return ["error"=>1,"msg"=>$e->getMessage()];
+ }
+ return ["error"=>200,"msg"=>"设置已保存"];
+ }
+
+ public function banUser($id,$uid){
+ if($id == $uid){
+ return ["error"=>1,"msg"=>"我的老伙计,你怎么能封禁你自己?"];
+ }
+ $userData = Db::name("users")->where("id",$id)->find();
+ $statusNew = $userData["user_status"] == 1 ? 0 : 1;
+ Db::name("users")->where("id",$id)->update(["user_status" => $statusNew]);
+ return ["error"=>200,"msg"=>"设置已保存"];
+ }
+
+ public function listGroup(){
+ $pageSize = empty(cookie('pageSize')) ? 10 : cookie('pageSize');
+ $this->pageData = Db::name("groups")
+ ->order("id DESC")
+ ->paginate($pageSize);
+ $this->dataTotal = Db::name("groups")
+ ->order("id DESC")
+ ->count();
+ $this->pageTotal = ceil($this->dataTotal/$pageSize);
+ $this->listData = $this->pageData->all();
+ $this->pageNow = input("?get.page")?input("get.page"):1;
+ foreach ($this->listData as $key => $value) {
+ $this->listData[$key]["policy"] = Db::name("policy")->where("id",$value["policy_name"])->find();
+ $this->listData[$key]["user_num"] = Db::name("users")->where("user_group",$value["id"])->count();
+ }
+ }
+
+ public function addUser($options){
+ $options["user_pass"] = md5(config('salt').$options["user_pass"]);
+ if(Db::name('users')->where('user_email',$options["user_email"])->find() !=null){
+ return ["error" => true,"msg"=>"该邮箱已被注册"];
+ }
+ $sqlData = [
+ 'user_email' => $options["user_email"],
+ 'user_pass' => $options["user_pass"],
+ 'user_status' => $options["user_status"],
+ 'user_group' => $options["user_group"],
+ 'group_primary' => $options["user_group"],
+ 'user_date' => date("Y-m-d H:i:s"),
+ 'user_nick' => $options["user_nick"],
+ 'user_activation_key' => "n",
+ 'used_storage' => 0,
+ 'two_step'=>"0",
+ 'webdav_key' =>$options["user_pass"],
+ 'delay_time' =>0,
+ 'avatar' => "default",
+ 'profile' => true,
+ ];
+ if(Db::name('users')->insert($sqlData)){
+ $userId = Db::name('users')->getLastInsID();
+ Db::name('folders')->insert( [
+ 'folder_name' => '根目录',
+ 'parent_folder' => 0,
+ 'position' => '.',
+ 'owner' => $userId,
+ 'date' => date("Y-m-d H:i:s"),
+ 'position_absolute' => '/',
+ ]);
+ }
+ return ["error"=>0,"msg"=>"设置已保存"];
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/Avatar.php b/application/index/model/Avatar.php
new file mode 100644
index 00000000..d95f530f
--- /dev/null
+++ b/application/index/model/Avatar.php
@@ -0,0 +1,146 @@
+avatarObj = $obj;
+ if(!$new){
+ $userData = Db::name("users")->where('id',$obj)->find();
+ $this->userData = $userData;
+ if($userData["avatar"] == "default"){
+ $this->avatarType = "default";
+ }else{
+ $avatarPrarm = explode(".",$userData["avatar"]);
+ $this->avatarType = $avatarPrarm[0];
+ $this->fileName = ltrim(ltrim($userData["avatar"],"g."),"f.");
+ }
+ }
+ }
+
+ public function SaveAvatar(){
+ $info = $this->avatarObj->validate(['size'=>2097152,'ext'=>'jpg,png,gif.bmp'])->rule('uniqid')->move(ROOT_PATH . 'public' . DS . 'avatars');
+ if($info){
+ $_path = ROOT_PATH.'public/avatars/'.$info->getSaveName();
+ $_img = new Image($_path);
+ $_img->thumb(200, 200);
+ $_img->output();
+ $_img = new Image($_path);
+ $_img->thumb(130, 130);
+ $_img->output("_130");
+ $_img = new Image($_path);
+ $_img->thumb(50, 50);
+ $_img->output("_50");
+ $this->fileName = $info->getSaveName();
+ return true;
+ }else{
+ $this->errorMsg=["result"=>"error","msg"=>$this->avatarObj->getError()];
+ return false;
+ }
+ }
+
+ public function bindUser($uid){
+ $this->avatarKey = "f.".$this->fileName;
+ Db::name("users")->where('id',$uid)->update(["avatar" => $this->avatarKey]);
+ }
+
+ public function Out($size){
+ switch ($this->avatarType) {
+ case 'f':
+ $this->outPutFile($size);
+ exit();
+ break;
+ case 'default':
+ $this->defaultAvatar($size);
+ exit();
+ break;
+ case 'g':
+ return $this->outGravatar($size);
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+
+ public function outPutFile($size){
+ switch ($size) {
+ case 's':
+ $siezSuffix = "_50";
+ break;
+ case 'm':
+ $siezSuffix = "_130";
+ break;
+ default:
+ $siezSuffix = "";
+ break;
+ }
+ $filePath = ROOT_PATH . 'public/avatars/' . $this->fileName.$siezSuffix;
+ if(file_exists($filePath)){
+ ob_end_clean();
+ header('Content-Type: '.FileManage::getMimetype($filePath));
+ $fileObj = fopen($filePath,"r");
+ while(!feof($fileObj)){
+ echo fread($fileObj,2097152);
+ }
+ }else{
+ $this->defaultAvatar($siezSuffix);
+ }
+ }
+
+ public function outGravatar($size){
+ switch ($size) {
+ case 's':
+ $siezSuffix = "50";
+ break;
+ case 'm':
+ $siezSuffix = "130";
+ break;
+ default:
+ $siezSuffix = "200";
+ break;
+ }
+ ob_end_clean();
+ $gravatarServer = Option::getValue("gravatar_server");
+ return $gravatarServer.$this->fileName."?d=mm&s=".$siezSuffix;
+ }
+
+ public function defaultAvatar($size){
+ switch ($size) {
+ case 's':
+ $siezSuffix = "_50";
+ break;
+ case 'm':
+ $siezSuffix = "_130";
+ break;
+ default:
+ $siezSuffix = "";
+ break;
+ }
+ ob_end_clean();
+ $filePath = ROOT_PATH . 'static/img/default.png' .$siezSuffix;
+ header('Content-Type: '.FileManage::getMimetype($filePath));
+ $fileObj = fopen($filePath,"r");
+ while(!feof($fileObj)){
+ echo fread($fileObj,2097152);
+ }
+ }
+
+ public function setGravatar(){
+ $this->avatarKey="g.".md5($this->userData["user_email"]);
+ Db::name("users")->where('id',$this->userData["id"])->update(["avatar" => $this->avatarKey]);
+ }
+
+}
\ No newline at end of file
diff --git a/application/index/model/BasicCallBack.php b/application/index/model/BasicCallBack.php
new file mode 100644
index 00000000..1c00bad5
--- /dev/null
+++ b/application/index/model/BasicCallBack.php
@@ -0,0 +1,39 @@
+callBack = $callBack;
+ $this->realm = 'CloudreveWebDav';
+
+ }
+
+
+ public function getDigestHash($realm, $username){
+ $cb = $this->callBack;
+ return $cb($realm,$username);
+ }
+
+}
\ No newline at end of file
diff --git a/application/index/model/CallbackHandler.php b/application/index/model/CallbackHandler.php
new file mode 100644
index 00000000..486994e8
--- /dev/null
+++ b/application/index/model/CallbackHandler.php
@@ -0,0 +1,206 @@
+CallbackData = $data;
+ }
+
+ public function qiniuHandler($header){
+ $jsonData = json_decode($this->CallbackData,true);
+ $CallbackSqlData = Db::name('callback')->where('callback_key',$jsonData['callbackkey'])->find();
+ $this->policyData = Db::name('policy')->where('id',$CallbackSqlData['pid'])->find();
+
+ if(!$this->IsQiniuCallback($header)){
+ $this->setError("Undelegated Request");
+ }
+ if($this->policyData == null){
+ $this->setError("CallbackKey Not Exist.");
+ }
+ if(!FileManage::sotrageCheck($CallbackSqlData["uid"],$jsonData["fsize"])){
+ $this->setError("空间容量不足",true);
+ }
+ $picInfo = $jsonData["picinfo"];
+ $addAction = FileManage::addFile($jsonData,$this->policyData,$CallbackSqlData["uid"],$picInfo);
+ if(!$addAction[0]){
+ $this->setError($addAction[1],true);
+ }
+ FileManage::storageCheckOut($CallbackSqlData["uid"],$jsonData["fsize"]);
+ $this->setSuccess($jsonData['fname']);
+ }
+
+ public function ossHandler($auth,$pubKey){
+ if(!$this->IsOssCallback($auth,$pubKey)){
+ $this->setError("Undelegated Request");
+ }
+ $jsonData = json_decode($this->CallbackData,true);
+ $jsonData["fname"] = urldecode($jsonData["fname"]);
+ $jsonData["objname"] = urldecode($jsonData["objname"]);
+ $jsonData["path"] = urldecode($jsonData["path"]);
+ $CallbackSqlData = Db::name('callback')->where('callback_key',$jsonData['callbackkey'])->find();
+ $this->policyData = Db::name('policy')->where('id',$CallbackSqlData['pid'])->find();
+ if($this->policyData == null){
+ $this->setError("CallbackKey Not Exist.");
+ }
+ if(!FileManage::sotrageCheck($CallbackSqlData["uid"],$jsonData["fsize"])){
+ $this->setError("空间容量不足",true);
+ }
+ $picInfo = $jsonData["picinfo"];
+ $addAction = FileManage::addFile($jsonData,$this->policyData,$CallbackSqlData["uid"],$picInfo);
+ if(!$addAction[0]){
+ $this->setError($addAction[1],true);
+ }
+ FileManage::storageCheckOut($CallbackSqlData["uid"],$jsonData["fsize"]);
+ $this->setSuccess($jsonData['fname']);
+ }
+
+ public function upyunHandler($token,$date,$md5){
+ $this->policyData = Db::name("policy")->where("id",$this->CallbackData["ext-param"]["pid"])->find();
+ if(!$this->IsUpyunCallback($token,$date,$md5)){
+ $this->setError("Undelegated Request",false,true);
+ }
+ if(!FileManage::sotrageCheck($this->CallbackData["ext-param"]["uid"],$this->CallbackData["file_size"])){
+ FileManage::deleteFile($this->CallbackData["url"],$this->policyData);
+ $this->setError("空间容量不足",false,true);
+ }
+ $picInfo = empty($this->CallbackData["image-width"]) ? "" :$this->CallbackData["image-width"].",".$this->CallbackData["image-height"];
+ $fileNameExplode = explode("CLSUFF",$this->CallbackData["url"]);
+ $jsonData["fname"] = end($fileNameExplode);
+ $jsonData["objname"] = $this->CallbackData["url"];
+ $jsonData["path"] = $this->CallbackData["ext-param"]["path"];
+ $jsonData["fsize"] = $this->CallbackData["file_size"];
+ $addAction = FileManage::addFile($jsonData,$this->policyData,$this->CallbackData["ext-param"]["uid"],$picInfo);
+ if(!$addAction[0]){
+ FileManage::deleteFile($this->CallbackData["url"],$this->policyData);
+ $this->setError($addAction[1],false,true);
+ }
+ FileManage::storageCheckOut($this->CallbackData["ext-param"]["uid"],$jsonData["fsize"]);
+ $this->setSuccess($jsonData['fname']);
+ }
+
+ public function s3Handler($key){
+ $CallbackSqlData = Db::name('callback')->where('callback_key',$key)->find();
+ //删除callback记录
+ if(empty($CallbackSqlData)){
+ $this->setError("Undelegated Request",false,true);
+ }
+ $this->policyData = Db::name('policy')->where('id',$CallbackSqlData['pid'])->find();
+ $this->userData = Db::name('users')->where('id',$CallbackSqlData['uid'])->find();
+ $paths = explode("/",$this->CallbackData["key"]);
+ $jsonData["fname"] = end($paths);
+ $jsonData["objname"] = $this->CallbackData["key"];
+ $jsonData["path"] ="";
+ foreach ($paths as $key => $value) {
+ if($key == 0 || $key == count($paths)-1) continue;
+ $jsonData["path"].=$value.",";
+ }
+ $jsonData["path"] = rtrim($jsonData["path"],",");
+ $jsonData["fsize"] = $this->getS3FileInfo();
+ if(!$jsonData["fsize"]){
+ $this->setError("File not exist",false,true);
+ }
+ $jsonData["fsize"] = $jsonData["fsize"]["size"];
+ $picInfo = "";
+ $addAction = FileManage::addFile($jsonData,$this->policyData,$this->userData["id"],"");
+ if(!$addAction[0]){
+ FileManage::deleteFile($this->CallbackData["key"],$this->policyData);
+ $this->setError($addAction[1],false,true);
+ }
+ FileManage::storageCheckOut($this->userData["id"],$jsonData["fsize"]);
+ $this->setSuccess($jsonData['fname']);
+ }
+
+ private function getS3FileInfo(){
+ $s3 = new \S3\S3($this->policyData["ak"], $this->policyData["sk"],false,$this->policyData["op_pwd"]);
+ $s3->setSignatureVersion('v4');
+ try {
+ $returnVal = $s3->getObjectInfo($this->policyData["bucketname"],$this->CallbackData["key"]);
+ } catch (Exception $e) {
+ return false;
+ }
+ return $returnVal;
+ }
+
+ public function setSuccess($fname){
+ die(json_encode(["key"=> $fname]));
+ }
+
+ public function setError($text,$delete = false,$ignore=false){
+ header("HTTP/1.1 401 Unauthorized");
+ if(!$ignore){
+ $deletedFile = json_decode($this->CallbackData,true);
+ $fileNmae = $deletedFile['objname'];
+ if($delete){
+ FileManage::deleteFile($fileNmae,$this->policyData);
+ }
+ }
+ die(json_encode(["error"=> $text]));
+ }
+
+ private function isUpyunCallback($token,$date,$md5){
+ if(UploadHandler::upyunSign($this->policyData["op_name"],md5($this->policyData["op_pwd"]),"POST","/Callback/Upyun",$date,$md5) != $token){
+ return false;
+ }
+ return true;
+ }
+
+ public function IsQiniuCallback($httpHeader){
+ $auth = new Auth($this->policyData['ak'], $this->policyData['sk']);
+ $callbackBody = $this->CallbackData;
+ $contentType = 'application/json';
+ $authorization = $httpHeader;
+ $url = Option::getValue("siteUrl")."Callback/Qiniu";
+ $isQiniuCallback = $auth->verifyCallback($contentType, $authorization, $url,$callbackBody);
+ if ($isQiniuCallback) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public function IsOssCallback($auth,$pubKey){
+ if (empty($auth) || empty($pubKey)){
+ header("http/1.1 403 Forbidden");
+ exit();
+ }
+ $authorization = base64_decode($auth);
+ $pubKeyUrl = base64_decode($pubKey);
+ $pubOssKey = file_get_contents($pubKeyUrl);
+ if ($pubOssKey == ""){
+ return false;
+ }
+ $body = file_get_contents('php://input');
+ $authStr = '';
+ $path = $_SERVER['REQUEST_URI'];
+ $pos = strpos($path, '?');
+ if ($pos === false){
+ $authStr = urldecode($path)."\n".$body;
+ }else{
+ $authStr = urldecode(substr($path, 0, $pos)).substr($path, $pos, strlen($path) - $pos)."\n".$body;
+ }
+ $ok = openssl_verify($authStr, $authorization, $pubOssKey, OPENSSL_ALGO_MD5);
+ if ($ok == 1){
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+}
+
+
+?>
\ No newline at end of file
diff --git a/application/index/model/CronHandler.php b/application/index/model/CronHandler.php
new file mode 100644
index 00000000..d57314d7
--- /dev/null
+++ b/application/index/model/CronHandler.php
@@ -0,0 +1,73 @@
+cornTasks = Db::name('corn')->where('enable',1)->order('rank desc')->select();
+ $this->timeNow = time();
+ }
+
+ public function checkInterval($interval,$last){
+ return ($last+$interval)<= $this->timeNow ? true : false;
+ }
+
+ public function setComplete($name){
+ Db::name('corn')->where('name', $name)->update(['last_excute' => $this->timeNow]);
+ }
+
+ public function Doit(){
+ foreach ($this->cornTasks as $key => $value) {
+ switch ($value["name"]) {
+ case 'delete_unseful_chunks':
+ if($this->checkInterval($value["interval_s"],$value["last_excute"])){
+ $this->deleteUnsefulChunks($value["interval_s"]);
+ }
+ break;
+ case 'delete_callback_data':
+ if($this->checkInterval($value["interval_s"],$value["last_excute"])){
+ $this->deleteCallbackData($value["interval_s"]);
+ }
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+ }
+
+ private function deleteUnsefulChunks($interval){
+ echo("deleteUnsefulChunks...");
+ $chunkInfo = Db::name('chunks')->whereTime('time', '<', date('Y-m-d', time()-86400))->select();
+ $deleteList=[];
+ foreach ($chunkInfo as $key => $value) {
+ $fileSize = @filesize(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
+ @unlink(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
+ FileManage::storageGiveBack($value["user"],$fileSize?$fileSize:0);
+ $deleteList["$key"] = $value["id"];
+ }
+ Db::name('chunks')->where(['id' => ["in",$deleteList],])->delete();
+ $this->setComplete("delete_unseful_chunks");
+ echo("Complete
");
+ }
+
+ private function deleteCallbackData($interval){
+ echo("deleteCallbackData...");
+ Db::name("callback")->delete(true);
+ echo("Complete
");
+ $this->setComplete("delete_callback_data");
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/DavAuth.php b/application/index/model/DavAuth.php
new file mode 100644
index 00000000..2462bc10
--- /dev/null
+++ b/application/index/model/DavAuth.php
@@ -0,0 +1,30 @@
+uid = $id;
+ }
+
+ public function __invoke($realm,$um){
+ $userData = Db::name("users")->where("id",$this->uid)->find();
+ if(empty($userData) || $userData["user_email"] != $um){
+ return null;
+ }
+ $userGroup = Db::name("groups")->where("id",$userData["user_group"])->find();
+ if(!$userGroup["webdav"]){
+ return null;
+ }
+ return $userData["webdav_key"];
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/application/index/model/Directory.php b/application/index/model/Directory.php
new file mode 100644
index 00000000..72f881a7
--- /dev/null
+++ b/application/index/model/Directory.php
@@ -0,0 +1,186 @@
+uid = $ex[0];
+ if(empty($this->uid)){
+ return false;
+ }
+ $t = strpos($path,$this->uid);
+ if($t == 0){
+ $this->myPath = substr($path,$t+strlen($this->uid));
+ }else{
+ $this->myPath = $path;
+ }
+ $this->myPath = empty($this->myPath) ? "/" : $this->myPath;
+ }
+
+ function createFile($name, $data = NULL){
+ $userData = Db::name("users")->where("id",$this->uid)->find();
+ $groupData = Db::name("groups")->where("id",$userData["user_group"])->find();
+ $policyData = Db::name("policy")->where("id",$groupData["policy_name"])->find();
+ $uploadHandle = new UploadHandler($groupData["policy_name"],$this->uid);
+ $allowedExt = UploadHandler::getAllowedExt(json_decode($policyData["filetype"],true));
+ if(!empty($allowedExt)){
+ $ex = explode(".",$name);
+ $fileSuffix = end($ex);
+ if(!in_array($fileSuffix, explode(",",$allowedExt))){
+ throw new DAV\Exception\InvalidResourceType('File type not allowed');
+ }
+ }
+ if($policyData["policy_type"] !="local"){
+ throw new DAV\Exception\Forbidden('Poliyc not supported yet');
+ }
+ $fileSize = fstat($data)["size"];
+ if(empty($fileSize)){
+ $fileSize = 0;
+ }
+ if($fileSize>$policyData["max_size"]){
+ throw new DAV\Exception\InsufficientStorage('File is to large');
+ }
+ if(!FileManage::sotrageCheck($this->uid,$fileSize)){
+ throw new DAV\Exception\InsufficientStorage('Quota is not enough');
+ }
+ if($policyData['autoname']){
+ $fileName = $uploadHandle->getObjName($policyData['namerule'],"local",$name);
+ }else{
+ $fileName = $name;
+ }
+ $generatePath = $uploadHandle->getDirName($policyData['dirrule']);
+ $savePath = ROOT_PATH . 'public/uploads/'.$generatePath;
+ if(!file_exists($savePath)){
+ mkdir($savePath,0777,true);
+ }
+ file_put_contents($savePath."/".$fileName, $data);
+ $jsonData = array(
+ "path" => str_replace("/",",",ltrim($this->myPath,"/")),
+ "fname" => $name,
+ "objname" => $generatePath."/".$fileName,
+ "fsize" => $fileSize,
+ );
+ @list($width, $height, $type, $attr) = getimagesize(rtrim($savePath, DS).DS.$fileName);
+ $picInfo = empty($width)?" ":$width.",".$height;
+ $addAction = FileManage::addFile($jsonData,$policyData,$this->uid,$picInfo);
+ if(!$addAction[0]){
+ unlink($savePath."/".$fileName);
+ throw new DAV\Exception\Conflict($addAction[1]);
+ }
+ FileManage::storageCheckOut($this->uid,$jsonData["fsize"]);
+ //echo json_encode(array("key" => $info["name"]));
+ }
+
+ function getQuotaInfo() {
+ $this->userObj = new User($this->uid,"",true);
+ $quotaInfo = json_decode($this->userObj->getMemory(true),true);
+ return [
+ $quotaInfo["used"],
+ $quotaInfo["total"]
+ ];
+
+ }
+
+ function setName($name){
+ $reqPath = $this->myPath;
+ $ex = explode("/",$reqPath);
+ $newPath = rtrim(dirname($reqPath) == "\\" ?"/":dirname($reqPath),"/")."/".$name;
+ $renameAction = json_decode(FileManage::RenameHandler($reqPath,$newPath,$this->uid,true),true);
+ if(!$renameAction["result"]["success"]){
+ throw new DAV\Exception\InvalidResourceType($renameAction["result"]["error"]);
+ }
+ }
+
+ function getChildren() {
+ $children = array();
+ $fileList = Db::name('files')->where('upload_user',$this->uid)->where('dir',$this->myPath)->select();
+ $dirList = Db::name('folders')->where('owner',$this->uid)->where('position',$this->myPath)->select();
+ foreach($fileList as $node) {
+ // Ignoring files staring with .
+ $children[] = $this->getChildFile($node,false);
+ }
+ foreach($dirList as $node) {
+ // Ignoring files staring with .
+ $children[] = $this->getChildDir($node,true);
+ }
+ return $children;
+ }
+
+ function getChildFile($name){
+ $path = $this->uid.rtrim($this->myPath,"/") . '/' . $name["orign_name"];
+ return new Object($path);
+ }
+
+ function getChildDir($name){
+ $path = $this->uid.rtrim($this->myPath,"/") . '/' . $name["folder_name"];
+ return new Directory($path);
+ }
+
+ function delete(){
+ foreach ($this->getChildren() as $child) $child->delete();
+ FileManage::DirDeleteHandler([0=>$this->myPath],$this->uid);
+ }
+
+ function getChild($name) {
+ if(!$this->childExists($name)){
+ throw new DAV\Exception\NotFound('File with name ' . $name . ' could not be located');
+ }
+ $path = $this->uid.rtrim($this->myPath,"/") . '/' . $name;
+ if($this->findDir(rtrim($this->myPath,"/") . '/' . $name)){
+ $returnObj = new Directory($path);
+ return $returnObj;
+ }else{
+ return new Object($path);
+ }
+ }
+
+ function childExists($name) {
+ $fileObj = new Object($this->uid.rtrim($this->myPath,"/") . '/' . $name);
+ if($this->findDir(rtrim($this->myPath,"/") . '/' . $name) || $fileObj->isExist){
+ return true;
+ }
+ return false;
+ }
+
+ public function findDir($path){
+ if($path == "/"){
+ return true;
+ }
+ $explode = explode("/",$path);
+ $dirName = end($explode);
+ $rootPath = rtrim($path,"/".$dirName);
+ $rootPath = empty($rootPath) ? "/" : $rootPath;
+ $dirData = Db::name('folders')->where('owner',$this->uid)->where('position',dirname($path) == "\\" ?"/":dirname($path))->where("folder_name",basename($path))->find();
+ if(empty($dirData)){
+ return false;
+ }
+ return true;
+ }
+
+ function getName() {
+ $explode = explode("/", $this->myPath);
+ return end($explode);
+
+ }
+
+ function createDirectory($name) {
+ $createAction = FileManage::createFolder($name,$this->myPath,$this->uid);
+ if(!$createAction["result"]["success"]){
+ die($this->myPath);
+ throw new DAV\Exception\InvalidResourceType($createAction["result"]["error"]);
+ }
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/FileManage.php b/application/index/model/FileManage.php
new file mode 100644
index 00000000..bb034543
--- /dev/null
+++ b/application/index/model/FileManage.php
@@ -0,0 +1,1238 @@
+filePath = $path;
+ $fileInfo = $this->getFileName($path);
+ $fileName = $fileInfo[0];
+ $path = $fileInfo[1];
+ $fileRecord = Db::name('files')->where('upload_user',$uid)->where('orign_name',$fileName)->where('dir',$path)->find();
+ if (empty($fileRecord)){
+ die('{ "result": { "success": false, "error": "文件不存在" } }');
+ }
+ $this->fileData = $fileRecord;
+ $this->userID = $uid;
+ $this->userData = Db::name('users')->where('id',$uid)->find();
+ $this->policyData = Db::name('policy')->where('id',$this->fileData["policy_id"])->find();
+ }
+
+ public function Source(){
+ if(!$this->policyData["origin_link"]){
+ die('{"url":"此文件不支持获取源文件URL"}');
+ }else{
+ echo ('{"url":"'.$this->policyData["url"].$this->fileData["pre_name"].'"}');
+ }
+ }
+
+ public function getContent(){
+ $sizeLimit=(int)Option::getValue("maxEditSize");
+ if($this->fileData["size"]>$sizeLimit){
+ die('{ "result": { "success": false, "error": "您当前用户组最大可编辑'.$sizeLimit.'字节的文件"} }');
+ }else{
+ switch ($this->policyData["policy_type"]) {
+ case 'local':
+ $filePath = ROOT_PATH . 'public/uploads/' . $this->fileData["pre_name"];
+ $fileContent = $this->getLocalFileContent($filePath);
+ break;
+ case 'qiniu':
+ $fileContent = $this->getQiniuFileContent();
+ break;
+ case 'oss':
+ $fileContent = $this->getOssFileContent();
+ break;
+ case 'upyun':
+ $fileContent = $this->getUpyunFileContent();
+ break;
+ case 's3':
+ $fileContent = $this->getS3FileContent();
+ break;
+ default:
+ # code...
+ break;
+ }
+ $result["result"] = $fileContent;
+ if(empty(json_encode($result))){
+ $result["result"] = iconv('gb2312','utf-8',$fileContent);
+ }
+ echo json_encode($result);
+ }
+ }
+
+ public function getLocalFileContent($path){
+ $fileObj = fopen($path,"r");
+ $fileContent = fread($fileObj,filesize($path)+1);
+ return $fileContent;
+ }
+
+ public function getQiniuFileContent(){
+ return file_get_contents($this->qiniuPreview()[1]);
+ }
+
+ public function getOssFileContent(){
+ return file_get_contents($this->ossPreview()[1]);
+ }
+
+ public function getUpyunFileContent(){
+ return file_get_contents($this->upyunPreview()[1]);
+ }
+
+ public function getS3FileContent(){
+ return file_get_contents($this->s3Preview()[1]);
+ }
+
+ public function saveContent($content){
+ $contentSize = strlen($content);
+ $originSize = $this->fileData["size"];
+ if(!FileManage::sotrageCheck($this->userID,$contentSize)){
+ die('{ "result": { "success": false, "error": "空间容量不足" } }');
+ }
+ switch ($this->policyData["policy_type"]) {
+ case 'local':
+ $filePath = ROOT_PATH . 'public/uploads/' . $this->fileData["pre_name"];
+ file_put_contents($filePath, "");
+ file_put_contents($filePath, $content);
+ break;
+ case 'qiniu':
+ $this->saveQiniuContent($content);
+ break;
+ case 'oss':
+ $this->saveOssContent($content);
+ break;
+ case 'upyun':
+ $this->saveUpyunContent($content);
+ break;
+ case 's3':
+ $this->saveS3Content($content);
+ break;
+ default:
+ # code...
+ break;
+ }
+ FileManage::storageGiveBack($this->userID,$originSize);
+ FileManage::storageCheckOut($this->userID,$contentSize);
+ Db::name('files')->where('id', $this->fileData["id"])->update(['size' => $contentSize]);
+ echo ('{ "result": { "success": true} }');
+ }
+
+ public function saveQiniuContent($content){
+ $auth = new Auth($this->policyData["ak"], $this->policyData["sk"]);
+ $expires = 3600;
+ $keyToOverwrite = $this->fileData["pre_name"];
+ $upToken = $auth->uploadToken($this->policyData["bucketname"], $keyToOverwrite, $expires, null, true);
+ $uploadMgr = new \Qiniu\Storage\UploadManager();
+ list($ret, $err) = $uploadMgr->put($upToken, $keyToOverwrite, $content);
+ if ($err !== null) {
+ die('{ "result": { "success": false, "error": "编辑失败" } }');
+ } else {
+ return true;
+ }
+ }
+
+ public function saveOssContent($content){
+ $accessKeyId = $this->policyData["ak"];
+ $accessKeySecret = $this->policyData["sk"];
+ $endpoint = "http".ltrim(ltrim($this->policyData["server"],"https"),"http");
+ try {
+ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);
+ } catch (OssException $e) {
+ die('{ "result": { "success": false, "error": "鉴权失败" } }');
+ }
+ try{
+ $ossClient->putObject($this->policyData["bucketname"], $this->fileData["pre_name"], $content);
+ } catch(OssException $e) {
+ die('{ "result": { "success": false, "error": "编辑失败" } }');
+ }
+ }
+
+ public function saveUpyunContent($content){
+ $bucketConfig = new Config($this->policyData["bucketname"], $this->policyData["op_name"], $this->policyData["op_pwd"]);
+ $client = new Upyun($bucketConfig);
+ if(empty($content)){
+ $content = " ";
+ }
+ $res=$client->write($this->fileData["pre_name"],$content);
+ }
+
+ public function saveS3Content($content){
+ $s3 = new \S3\S3($this->policyData["ak"], $this->policyData["sk"],false,$this->policyData["op_pwd"]);
+ $s3->setSignatureVersion('v4');
+ $s3->putObjectString($content, $this->policyData["bucketname"], $this->fileData["pre_name"]);
+ }
+
+ static function fileNameValidate($value){
+ $validate = new Validate([
+ 'val' => 'require|max:250',
+ 'val' => 'chsDash'
+ ]);
+ $data = [
+ 'val' => $value
+ ];
+ if (!$validate->check($data)) {
+ return false;
+ }
+ return true;
+ }
+
+ static function RenameHandler($fname,$new,$uid,$notEcho = false){
+ $folderTmp = $new;
+ $originFolder = $fname;
+ $new = str_replace("/", "", self::getFileName($new)[0]);
+ if(!$notEcho){
+ $new = str_replace(" ", "", $new);
+ }
+ if(!self::fileNameValidate($new)){
+ if($notEcho){
+ return '{ "result": { "success": false, "error": "文件名只支持数字、字母、下划线" } }';
+ }
+ die('{ "result": { "success": false, "error": "文件名只支持数字、字母、下划线" } }');
+ }
+ $path = self::getFileName($fname)[1];
+ $fname = self::getFileName($fname)[0];
+ $fileRecord = Db::name('files')->where('upload_user',$uid)->where('orign_name',$fname)->where('dir',$path)->find();
+ if (empty($new)){
+ if($notEcho){
+ return '{ "result": { "success": false, "error": "文件重名或文件名非法" } }';
+ }
+ die('{ "result": { "success": false, "error": "文件重名或文件名非法" } }');
+ }
+ if(empty($fileRecord)){
+ self::folderRename($originFolder,$folderTmp,$uid,$notEcho);
+ die();
+ }
+ $originSuffix = explode(".",$fileRecord["orign_name"]);
+ $newSuffix = explode(".",$new);
+ if(end($originSuffix) != end($newSuffix)){
+ if($notEcho){
+ return '{ "result": { "success": false, "error": "请不要更改文件扩展名" } }';
+ }
+ die('{ "result": { "success": false, "error": "请不要更改文件扩展名" } }');
+ }
+ Db::name('files')->where([
+ 'upload_user' => $uid,
+ 'dir' => $path,
+ 'orign_name' =>$fname,
+ ])->setField('orign_name', $new);
+ if($notEcho){
+ return '{ "result": { "success": true} }';
+ }
+ echo ('{ "result": { "success": true} }');
+ }
+
+ static function folderRename($fname,$new,$uid,$notEcho = false){
+ $newTmp = $new;
+ $nerFolderTmp = explode("/",$new);
+ $new = array_pop($nerFolderTmp);
+ $oldFolderTmp = explode("/",$fname);
+ $old = array_pop($oldFolderTmp);
+ if(!self::fileNameValidate($new)){
+ if($notEcho){
+ return '{ "result": { "success": false, "error": "目录名只支持数字、字母、下划线" } }';
+ }
+ die('{ "result": { "success": false, "error": "目录名只支持数字、字母、下划线" } }');
+ }
+ $folderRecord = Db::name('folders')->where('owner',$uid)->where('position_absolute',$fname)->find();
+ if(empty($folderRecord)){
+ if($notEcho){
+ return '{ "result": { "success": false, "error": "目录不存在" } }';
+ }
+ die('{ "result": { "success": false, "error": "目录不存在" } }');
+ }
+ $newPositionAbsolute = substr($fname, 0, strrpos( $fname, '/'))."/".$new;
+ Db::name('folders')->where('owner',$uid)->where('position_absolute',$fname)->update([
+ 'folder_name' => $new,
+ 'position_absolute' => $newPositionAbsolute,
+ ]);
+ $childFolder = Db::name('folders')->where('owner',$uid)->where('position',"like",$fname."%")->select();
+ foreach ($childFolder as $key => $value) {
+ $tmpPositionAbsolute = "";
+ $tmpPosition = "";
+ $pos = strpos($value["position_absolute"], $fname);
+ if ($pos === false) {
+ $tmpPositionAbsolute = $value["position_absolute"];
+ }
+ $tmpPositionAbsolute = substr_replace($value["position_absolute"], $newTmp, $pos, strlen($fname));
+ $pos = strpos($value["position"], $fname);
+ if ($pos === false) {
+ $tmpPosition = $value["position"];
+ }
+ $tmpPosition = substr_replace($value["position"], $newTmp, $pos, strlen($fname));
+ Db::name('folders')->where('id',$value["id"])->update([
+ 'position_absolute' => $tmpPositionAbsolute,
+ 'position' =>$tmpPosition,
+ ]);
+ }
+ $childFiles = Db::name('files')->where('upload_user',$uid)->where('dir',"like",$fname."%")->select();
+ foreach ($childFiles as $key => $value) {
+ $tmpPosition = "";
+ $pos = strpos($value["dir"], $fname);
+ if ($pos === false) {
+ $tmpPosition = $value["dir"];
+ }
+ $tmpPosition = substr_replace($value["dir"], $newTmp, $pos, strlen($fname));
+ Db::name('files')->where('id',$value["id"])->update([
+ 'dir' =>$tmpPosition,
+ ]);
+ }
+ if($notEcho){
+ return '{ "result": { "success": true} }';
+ }
+ echo ('{ "result": { "success": true} }');
+ }
+
+ static function getFileName($path){
+ $pathSplit = explode("/",$path);
+ $fileName = end($pathSplit);
+ $pathSplitDelete = array_pop($pathSplit);
+ $path="";
+ foreach ($pathSplit as $key => $value) {
+ if (empty($value)){
+
+ }else{
+ $path =$path."/".$value;
+ }
+ }
+ $path = empty($path)?"/":$path;
+ return [$fileName,$path];
+ }
+
+ public function PreviewHandler($isAdmin=false){
+ switch ($this->policyData["policy_type"]) {
+ case 'qiniu':
+ $Redirect = $this->qiniuPreview();
+ return $Redirect;
+ break;
+ case 'local':
+ $Redirect = $this->localPreview($isAdmin);
+ return $Redirect;
+ break;
+ case 'oss':
+ $Redirect = $this->ossPreview();
+ return $Redirect;
+ break;
+ case 'upyun':
+ $Redirect = $this->upyunPreview();
+ return $Redirect;
+ break;
+ case 's3':
+ $Redirect = $this->s3Preview();
+ return $Redirect;
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+
+ public function getThumb(){
+ switch ($this->policyData["policy_type"]) {
+ case 'qiniu':
+ $Redirect = $this->getQiniuThumb();
+ return $Redirect;
+ case 'local':
+ $Redirect = $this->getLocalThumb();
+ return $Redirect;
+ break;
+ case 'oss':
+ $Redirect = $this->getOssThumb();
+ return $Redirect;
+ break;
+ case 'upyun':
+ $Redirect = $this->getUpyunThumb();
+ return $Redirect;
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+
+ public function Download($isAdmin=false){
+ switch ($this->policyData["policy_type"]) {
+ case 'qiniu':
+ return $DownloadHandler = $this->qiniuDownload();
+ break;
+ case 'local':
+ return $DownloadHandler = $this->localDownload($isAdmin);
+ break;
+ case 'oss':
+ return $DownloadHandler = $this->ossDownload();
+ break;
+ case 'upyun':
+ return $DownloadHandler = $this->upyunDownload();
+ break;
+ case 's3':
+ return $DownloadHandler = $this->s3Download();
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+
+ static function DirDeleteHandler($path,$uid){
+ global $toBeDeleteDir;
+ global $toBeDeleteFile;
+ $toBeDeleteDir = [];
+ $toBeDeleteFile = [];
+ foreach ($path as $key => $value) {
+ array_push($toBeDeleteDir,$value);
+ }
+
+ foreach ($path as $key => $value) {
+ self::listToBeDelete($value,$uid);
+ }
+ if(!empty($toBeDeleteFile)){
+ self::DeleteHandler($toBeDeleteFile,$uid);
+ }
+ if(!empty($toBeDeleteDir)){
+ self::deleteDir($toBeDeleteDir,$uid);
+ }
+ }
+
+ static function listToBeDelete($path,$uid){
+ global $toBeDeleteDir;
+ global $toBeDeleteFile;
+ $fileData = Db::name('files')->where([
+ 'dir' => $path,
+ 'upload_user' => $uid,
+ ])->select();
+ foreach ($fileData as $key => $value) {
+ array_push($toBeDeleteFile,$path."/".$value["orign_name"]);
+ }
+ $dirData = Db::name('folders')->where([
+ 'position' => $path,
+ 'owner' => $uid,
+ ])->select();
+ foreach ($dirData as $key => $value) {
+ array_push($toBeDeleteDir,$value["position_absolute"]);
+ self::listToBeDelete($value["position_absolute"],$uid);
+ }
+ }
+
+ static function deleteDir($path,$uid){
+ Db::name('folders')
+ ->where("owner",$uid)
+ ->where([
+ 'position_absolute' => ["in",$path],
+ ])->delete();
+ }
+
+ static function DeleteHandler($path,$uid){
+ if(empty($path)){
+ return ["result"=>["success"=>true,"error"=>null]];
+ }
+ foreach ($path as $key => $value) {
+ $fileInfo = self::getFileName($value);
+ $fileName = $fileInfo[0];
+ $filePath = $fileInfo[1];
+ $fileNames[$key] = $fileName;
+ $filePathes[$key] = $filePath;
+ }
+ $fileData = Db::name('files')->where([
+ 'orign_name' => ["in",$fileNames],
+ 'dir' => ["in",$filePathes],
+ 'upload_user' => $uid,
+ ])->select();
+ $fileListTemp=[];
+ $uniquePolicy = self::uniqueArray($fileData);
+ foreach ($fileData as $key => $value) {
+ if(empty($fileListTemp[$value["policy_id"]])){
+ $fileListTemp[$value["policy_id"]] = [];
+ }
+ array_push($fileListTemp[$value["policy_id"]],$value);
+ }
+ foreach ($fileListTemp as $key => $value) {
+ if(in_array($key,$uniquePolicy["qiniuList"])){
+ self::qiniuDelete($value,$uniquePolicy["qiniuPolicyData"][$key][0]);
+ }else if(in_array($key,$uniquePolicy["localList"])){
+ self::localDelete($value,$uniquePolicy["localPolicyData"][$key][0]);
+ }else if(in_array($key,$uniquePolicy["ossList"])){
+ self::ossDelete($value,$uniquePolicy["ossPolicyData"][$key][0]);
+ }else if(in_array($key,$uniquePolicy["upyunList"])){
+ self::upyunDelete($value,$uniquePolicy["upyunPolicyData"][$key][0]);
+ }else if(in_array($key,$uniquePolicy["s3List"])){
+ self::s3Delete($value,$uniquePolicy["s3PolicyData"][$key][0]);
+ }
+ }
+ return ["result"=>["success"=>true,"error"=>null]];
+ }
+
+ static function MoveHandler($file,$dir,$new,$uid){
+ if(in_array($new,$dir)){
+ die('{ "result": { "success": false, "error": "不能移动目录到自身" } }');
+ }
+ if(Db::name('folders')->where('owner',$uid)->where('position_absolute',$new)->find() == null){
+ die('{ "result": { "success": false, "error": "目录不存在" } }');
+ }
+ $moveName=[];
+ $movePath=[];
+ foreach ($file as $key => $value) {
+ $fileInfo = self::getFileName($value);
+ $moveName[$key] = $fileInfo[0];
+ $movePath[$key] = $fileInfo[1];
+ }
+ $dirName=[];
+ $dirPa=[];
+ foreach ($dir as $key => $value) {
+ $dirInfo = self::getFileName($value);
+ $dirName[$key] = $dirInfo[0];
+ $dirPar[$key] = $dirInfo[1];
+ }
+ $nameCheck = Db::name('files')->where([
+ 'upload_user' => $uid,
+ 'dir' => $new,
+ 'orign_name' =>["in",$moveName],
+ ])->find();
+ $dirNameCheck = array_merge($dirName,$moveName);
+ $dirCheck = Db::name('folders')->where([
+ 'owner' => $uid,
+ 'position' => $new,
+ 'folder_name' =>["in",$dirNameCheck],
+ ])->find();
+ if($nameCheck || $dirCheck){
+ die('{ "result": { "success": false, "error": "文件名冲突,请检查是否重名" } }');
+ }
+ if(!empty($dir)){
+ die('{ "result": { "success": false, "error": "暂不支持移动目录" } }');
+ }
+ Db::name('files')->where([
+ 'upload_user' => $uid,
+ 'dir' => ["in",$movePath],
+ 'orign_name' =>["in",$moveName],
+ ])->setField('dir', $new);
+ echo ('{ "result": { "success": true} }');
+ }
+
+ static function moveFile($file,$path){
+
+ }
+
+ static function localDelete($fileList,$policyData){
+ $fileListTemp = array_column($fileList, 'pre_name');
+ foreach ($fileListTemp as $key => $value) {
+ @unlink(ROOT_PATH . 'public/uploads/'.$value);
+ if(file_exists(ROOT_PATH . 'public/thumb/'.$value."_thumb")){
+ @unlink(ROOT_PATH . 'public/thumb/'.$value."_thumb");
+ }
+ }
+ self::deleteFileRecord(array_column($fileList, 'id'),array_sum(array_column($fileList, 'size')),$fileList[0]["upload_user"]);
+ }
+
+ static function qiniuDelete($fileList,$policyData){
+ $auth = new Auth($policyData["ak"], $policyData["sk"]);
+ $config = new \Qiniu\Config();
+ $bucketManager = new \Qiniu\Storage\BucketManager($auth);
+ $fileListTemp = array_column($fileList, 'pre_name');
+ $ops = $bucketManager->buildBatchDelete($policyData["bucketname"], $fileListTemp);
+ list($ret, $err) = $bucketManager->batch($ops);
+ self::deleteFileRecord(array_column($fileList, 'id'),array_sum(array_column($fileList, 'size')),$fileList[0]["upload_user"]);
+ }
+
+ static function ossDelete($fileList,$policyData){
+ $accessKeyId = $policyData["ak"];
+ $accessKeySecret = $policyData["sk"];
+ $endpoint = "http".ltrim(ltrim($policyData["server"],"https"),"http");
+ try {
+ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);
+ } catch (OssException $e) {
+ return false;
+ }
+ try{
+ $ossClient->deleteObjects($policyData["bucketname"], array_column($fileList, 'pre_name'));
+ } catch(OssException $e) {
+ return false;
+ }
+ self::deleteFileRecord(array_column($fileList, 'id'),array_sum(array_column($fileList, 'size')),$fileList[0]["upload_user"]);
+ }
+
+ static function upyunDelete($fileList,$policyData){
+ foreach (array_column($fileList, 'pre_name') as $key => $value) {
+ self::deleteUpyunFile($value,$policyData);
+ }
+ self::deleteFileRecord(array_column($fileList, 'id'),array_sum(array_column($fileList, 'size')),$fileList[0]["upload_user"]);
+ }
+
+ static function s3Delete($fileList,$policyData){
+ foreach (array_column($fileList, 'pre_name') as $key => $value) {
+ self::deleteS3File($value,$policyData);
+ }
+ self::deleteFileRecord(array_column($fileList, 'id'),array_sum(array_column($fileList, 'size')),$fileList[0]["upload_user"]);
+ }
+
+ static function deleteFileRecord($id,$size,$uid){
+ Db::name('files')->where([
+ 'id' => ["in",$id],
+ ])->delete();
+ Db::name('shares')
+ ->where(['owner' => $uid])
+ ->where(['source_type' => "file"])
+ ->where(['source_name' => ["in",$id],])
+ ->delete();
+ Db::name('users')->where([
+ 'id' => $uid,
+ ])->setDec('used_storage', $size);
+ }
+
+ static function getThumbSize($width,$height){
+ $rate = $width/$height;
+ $maxWidth = 90;
+ $maxHeight = 39;
+ $changeWidth = 39*$rate;
+ $changeHeight = 90/$rate;
+ if($changeWidth>=$maxWidth){
+ return [(int)$changeHeight,90];
+ }
+ return [39,(int)$changeWidth];
+ }
+
+ static function outputThumb($path){
+ ob_end_clean();
+ if(!input("get.cache")=="no"){
+ header("Cache-Control: max-age=10800");
+ }
+ header('Content-Type: '.self::getMimetype($path));
+ $fileObj = fopen($path,"r");
+ echo fread($fileObj,filesize($path));
+ fclose($file);
+ }
+
+ public function getLocalThumb(){
+ $picInfo = explode(",",$this->fileData["pic_info"]);
+ $picInfo = self::getThumbSize($picInfo[0],$picInfo[1]);
+ if(file_exists(ROOT_PATH . "public/thumb/".$this->fileData["pre_name"]."_thumb")){
+ self::outputThumb(ROOT_PATH . "public/thumb/".$this->fileData["pre_name"]."_thumb");
+ return [0,0];
+ }
+ $thumbImg = new Thumb(ROOT_PATH . "public/uploads/".$this->fileData["pre_name"]);
+ $thumbImg->thumb($picInfo[1], $picInfo[0]);
+ if(!is_dir(dirname(ROOT_PATH . "public/thumb/".$this->fileData["pre_name"]))){
+ mkdir(dirname(ROOT_PATH . "public/thumb/".$this->fileData["pre_name"]),0777,true);
+ }
+ $thumbImg->out(ROOT_PATH . "public/thumb/".$this->fileData["pre_name"]."_thumb");
+ self::outputThumb(ROOT_PATH . "public/thumb/".$this->fileData["pre_name"]."_thumb");
+ return [0,0];
+ }
+
+ public function getOssThumb(){
+ if(!$this->policyData['bucket_private']){
+ $fileUrl = $this->policyData["url"].$this->fileData["pre_name"]."?x-oss-process=image/resize,m_lfit,h_39,w_90";
+ return[true,$fileUrl];
+ }else{
+ $accessKeyId = $this->policyData["ak"];
+ $accessKeySecret = $this->policyData["sk"];
+ $endpoint = $this->policyData["url"];
+ try {
+ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);
+ } catch (OssException $e) {
+ return [false,0];
+ }
+ $baseUrl = $this->policyData["url"].$this->fileData["pre_name"];
+ try{
+ $signedUrl = $ossClient->signUrl($this->policyData["bucketname"], $this->fileData["pre_name"], Option::getValue("timeout"),'GET', array("x-oss-process" => 'image/resize,m_lfit,h_39,w_90'));
+ } catch(OssException $e) {
+ return [false,0];
+ }
+ return[true,$signedUrl];
+ }
+ }
+
+ public function getQiniuThumb(){
+ return $this->qiniuPreview("?imageView2/2/w/90/h/39");
+ }
+
+ private function getUpyunThumb(){
+ $picInfo = explode(",",$this->fileData["pic_info"]);
+ $thumbSize = self::getThumbSize($picInfo[0],$picInfo[1]);
+ $baseUrl =$this->policyData["url"].$this->fileData["pre_name"]."!/fwfh/90x39";
+ return [1,$this->upyunPreview($baseUrl,$this->fileData["pre_name"]."!/fwfh/90x39")[1]];
+ }
+
+ public function s3Preview(){
+ $timeOut = Option::getValue("timeout");
+ return [1,\S3\S3::aws_s3_link($this->policyData["ak"], $this->policyData["sk"],$this->policyData["bucketname"],"/".$this->fileData["pre_name"],3600,$this->policyData["op_name"])];
+ }
+
+ public function upyunPreview($base=null,$name=null){
+ if(!$this->policyData['bucket_private']){
+ $fileUrl = $this->policyData["url"].$this->fileData["pre_name"]."?auth=0";
+ if(!empty($base)){
+ $fileUrl = $base;
+ }
+ return[true,$fileUrl];
+ }else{
+ $baseUrl = $this->policyData["url"].$this->fileData["pre_name"];
+ if(!empty($base)){
+ $baseUrl = $base;
+ }
+ $etime = time() + Option::getValue("timeout");
+ $key = $this->policyData["sk"];
+ $path = "/".$this->fileData["pre_name"];
+ if(!empty($name)){
+ $path = "/".$name;
+ }
+ $sign = substr(md5($key.'&'.$etime.'&'.$path), 12, 8).$etime;
+ $signedUrl = $baseUrl."?_upt=".$sign;
+ return[true,$signedUrl];
+ }
+ }
+
+ public function qiniuPreview($thumb=null){
+ if(!$this->policyData['bucket_private']){
+ $fileUrl = $this->policyData["url"].$this->fileData["pre_name"].$thumb;
+ return[true,$fileUrl];
+ }else{
+ $auth = new Auth($this->policyData["ak"], $this->policyData["sk"]);
+ $baseUrl = $this->policyData["url"].$this->fileData["pre_name"].$thumb;
+ $signedUrl = $auth->privateDownloadUrl($baseUrl);
+ return[true,$signedUrl];
+ }
+ }
+
+ public function ossPreview(){
+ if(!$this->policyData['bucket_private']){
+ $fileUrl = $this->policyData["url"].$this->fileData["pre_name"];
+ return[true,$fileUrl];
+ }else{
+ $accessKeyId = $this->policyData["ak"];
+ $accessKeySecret = $this->policyData["sk"];
+ $endpoint = $this->policyData["url"];
+ try {
+ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);
+ } catch (OssException $e) {
+ return [false,0];
+ }
+ $baseUrl = $this->policyData["url"].$this->fileData["pre_name"];
+ try{
+ $signedUrl = $ossClient->signUrl($this->policyData["bucketname"], $this->fileData["pre_name"], Option::getValue("timeout"));
+ } catch(OssException $e) {
+ return [false,0];
+ }
+ return[true,$signedUrl];
+ }
+ }
+
+ public function qiniuDownload(){
+ if(!$this->policyData['bucket_private']){
+ $fileUrl = $this->policyData["url"].$this->fileData["pre_name"]."?attname=".urlencode($this->fileData["orign_name"]);
+ return[true,$fileUrl];
+ }else{
+ $auth = new Auth($this->policyData["ak"], $this->policyData["sk"]);
+ $baseUrl = $this->policyData["url"].$this->fileData["pre_name"]."?attname=".urlencode($this->fileData["orign_name"]);
+ $signedUrl = $auth->privateDownloadUrl($baseUrl);
+ return[true,$signedUrl];
+ }
+ }
+
+ public function upyunDownload(){
+ return [true,$this->upyunPreview()[1]."&_upd=".urlencode($this->fileData["orign_name"])];
+ }
+
+ public function s3Download(){
+ $timeOut = Option::getValue("timeout");
+ return [1,\S3\S3::aws_s3_link($this->policyData["ak"], $this->policyData["sk"],$this->policyData["bucketname"],"/".$this->fileData["pre_name"],3600,$this->policyData["op_name"],array(),false)];
+ }
+
+ public function ossDownload(){
+ if(!$this->policyData['bucket_private']){
+ $fileUrl = $this->policyData["url"].$this->fileData["pre_name"]."?response-content-disposition=".urlencode('attachment; filename='.$this->fileData["orign_name"]);
+ return[true,$fileUrl];
+ }else{
+ $accessKeyId = $this->policyData["ak"];
+ $accessKeySecret = $this->policyData["sk"];
+ $endpoint = $this->policyData["url"];
+ try {
+ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);
+ } catch (OssException $e) {
+ return [false,0];
+ }
+ $baseUrl = $this->policyData["url"].$this->fileData["pre_name"];
+ try{
+ $signedUrl = $ossClient->signUrl($this->policyData["bucketname"], $this->fileData["pre_name"], Option::getValue("timeout"),'GET', array("response-content-disposition" => 'attachment; filename='.$this->fileData["orign_name"]));
+ } catch(OssException $e) {
+ return [false,0];
+ }
+ return[true,$signedUrl];
+ }
+ }
+
+ public function localPreview($isAdmin=false){
+ $speedLimit = Db::name('groups')->where('id',$this->userData["user_group"])->find();
+ $rangeTransfer = $speedLimit["range_transfer"];
+ $speedLimit = $speedLimit["speed"];
+ if($isAdmin){
+ $speedLimit="";
+ }
+ if($speedLimit == "0"){
+ exit();
+ }else if(empty($speedLimit)){
+ header("Cache-Control: max-age=10800");
+ $this->outputWithoutLimit(false,$rangeTransfer);
+ exit();
+ }else if((int)$speedLimit > 0){
+ header("Cache-Control: max-age=10800");
+ $this->outputWithLimit($speedLimit);
+ }
+ }
+
+ public function localDownload($isAdmin=false){
+ $speedLimit = Db::name('groups')->where('id',$this->userData["user_group"])->find();
+ $rangeTransfer = $speedLimit["range_transfer"];
+ $speedLimit = $speedLimit["speed"];
+ if($isAdmin){
+ $speedLimit = "";
+ }
+ if($speedLimit == "0"){
+ exit();
+ }else if(empty($speedLimit)){
+ $this->outputWithoutLimit(true,$rangeTransfer);
+ exit();
+ }else if((int)$speedLimit > 0){
+ $this->outputWithLimit($speedLimit,true);
+ }
+ }
+
+ public function outputWithoutLimit($download = false,$reload = false){
+ ignore_user_abort(false);
+ $filePath = ROOT_PATH . 'public/uploads/' . $this->fileData["pre_name"];
+ set_time_limit(0);
+ session_write_close();
+ $file_size = filesize($filePath);
+ $ranges = $this->getRange($file_size);
+ if($reload == 1 && $ranges!=null){
+ header('HTTP/1.1 206 Partial Content');
+ header('Accept-Ranges:bytes');
+ header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));
+ header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end']-1, $file_size));
+ }
+ if($download){
+ header('Cache-control: private');
+ header('Content-Type: application/octet-stream');
+ header('Content-Length: '.filesize($filePath));
+ header('Content-Disposition: filename='.str_replace(",","",$this->fileData["orign_name"]));
+ ob_flush();
+ flush();
+ }
+ if(file_exists($filePath)){
+ if(!$download){
+ header('Content-Type: '.self::getMimetype($filePath));
+ ob_flush();
+ flush();
+ }
+ $fileObj = fopen($filePath,"rb");
+ if($reload == 1){
+ fseek($fileObj, sprintf('%u', $ranges['start']));
+ }
+ while(!feof($fileObj)){
+ echo fread($fileObj,10240);
+ ob_flush();
+ flush();
+ }
+ fclose($fileObj);
+ }
+ }
+
+ public function outputWithLimit($speed,$download = false){
+ ignore_user_abort(false);
+ $filePath = ROOT_PATH . 'public/uploads/' . $this->fileData["pre_name"];
+ set_time_limit(0);
+ session_write_close();
+ if($download){
+ header('Cache-control: private');
+ header('Content-Type: application/octet-stream');
+ header('Content-Length: '.filesize($filePath));
+ header('Content-Disposition: filename='.$this->fileData["orign_name"]);
+ ob_flush();
+ flush();
+ }else{
+ header('Content-Type: '.self::getMimetype($filePath));
+ ob_flush();
+ flush();
+ }
+ if(file_exists($filePath)){
+ $fileObj = fopen($filePath,"r");
+ while (!feof($fileObj)){
+ echo fread($fileObj,round($speed*1024));
+ ob_flush();
+ flush();
+ sleep(1);
+ }
+ fclose($fileObj);
+ }
+ }
+
+ static function getMimetype($path){
+ $finfoObj = finfo_open(FILEINFO_MIME);
+ $mimetype = finfo_file($finfoObj, $path);
+ finfo_close($finfoObj);
+ return $mimetype;
+ }
+
+ private function getRange($file_size){
+ if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])){
+ $range = $_SERVER['HTTP_RANGE'];
+ $range = preg_replace('/[\s|,].*/', '', $range);
+ $range = explode('-', substr($range, 6));
+ if(count($range)<2){
+ $range[1] = $file_size;
+ }
+ $range = array_combine(array('start','end'), $range);
+ if(empty($range['start'])){
+ $range['start'] = 0;
+ }
+ if(empty($range['end'])){
+ $range['end'] = $file_size;
+ }
+ return $range;
+ }
+ return null;
+ }
+
+ /**
+ * [List description]
+ * @param [type] $path [description]
+ * @param [type] $uid [description]
+ */
+ static function ListFile($path,$uid){
+ $fileList = Db::name('files')->where('upload_user',$uid)->where('dir',$path)->select();
+ $dirList = Db::name('folders')->where('owner',$uid)->where('position',$path)->select();
+ $count= 0;
+ $fileListData=[];
+ foreach ($dirList as $key => $value) {
+ $fileListData['result'][$count]['name'] = $value['folder_name'];
+ $fileListData['result'][$count]['rights'] = "drwxr-xr-x";
+ $fileListData['result'][$count]['size'] = "0";
+ $fileListData['result'][$count]['date'] = $value['date'];
+ $fileListData['result'][$count]['type'] = 'dir';
+ $fileListData['result'][$count]['name2'] = "";
+ $fileListData['result'][$count]['id'] = $value['id'];
+ $fileListData['result'][$count]['pic'] = "";
+ $count++;
+ }
+ foreach ($fileList as $key => $value) {
+ $fileListData['result'][$count]['name'] = $value['orign_name'];
+ $fileListData['result'][$count]['rights'] = "drwxr-xr-x";
+ $fileListData['result'][$count]['size'] = $value['size'];
+ $fileListData['result'][$count]['date'] = $value['upload_date'];
+ $fileListData['result'][$count]['type'] = 'file';
+ $fileListData['result'][$count]['name2'] = $value["dir"];
+ $fileListData['result'][$count]['id'] = $value["id"];
+ $fileListData['result'][$count]['pic'] = $value["pic_info"];
+ $count++;
+ }
+
+ return $fileListData;
+ }
+
+ static function listPic($path,$uid,$url="/File/Preview?"){
+ $firstPreview = self::getFileName($path);
+ $path=$firstPreview[1];
+ $fileList = Db::name('files')
+ ->where('upload_user',$uid)
+ ->where('dir',$path)
+ ->where('pic_info',"<>"," ")
+ ->where('pic_info',"<>","0,0")
+ ->where('pic_info',"<>","null,null")
+ ->select();
+ $count= 0;
+ $fileListData=[];
+ foreach ($fileList as $key => $value) {
+ if($value["orign_name"] == $firstPreview[0]){
+ $previewPicInfo = explode(",",$value["pic_info"]);
+ $previewSrc = $url."action=preview&path=".$path."/".$value["orign_name"];
+ }else{
+ $picInfo = explode(",",$value["pic_info"]);
+ $fileListData[$count]['src'] = $url."action=preview&path=".$path."/".$value["orign_name"];
+ $fileListData[$count]['w'] = $picInfo[0];
+ $fileListData[$count]['h'] = $picInfo[1];
+ $fileListData[$count]['title'] = $value["orign_name"];
+ $count++;
+ }
+ }
+ array_unshift($fileListData,array(
+ 'src' => $previewSrc,
+ 'w' => $previewPicInfo[0],
+ 'h' => $previewPicInfo[1],
+ 'title' => $firstPreview[0],
+ ));
+ return $fileListData;
+ }
+
+ /**
+ * [createFolder description]
+ * @param [type] $dirName [description]
+ * @param [type] $dirPosition [description]
+ * @param [type] $uid [description]
+ * @return [type] [description]
+ */
+ static function createFolder($dirName,$dirPosition,$uid){
+ $dirName = str_replace(" ","",$dirName);
+ $dirName = str_replace("/","",$dirName);
+ if(empty($dirName)){
+ return ["result"=>["success"=>false,"error"=>"目录名不能为空"]];
+ }
+ if(Db::name('folders')->where('position_absolute',$dirPosition)->find() ==null || Db::name('folders')->where('position',$dirPosition)->where('folder_name',$dirName)->find() !=null || Db::name('files')->where('dir',$dirPosition)->where('pre_name',$dirName)->find() !=null){
+ return ["result"=>["success"=>false,"error"=>"路径不存在或文件已存在"]];
+ }
+ $sqlData = [
+ 'folder_name' => $dirName,
+ 'parent_folder' => Db::name('folders')->where('position_absolute',$dirPosition)->value('id'),
+ 'position' => $dirPosition,
+ 'owner' => $uid,
+ 'date' => date("Y-m-d H:i:s"),
+ 'position_absolute' => ($dirPosition == "/")?($dirPosition.$dirName):($dirPosition."/".$dirName),
+ ];
+ if(Db::name('folders')->insert($sqlData)){
+ return ["result"=>["success"=>true,"error"=>null]];
+ }
+
+ }
+
+ static function getTotalStorage($uid){
+ $userData = Db::name('users')->where('id',$uid)->find();
+ $basicStronge = Db::name('groups')->where('id',$userData['user_group'])->find();
+ $addOnStorage = Db::name('storage_pack')
+ ->where('uid',$uid)
+ ->where('dlay_time',">",time())
+ ->sum('pack_size');
+ return (int)$addOnStorage+(int)$basicStronge["max_storage"];
+ }
+
+ static function getUsedStorage($uid){
+ $userData = Db::name('users')->where('id',$uid)->find();
+ return $userData['used_storage'];
+ }
+
+ static function sotrageCheck($uid,$fsize){
+ $totalStorage = self::getTotalStorage($uid);
+ $usedStorage = self::getUsedStorage($uid);
+ return ($totalStorage > ($usedStorage + $fsize)) ? True : False;
+ }
+
+ static function storageCheckOut($uid,$size){
+ Db::name('users')->where('id',$uid)->setInc('used_storage',$size);
+ }
+
+ static function storageGiveBack($uid,$size){
+ Db::name('users')->where('id',$uid)->setDec('used_storage',$size);
+ }
+
+ static function addFile($jsonData,$policyData,$uid,$picInfo=" "){
+ $dir = "/".str_replace(",","/",$jsonData['path']);
+ $fname = $jsonData['fname'];
+ if(self::isExist($dir,$fname,$uid)){
+ return[false,"文件已存在"];
+ }
+ $folderBelong = Db::name('folders')->where('owner',$uid)->where('position_absolute',$dir)->find();
+ if($folderBelong ==null){
+ return[false,"目录不存在"];
+ }
+ $sqlData = [
+ 'orign_name' => $jsonData['fname'],
+ 'pre_name' => $jsonData['objname'],
+ 'upload_user' => $uid,
+ 'size' => $jsonData['fsize'],
+ 'upload_date' => date("Y-m-d H:i:s"),
+ 'parent_folder' => $folderBelong['id'],
+ 'policy_id' => $policyData['id'],
+ 'dir' => $dir,
+ 'pic_info' => $picInfo,
+ ];
+ if(Db::name('files')->insert($sqlData)){
+ return [true,"上传成功"];
+ }
+
+ }
+
+ static function isExist($dir,$fname,$uid){
+ if(Db::name('files')->where('upload_user',$uid)->where('dir',$dir)->where('orign_name',$fname)->find() !=null){
+ return true;
+ }else{
+ return false;
+ }
+ }
+
+ static function deleteFile($fname,$policy){
+ switch ($policy['policy_type']) {
+ case 'qiniu':
+ return self::deleteQiniuFile($fname,$policy);
+ break;
+ case 'oss':
+ return self::deleteOssFile($fname,$policy);
+ break;
+ case 'upyun':
+ return self::deleteUpyunFile($fname,$policy);
+ break;
+ case 's3':
+ return self::deleteS3File($fname,$policy);
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+
+ static function deleteQiniuFile($fname,$policy){
+ $auth = new Auth($policy["ak"], $policy["sk"]);
+ $config = new \Qiniu\Config();
+ $bucketManager = new \Qiniu\Storage\BucketManager($auth);
+ $err = $bucketManager->delete($policy["bucketname"], $fname);
+ if ($err) {
+ return false;
+ }else{
+ return true;
+ }
+ }
+
+ static function deleteOssFile($fname,$policy){
+ $accessKeyId = $policy["ak"];
+ $accessKeySecret = $policy["sk"];
+ $endpoint = "http".ltrim(ltrim($policy["server"],"https"),"http");
+ try {
+ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);
+ } catch (OssException $e) {
+ return false;
+ }
+ try{
+ $ossClient->deleteObject($policy["bucketname"], $fname);
+ } catch(OssException $e) {
+ return false;
+ }
+ return true;
+ }
+
+ static function deleteUpyunFile($fname,$policy){
+ $bucketConfig = new Config($policy["bucketname"], $policy["op_name"], $policy["op_pwd"]);
+ $client = new Upyun($bucketConfig);
+ $res=$client->delete($fname,true);
+ }
+
+ static function deleteS3File($fname,$policy){
+ $s3 = new \S3\S3($policy["ak"], $policy["sk"],false,$policy["op_pwd"]);
+ $s3->setSignatureVersion('v4');
+ return $s3->deleteObject($policy["bucketname"],$fname);
+ }
+
+ static function uniqueArray($data = array()){
+ $tempList = [];
+ $qiniuList = [];
+ $qiniuPolicyData = [];
+ $localList = [];
+ $localPolicyData = [];
+ $ossList = [];
+ $ossPolicyData = [];
+ $upyunList = [];
+ $upyunPolicyData = [];
+ $s3List = [];
+ $s3PolicyData = [];
+ foreach ($data as $key => $value) {
+ if(!in_array($value['policy_id'],$tempList)){
+ array_push($tempList,$value['policy_id']);
+ $policyTempData = Db::name('policy')->where('id',$value['policy_id'])->find();
+ switch ($policyTempData["policy_type"]) {
+ case 'qiniu':
+ array_push($qiniuList,$value['policy_id']);
+ if(empty($qiniuPolicyData[$value['policy_id']])){
+ $qiniuPolicyData[$value['policy_id']] = [];
+ }
+ array_push($qiniuPolicyData[$value['policy_id']],$policyTempData);
+ break;
+ case 'local':
+ array_push($localList,$value['policy_id']);
+ if(empty($localPolicyData[$value['policy_id']])){
+ $localPolicyData[$value['policy_id']] = [];
+ }
+ array_push($localPolicyData[$value['policy_id']],$policyTempData);
+ break;
+ case 'oss':
+ array_push($ossList,$value['policy_id']);
+ if(empty($ossPolicyData[$value['policy_id']])){
+ $ossPolicyData[$value['policy_id']] = [];
+ }
+ array_push($ossPolicyData[$value['policy_id']],$policyTempData);
+ break;
+ case 'upyun':
+ array_push($upyunList,$value['policy_id']);
+ if(empty($upyunPolicyData[$value['policy_id']])){
+ $upyunPolicyData[$value['policy_id']] = [];
+ }
+ array_push($upyunPolicyData[$value['policy_id']],$policyTempData);
+ break;
+ case 's3':
+ array_push($s3List,$value['policy_id']);
+ if(empty($s3PolicyData[$value['policy_id']])){
+ $s3PolicyData[$value['policy_id']] = [];
+ }
+ array_push($s3PolicyData[$value['policy_id']],$policyTempData);
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+ }
+ $returenValue=array(
+ 'policyId' => $tempList ,
+ 'qiniuList' => $qiniuList,
+ 'qiniuPolicyData' => $qiniuPolicyData,
+ 'localList' => $localList,
+ 'localPolicyData' => $localPolicyData,
+ 'ossList' => $ossList,
+ 'ossPolicyData' => $ossPolicyData,
+ 'upyunList' => $upyunList,
+ 'upyunPolicyData' => $upyunPolicyData,
+ 's3List' => $s3List,
+ 's3PolicyData' => $s3PolicyData,
+ );
+ return $returenValue;
+ }
+
+ public function signTmpUrl(){
+ switch ($this->policyData["policy_type"]) {
+ case 'qiniu':
+ return $this->qiniuPreview()[1];
+ break;
+ case 'oss':
+ return $this->ossPreview()[1];
+ break;
+ case 'upyun':
+ return $this->upyunPreview()[1];
+ break;
+ case 's3':
+ return $this->s3Preview()[1];
+ break;
+ case 'local':
+ $options = Option::getValues(["oss","basic"]);
+ $timeOut = $options["timeout"];
+ $delayTime = time()+$timeOut;
+ $key=$this->fileData["id"].":".$delayTime.":".md5($this->userData["user_pass"].$this->fileData["id"].$delayTime.config("salt"));
+ return $options['siteURL']."Callback/TmpPreview/key/".$key;
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/Image.php b/application/index/model/Image.php
new file mode 100644
index 00000000..c0658e51
--- /dev/null
+++ b/application/index/model/Image.php
@@ -0,0 +1,89 @@
+file = $_file;
+ list($this->width, $this->height, $this->itype) = getimagesize($this->file);
+ $this->img = $this->getFromImg($this->file, $this->itype);
+ }
+ //缩略图(固定长高容器,图像等比例,扩容填充,裁剪)[固定了大小,不失真,不变形]
+ public function thumb($new_width = 0,$new_height = 0) {
+
+ if (empty($new_width) && empty($new_height)) {
+ $new_width = $this->width;
+ $new_height = $this->height;
+ }
+
+ if (!is_numeric($new_width) || !is_numeric($new_height)) {
+ $new_width = $this->width;
+ $new_height = $this->height;
+ }
+
+ //创建一个容器
+ $_n_w = $new_width;
+ $_n_h = $new_height;
+
+ //创建裁剪点
+ $_cut_width = 0;
+ $_cut_height = 0;
+
+ if ($this->width < $this->height) {
+ $new_width = ($new_height / $this->height) * $this->width;
+ } else {
+ $new_height = ($new_width / $this->width) * $this->height;
+ }
+ if ($new_width < $_n_w) { //如果新高度小于新容器高度
+ $r = $_n_w / $new_width; //按长度求出等比例因子
+ $new_width *= $r; //扩展填充后的长度
+ $new_height *= $r; //扩展填充后的高度
+ $_cut_height = ($new_height - $_n_h) / 2; //求出裁剪点的高度
+ }
+
+ if ($new_height < $_n_h) { //如果新高度小于容器高度
+ $r = $_n_h / $new_height; //按高度求出等比例因子
+ $new_width *= $r; //扩展填充后的长度
+ $new_height *= $r; //扩展填充后的高度
+ $_cut_width = ($new_width - $_n_w) / 2; //求出裁剪点的长度
+ }
+
+ $this->new = imagecreatetruecolor($_n_w,$_n_h);
+ imagecopyresampled($this->new,$this->img,0,0,$_cut_width,$_cut_height,$new_width,$new_height,$this->width,$this->height);
+ }
+
+ //加载图片,各种类型,返回图片的资源句柄
+ public function getFromImg($_file, $_type) {
+ switch ($_type) {
+ case 1 :
+ $img = imagecreatefromgif($_file);
+ break;
+ case 2 :
+ $img = imagecreatefromjpeg($_file);
+ break;
+ case 3 :
+ $img = imagecreatefrompng($_file);
+ break;
+ default:
+ $img = '';
+ }
+ return $img;
+ }
+
+ //图像输出
+ public function output($name = "") {
+ imagepng($this->new,$this->file.$name);//第二个参数为新生成的图片名
+ imagedestroy($this->img);
+ imagedestroy($this->new);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/Mail.php b/application/index/model/Mail.php
new file mode 100644
index 00000000..c7eb4dca
--- /dev/null
+++ b/application/index/model/Mail.php
@@ -0,0 +1,60 @@
+fromName = $mailOptions["fromName"];
+ $this->fromAdress = $mailOptions["fromAdress"];
+ $this->smtpHost = $mailOptions["smtpHost"];
+ $this->smtpPort = $mailOptions["smtpPort"];
+ $this->replyTo = $mailOptions["replyTo"];
+ $this->smtpUser = $mailOptions["smtpUser"];
+ $this->smtpPass = $mailOptions["smtpPass"];
+ $this->encriptionType = $mailOptions["encriptionType"];
+ }
+
+ public function Send($to,$name,$title,$content){
+ $mail = new PHPMailer();
+ $mail->isSMTP();
+ $mail->SMTPAuth=true;
+ $mail->Host = $this->smtpHost;
+ if(!empty($this->encriptionType) && $this->encriptionType != "no"){
+ $mail->SMTPSecure = $this->encriptionType;
+ }
+ $mail->Port = $this->smtpPort;
+ $mail->CharSet = 'UTF-8';
+ $mail->FromName = $this->fromName;
+ $mail->Username =$this->smtpUser;
+ $mail->Password = $this->smtpPass;
+ $mail->From = $this->fromAdress;
+ $mail->isHTML(true);
+ $mail->addAddress($to,$name);
+ $mail->Subject = $title;
+ $mail->Body = $content;
+ $status = $mail->send();
+ if(!$status){
+ $this->errorMsg = $mail->ErrorInfo;
+ return false;
+ }
+ return true;
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/Object.php b/application/index/model/Object.php
new file mode 100644
index 00000000..917860da
--- /dev/null
+++ b/application/index/model/Object.php
@@ -0,0 +1,95 @@
+uid = $ex[0];
+ $t = strpos($path,$this->uid);
+ if($t == 0){
+ $this->myPath = substr($path,$t+strlen($this->uid));
+ }else{
+ $this->myPath = $path;
+ }
+ $this->fileName = end($ex);
+ $this->dir = dirname($this->myPath) == "\\" ? "/" :dirname($this->myPath);
+ $this->fileData = Db::name('files')->where('upload_user',$this->uid)->where('dir',$this->dir)->where('orign_name',$this->fileName)->find();
+ if(empty($this->fileData)){
+ $this->isExist = false;
+ }else{
+ $this->isExist = true;
+ }
+ $this->actualPath = ROOT_PATH . 'public/uploads/'.$this->fileData["pre_name"];
+ }
+
+ function getName() {
+ return $this->fileName;
+ }
+
+ function get() {
+ return fopen($this->actualPath, 'r');
+ }
+
+ function getSize() {
+ return $this->fileData["size"];
+ }
+
+ function setName($name){
+ $reqPath = $this->myPath;
+ $ex = explode("/",$reqPath);
+ $newPath = rtrim($reqPath,end($ex)).$name;
+ $renameAction = json_decode(FileManage::RenameHandler($reqPath,$newPath,$this->uid,true),true);
+ if(!$renameAction["result"]["success"]){
+ throw new DAV\Exception\Forbidden($renameAction["result"]["error"]);
+ }
+ }
+
+ function getContentType() {
+ return null;
+ }
+
+ function put($data){
+ $fileSize = (int)$_SERVER['CONTENT_LENGTH'];
+ if(!FileManage::sotrageCheck($this->uid,$fileSize)){
+ throw new DAV\Exception\InsufficientStorage("Quota is not enough");
+ }
+ $filePath = ROOT_PATH . 'public/uploads/' . $this->fileData["pre_name"];
+ file_put_contents($filePath, "");
+ file_put_contents($filePath, $data);
+ FileManage::storageGiveBack($this->uid,$this->fileData["size"]);
+ FileManage::storageCheckOut($this->uid,$fileSize);
+ @list($width, $height, $type, $attr) = getimagesize($filePath);
+ $picInfo = empty($width)?" ":$width.",".$height;
+ Db::name('files')->where('id', $this->fileData["id"])->update(['size' => $fileSize,'pic_info' => $picInfo]);
+ }
+
+ function delete(){
+ FileManage::DeleteHandler([0=>$this->myPath],$this->uid);
+ }
+
+ function getETag() {
+
+ return '"' . sha1(
+ fileinode($this->actualPath) .
+ filesize($this->actualPath) .
+ filemtime($this->actualPath)
+ ) . '"';
+
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/Option.php b/application/index/model/Option.php
new file mode 100644
index 00000000..b85836d5
--- /dev/null
+++ b/application/index/model/Option.php
@@ -0,0 +1,16 @@
+where('option_type','in',$groups)->column('option_value','option_name');
+ return $t;
+ }
+ static function getValue($optionName){
+ return Db::name('options')->where('option_name',$optionName)->value('option_value');
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/ShareHandler.php b/application/index/model/ShareHandler.php
new file mode 100644
index 00000000..ebbd27cd
--- /dev/null
+++ b/application/index/model/ShareHandler.php
@@ -0,0 +1,308 @@
+shareData = Db::name('shares')->where('share_key',$key)->find();
+ if(empty($this->shareData)){
+ $this->querryStatus = false;
+ }else{
+ if($notExist){
+ if($this->shareData["source_type"] == "file"){
+ $this->fileShareHandler();
+ }else{
+ $this->dirShareHandler();
+ }
+ }
+ }
+ if($this->shareData["type"] == "private"){
+ $this->lockStatus = Session::has("share".$this->shareData["id"])?false:true;
+ }
+
+ }
+
+ public function deleteShare($uid){
+ if($this->shareData["owner"] != $uid){
+ return array(
+ "error" => 1,
+ "msg" => "无权操作"
+ );
+ }
+ Db::name('shares')->where('share_key',$this->shareData["share_key"])->delete();
+ return array(
+ "error" => 0,
+ "msg" => "分享取消成功"
+ );
+ }
+
+ public function changePromission($uid,$ignore=false){
+ if($this->shareData["owner"] != $uid && $ignore == false){
+ return array(
+ "error" => 1,
+ "msg" => "无权操作"
+ );
+ }
+ Db::name('shares')->where('share_key',$this->shareData["share_key"])->update([
+ 'type' => $this->shareData["type"] == "public"?"private":"public",
+ 'share_pwd' => self::getRandomKey(6)
+ ]);
+ return array(
+ "error" =>0,
+ "msg" => "更改成功"
+ );
+ }
+
+ public function checkPwd($pwd){
+ if($pwd == $this->shareData["share_pwd"]){
+ Session::set("share".$this->shareData["id"],"1");
+ return array(
+ "error" =>0,
+ );
+ }else{
+ return array(
+ "error" =>1,
+ "msg" => "密码错误"
+ );
+ }
+ }
+
+ public function checkSession($user){
+ if($this->lockStatus){
+ return [false,"会话过期,请刷新页面"];
+ }
+ if(Option::getValue("allowdVisitorDownload") == "false" && !$user->loginStatus){
+ return [false,"未登录用户禁止下载,请先登录"];
+ }
+ if(!$this->querryStatus){
+ return [false,"分享不存在,请检查链接是否正确"];
+ }
+ return[true,null];
+ }
+
+ public function Download($user){
+ $checkStatus = $this->checkSession($user);
+ if(!$checkStatus[0]){
+ return [$checkStatus[0],$checkStatus[1]];
+ }
+ $reqPath = Db::name('files')->where('id',$this->shareData["source_name"])->find();
+ if($reqPath["dir"] == "/"){
+ $reqPath["dir"] = $reqPath["dir"].$reqPath["orign_name"];
+ }else{
+ $reqPath["dir"] = $reqPath["dir"]."/".$reqPath["orign_name"];
+ }
+ $fileObj = new FileManage($reqPath["dir"],$this->shareData["owner"]);
+ $FileHandler = $fileObj->Download();
+ return $FileHandler;
+ }
+
+ public function DownloadFolder($user,$path){
+ $checkStatus = $this->checkSession($user);
+ if(!$checkStatus[0]){
+ return [$checkStatus[0],$checkStatus[1]];
+ }
+ $reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
+ $path = $path == "/"?"":$path;
+ $fileObj = new FileManage($reqPath["position_absolute"].$path,$this->shareData["owner"]);
+ $this->numIncrease("download_num");
+ $FileHandler = $fileObj->Download();
+ return $FileHandler;
+ }
+
+ public function ListFile($path){
+ if($this->lockStatus){
+ die('{ "result": { "success": false, "error": "会话过期,请重新登陆" } }');
+ }
+ if(!$this->querryStatus){
+ return [false,"分享不存在,请检查链接是否正确"];
+ }
+ $reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
+ $path = $path == "/"?"":$path;
+ return FileManage::ListFile($this->shareData["source_name"].$path,$this->shareData["owner"]);
+ }
+
+ public function Preview($user){
+ $checkStatus = $this->checkSession($user);
+ if(!$checkStatus[0]){
+ return [$checkStatus[0],$checkStatus[1]];
+ }
+ $reqPath = Db::name('files')->where('id',$this->shareData["source_name"])->find();
+ if($reqPath["dir"] == "/"){
+ $reqPath["dir"] = $reqPath["dir"].$reqPath["orign_name"];
+ }else{
+ $reqPath["dir"] = $reqPath["dir"]."/".$reqPath["orign_name"];
+ }
+ $fileObj = new FileManage($reqPath["dir"],$this->shareData["owner"]);
+ return $fileObj->PreviewHandler();
+ }
+
+ public function PreviewFolder($user,$path,$folder=false){
+ $checkStatus = $this->checkSession($user);
+ if(!$checkStatus[0]){
+ return [$checkStatus[0],$checkStatus[1]];
+ }
+ $reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
+ if($folder){
+ $fileObj = new FileManage($path,$this->shareData["owner"]);
+ }else{
+ $fileObj = new FileManage($reqPath["position_absolute"].$path,$this->shareData["owner"]);
+ }
+ return $fileObj->PreviewHandler();
+ }
+
+ public function listPic($id,$path){
+ if($this->lockStatus){
+ die('{ "result": { "success": false, "error": "会话过期,请重新登陆" } }');
+ }
+ if(!$this->querryStatus){
+ return [false,"分享不存在,请检查链接是否正确"];
+ }
+ $reqPath = Db::name('folders')->where('position_absolute',$this->shareData["source_name"])->find();
+ $path = $path == "/"?"":$path;
+ return FileManage::listPic($this->shareData["source_name"].$path,$this->shareData["owner"],"/Share/Preview/".$this->shareData["share_key"]."?folder=true");
+ }
+
+ public function numIncrease($name){
+ Db::name('shares')->where('share_key',$this->shareData["share_key"])->setInc($name);
+ }
+
+ public function getDownloadUrl($user){
+ if(Option::getValue("allowdVisitorDownload") == "false" && !$user->loginStatus){
+ return array(
+ "error" => 1,
+ "msg" => "未登录用户禁止下载,请先登录",
+ );
+ }else{
+ $this->numIncrease("download_num");
+ return array(
+ "error" => 0,
+ "result" => "/Share/Download/".$this->shareData["share_key"],
+ );
+ }
+ }
+
+ public function fileShareHandler(){
+ $this->shareOwner = new User($this->shareData["owner"],null,true);
+ $this->fileData = Db::name('files')
+ ->where('upload_user',$this->shareData["owner"])
+ ->where('id',(int)$this->shareData["source_name"])
+ ->find();
+ if(!$this->shareOwner->loginStatus || empty($this->fileData)){
+ $this->querryStatus = false;
+ }else{
+ $this->querryStatus = true;
+ }
+ }
+
+ public function dirShareHandler(){
+ $this->shareOwner = new User($this->shareData["owner"],null,true);
+ $this->dirData = Db::name('folders')
+ ->where('owner',$this->shareData["owner"])
+ ->where('position_absolute',$this->shareData["source_name"])
+ ->find();
+ if(!$this->shareOwner->loginStatus || empty($this->dirData)){
+ $this->querryStatus = false;
+ }else{
+ $this->querryStatus = true;
+ }
+ }
+
+ static function createShare($fname,$type,$user,$group){
+ if(!$group["allow_share"]){
+ self::setError("您当前的用户组无权分享文件");
+ }
+ $path = FileManage::getFileName($fname)[1];
+ $fnameTmp = FileManage::getFileName($fname)[0];
+ $fileRecord = Db::name('files')->where('upload_user',$user["id"])->where('orign_name',$fnameTmp)->where('dir',$path)->find();
+ if(empty($fileRecord)){
+ self::createDirShare($fname,$type,$user,$group);
+ }else{
+ self::createFileShare($fileRecord,$type,$user,$group);
+ }
+ }
+
+ static function setError($text){
+ die('{ "result": { "success": false, "error": "'.$text.'" } }');
+ }
+
+ static function setSuccess($text){
+ die('{ "result": "'.$text.'" }');
+ }
+
+ static function createDirShare($fname,$type,$user,$group){
+ $dirRecord = Db::name('folders')->where('owner',$user["id"])->where('position_absolute',$fname)->find();
+ if(empty($dirRecord)){
+ self::setError("目录不存在");
+ }
+ $shareKey = self::getRandomKey(8);
+ $sharePwd = $type=="public" ? "0" : self::getRandomKey(6);
+ $SQLData = [
+ 'type' => $type=="public" ? "public" : "private",
+ 'share_time' => date("Y-m-d H:i:s"),
+ 'owner' => $user["id"],
+ 'source_name' => $fname,
+ 'origin_name' => $fname,
+ 'download_num' => 0,
+ 'view_num' => 0,
+ 'source_type' => "dir",
+ 'share_key' => $shareKey,
+ 'share_pwd' => $sharePwd,
+ ];
+ if(Db::name('shares')->insert($SQLData)){
+ if($sharePwd == "0"){
+ self::setSuccess(Option::getValue("siteURL")."s/".$shareKey);
+ }else{
+ self::setSuccess("链接:".Option::getValue("siteURL")."s/".$shareKey." 密码:".$sharePwd);
+ }
+ }
+ }
+
+ static function createFileShare($file,$type,$user,$group){
+ $shareKey = self::getRandomKey(8);
+ $sharePwd = $type=="public" ? "0" : self::getRandomKey(6);
+ $SQLData = [
+ 'type' => $type=="public" ? "public" : "private",
+ 'share_time' => date("Y-m-d H:i:s"),
+ 'owner' => $user["id"],
+ 'source_name' => $file["id"],
+ 'origin_name' => $file["orign_name"],
+ 'download_num' => 0,
+ 'view_num' => 0,
+ 'source_type' => "file",
+ 'share_key' => $shareKey,
+ 'share_pwd' => $sharePwd,
+ ];
+ if(Db::name('shares')->insert($SQLData)){
+ if($sharePwd == "0"){
+ self::setSuccess(Option::getValue("siteURL")."s/".$shareKey);
+ }else{
+ self::setSuccess("链接:".Option::getValue("siteURL")."s/".$shareKey." 密码:".$sharePwd);
+ }
+ }
+ }
+
+ static function getRandomKey($length = 16){
+ $charTable = 'abcdefghijklmnopqrstuvwxyz0123456789';
+ $result = "";
+ for ( $i = 0; $i < $length; $i++ ){
+ $result .= $charTable[ mt_rand(0, strlen($charTable) - 1) ];
+ }
+ return $result;
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/Thumb.php b/application/index/model/Thumb.php
new file mode 100644
index 00000000..6098f802
--- /dev/null
+++ b/application/index/model/Thumb.php
@@ -0,0 +1,91 @@
+file = $_file;
+ list($this->width, $this->height, $this->img_type) = getimagesize($this->file);
+ $this->img = $this->getFromImg($this->file, $this->img_type);
+ }
+ //缩略图(固定长高容器,图像等比例,扩容填充,裁剪)[固定了大小,不失真,不变形]
+ public function thumb($new_width = 0,$new_height = 0) {
+
+ if (empty($new_width) && empty($new_height)) {
+ $new_width = $this->width;
+ $new_height = $this->height;
+ }
+
+ if (!is_numeric($new_width) || !is_numeric($new_height)) {
+ $new_width = $this->width;
+ $new_height = $this->height;
+ }
+
+ //创建一个容器
+ $_n_w = $new_width;
+ $_n_h = $new_height;
+
+ //创建裁剪点
+ $_cut_width = 0;
+ $_cut_height = 0;
+
+ if ($this->width < $this->height) {
+ $new_width = ($new_height / $this->height) * $this->width;
+ } else {
+ $new_height = ($new_width / $this->width) * $this->height;
+ }
+ if ($new_width < $_n_w) { //如果新高度小于新容器高度
+ $r = $_n_w / $new_width; //按长度求出等比例因子
+ $new_width *= $r; //扩展填充后的长度
+ $new_height *= $r; //扩展填充后的高度
+ $_cut_height = ($new_height - $_n_h) / 2; //求出裁剪点的高度
+ }
+
+ if ($new_height < $_n_h) { //如果新高度小于容器高度
+ $r = $_n_h / $new_height; //按高度求出等比例因子
+ $new_width *= $r; //扩展填充后的长度
+ $new_height *= $r; //扩展填充后的高度
+ $_cut_width = ($new_width - $_n_w) / 2; //求出裁剪点的长度
+ }
+
+ $this->new = imagecreatetruecolor($_n_w,$_n_h);
+ imagecopyresampled($this->new,$this->img,0,0,$_cut_width,$_cut_height,$new_width,$new_height,$this->width,$this->height);
+ }
+
+ //加载图片,各种类型,返回图片的资源句柄
+ private function getFromImg($_file, $_type) {
+ switch ($_type) {
+ case 1 :
+ $img = imagecreatefromgif($_file);
+ break;
+ case 2 :
+ $img = imagecreatefromjpeg($_file);
+ break;
+ case 3 :
+ $img = imagecreatefrompng($_file);
+ break;
+ default:
+ $img = '';
+ }
+ return $img;
+ }
+
+ //图像输出
+ public function out($name) {
+ imagepng($this->new,$name);//第二个参数为新生成的图片名
+ imagedestroy($this->img);
+ imagedestroy($this->new);
+ }
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/TwoFactor.php b/application/index/model/TwoFactor.php
new file mode 100644
index 00000000..430b0116
--- /dev/null
+++ b/application/index/model/TwoFactor.php
@@ -0,0 +1,53 @@
+ga = new PHPGangsta_GoogleAuthenticator();
+ }
+
+ public function qrcodeRender(){
+ ob_end_clean();
+ header("content-type: image/png");
+ $this->secretKey = $this->ga->createSecret();
+ $qrCode = new QrCode();
+ session("two_factor_enable",$this->secretKey);
+ $qrCode->setText(urldecode($this->ga->getQRCodeGoogleUrl(Option::getValue("siteName"), $this->secretKey)))
+ ->setPadding(5)
+ ->render();
+ }
+
+ public function confirmCode($key,$code){
+ $this->secretKey = $key;
+ if(empty($code)){
+ return [0,"验证码不能为空"];
+ }
+ if(empty($key)){
+ return [0,"二维码过期,请刷新页面后重新扫描"];
+ }
+ $this->checkResult = $this->ga->verifyCode($key, $code, 2);
+ if($this->checkResult){
+ return [1,"验证成功"];
+ }else{
+ return [0,"验证码错误"];
+ }
+ }
+
+ public function bindUser($uid){
+ Db::name("users")->where("id",$uid)->update(["two_step" => $this->secretKey]);
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/application/index/model/UploadHandler.php b/application/index/model/UploadHandler.php
new file mode 100644
index 00000000..8f9167f3
--- /dev/null
+++ b/application/index/model/UploadHandler.php
@@ -0,0 +1,452 @@
+policyId = $id;
+ $this->userId = $uid;
+ $this->policyContent = Db::name('policy')->where('id',$id)->find();
+ }
+
+ public function setChunk($chunkId,$chunkSum,$file){
+ $sqlData = [
+ 'user' => $this->userId,
+ 'ctx' => self::getRandomKey(),
+ 'obj_name' => self::getRandomKey(8),
+ 'time' => date("Y-m-d H:i:s"),
+ 'chunk_id' => $chunkId,
+ 'sum' => $chunkSum,
+ ];
+ $this->chunkData = $sqlData;
+ Db::name('chunks')->insert($sqlData);
+ $this->saveChunk($file);
+ $this->chunkInfo();
+ }
+
+ public function saveChunk($file){
+ $chunkSize = strlen($file);
+ if(!FileManage::sotrageCheck($this->userId,$chunkSize)){
+ $this->setError("空间容量不足",false);
+ }
+ FileManage::storageCheckOut($this->userId,$chunkSize);
+ if($chunkSize >=4195304){
+ $this->setError("分片错误",false);
+ }
+ $chunkObj=fopen (ROOT_PATH . 'public/uploads/chunks/'.$this->chunkData["obj_name"].".chunk","w+");
+ $chunkObjWrite = fwrite ($chunkObj,$file);
+ if(!$chunkObj || !$chunkObjWrite){
+ $this->setError("分片创建错误",false);
+ }
+ }
+
+ public function chunkInfo(){
+ $returnJson = array(
+ "ctx" => $this->chunkData["ctx"],
+ );
+ echo json_encode($returnJson);
+ return 0;
+ }
+
+ public function generateFile($ctx,$fname,$path){
+ $ctxTmp = explode(",",$ctx);
+ $chunks = Db::name('chunks')->where([
+ 'ctx' => ["in",$ctxTmp],
+ ])->order('id asc')->select();
+ $file = $this->combineChunks($chunks);
+ $this->filterCheck($file,$fname);
+ $suffixTmp = explode('.', $fname);
+ $fileSuffix = array_pop($suffixTmp);
+ if($this->policyContent['autoname']){
+ $fileName = $this->getObjName($this->policyContent['namerule'],"local",$fname).".".$fileSuffix;
+ }else{
+ $fileName = $fname;
+ }
+ $generatePath = $this->getDirName($this->policyContent['dirrule']);
+ $savePath = ROOT_PATH . 'public/uploads/'.$generatePath;
+ is_dir($savePath)? :mkdir($savePath,0777,true);
+ if(file_exists($savePath.DS.$fileName)){
+ $this->setError("文件重名",true,$file,ROOT_PATH . 'public/uploads/chunks/');
+ }
+ if(!@rename(ROOT_PATH . 'public/uploads/chunks/'.$file,$savePath.DS.$fileName)){
+ $this->setError("文件创建失败",true,$file,ROOT_PATH . 'public/uploads/chunks/');
+ }else{
+ if($path == "ROOTDIR"){
+ $path = "";
+ }
+ $jsonData = array(
+ "path" => $path,
+ "fname" => $fname,
+ "objname" => $generatePath."/".$fileName,
+ "fsize" => $this->fileSizeTmp,
+ );
+ $addAction = FileManage::addFile($jsonData,$this->policyContent,$this->userId);
+ if(!$addAction[0]){
+ $this->setError($addAction[1],true,$fileName,$savePath);
+ }
+ echo json_encode(array("key" => $fname));
+ }
+ }
+
+ public function filterCheck($file,$fname){
+ $fileSize = filesize(ROOT_PATH . 'public/uploads/chunks/'.$file);
+ $suffixTmp = explode('.', $fname);
+ $fileSuffix = array_pop($suffixTmp);
+ $allowedSuffix = explode(',', self::getAllowedExt(json_decode($this->policyContent["filetype"],true)));
+ $sufficCheck = !in_array($fileSuffix,$allowedSuffix);
+ if(empty(self::getAllowedExt(json_decode($this->policyContent["filetype"],true)))){
+ $sufficCheck = false;
+ }
+ if(($fileSize >= (int)$this->policyContent["max_size"]) || $sufficCheck){
+ FileManage::storageGiveBack($this->userId,$fileSize);
+ $this->setError("文件效验失败",true,$file,ROOT_PATH . 'public/uploads/chunks/');
+ }
+ $this->fileSizeTmp = $fileSize;
+ }
+
+ public function combineChunks($fname){
+ $fileName = "file_".self::getRandomKey(8);
+ $fileObj=fopen (ROOT_PATH . 'public/uploads/chunks/'.$fileName,"a+");
+ $deleteList=[];
+ foreach ($fname as $key => $value) {
+ $chunkObj = fopen(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk", "rb");
+ if(!$fileObj || !$chunkObj){
+ $this->setError("文件创建失败",false);
+ }
+ $content = fread($chunkObj, 4195304);
+ fwrite($fileObj, $content, 4195304);
+ unset($content);
+ fclose($chunkObj);
+ unlink(ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
+ array_push($deleteList, $value["id"]);
+ }
+ $chunks = Db::name('chunks')->where([
+ 'id' => ["in",$deleteList],
+ ])->delete();
+ return $fileName;
+ }
+
+ public function fileReceive($file,$info){
+ $allowedExt = self::getAllowedExt(json_decode($this->policyContent["filetype"],true));
+ $filter = array('size'=>(int)$this->policyContent["max_size"]);
+ if(!empty($allowedExt)){
+ $filter = array_merge($filter,array("ext" => $allowedExt));
+ }
+ if(!FileManage::sotrageCheck($this->userId,$file->getInfo('size'))){
+ $this->setError("空间容量不足",false);
+ }
+ if($this->policyContent['autoname']){
+ $fileName = $this->getObjName($this->policyContent['namerule'],"local",$file->getInfo('name'));
+ }else{
+ $fileName = $file->getInfo('name');
+ }
+ $generatePath = $this->getDirName($this->policyContent['dirrule']);
+ $savePath = ROOT_PATH . 'public/uploads/'.$generatePath;
+ $Uploadinfo = $file
+ ->validate($filter)
+ ->move($savePath,$fileName,false);
+ if($Uploadinfo){
+ $jsonData = array(
+ "path" => $info["path"],
+ "fname" => $info["name"],
+ "objname" => $generatePath."/".$Uploadinfo->getSaveName(),
+ "fsize" => $Uploadinfo->getSize(),
+ );
+ @list($width, $height, $type, $attr) = getimagesize(rtrim($savePath, DS).DS.$Uploadinfo->getSaveName());
+ $picInfo = empty($width)?" ":$width.",".$height;
+ $addAction = FileManage::addFile($jsonData,$this->policyContent,$this->userId,$picInfo);
+ if(!$addAction[0]){
+ $tmpFileName = $Uploadinfo->getSaveName();
+ unset($Uploadinfo);
+ $this->setError($addAction[1],true,$tmpFileName,$savePath);
+ }
+ FileManage::storageCheckOut($this->userId,$jsonData["fsize"],$Uploadinfo->getInfo('size'));
+ echo json_encode(array("key" => $info["name"]));
+ }else{
+ header("HTTP/1.1 401 Unauthorized");
+ echo json_encode(array("error" => $file->getError()));
+ }
+ }
+
+ public function setError($text,$delete = false,$fname="",$path=""){
+ header("HTTP/1.1 401 Unauthorized");
+ if($delete){
+ unlink(rtrim($path, DS).DS.$fname);
+ }
+ die(json_encode(["error"=> $text]));
+ }
+
+ static function getAllowedExt($ext){
+ $returnValue = "";
+ foreach ($ext as $key => $value) {
+ $returnValue .= $value["ext"].",";
+ }
+ return rtrim($returnValue, ",");
+ }
+
+ public function getToken(){
+ switch ($this->policyContent['policy_type']) {
+ case 'qiniu':
+ return $this->getQiniuToken();
+ break;
+ case 'local':
+ return $this->getLocalToken();
+ break;
+ case 'oss':
+ return $this->getOssToken();
+ break;
+ case 'upyun':
+ return $this->getUpyunToken();
+ break;
+ case 's3':
+ return $this->getS3Token();
+ break;
+ default:
+ # code...
+ break;
+ }
+ }
+
+ public function getObjName($expression,$type = "qiniu",$origin = ""){
+ $policy = array(
+ '{date}' =>date("Ymd"),
+ '{datetime}' =>date("YmdHis"),
+ '{uid}' =>$this->userId,
+ '{timestamp}' =>time(),
+ '{randomkey16}' =>self::getRandomKey(16),
+ '{randomkey8}' =>self::getRandomKey(8),
+ );
+ if($type == "qiniu"){
+ $policy = array_merge($policy,array("{originname}" => "$(fname)"));
+ }else if($type == "local"){
+ $policy = array_merge($policy,array("{originname}" => $origin));
+ }else if ($type="oss"){
+ $policy = array_merge($policy,array("{originname}" => '${filename}'));
+ }else if ($type="upyun"){
+ $policy = array_merge($policy,array("{originname}" => '{filename}{.suffix}'));
+ }
+ return strtr($expression,$policy);
+ }
+
+ public function getDirName($expression){
+ $policy = array(
+ '{date}' =>date("Ymd"),
+ '{datetime}' =>date("YmdHis"),
+ '{uid}' =>$this->userId,
+ '{timestamp}' =>time(),
+ '{randomkey16}' =>self::getRandomKey(16),
+ '{randomkey8}' =>self::getRandomKey(8),
+ );
+ return trim(strtr($expression,$policy),"/");
+ }
+
+ public function getQiniuToken(){
+ $callbackKey = $this->getRandomKey();
+ $sqlData = [
+ 'callback_key' => $callbackKey,
+ 'pid' => $this->policyId,
+ 'uid' => $this->userId
+ ];
+ Db::name('callback')->insert($sqlData);
+ $auth = new Auth($this->policyContent['ak'], $this->policyContent['sk']);
+ $policy = array(
+ 'callbackUrl' =>Option::getValue("siteURL").'Callback/Qiniu',
+ 'callbackBody' => '{"fname":"$(fname)","objname":"$(key)","fsize":"$(fsize)","callbackkey":"'.$callbackKey.'","path":"$(x:path)","picinfo":"$(imageInfo.width),$(imageInfo.height)"}',
+ 'callbackBodyType' => 'application/json',
+ 'fsizeLimit' => (int)$this->policyContent['max_size'],
+ );
+ $dirName = $this->getObjName($this->policyContent['dirrule']);
+ if($this->policyContent["autoname"]){
+ $policy = array_merge($policy,array("saveKey" => $dirName.(empty($dirName)?"":"/").$this->getObjName($this->policyContent['namerule'])));
+ }else{
+ $policy = array_merge($policy,array("saveKey" => $dirName.(empty($dirName)?"":"/")."$(fname)"));
+ }
+ if(!empty($this->policyContent['mimetype'])){
+ $policy = array_merge($policy,array("mimeLimit" => $this->policyContent['mimetype']));
+ }
+ $token = $auth->uploadToken($this->policyContent['bucketname'], null, 3600, $policy);
+ return $token;
+ }
+
+ static function upyunSign($key, $secret, $method, $uri, $date, $policy=null, $md5=null){
+ $elems = array();
+ foreach (array($method, $uri, $date, $policy, $md5) as $v){
+ if ($v){
+ $elems[] = $v;
+ }
+ }
+ $value = implode('&', $elems);
+ $sign = base64_encode(hash_hmac('sha1', $value, $secret, true));
+ return 'UPYUN ' . $key . ':' . $sign;
+ }
+
+
+ public function getUpyunToken(){
+ $callbackKey = $this->getRandomKey();
+ $sqlData = [
+ 'callback_key' => $callbackKey,
+ 'pid' => $this->policyId,
+ 'uid' => $this->userId
+ ];
+ Db::name('callback')->insert($sqlData);
+ $options = Option::getValues(["oss","basic"]);
+ $dateNow = gmdate('D, d M Y H:i:s \G\M\T');
+ $policy=[
+ "bucket" => $this->policyContent['bucketname'],
+ "expiration" => time()+$options["timeout"],
+ "notify-url" => $options["siteURL"]."Callback/Upyun",
+ "content-length-range" =>"0,".$this->policyContent['max_size'],
+ "date" => $dateNow,
+ "ext-param"=>json_encode([
+ "path"=>cookie("path"),
+ "uid" => $this->userId,
+ "pid" => $this->policyId,
+ ]),
+ ];
+ $allowedExt = self::getAllowedExt(json_decode($this->policyContent["filetype"],true));
+ if(!empty($allowedExt)){
+ $policy = array_merge($policy,array("allow-file-type" => $allowedExt));
+ }
+ $dirName = $this->getObjName($this->policyContent['dirrule']);
+ $policy = array_merge($policy,array("save-key" => $dirName.(empty($dirName)?"":"/").uniqid()."CLSUFF{filename}{.suffix}"));
+ $this->upyunPolicy = base64_encode(json_encode($policy));
+ return self::upyunSign($this->policyContent['op_name'], md5($this->policyContent['op_pwd']), "POST", "/".$this->policyContent['bucketname'],$dateNow,$this->upyunPolicy);
+ }
+
+ public function ossCallback(){
+ $callbackKey = $this->getRandomKey();
+ $sqlData = [
+ 'callback_key' => $callbackKey,
+ 'pid' => $this->policyId,
+ 'uid' => $this->userId
+ ];
+ Db::name('callback')->insert($sqlData);
+ $returnValue["callbackUrl"] = Option::getValue("siteUrl").'Callback/Oss';
+ $returnValue["callbackBody"] = '{"fname":"${x:fname}","objname":"${object}","fsize":"${size}","callbackkey":"'.$callbackKey.'","path":"${x:path}","picinfo":"${imageInfo.width},${imageInfo.height}"}';
+ $this->ossCallBack = base64_encode(json_encode($returnValue));
+ return base64_encode(json_encode($returnValue));
+ }
+
+ public function getS3Token(){
+ $dirName = $this->getDirName($this->policyContent['dirrule']);
+ $longDate = gmdate('Ymd\THis\Z');
+ $shortDate = gmdate('Ymd');
+ $credential = $this->policyContent['ak'] . '/' . $shortDate . '/' . $this->policyContent['op_name'] . '/s3/aws4_request';
+ $callbackKey = $this->getRandomKey();
+ $sqlData = [
+ 'callback_key' => $callbackKey,
+ 'pid' => $this->policyId,
+ 'uid' => $this->userId
+ ];
+ Db::name('callback')->insert($sqlData);
+ $this->siteUrl = Option::getValue("siteUrl");
+ $returnValue = [
+ "expiration" => date("Y-m-d",time()+1800)."T".date("H:i:s",time()+1800).".000Z",
+ "conditions" => [
+ 0 => ["bucket" => $this->policyContent['bucketname']],
+ 1 => ["starts-with",'$key', $dirName],
+ 2 => ["starts-with",'$success_action_redirect' ,$this->siteUrl."Callback/S3/key/".$callbackKey],
+ 3 => ["content-length-range",1,(int)$this->policyContent['max_size']],
+ 4 => ['x-amz-algorithm' => 'AWS4-HMAC-SHA256'],
+ 5 => ['x-amz-credential' => $credential],
+ 6 => ['x-amz-date' => $longDate],
+ 7 => ["starts-with", '$name', ""],
+ 8 => ["starts-with", '$Content-Type', ""],
+ ]
+ ];
+ $this->s3Policy = base64_encode(json_encode($returnValue));
+ $signingKey = hash_hmac("sha256",$shortDate,"AWS4".$this->policyContent['sk'],true);
+ $signingKey = hash_hmac("sha256",$this->policyContent['op_name'],$signingKey,true);
+ $signingKey = hash_hmac("sha256","s3",$signingKey,true);
+ $signingKey = hash_hmac("sha256","aws4_request",$signingKey,true);
+ $signingKey = hash_hmac("sha256",$this->s3Policy,$signingKey);
+ $this->s3Sign = $signingKey;
+ $this->dirName = $dirName;
+ $this->s3Credential = $credential;
+ $this->x_amz_date = $longDate;
+ $this->callBackKey = $callbackKey;
+ }
+
+ public function getOssToken(){
+ $dirName = $this->getObjName($this->policyContent['dirrule']);
+ $returnValu["expiration"] = date("Y-m-d",time()+1800)."T".date("H:i:s",time()+1800).".000Z";
+ $returnValu["conditions"][0]["bucket"] = $this->policyContent['bucketname'];
+ $returnValu["conditions"][1][0]="starts-with";
+ $returnValu["conditions"][1][1]='$key';
+ if($this->policyContent["autoname"]){
+ $this->ossFileName = $dirName.(empty($dirName)?"":"/").$this->getObjName($this->policyContent['namerule'],"oss");;
+ }else{
+ $this->ossFileName = $dirName.(empty($dirName)?"":"/").'${filename}';
+ }
+ $returnValu["conditions"][1][2]=$dirName.(empty($dirName)?"":"/");
+ $returnValu["conditions"][2]=["content-length-range",1,(int)$this->policyContent['max_size']];
+ $returnValu["conditions"][3]["callback"] = $this->ossCallback();
+ $this->ossToken=base64_encode(json_encode($returnValu));
+ $this->ossSignToken();
+ $this->ossAccessId = $this->policyContent['ak'];
+ return false;
+ }
+
+ public function ossSignToken(){
+ $this->ossSign = base64_encode(hash_hmac("sha1", $this->ossToken, $this->policyContent['sk'],true));
+ }
+
+ public function getLocalToken(){
+ $auth = new Auth($this->policyContent['ak'], $this->policyContent['sk']);
+ $policy = array(
+ 'callbackBody' => '{"path":"'.cookie('path').'"}',
+ 'callbackBodyType' => 'application/json',
+ );
+ $token = $auth->uploadToken($this->policyContent['bucketname'], null, 3600, $policy);
+ return $token;
+ }
+
+ static function getRandomKey($length = 16){
+ $charTable = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $result = "";
+ for ( $i = 0; $i < $length; $i++ ){
+ $result .= $charTable[ mt_rand(0, strlen($charTable) - 1) ];
+ }
+ return $result;
+ }
+
+ static function b64Decode($string) {
+ $data = str_replace(array('-','_'),array('+','/'),$string);
+ $mod4 = strlen($data) % 4;
+ if ($mod4) {
+ $data .= substr('====', $mod4);
+ }
+ return base64_decode($data);
+ }
+
+}
+
+
+?>
\ No newline at end of file
diff --git a/application/index/model/User.php b/application/index/model/User.php
new file mode 100644
index 00000000..7497cbf0
--- /dev/null
+++ b/application/index/model/User.php
@@ -0,0 +1,375 @@
+where('id',$userId)->where('user_status',0)->find();
+ if(empty($userData)){
+ $this->loginStatus = false;
+ $this->setUser();
+ return false;
+ }
+ if(!$ignoreLogin){
+ if(md5($userData['user_email'].$userData['user_pass'].config('salt')) != $userKey){
+ $this->loginStatus = false;
+ $this->setUser();
+ return false;
+ }
+ }
+ $this->groupData = Db::name('groups')->where('id',$userData['user_group'])->find();
+ $this->loginStatus = true;
+ $this->uid = $userId;
+ $this->groupId = $userData['user_group'];
+ $this->regDate = $userData['user_date'];
+ $this->userNick = $userData['user_nick'];
+ $this->userMail = $userData['user_email'];
+ $this->varifyKey = $userKey;
+ $this->userSQLData = $userData;
+ }
+
+
+ public function setUser(){
+ $this->groupData = Db::name('groups')->where('id',2)->find();
+ $this->uid = -1;
+ }
+
+ static function resetPwd($key,$pwd){
+ $key = explode("_",$key);
+ $resetKey = $key[0]."_".$key[1];
+ $userId = $key[2];
+ $keyCheck = self::resetUser($resetKey,$userId);
+ if(!$keyCheck[0]){
+ return $keyCheck;
+ }else{
+ if ((mb_strlen($pwd,'UTF8')>64) || (mb_strlen($pwd,'UTF8')<4)){
+ return [false,"密码不符合规范"];
+ }
+ self::Reset($userId,$pwd);
+ return [true,"密码重设成功"];
+ }
+ }
+
+ static function Reset($uid,$pwd){
+ Db::name('users')->where('id',$uid)
+ ->update([
+ 'user_pass' => md5(config('salt').$pwd),
+ ]);
+ }
+
+ /**
+ * [register description]
+ * @param [type] $userEmail [description]
+ * @param [type] $userPass [description]
+ * @return [type] [description]
+ */
+ static function register($userEmail,$userPass,$captchaCode){
+ if(Option::getValue("login_captcha")=="1"){
+ if(!self::checkCaptcha($captchaCode)){
+ return [false,"验证码错误"];
+ }
+ }
+ if (\app\index\model\Option::getValue("regStatus") == '1'){
+ return [false,"当前站点关闭注册"];
+ }
+ $userName = str_replace(" ", "", $userEmail);
+ $passWord = $userPass;
+ if ( !filter_var($userName,FILTER_VALIDATE_EMAIL) || (mb_strlen($userName,'UTF8')>22) || (mb_strlen($userName,'UTF8')<4) || (mb_strlen($passWord,'UTF8')>64) || (mb_strlen($passWord,'UTF8')<4)){
+ return [false,"邮箱或密码不符合规范"];
+ }
+ if(Db::name('users')->where('user_email',$userName)->find() !=null){
+ return [false,"该邮箱已被注册"];
+ }
+ $defaultGroup = (int)\app\index\model\Option::getValue("defaultGroup");
+ $regOptions = Option::getValues(["register"]);
+ if($regOptions["email_active"] == "1"){
+ $activationKey = md5(uniqid(rand(), TRUE));
+ $userStatus = 1;
+ }else{
+ $activationKey = "n";
+ $userStatus = 0;
+ }
+ $sqlData = [
+ 'user_email' => $userName,
+ 'user_pass' => md5(config('salt').$passWord),
+ 'user_status' => $userStatus,
+ 'user_group' => $defaultGroup,
+ 'group_primary' => 0,
+ 'user_date' => date("Y-m-d H:i:s"),
+ 'user_nick' => explode("@",$userName)[0],
+ 'user_activation_key' => $activationKey,
+ 'used_storage' => 0,
+ 'two_step'=>"0",
+ 'webdav_key' =>md5(config('salt').$passWord),
+ 'delay_time' =>0,
+ 'avatar' => "default",
+ 'profile' => true,
+ ];
+ if(Db::name('users')->insert($sqlData)){
+ $userId = Db::name('users')->getLastInsID();
+ Db::name('folders')->insert( [
+ 'folder_name' => '根目录',
+ 'parent_folder' => 0,
+ 'position' => '.',
+ 'owner' => $userId,
+ 'date' => date("Y-m-d H:i:s"),
+ 'position_absolute' => '/',
+ ]);
+ if($regOptions["email_active"] == "1"){
+ $options = Option::getValues(["basic","mail_template"]);
+ $replace = array(
+ '{siteTitle}' =>$options["siteName"],
+ '{userName}' =>explode("@",$userName)[0],
+ '{siteUrl}' =>$options["siteURL"],
+ '{siteSecTitle}' =>$options["siteTitle"],
+ '{activationUrl}' =>$options["siteURL"]."Member/emailActivate/".$activationKey,
+ );
+ $mailContent = strtr($options["mail_activation_template"],$replace);
+ $mailObj = new Mail();
+ $mailObj->Send($userName,explode("@",$userName)[0],"【".$options["siteName"]."】"."注册激活",$mailContent);
+ return [true,"ec"];
+ }
+ return [true,"注册成功"];
+ }
+ }
+
+ static function activicateUser($key){
+ $userData = Db::name('users')
+ ->where('user_activation_key','neq','n')
+ ->where("user_activation_key",$key)->find();
+ if(empty($userData)){
+ return [0,"激活失败,用户在不存在"];
+ }else{
+ Db::name('users')->where("id",$userData["id"])->update([
+ "user_activation_key" => "n",
+ "user_status" => 0,
+ ]);
+ return [1,1];
+ }
+ }
+
+ static function resetUser($key,$uid){
+ $timeNow = time();
+ if(empty($key)||empty($uid)){
+ return [0,"URL参数错误"];
+ }
+ $key = explode("_",$key);
+ $userData = Db::name('users')
+ ->where('user_status',0)
+ ->where("id",$uid)->find();
+ if(empty($userData)){
+ return [0,"用户不存在"];
+ }
+ if(md5($userData["user_pass"].$key[1]) != $key[0]){
+ return [0,"参数无效,请检查邮件链接"];
+ }
+ if(($timeNow - $key[1])>7200){
+ return [0,"重设链接过期,请重新提交"];
+ }
+ return [1,1];
+ }
+
+ static function findPwd($email,$captchaCode){
+ if(Option::getValue("login_captcha")=="1"){
+ if(!self::checkCaptcha($captchaCode)){
+ return [false,"验证码错误"];
+ }
+ }
+ $userData = Db::name('users')->where('user_email',$email)->find();
+ if(empty($userData)){
+ return [1,1];
+ }
+ $timeNow = time();
+ $resetHash = md5($userData["user_pass"].$timeNow);
+ $resetKey = $resetHash."_".$timeNow;
+ $options = Option::getValues(["basic","mail_template"]);
+ $replace = array(
+ '{siteTitle}' =>$options["siteName"],
+ '{userName}' =>$userData["user_nick"],
+ '{siteUrl}' =>$options["siteURL"],
+ '{siteSecTitle}' =>$options["siteTitle"],
+ '{resetUrl}' =>$options["siteURL"]."Member/resetPwd/".$resetKey."?uid=".$userData["id"],
+ );
+ $mailContent = strtr($options["mail_reset_pwd_template"],$replace);
+ $mailObj = new Mail();
+ $mailObj->Send($email,$userData["user_nick"],"【".$options["siteName"]."】"."密码重置",$mailContent);
+ return [true,"ec"];
+ }
+
+ /**
+ * [login description]
+ * @param [type] $userEmail [description]
+ * @param [type] $userPass [description]
+ * @return [type] [description]
+ */
+ static function login($userEmail,$userPass,$captchaCode){
+ $userEmail = str_replace(" ", "", $userEmail);
+ $userData =Db::name('users')->where('user_email',$userEmail)->find();
+ if(empty($userEmail) || empty($userPass)){
+ return [false,"表单不完整"];
+ }
+ if(Option::getValue("login_captcha")=="1"){
+ if(!self::checkCaptcha($captchaCode)){
+ return [false,"验证码错误"];
+ }
+ }
+ if(Db::name('users')->where('user_email',$userEmail)->value('user_pass') != md5(config('salt').$userPass)){
+ return [false,"用户名或密码错误"];
+ }
+ if(Db::name('users')->where('user_email',$userEmail)->value('user_status') != 0){
+ return [false,"账号被禁用或未激活"];
+ }
+ if($userData["two_step"] != "0"){
+ session("user_id_tmp",Db::name('users')->where('user_email',$userEmail)->value('id'));
+ session("login_status_tmp","ok");
+ session("login_key_tmp",md5($userEmail.md5(config('salt').$userPass).config('salt')));
+ return [false,"tsp"];
+ }
+ $loginKey = md5($userEmail.md5(config('salt').$userPass).config('salt'));
+ cookie('user_id',Db::name('users')->where('user_email',$userEmail)->value('id'),604800);
+ cookie('login_status','ok',604800);
+ cookie('login_key',$loginKey,604800);
+ return [true,"登录成功",$loginKey];
+ }
+
+ static function checkCaptcha($code){
+ if(!captcha_check($code)){
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * [clear description]
+ * @return [type] [description]
+ */
+ public function clear(){
+ $this->loginStatus = false;
+ $this->uid = null;
+ $this->groupId = null;
+ $this->regDate = null;
+ $this->varifyKey = null;
+ cookie('user_id', null);
+ cookie('login_status', null);
+ cookie('login_key', null);
+ }
+
+ /**
+ * [getInfo description]
+ * @return [type] [description]
+ */
+ public function getInfo(){
+ return [
+ 'uid' => $this->uid,
+ 'groupId' => $this->groupId,
+ 'regDate' => $this->regDate,
+ 'loginStatus' => $this->loginStatus,
+ 'userNick' => $this->userNick,
+ 'userMail' => $this->userMail,
+ 'groupData' => $this->groupData,
+ 'sqlData' => $this->userSQLData,
+ ];
+ }
+
+ public function getSQLData(){
+ return $this->userSQLData;
+ }
+
+ public function getPolicy(){
+ return Db::name('policy')->where('id',$this->groupData["policy_name"])->find();
+ }
+
+ public function getGroupData(){
+ return $this->groupData;
+ }
+
+ public function getMemory($notEcho = false){
+ $usedMemory = $this->userSQLData["used_storage"];
+ $groupStorage = (int)$this->groupData["max_storage"];
+ $packetStorage = (int)Db::name('storage_pack')
+ ->where('uid',$this->uid)
+ ->where('dlay_time',">",time())
+ ->sum('pack_size');
+ $returnData["used"] = self::countSize((int)$usedMemory);
+ $returnData["total"] = self::countSize($groupStorage+$packetStorage);
+ $returnData["rate"] = floor((int)$usedMemory/($groupStorage+$packetStorage)*100);
+ $returnData["basic"] = self::countSize((int)$groupStorage);
+ $returnData["pack"] = self::countSize((int)$packetStorage);
+ if($usedMemory > $groupStorage){
+ $returnData["r1"] = floor((int)$usedMemory/($groupStorage+$packetStorage)*100);
+ $returnData["r2"] = 0;
+ $returnData["r3"] = 100-$returnData["r1"];
+ }else{
+ $returnData["r1"] = floor((int)$usedMemory/($groupStorage+$packetStorage)*100);
+ $returnData["r2"] = floor(((int)$groupStorage-$usedMemory)/($groupStorage+$packetStorage)*100);;
+ $returnData["r3"] = 100-$returnData["r1"]-$returnData["r2"];
+ }
+ if($notEcho){
+ return json_encode($returnData);
+ }
+ echo json_encode($returnData);
+ }
+
+ static function countSize($bit) {
+ $type = array('Bytes','KB','MB','GB','TB');
+ for($i = 0; $bit >= 1024; $i++) {
+ $bit/=1024;
+ }
+ return (floor($bit*100)/100).$type[$i];
+ }
+
+ public function changeNick($nick){
+ $nick=["nick" => $nick];
+ $rules = [
+ 'nick' => ['require','max'=>'25','chsDash'],
+ ];
+ $validate = new Validate($rules);
+ if (!$validate->check($nick)) {
+ return [0,"昵称必须是1-25位字符,只能包含中英文等常见字符"];
+ }else{
+ Db::name("users")->where("id",$this->uid)->update(["user_nick" => $nick["nick"]]);
+ return [1,1];
+ }
+ }
+
+ public function changePwd($origin,$new){
+ if(md5(config('salt').$origin) != $this->userSQLData["user_pass"]){
+ return [0,"原密码错误"];
+ }
+ if ((mb_strlen($new,'UTF8')>64) || (mb_strlen($new,'UTF8')<4)){
+ return [false,"密码不符合规范"];
+ }
+ self::Reset($this->uid,$new);
+ return [true,"密码重设成功"];
+ }
+
+ public function homePageToggle($status){
+ Db::name("users")->where("id",$this->uid)->update(["profile" => $status=="true"?1:0]);
+ return [1,1];
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/application/index/view/admin/about.html b/application/index/view/admin/about.html
new file mode 100644
index 00000000..5e553a8a
--- /dev/null
+++ b/application/index/view/admin/about.html
@@ -0,0 +1,72 @@
+{extend name="header_admin" /}
+{block name="title"}基础设置- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 其他
+ - 关于
+
+
+
+
+
+
关于
+
+
+
+
+
+
+
+
+ - 服务器信息:{:$_SERVER ['SERVER_SOFTWARE']}
+ - 服务端系统:{:PHP_OS}
+ - 最大上传限制:{:get_cfg_var ("upload_max_filesize")?get_cfg_var ("upload_max_filesize"):"不允许上传"}
+ - 脚本最大执行时间:{:get_cfg_var("max_execution_time")."s "}
+ - 脚本最大内存:{:get_cfg_var ("memory_limit")?get_cfg_var("memory_limit"):"无"}
+ - PHP扩展:curl{eq name=":extension_loaded('curl')" value="true"}√{else/}×{/eq} openssl{eq name=":extension_loaded('openssl')" value="true"}√{else/}×{/eq} GD{eq name=":extension_loaded('gd')" value="true"}√{else/}×{/eq} fileinfo{eq name=":extension_loaded('fileinfo')" value="true"}√{else/}×{/eq}
+
+
+
+
+
+
+
+
+
Cloudreve {$programVersion.type} {$programVersion.version}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/add_group.html b/application/index/view/admin/add_group.html
new file mode 100644
index 00000000..7e190809
--- /dev/null
+++ b/application/index/view/admin/add_group.html
@@ -0,0 +1,164 @@
+{extend name="header_admin" /}
+{block name="title"}注册访问- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 用户组
+ - 添加用户组
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/add_policy.html b/application/index/view/admin/add_policy.html
new file mode 100644
index 00000000..ce471801
--- /dev/null
+++ b/application/index/view/admin/add_policy.html
@@ -0,0 +1,815 @@
+{extend name="header_admin" /}
+{block name="title"}添加上传策略- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ -
+ 上传策略
+
+ - 添加
+
+
+
+
+
+
添加上传策略
+
+
+
+
+
+

+
+
本地服务器
+
将文件存放在Cloudreve主程序的同一个服务器上
+
添加
+
+
+
+
+
+

+
+
七牛云存储
+
使用七牛云提供的云存储及CDN服务
+
添加
+
+
+
+
+
+

+
+
阿里云OSS
+
使用OSS对象存储存放文件,推荐配合阿里云CDN使用
+
添加
+
+
+
+
+
+

+
+
又拍云
+
使用又拍云存储提供的服务,每月有一定免费额度
+
添加
+
+
+
+
+
+
+

+
+
Amazon S3
+
Amazon S3专为从任意位置存储和检索任意数量的数据而构建的对象存储
+
添加
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 阿里云OSS创建空间后请进行如下操作,否则无法正常上传。
+
+ - 转到 空间管理 - 基础设置 - 跨域设置;
+ - 创建规则,其中来源填写“*”,允许 Methods全部勾选,允许 Headers填写“*”,其他保持默认,点击确定保存.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 变量字段 |
+ 说明 |
+ 示例 |
+ 适用范围 |
+
+
+
+
+ {date} |
+ 上传日期 |
+ 20180118 |
+ 全部 |
+
+
+ {datetime} |
+ 上传日期时间 |
+ 20180118121049 |
+ 全部 |
+
+
+ {uid} |
+ 上传者UID |
+ 154 |
+ 全部 |
+
+
+ {timestamp} |
+ 时间戳 |
+ 1516277624 |
+ 全部 |
+
+
+ {randomkey16} |
+ 16位随机字符 |
+ 16D8lhjErTDWAQjW |
+ 全部 |
+
+
+ {randomkey8} |
+ 8位随机字符 |
+ hM4Tpdh6 |
+ 全部 |
+
+
+ {originname} |
+ 原始文件名 |
+ plus1s.jpg |
+ 全部 |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 变量字段 |
+ 说明 |
+ 示例 |
+ 适用范围 |
+
+
+
+
+ {date} |
+ 上传日期 |
+ 20180118 |
+ 全部 |
+
+
+ {datetime} |
+ 上传日期时间 |
+ 20180118121049 |
+ 全部 |
+
+
+ {uid} |
+ 上传者UID |
+ 154 |
+ 全部 |
+
+
+ {timestamp} |
+ 时间戳 |
+ 1516277624 |
+ 全部 |
+
+
+ {randomkey16} |
+ 16位随机字符 |
+ 16D8lhjErTDWAQjW |
+ 全部 |
+
+
+ {randomkey8} |
+ 8位随机字符 |
+ hM4Tpdh6 |
+ 全部 |
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/add_policy_s3.html b/application/index/view/admin/add_policy_s3.html
new file mode 100644
index 00000000..8a3cf99b
--- /dev/null
+++ b/application/index/view/admin/add_policy_s3.html
@@ -0,0 +1,175 @@
+{extend name="header_admin" /}
+{block name="title"}添加上传策略- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ -
+ 上传策略
+
+ - 添加
+
+
+
+
+
+
添加上传策略
+
+
+
+
+
+
+ 创建储存桶后请在储存桶控制面板添加CORS跨域规则,允许本站的POST请求。请确保您的服务器和用户可以正常连接到AWS服务器。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/admin_index.html b/application/index/view/admin/admin_index.html
new file mode 100644
index 00000000..d14ba5d5
--- /dev/null
+++ b/application/index/view/admin/admin_index.html
@@ -0,0 +1,229 @@
+{extend name="header_admin" /}
+{block name="title"}管理面板- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 数据概况
+
+
+
+
+
+
+
+
+
+
{$statics.userNum} 位用户
+
+
+
+
+
+
+
+
+
+
+
{$statics.fileNum} 个文件
+
+
+
+
+
+
+
+
+
+
+
{$statics.publicShareNum} 个公开分享
+
+
+
+
+
+
+
+
+
+
+
{$statics.privateShareNum} 个私密分享
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/basic_setting.html b/application/index/view/admin/basic_setting.html
new file mode 100644
index 00000000..7a07d405
--- /dev/null
+++ b/application/index/view/admin/basic_setting.html
@@ -0,0 +1,83 @@
+{extend name="header_admin" /}
+{block name="title"}基础设置- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 设置
+ - 基础设置
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/config_file.html b/application/index/view/admin/config_file.html
new file mode 100644
index 00000000..7fe722ba
--- /dev/null
+++ b/application/index/view/admin/config_file.html
@@ -0,0 +1,51 @@
+{extend name="header_admin" /}
+{block name="title"}基础设置- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 设置
+ - 配置文件
+
+
+
+
+
+
配置文件
+ {$path}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/cron_list.html b/application/index/view/admin/cron_list.html
new file mode 100644
index 00000000..ea8ebaa0
--- /dev/null
+++ b/application/index/view/admin/cron_list.html
@@ -0,0 +1,84 @@
+{extend name="header_admin" /}
+{block name="title"}基础设置- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 其他
+ - 定时任务
+
+
+
+
+
+
定时任务
+
+ {eq name="neverExcute" value="true"}
+
+ 定时任务从未执行!请将 {$options.siteURL}Cron 加入到您的定时任务列队中(如Crontab)。
+
+ {/eq}
+ {volist name="cron" id="c"}
+
+ {/volist}
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/edit_group.html b/application/index/view/admin/edit_group.html
new file mode 100644
index 00000000..56a625cc
--- /dev/null
+++ b/application/index/view/admin/edit_group.html
@@ -0,0 +1,171 @@
+{extend name="header_admin" /}
+{block name="title"}注册访问- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 用户组
+ - 编辑用户组
+
+
+
+
+
+
编辑用户组
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/edit_policy.html b/application/index/view/admin/edit_policy.html
new file mode 100644
index 00000000..dc5ea3ed
--- /dev/null
+++ b/application/index/view/admin/edit_policy.html
@@ -0,0 +1,962 @@
+{extend name="header_admin" /}
+{block name="title"}编辑上传策略- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ -
+ 上传策略
+
+ - 编辑
+
+
+
+
+
+
编辑上传策略
+
+ {switch name="policy.policy_type"}
+ {case value="local"}
+
+
+
+
+
+
+
+ {/case}
+ {case value="qiniu"}
+
+
+
+
+
+
+
+ {/case}
+ {case value="oss"}
+
+{/case}
+ {case value="upyun"}
+
+ {/case}
+ {case value="s3"}
+
+
+ {/case}
+{/switch}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 变量字段 |
+ 说明 |
+ 示例 |
+ 适用范围 |
+
+
+
+
+ {date} |
+ 上传日期 |
+ 20180118 |
+ 全部 |
+
+
+ {datetime} |
+ 上传日期时间 |
+ 20180118121049 |
+ 全部 |
+
+
+ {uid} |
+ 上传者UID |
+ 154 |
+ 全部 |
+
+
+ {timestamp} |
+ 时间戳 |
+ 1516277624 |
+ 全部 |
+
+
+ {randomkey16} |
+ 16位随机字符 |
+ 16D8lhjErTDWAQjW |
+ 全部 |
+
+
+ {randomkey8} |
+ 8位随机字符 |
+ hM4Tpdh6 |
+ 全部 |
+
+
+ {originname} |
+ 原始文件名 |
+ plus1s.jpg |
+ 全部 |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 变量字段 |
+ 说明 |
+ 示例 |
+ 适用范围 |
+
+
+
+
+ {date} |
+ 上传日期 |
+ 20180118 |
+ 全部 |
+
+
+ {datetime} |
+ 上传日期时间 |
+ 20180118121049 |
+ 全部 |
+
+
+ {uid} |
+ 上传者UID |
+ 154 |
+ 全部 |
+
+
+ {timestamp} |
+ 时间戳 |
+ 1516277624 |
+ 全部 |
+
+
+ {randomkey16} |
+ 16位随机字符 |
+ 16D8lhjErTDWAQjW |
+ 全部 |
+
+
+ {randomkey8} |
+ 8位随机字符 |
+ hM4Tpdh6 |
+ 全部 |
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/file_list.html b/application/index/view/admin/file_list.html
new file mode 100644
index 00000000..0133cee9
--- /dev/null
+++ b/application/index/view/admin/file_list.html
@@ -0,0 +1,194 @@
+{extend name="header_admin" /}
+{block name="title"}文件列表- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 文件
+
+
+
+
文件
+
+
+
+
+
+
+
+
+
高级检索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
文件名:
+
5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg
+
+
+
源文件名:
+
5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg
+
+
+
+
+
+
+
+
+
+
+
+
+ {/block}
+ {block name="js"}
+
+
+ {/block}
\ No newline at end of file
diff --git a/application/index/view/admin/group_list.html b/application/index/view/admin/group_list.html
new file mode 100644
index 00000000..cca5f268
--- /dev/null
+++ b/application/index/view/admin/group_list.html
@@ -0,0 +1,131 @@
+{extend name="header_admin" /}
+{block name="title"}上传策略- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 用户组
+
+
+
+
+
+
用户组
+
+
+
+
+
+
+
+
+
+
+
+ # | 名称 | 上传策略 | 最大容量 | 下属用户数 | 操作 |
+
+
+ # | 名称 | 上传策略 | 最大容量 | 下属用户数 | 操作 |
+
+
+
+
+ {volist name='list' id='group'}
+
+ {$group.id} |
+
+ {$group.group_name}
+ |
+
+ {$originList[$key]["policy"]["policy_name"]}
+ |
+ {:countSize($group["max_storage"])} |
+ {$originList[$key]["user_num"]} |
+
+
+
+ |
+
+ {/volist}
+
+
+
+
+
+
+
展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
文件名:
+
5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg
+
+
+
源文件名:
+
5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg
+
+
+
+
+
+
+
+
+
+
+
+
+ {/block}
+ {block name="js"}
+
+
+ {/block}
\ No newline at end of file
diff --git a/application/index/view/admin/mail_setting.html b/application/index/view/admin/mail_setting.html
new file mode 100644
index 00000000..278d72ab
--- /dev/null
+++ b/application/index/view/admin/mail_setting.html
@@ -0,0 +1,206 @@
+{extend name="header_admin" /}
+{block name="title"}邮件收发- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+
+ -
+ 管理面板
+
+ - 设置
+ - 邮件设置
+
+
+
+
+
+
邮件收发
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/other_setting.html b/application/index/view/admin/other_setting.html
new file mode 100644
index 00000000..db5bf6e5
--- /dev/null
+++ b/application/index/view/admin/other_setting.html
@@ -0,0 +1,96 @@
+{extend name="header_admin" /}
+{block name="title"}注册访问- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 设置
+ - 杂项
+
+
+
+
+
+
+
杂项设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/policy_list.html b/application/index/view/admin/policy_list.html
new file mode 100644
index 00000000..9a12a06b
--- /dev/null
+++ b/application/index/view/admin/policy_list.html
@@ -0,0 +1,168 @@
+{extend name="header_admin" /}
+{block name="title"}上传策略- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 上传策略
+
+
+
+
+
+
上传策略
+
+
+
+
+
+
+
+
+
+
+
+ # | 名称 | 类型 | 下属文件数 | 数据量 | 操作 |
+
+
+ # | 名称 | 类型 | 下属文件数 | 数据量 | 操作 |
+
+
+
+
+ {volist name='list' id='policy'}
+
+ {$policy.id} |
+
+ {$policy.policy_name}
+ |
+
+ {switch name="policy.policy_type"}
+ {case value="local"}本地{/case}
+ {case value="qiniu"}七牛{/case}
+ {case value="oss"}OSS{/case}
+ {case value="upyun"}又拍云{/case}
+ {case value="s3"}Amazon S3{/case}
+ {default /}其他
+ {/switch}
+ |
+ {$originList[$key]["file_num"]} |
+ {:countSize($originList[$key]["file_size"])} |
+
+
+
+ |
+
+ {/volist}
+
+
+
+
+
+
+
展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
文件名:
+
5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg
+
+
+
源文件名:
+
5c06e532e7afdb4389e4ae846ea7876c_w - 副本 - 副本.jpg
+
+
+
+
+
+
+
+
+
+
+
+
+ {/block}
+ {block name="js"}
+
+
+ {/block}
\ No newline at end of file
diff --git a/application/index/view/admin/reg_setting.html b/application/index/view/admin/reg_setting.html
new file mode 100644
index 00000000..b2bf4af0
--- /dev/null
+++ b/application/index/view/admin/reg_setting.html
@@ -0,0 +1,134 @@
+{extend name="header_admin" /}
+{block name="title"}注册访问- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 设置
+ - 注册访问
+
+
+
+
+
+
+
注册与访问
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/share_list.html b/application/index/view/admin/share_list.html
new file mode 100644
index 00000000..3a24b17e
--- /dev/null
+++ b/application/index/view/admin/share_list.html
@@ -0,0 +1,110 @@
+{extend name="header_admin" /}
+{block name="title"}文件列表- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 分享
+
+
+
+
+
+
分享
+
+
+
+
+
+
+
+
展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据
+
+
+
+
+
+
+
+
+
+
+
+ {/block}
+ {block name="js"}
+
+
+ {/block}
\ No newline at end of file
diff --git a/application/index/view/admin/theme.html b/application/index/view/admin/theme.html
new file mode 100644
index 00000000..015f43c6
--- /dev/null
+++ b/application/index/view/admin/theme.html
@@ -0,0 +1,51 @@
+{extend name="header_admin" /}
+{block name="title"}基础设置- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 模板
+
+
+
+
+
+
编辑模板
+ application/index/view/{:rtrim($path,"/")}/{$name}.html
+
+
+
+
+
+
+
+
+
+
+
+
+ {volist name="list" id="file"}
+
{$file}
+ {/volist}
+
+
+
+
+
+
+
+
+
+
+
+
+{/block}
+{block name="js"}
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/admin/user_list.html b/application/index/view/admin/user_list.html
new file mode 100644
index 00000000..f7048b44
--- /dev/null
+++ b/application/index/view/admin/user_list.html
@@ -0,0 +1,298 @@
+{extend name="header_admin" /}
+{block name="title"}文件列表- {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+ -
+ 管理面板
+
+ - 用户
+
+
+
+
+
+
用户
+
+
+
+
+
+
+
+
+
+
高级检索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
展示第 {$pageNow} 页,共 {$pageTotal} 页 {$dataTotal} 条数据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/block}
+ {block name="js"}
+
+
+ {/block}
\ No newline at end of file
diff --git a/application/index/view/callback/payment_success.html b/application/index/view/callback/payment_success.html
new file mode 100644
index 00000000..6594c8f5
--- /dev/null
+++ b/application/index/view/callback/payment_success.html
@@ -0,0 +1,23 @@
+{extend name="header_public" /}
+{block name="title"}支付成功 - {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+
+
+
+
+
+
+
+
支付成功
+
+
付款成功,您所购买的服务已开通。
+
查看详情
+
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/error.html b/application/index/view/error.html
new file mode 100644
index 00000000..c7e74ff2
--- /dev/null
+++ b/application/index/view/error.html
@@ -0,0 +1,24 @@
+{extend name="header_public" /}
+{block name="title"}错误提示 - {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+
+
+
+
+
+
+
+
发生错误
+
+
{$msg}
+
<< 返回
+
+
+
+{$options.js_code}
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/exception.html b/application/index/view/exception.html
new file mode 100644
index 00000000..c7e74ff2
--- /dev/null
+++ b/application/index/view/exception.html
@@ -0,0 +1,24 @@
+{extend name="header_public" /}
+{block name="title"}错误提示 - {$options.siteName}{/block}
+{block name="content"}
+
+
+
+
+
+
+
+
+
+
+
+
发生错误
+
+
{$msg}
+
<< 返回
+
+
+
+{$options.js_code}
+
+{/block}
\ No newline at end of file
diff --git a/application/index/view/explore/result.html b/application/index/view/explore/result.html
new file mode 100644
index 00000000..db89f0bc
--- /dev/null
+++ b/application/index/view/explore/result.html
@@ -0,0 +1,76 @@
+{extend name="header_public" /}
+{block name="title"}“{$keyWords}”搜索结果 - {$options.siteName}{/block}
+{block name="content"}
+
+
+
+