├── .gitattributes ├── .gitignore ├── .htaccess ├── README.MD ├── app ├── Bootstrap.php ├── Debug.php ├── controllers │ ├── Api.php │ ├── Auth.php │ ├── Books.php │ ├── Card.php │ ├── Error.php │ ├── File.php │ ├── Password.php │ ├── Printers.php │ ├── School.php │ ├── Share.php │ ├── Tags.php │ ├── Task.php │ ├── Test.php │ └── User.php ├── email │ ├── pwd.tpl │ └── verify.tpl ├── models │ ├── Book.php │ ├── Card.php │ ├── Cardlog.php │ ├── Facade.php │ ├── File.php │ ├── Printer.php │ ├── School.php │ ├── Share.php │ ├── Tag.php │ ├── Task.php │ └── User.php ├── modules │ └── Printer │ │ └── controllers │ │ ├── Auth.php │ │ ├── Books.php │ │ ├── Info.php │ │ ├── Password.php │ │ ├── Task.php │ │ └── User.php ├── plugins │ └── Tracer.php └── views │ ├── api │ ├── choice.phtml │ └── index.phtml │ └── jump.phtml ├── backup.php ├── conf ├── app.ini └── secret.common.ini ├── config.yaml ├── init.sh ├── library ├── Auth.php ├── Cache.php ├── Config.php ├── Cookie.php ├── Encrypt.php ├── File.php ├── Input.php ├── Kv.php ├── Log.php ├── Mail.php ├── Model.php ├── Parse │ ├── Filter.php │ └── Xml.php ├── PhpConsole │ ├── Auth.php │ ├── Connector.php │ ├── Dispatcher.php │ ├── Dispatcher │ │ ├── Debug.php │ │ ├── Errors.php │ │ └── Evaluate.php │ ├── Dumper.php │ ├── EvalProvider.php │ ├── Handler.php │ ├── Helper.php │ ├── LICENSE │ ├── Storage.php │ ├── Storage │ │ ├── AllKeysList.php │ │ ├── ExpiringKeyValue.php │ │ ├── File.php │ │ ├── Memcache.php │ │ ├── MongoDB.php │ │ └── Session.php │ └── __autoload.php ├── README.md ├── Random.php ├── Rest.php ├── Rsa.php ├── Safe.php ├── School.php ├── Service │ ├── Api.php │ ├── Db.php │ ├── Message.php │ ├── Qiniu.php │ ├── README.MD │ ├── Smtp.php │ └── Ucpaas.php ├── Session.php ├── Sms.php ├── Storage │ └── File.php ├── Validate.php └── Verify │ ├── Connect.php │ ├── GZPYP.php │ ├── HEBUT.php │ ├── HNIST.php │ ├── NKU.php │ ├── README.MD │ ├── TIFERT.php │ └── TJU.php └── public ├── .htaccess ├── favicon.ico ├── index.php └── robots.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #tempFile 2 | #临时文件 3 | temp/ 4 | 5 | #localfile 6 | #本地文件 7 | *.local 8 | 9 | # Windows image file caches 10 | Thumbs.db 11 | ehthumbs.db 12 | 13 | # Folder config file 14 | Desktop.ini 15 | 16 | # Recycle Bin used on file shares 17 | $RECYCLE.BIN/ 18 | 19 | # Windows Installer files 20 | *.cab 21 | *.msi 22 | *.msm 23 | *.msp 24 | 25 | # Windows shortcuts 26 | *.lnk 27 | 28 | # ========================= 29 | # Operating System Files 30 | # ========================= 31 | 32 | # OSX 33 | # ========================= 34 | 35 | .DS_Store 36 | .AppleDouble 37 | .LSOverride 38 | 39 | # Thumbnails 40 | ._* 41 | 42 | # Files that might appear on external disk 43 | .Spotlight-V100 44 | .Trashes 45 | 46 | # Directories potentially created on remote AFP share 47 | .AppleDB 48 | .AppleDesktop 49 | Network Trash Folder 50 | Temporary Items 51 | .apdisk 52 | conf/secret.product.ini 53 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Options +FollowSymlinks 3 | RewriteEngine On 4 | RewriteBase / 5 | RewriteRule ^(.*)$ public/$1 [QSA,PT,L] 6 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | 云印新版服务接口 2 | ==================== 3 | 4 | 云印后端API库 5 | 6 | 7 | 基于YYF的云印REST接口 8 | 9 | [接口文档Wiki](https://github.com/YunYinORG/YunYinService/wiki) 10 | 11 | ## 开发设置[dev] 12 | 13 | * 环境: 14 | 本地开发调试[请使用云印虚拟机](https://github.com/YunYinORG/vagrant)快速部署 15 | * 配置(init.sh): 16 | copy `./conf/secret.common.ini` 到 `./conf/secret.local`;Linux 赋予`chmod 777 tmep` 17 | 18 | 19 | ## 生产环境[product] 20 | 21 | 请将web根目录设为public -------------------------------------------------------------------------------- /app/Bootstrap.php: -------------------------------------------------------------------------------- 1 | getRouter()->addConfig(Config::get('routes')); 16 | } 17 | } -------------------------------------------------------------------------------- /app/Debug.php: -------------------------------------------------------------------------------- 1 | isActiveClient()) 22 | { 23 | Log::write('PHP Console 已经链接', 'INFO'); 24 | 25 | $handler = PhpConsole\Handler::getInstance(); 26 | $dispatcher = $connector->getDebugDispatcher(); 27 | $handler->start(); 28 | 29 | $connector->setSourcesBasePath(APP_PATH); 30 | $connector->setServerEncoding('utf8'); 31 | $dispatcher->detectTraceAndSource = true; //跟踪信息 32 | 33 | if ($pwd = Config::get('debug.auth')) //是否需要验证 34 | { 35 | $connector->setPassword($pwd); 36 | $evalProvider = $connector->getEvalDispatcher()->getEvalProvider(); 37 | // $evalProvider->disableFileAccessByOpenBaseDir(); // means disable functions like include(), require(), file_get_contents() & etc 38 | // $evalProvider->addSharedVar('uri', $_SERVER['REQUEST_URI']); // so you can access $_SERVER['REQUEST_URI'] just as $uri in terminal 39 | // $evalProvider->addSharedVarReference('post', $_POST); 40 | $connector->startEvalRequestsListener(); 41 | } 42 | } 43 | PhpConsole\Helper::register(); 44 | } 45 | } 46 | 47 | /** 48 | * 加载插件 49 | * @method _initPlugin 50 | * @param Yaf_Dispatcher $dispatcher [description] 51 | * @return [type] [description] 52 | * @access private 53 | * @author NewFuture 54 | */ 55 | public function _initPlugin(Yaf_Dispatcher $dispatcher) 56 | { 57 | $tracer = new TracerPlugin(); 58 | $dispatcher->registerPlugin($tracer); 59 | } 60 | 61 | /** 62 | * 开启调试输出 63 | * @method _initRoute 64 | * @author NewFuture 65 | */ 66 | public function _initRoute(Yaf_Dispatcher $dispatcher) 67 | { 68 | $dispatcher->getRouter()->addConfig(Config::get('routes')); 69 | } 70 | } -------------------------------------------------------------------------------- /app/controllers/Api.php: -------------------------------------------------------------------------------- 1 | redirect($redirect); 30 | exit(); 31 | } 32 | else 33 | { 34 | //显示成功页面 35 | Yaf_Dispatcher::getInstance()->autoRender(false); 36 | $this->_view->display('api/choice.phtml'); 37 | } 38 | 39 | } 40 | elseif (Session::get('reg')) 41 | { 42 | //正在注册 43 | $this->_view->assign('msg', '还差一步,请设置密码')->assign('reg', 1); 44 | } 45 | 46 | } 47 | 48 | /** 49 | * 确认注册【设定密码】 50 | * 无password时,使用验证密码 51 | * @method registerAction 52 | * @return [type] [description] 53 | * @author NewFuture 54 | */ 55 | public function registerAction() 56 | { 57 | if (!$regInfo = Session::get('reg')) 58 | { 59 | $this->jump('/', '注册信息已失效'); 60 | } 61 | else 62 | { 63 | Session::del('reg'); 64 | if (Input::post('password', $password, 'trim')) 65 | { 66 | $password = md5($password); 67 | } 68 | else 69 | { 70 | /*未设置密码*/ 71 | $password = $regInfo['password']; 72 | } 73 | 74 | $regInfo['password'] = Encrypt::encryptPwd($password, $regInfo['number']); 75 | if ($id = UserModel::insert($regInfo)) 76 | { 77 | /*注册成功*/ 78 | $regInfo['id'] = $id; 79 | $token = Auth::token($regInfo); 80 | Cookie::set('token', [$id => $token]); 81 | unset($regInfo['password']); 82 | Session::set('user', $regInfo); 83 | $this->_response->setHeader('HTTP/1.1 303 See Other', ''); 84 | $this->redirect('/'); 85 | } 86 | else 87 | { 88 | $this->jump('/', '注册失败'); 89 | } 90 | } 91 | 92 | } 93 | 94 | /** 95 | * 注销 96 | * @method logout 97 | * @return 重定向或者json字符 98 | */ 99 | public function logoutAction() 100 | { 101 | Input::I('url', $url, FILTER_VALIDATE_URL, '/'); 102 | Cookie::flush(); 103 | Session::flush(); 104 | $this->redirect($url); 105 | } 106 | 107 | /** 108 | * 验证码 109 | * @method codeAction 110 | * @param integer $sch_id [学校id] 111 | * @return [image] [description] 112 | * @author NewFuture 113 | */ 114 | public function codeAction($sch_id = 0) 115 | { 116 | $code = School::code($sch_id); 117 | $this->_response->setHeader('Content-type', 'image/jpeg'); 118 | echo $code; 119 | } 120 | 121 | /** 122 | * 邮箱验证 123 | * @method emailAction 124 | * @param $code 125 | * @author NewFuture 126 | */ 127 | public function emailAction($code = '') 128 | { 129 | if ($code && Validate::char_num($code)) 130 | { 131 | $Code = new Model('code'); 132 | 133 | if (!$Code->where('code', $code)->field('use_id,type,content')->find()) 134 | { 135 | $this->jump('/', '验证信息不存在', 10); 136 | } 137 | elseif (!UserModel::saveEmail($Code['content'], $Code['use_id'])) 138 | { 139 | $this->jump('/', '邮箱设置失败', 10); 140 | } 141 | else 142 | { 143 | $Code->delete(); 144 | $this->jump('/', '邮箱绑定成功', 3); 145 | } 146 | } 147 | else 148 | { 149 | $this->jump('/', '验证码信息有误', 10); 150 | } 151 | } 152 | 153 | /** 154 | * 页面跳转 155 | * @method jump 156 | * @param string $url [url] 157 | * @param string $msg [消息] 158 | * @param integer $time [跳转时间] 159 | * @author NewFuture 160 | */ 161 | protected function jump($url, $msg = null, $time = 1) 162 | { 163 | Yaf_Dispatcher::getInstance()->autoRender(false); 164 | if ($msg) 165 | { 166 | $this->_view->assign('time', $time)->assign('url', $url)->assign('msg', $msg)->display('jump.phtml'); 167 | } 168 | else 169 | { 170 | $this->_response->setHeader('HTTP/1.1 303 See Other', ''); 171 | $this->redirect($url); 172 | } 173 | } 174 | } 175 | ?> -------------------------------------------------------------------------------- /app/controllers/Books.php: -------------------------------------------------------------------------------- 1 | page($page); 17 | if (Input::get('key', $key, 'tag')) //关键字 18 | { 19 | $key = '%' . strtr($key, ' ', '%') . '%'; 20 | $Book->where('name', 'LIKE', $key)->orWhere('detail', 'LIKE', $key); 21 | } 22 | 23 | $books = $Book->select('id,name,detail,pri_id'); 24 | $this->response(1, $books); 25 | } 26 | 27 | /** 28 | * 获取书籍详情 29 | * @method GET_infoAction 30 | * @param integer $id [description] 31 | * @author NewFuture 32 | */ 33 | public function GET_infoAction($id = 0) 34 | { 35 | // $uid = $this->auth(); 36 | if ($book = BookModel::belongs('printer')->find($id)) 37 | { 38 | $this->response(1, $book); 39 | } 40 | else 41 | { 42 | $this->response(0, '信息已经删除'); 43 | } 44 | } 45 | 46 | /** 47 | * 打印书籍 48 | * @method POST_printAction 49 | * @todo 计价 50 | * @param integer $id [description] 51 | * @author NewFuture 52 | */ 53 | public function POST_printAction($id = 0) 54 | { 55 | $uid = $this->auth(); 56 | $response['status'] = 0; 57 | if (!$Book = BookModel::find($id)) 58 | { 59 | $response['info'] = '无效书籍'; 60 | } 61 | else 62 | { 63 | $task = ['use_id' => $uid, 'url' => 'book/' . $id]; 64 | $task['pri_id'] = $Book['pri_id']; 65 | $task['name'] = $Book['name']; 66 | if ($tid = TaskModel::insert($task)) 67 | { 68 | $Book->inc('count'); 69 | $response['info'] = ['id' => $tid, 'msg' => '保存成功']; 70 | } 71 | else 72 | { 73 | $response['info'] = '保存出错'; 74 | } 75 | } 76 | $this->response = $response; 77 | } 78 | } -------------------------------------------------------------------------------- /app/controllers/Card.php: -------------------------------------------------------------------------------- 1 | response(-3, 'API key无效'); 14 | exit(); 15 | } 16 | } 17 | 18 | /** 19 | * 校园卡信息验证接口 20 | */ 21 | public function indexAction() 22 | { 23 | if (!Input::post('name', $name, 'name')) 24 | { 25 | //姓名输入过滤 26 | $this->response(0, '姓名无效'); 27 | } 28 | elseif (!Input::post('number', $number, 'card')) 29 | { 30 | //学号输入过滤 31 | $this->response(0, '学号无效'); 32 | } 33 | else 34 | { 35 | $User = UserModel::where('number', $number)->field('id,name,sch_id,number,phone,email'); 36 | if (Input::post('school', $sch_id, 'int') && $User->where('sch_id', $sch_id)->find()) 37 | { 38 | if ($User['name'] != $name) 39 | { 40 | $this->response(parent::AUTH_BAN, '姓名不匹配'); 41 | } 42 | else 43 | { 44 | $user = UserModel::decrypt($User); 45 | $this->response(1, $user); 46 | } 47 | } 48 | elseif ($User->where('name', $name)->find()) 49 | { 50 | $user = UserModel::decrypt($User); 51 | $this->response(1, $user); 52 | } 53 | else 54 | { 55 | $this->response(0, '未找到此人信息'); 56 | } 57 | } 58 | } 59 | 60 | /** 61 | * 绑定用户手机 62 | * @method post_phoneAction 63 | * @return [type] [description] 64 | * @author NewFuture 65 | */ 66 | public function post_phoneAction() 67 | { 68 | $uid = $this->auth(); 69 | if (!Input::post('phone', $phone, 'phone')) 70 | { 71 | $this->response(0, '无效手机号'); 72 | } 73 | elseif(UserModel::where('id','=',$uid)->get('phone')) 74 | { 75 | $this->response(0, '此接口不允许修改手机号'); 76 | } 77 | elseif (UserModel::savePhone($phone)) 78 | { 79 | $this->response(1, '修改成功'); 80 | } 81 | else 82 | { 83 | $this->response(0, '修改出错'); 84 | } 85 | 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /app/controllers/Error.php: -------------------------------------------------------------------------------- 1 | disableView(); 10 | $code = $exception->getCode(); 11 | $message = $exception->getMessage(); 12 | $url = $this->_request->getRequestUri(); 13 | Log::write('[' . $code . '](' . $url . '):' . $message, 'ERROR'); 14 | $response['status'] = -10; 15 | $response['info'] = ['code' => $code, 'msg' => '请求异常!', 'uri' => $url]; 16 | header('HTTP/1.1 ' . $code); 17 | header('Content-type: application/json'); 18 | echo json_encode($response, JSON_UNESCAPED_UNICODE); //unicode不转码 19 | } 20 | } -------------------------------------------------------------------------------- /app/controllers/File.php: -------------------------------------------------------------------------------- 1 | auth(); 17 | Input::get('page', $page, 'int', 1); 18 | $File = FileModel::where('use_id', '=', $userid) 19 | ->where('status', '>', 0) 20 | ->page($page) 21 | ->field('id,name,time,status')->order('id', true); 22 | if (Input::get('key', $key, 'tag')) //关键字 23 | { 24 | $key = '%' . strtr($key, ' ', '%') . '%'; 25 | $File->where('name', 'LIKE', $key); 26 | } 27 | $files = $File->select('id,name,time'); 28 | $this->response(1, $files); 29 | } 30 | 31 | /** 32 | * 上传文件 33 | * POST /file/ 34 | * @method POST_index 35 | * @param key 获取token时返回的key 36 | */ 37 | public function POST_indexAction() 38 | { 39 | 40 | if (!Input::post('key', $key, 'filename')) 41 | { 42 | $this->response(0, '未收到数据'); 43 | return; 44 | } 45 | list(, $userid) = explode('_', $key, 3); 46 | $userid = $this->auth($userid); 47 | $response['status'] = 0; 48 | 49 | if (!$name = Cache::get($key)) 50 | { 51 | $response['info'] = '文件不存在'; 52 | } 53 | else 54 | { 55 | 56 | Cache::del($key); 57 | /*文件名由 t_xxxx,重命名为 f_xxxx*/ 58 | $bucket = Config::getSecret('qiniu', 'file'); 59 | $uri = $bucket . ':f_' . substr($key, 2); 60 | $file['name'] = $name; 61 | $file['url'] = $uri; 62 | $file['use_id'] = $userid; 63 | 64 | if (!File::set($bucket . ':' . $key, $uri)) //修改文件名 65 | { 66 | $response['info'] = '文件校验失败'; 67 | } 68 | elseif (!$fid = FileModel::add($file)) 69 | { 70 | $response['info'] = '文件保存失败'; 71 | } 72 | else 73 | { 74 | $response['status'] = 1; 75 | $response['info'] = ['msg' => '保存成功', 'id' => $fid]; 76 | } 77 | } 78 | $this->response = $response; 79 | } 80 | 81 | /** 82 | * 获取上传token 83 | * POST /file/token 84 | * @method POST_token 85 | * @param name 文件名 86 | */ 87 | public function POST_tokenAction() 88 | { 89 | $userid = $this->auth(); 90 | if (Input::post('name', $name, 'title') && $name = File::filterName($name)) 91 | { 92 | $key = uniqid('t_' . $userid . '_') . strrchr($name, '.'); 93 | $bucket = Config::getSecret('qiniu', 'file'); 94 | $token = File::token($bucket, $key); 95 | if ($token) 96 | { 97 | // header('Access-Control-Allow-Origin:http://upload.qiniu.com'); 98 | Cache::set($key, $name, 1200); 99 | $response['token'] = $token; 100 | // $response['key'] = $key; 101 | $response['name'] = $name; 102 | $this->response(1, $response); 103 | } 104 | else 105 | { 106 | $this->response(0, 'token获取失败'); 107 | } 108 | } 109 | else 110 | { 111 | $this->response(0, '文件名无效'); 112 | } 113 | } 114 | 115 | /** 116 | * 删除上传token,放弃上传 117 | * DELETE /file/token/tmp_ae1233 118 | * @method POST_token 119 | * @param name 文件名 120 | */ 121 | public function DELETE_tokenAction($key = null) 122 | { 123 | if ($key && $name = Cache::get($key)) 124 | { 125 | list(, $userid) = explode('_', $key, 3); 126 | 127 | $userid = $this->auth($userid); 128 | Cache::del($key); 129 | $bucket = Config::getSecret('qiniu', 'file'); 130 | File::del($bucket . ':' . $key); 131 | $this->response(1, '已经成功删除' . $name); 132 | } 133 | else 134 | { 135 | $this->response(0, '此上传信息不存在'); 136 | } 137 | } 138 | 139 | /** 140 | * 文件详细信息 141 | * GET /file/1 142 | * @method GET_info 143 | * @author NewFuture 144 | */ 145 | public function GET_infoAction($id) 146 | { 147 | $userid = $this->auth(); 148 | if ($file = FileModel::where('use_id', '=', $userid)->find($id)) 149 | { 150 | $file->url = File::get($file->url, $file->name); 151 | $this->response(1, $file); 152 | } 153 | else 154 | { 155 | $this->response(0, '你没有该文件'); 156 | } 157 | } 158 | 159 | /** 160 | * 文件信息修改 161 | * PUT /file/1 162 | * @method PUT_info 163 | * @author NewFuture 164 | * @param name 文件名 165 | */ 166 | public function PUT_infoAction($id = 0) 167 | { 168 | $userid = $this->auth(); 169 | if (Input::put('name', $name, 'title')) 170 | { 171 | if (FileModel::saveName($id, $name)) 172 | { 173 | $this->response(1, '成功修改为:' . $name); 174 | } 175 | else 176 | { 177 | $this->response(0, '修改失败'); 178 | } 179 | } 180 | else 181 | { 182 | $this->response(0, '文件名无效'); 183 | } 184 | } 185 | 186 | /** 187 | * 文件删除 188 | * DELETE /file/1 189 | * @method DELETE_info 190 | * @author NewFuture 191 | */ 192 | public function DELETE_infoAction($id = 0) 193 | { 194 | $userid = $this->auth(); 195 | $File = FileModel::where('use_id', '=', $userid)->field('url')->find($id); 196 | $response['status'] = 0; 197 | if (!$uri = $File['url']) 198 | { 199 | $response['info'] = '没有找这个文件'; 200 | } 201 | elseif (!File::del($uri)) 202 | { 203 | $response['info'] = '删除出错'; 204 | } 205 | if ($File->update(['url' => '', 'status' => 0])) 206 | { 207 | $response['status'] = 1; 208 | $response['info'] = '已经删除'; 209 | } 210 | else 211 | { 212 | $response['info'] = '文件状态更新失败'; 213 | } 214 | $this->response = $response; 215 | } 216 | 217 | /** 218 | * 打印文件 219 | * POST /file/:id/print 220 | * @method 221 | */ 222 | public function POST_printAction($id) 223 | { 224 | $userid = $this->auth(); 225 | $response['status'] = 0; 226 | 227 | if (!$id = intval($id)) 228 | { 229 | $response['info'] = '未选择文件'; 230 | } 231 | elseif (!Input::post('pid', $pid, 'int')) 232 | { 233 | $response['info'] = '未选择打印店'; 234 | } 235 | elseif (!$file = FileModel::where('use_id', $userid)->where('status', '>', 0)->field('url,name,status')->find($id)) 236 | { 237 | $response['info'] = '没有该文件或者此文件已经删除'; 238 | } 239 | else 240 | { 241 | $task = TaskModel::create('post'); 242 | $task['name'] = $file['name']; 243 | $task['use_id'] = $userid; 244 | $task['pri_id'] = $pid; 245 | 246 | if (!$task['url'] = File::addTask($file['url'])) 247 | { 248 | $response['info'] = '文件转换出错'; 249 | } 250 | elseif (!$tid = TaskModel::insert($task)) 251 | { 252 | $response['info'] = '任务添加失败'; 253 | } 254 | else 255 | { 256 | 257 | $response['status'] = 1; 258 | $response['info'] = [ 259 | 'msg' => '打印任务添加成功', 260 | 'id' => $tid, 261 | 'name' => $file['name'], 262 | ]; 263 | } 264 | } 265 | $this->response = $response; 266 | } 267 | } -------------------------------------------------------------------------------- /app/controllers/Printers.php: -------------------------------------------------------------------------------- 1 | where('status', '>', 0)->order('rank', 'DESC')->page($page); 15 | if (Input::get('sch_id', $sch_id, 'is_numeric')) 16 | { 17 | $Printer->where('sch_id', $sch_id); 18 | } 19 | Input::get('page', $page, 'int', 1); 20 | $printers = $Printer->select('id,name,sch_id,address'); 21 | $this->response(1, $printers); 22 | } 23 | 24 | /** 25 | * 获取打印店详情 26 | * @method GET_infoAction 27 | * @param integer $id [description] 28 | * @author NewFuture 29 | */ 30 | public function GET_infoAction($id = 0) 31 | { 32 | $this->auth(); 33 | if ($printer = PrinterModel::field('name,sch_id,address,phone,email,qq,profile,image,open,price,other')->find($id)) 34 | { 35 | if (isset($printer['price'])) 36 | { 37 | $printer['price'] = json_decode($printer['price']); 38 | } 39 | $this->response(1, $printer); 40 | } 41 | else 42 | { 43 | $this->response(0, '不存在'); 44 | } 45 | } 46 | 47 | /** 48 | * 获取价格 49 | * GET /printers/123/price 50 | * @method GET_priceAction 51 | * @param integer $id [description] 52 | * @author NewFuture 53 | */ 54 | public function GET_priceAction($id = 0) 55 | { 56 | $this->auth(); 57 | if ($printer = PrinterModel::field('price,other')->find($id)) 58 | { 59 | $price = json_decode($printer['price']); 60 | $price->other = $printer['other']; 61 | $this->response(1, $price); 62 | } 63 | else 64 | { 65 | $this->response(0, '不存在此店'); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /app/controllers/School.php: -------------------------------------------------------------------------------- 1 | select($fileds); 18 | $this->response(1, $schools); 19 | } 20 | elseif ($schools = SchoolModel::all($fileds)) 21 | { 22 | $this->response(1, $schools); 23 | } 24 | else 25 | { 26 | $this->response(0, '无法查看学校信息'); 27 | } 28 | 29 | } 30 | 31 | /** 32 | * 学校信息 33 | * @method GET_infoAction 34 | * @param integer $id [description] 35 | * @author NewFuture 36 | */ 37 | public function GET_infoAction($id = 0) 38 | { 39 | if ($school = SchoolModel::find($id)) 40 | { 41 | $school['number'] = Config::get('regex.number.' . strtolower($school['abbr'])); 42 | $this->response(1, $school); 43 | } 44 | else 45 | { 46 | $this->response(0, $id); 47 | } 48 | } 49 | 50 | /** 51 | * 获取学校验证码 52 | * @method GET_codeAction 53 | * @param integer $id [description] 54 | * @author NewFuture 55 | */ 56 | public function GET_codeAction($id = 0) 57 | { 58 | if ($code = School::code($id)) 59 | { 60 | $code['img'] = 'data:image/png;base64,' . base64_encode($code['img']); 61 | $this->response(1, $code); 62 | } 63 | elseif ($code === false) 64 | { 65 | $this->response(0, '无需验证码'); 66 | } 67 | else 68 | { 69 | Log::write('验证码获取失败' . $id, 'ERROR'); 70 | $this->response(-3, $id.'验证码获取失败'); 71 | } 72 | } 73 | 74 | /** 75 | * 分析学号所在学校 76 | * @method POST_numberAction 77 | * @author NewFuture 78 | */ 79 | public function POST_numberAction() 80 | { 81 | if (Input::post('number', $number, 'card')) 82 | { 83 | /*排除学校*/ 84 | if (Input::post('black', $black)) 85 | { 86 | $this->parse($black); 87 | } 88 | /*限定学校*/ 89 | if (Input::post('white', $white)) 90 | { 91 | $this->parse($white); 92 | } 93 | 94 | if ($schools = School::guess($number, $black, $white)) 95 | { 96 | if ($reg = UserModel::where('number', $number)->select('sch_id')) 97 | { 98 | foreach ($reg as $user) 99 | { 100 | $schools[$user['sch_id']] = 0; 101 | } 102 | } 103 | $this->response(1, $schools); 104 | } 105 | else 106 | { 107 | $this->response(0, '无相关学校,请检查学号是否正确'); 108 | } 109 | } 110 | else 111 | { 112 | $this->response(0, '学号格式有误'); 113 | } 114 | } 115 | 116 | private function parse(&$s) 117 | { 118 | /*如果是字符切成数组*/ 119 | if (is_string($s)) 120 | { 121 | $s = explode(',', $s); 122 | } 123 | /*id转成缩写*/ 124 | if (is_numeric(end($s))) 125 | { 126 | array_walk($s, function (&$v) 127 | { 128 | $v = School::getAbbr($v); 129 | }); 130 | } 131 | return $s; 132 | } 133 | } -------------------------------------------------------------------------------- /app/controllers/Share.php: -------------------------------------------------------------------------------- 1 | auth(); 20 | Input::get('page', $page, 'int', 1); 21 | $shares = ShareModel::where('use_id', '=', $userid)->page($page)->select('id,name,time'); 22 | $this->response(1, $shares); 23 | } 24 | 25 | /** 26 | * 分享文件 27 | * POST /share/ 28 | * @method POST_index 29 | * @param key 获取token时返回的key 30 | */ 31 | public function POST_indexAction() 32 | { 33 | $userid = $this->auth(); 34 | $response['status'] = 0; 35 | if (!Input::post('fid', $fid, 'int')) 36 | { 37 | $response['info'] = '未选择文件'; 38 | } 39 | elseif (!$File = FileModel::field('name,url,status') 40 | ->where('use_id', '=', $userid) 41 | ->where('status', '>', 0) 42 | ->find($fid)) 43 | { 44 | /*数据库中查询的文件*/ 45 | $response['info'] = '文件无效'; 46 | } 47 | elseif ($File['status']&self::SHARED_FLAG)//位标记 48 | { 49 | /*是否已经共享*/ 50 | $response['info'] = '文件已分享'; 51 | } 52 | elseif(!$share['url'] = File::share($File->url)) 53 | { 54 | /*发布到共享空间*/ 55 | $response['info'] = '文件转移出错'; 56 | }else 57 | { 58 | /*验证完成,开始插入*/ 59 | $share['fil_id'] = $fid; 60 | $share['use_id'] = $userid; 61 | $share['name'] = Input::post('name', $name, 'title') ? $name : $File->name; 62 | 63 | if (Input::post('detail', $detail, 'text')) 64 | { 65 | $share['detail'] = $detail; 66 | } 67 | if (Input::post('anonymous', $anonymous)) 68 | { 69 | $share['anonymous'] = boolval($anonymous); 70 | } 71 | 72 | if ($sid = ShareModel::Insert($share)) 73 | { 74 | //插入成功 75 | //文件状态,更新为已分享 76 | $File->save(['status' => $File['status']|self::SHARED_FLAG]); 77 | //TODO 78 | //分享文件预处理 79 | $response['status'] = 1; 80 | $response['info'] = ['msg' => '分享成功', 'id' => $sid]; 81 | } 82 | else 83 | { 84 | $response['info'] = '分享失败'; 85 | } 86 | } 87 | $this->response = $response; 88 | } 89 | 90 | /** 91 | * 分享文件详细信息 92 | * GET /share/1 93 | * @method GET_info 94 | * @author NewFuture 95 | * @todo 预览等,权限 96 | */ 97 | public function GET_infoAction($id = 0) 98 | { 99 | $uid = $this->auth(); 100 | if ($share = ShareModel::find($id)) 101 | { 102 | $share['user'] = $share['anonymous'] ? '不愿透露姓名的同学' : UserModel::where('id', $share['use_id'])->get('name'); 103 | if ($uid != $share['use_id']) 104 | { 105 | unset($share['use_id']); 106 | unset($share['fil_id']); 107 | } 108 | $this->response(1, $share); 109 | } 110 | else 111 | { 112 | $this->response(0, '该分享不存在'); 113 | } 114 | } 115 | 116 | /** 117 | * 信息修改 118 | * PUT /share/1 119 | * @method PUT_info 120 | * @author NewFuture 121 | * @param name 文件名 122 | */ 123 | public function PUT_infoAction($id = 0) 124 | { 125 | $userid = $this->auth(); 126 | /*检查输入*/ 127 | if (Input::put('name', $name, 'title')) 128 | { 129 | $share['name'] = $name; 130 | } 131 | if (Input::put('anonymous', $anonymous)) 132 | { 133 | $share['anonymous'] = boolval($anonymous); 134 | } 135 | if (Input::put('detail', $detail, 'text')) 136 | { 137 | $share['detail'] = $detail; 138 | } 139 | /*保存*/ 140 | if (empty($share)) 141 | { 142 | $this->response(0, '没有任何有效的修改内容'); 143 | } 144 | elseif (ShareModel::where('id', $id)->where('use_id', $use_id)->update($share)) 145 | { 146 | $this->response(1, $share); 147 | } 148 | else 149 | { 150 | $this->response(0, '保存失败'); 151 | } 152 | } 153 | 154 | /** 155 | * 删除 156 | * DELETE /share/1 157 | * @method DELETE_info 158 | * @author NewFuture 159 | */ 160 | public function DELETE_infoAction($id = 0) 161 | { 162 | $userid = $this->auth(); 163 | if (!$share = ShareModel::where('use_id', $userid)->field('url')->find(intval($id))) 164 | { 165 | $this->response(0, '您无此分享文件'); 166 | } 167 | elseif (!$url = ($share['url'])) 168 | { 169 | $this->response(0, '此共享已经删除'); 170 | } 171 | elseif ($share->set('url', '')->save()) 172 | { 173 | File::del($url); 174 | $this->response(1, '删除成功'); 175 | } 176 | else 177 | { 178 | $this->response(0, '删除失败'); 179 | } 180 | } 181 | 182 | /** 183 | * 删除 184 | * POST /share/123/print 185 | * @method 添加打印任务 186 | * @author NewFuture 187 | */ 188 | public function POST_printAction($id = 0) 189 | { 190 | $userid = $this->auth(); 191 | $response['status'] = 0; 192 | if (!$share = ShareModel::where('status', '>', 0)->field('name,url')->find()) 193 | { 194 | $response['info'] = '此分享已经删除!'; 195 | } 196 | elseif (!Input::post('pid', $pid, 'int')) 197 | { 198 | $response['info'] = '请选择打印店!'; 199 | } 200 | else 201 | { 202 | $task = TaskModel::create('post'); 203 | $task['use_id'] = $userid; 204 | $task['pid'] = $pid; 205 | $task['url'] = File::addTask($share['url']); 206 | $task['name'] = $share['name']; 207 | 208 | if (!$tid = TaskModel::insert($task)) 209 | { 210 | $response['info'] = '任务添加失败'; 211 | } 212 | else 213 | { 214 | $response['status'] = 1; 215 | $response['info'] = ['msg' => '任务添加成功', 'id' => $tid]; 216 | } 217 | } 218 | $this->response = $response; 219 | } 220 | 221 | /** 222 | * 搜索 223 | * @method GET_searchAction 224 | * @todo 标签 225 | * @author NewFuture 226 | */ 227 | public function GET_searchAction() 228 | { 229 | Input::get('page', $page, 'int', 1); 230 | $Share = ShareModel::page($page)->field('id,name,time'); 231 | if (Input::get('key', $key)) 232 | { 233 | $key = '%' . strtr($key, ' ', '%') . '%'; 234 | $Share -> where('name', 'LIKE', $key)->orWhere('detail', 'LIKE', $key); 235 | } 236 | 237 | if (Input::get('key', $tag, 'int')) 238 | { 239 | //标签筛选 240 | } 241 | $shares = $Share->select(); 242 | $this->response(1, $shares); 243 | } 244 | 245 | // /** 246 | // * 赞 247 | // * POST /share/123/up 248 | // */ 249 | // public function POST_upAction($id) 250 | // { 251 | // } 252 | } 253 | -------------------------------------------------------------------------------- /app/controllers/Tags.php: -------------------------------------------------------------------------------- 1 | order('count', 'DESC')->page($page)->select('id,name'); 20 | } 21 | else 22 | { 23 | $tags = TagModel::order('count', 'DESC')->page($page)->select('id,name'); 24 | } 25 | $this->response(1, $tags); 26 | } 27 | 28 | /** 29 | * 添加标签 30 | * @method POST_indexAction 31 | * @param integer $id [description] 32 | * @author NewFuture 33 | */ 34 | public function POST_indexAction() 35 | { 36 | $uid = $this->auth(); 37 | if (Input::post('name', $name, 'tag')) 38 | { 39 | $tag = ['name' => $name, 'use_id' => $uid]; 40 | if ($tid = TagModel::insert($tag)) 41 | { 42 | $result = ['msg' => '添加成功', 'id' => $tid]; 43 | $this->response(1, $result); 44 | } 45 | else 46 | { 47 | $this->response(0, '添加失败'); 48 | } 49 | } 50 | else 51 | { 52 | $this->response(0, '标签名不合法'); 53 | } 54 | } 55 | 56 | /** 57 | * 获取标签详情 58 | * @method GET_infoAction 59 | * @param integer $id [description] 60 | * @author NewFuture 61 | * @todo 标签引用的书籍 62 | */ 63 | public function GET_infoAction($id = 0) 64 | { 65 | $uid = $this->auth(); 66 | if ($tag = TagModel::belongs('user')->find($id)) 67 | { 68 | $this->response(1, $tag); 69 | } 70 | else 71 | { 72 | $this->response(0, '信息已经删除'); 73 | } 74 | } 75 | 76 | /** 77 | * 添加标签 78 | * 开放权限 79 | * @method POST_infoAction 80 | * @param integer $id [description] 81 | * @author NewFuture 82 | */ 83 | public function POST_infoAction($id = 0) 84 | { 85 | $uid = $this->auth(); 86 | if (Input::post('sid', $sid, 'int') && TagModel::where('id', $id)->inc('count')) 87 | { 88 | $Hastag = new Model('hastag'); 89 | $hastag = ['tag_id' => $id, 'sha_id' => $sid]; 90 | try{ 91 | 92 | $Hastag->insert($hastag); 93 | $this->response(1, '添加成功'); 94 | } 95 | catch (Exception $e) 96 | { 97 | TagModel::where('id', $id)->inc('count', '-1'); 98 | $this->response(0, '添加出错'); 99 | } 100 | } 101 | else 102 | { 103 | $this->response(0, '分享或者标签有误'); 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /app/controllers/Task.php: -------------------------------------------------------------------------------- 1 | auth(); 17 | Input::get('page', $page, 'int', 1); 18 | $tasks = TaskModel::where('use_id', '=', $userid) 19 | ->where('status', '>', 0) 20 | ->belongs('printer') 21 | ->page($page) 22 | ->order('id', 'DESC') 23 | ->select('id,color,copies,double,format,name,payed,pri_id,status,time'); 24 | $this->response(1, $tasks); 25 | } 26 | 27 | /** 28 | * 打印任务 29 | * POST /task/ 30 | * @method POST_index 31 | * @param fid 文件id 32 | * @param pid 打印店id 33 | * @param 34 | */ 35 | public function POST_indexAction() 36 | { 37 | $userid = $this->auth(); 38 | $response['status'] = 0; 39 | 40 | if (!Input::post('fid', $fid, 'int')) 41 | { 42 | $response['info'] = '未选择文件'; 43 | } 44 | elseif (!Input::post('pid', $pid, 'int')) 45 | { 46 | $response['info'] = '未选择打印店'; 47 | } 48 | elseif (!$file = FileModel::where('use_id', $userid)->where('status', '>', 0)->field('url,name,status')->find($fid)) 49 | { 50 | $response['info'] = '没有该文件或者此文件已经删除'; 51 | } 52 | else 53 | { 54 | $task = TaskModel::create('post'); 55 | $task['name'] = $file['name']; 56 | $task['use_id'] = $userid; 57 | $task['pri_id'] = $pid; 58 | 59 | if (!$task['url'] = File::addTask($file['url'])) 60 | { 61 | $response['info'] = '文件转换出错'; 62 | } 63 | elseif (!$tid = TaskModel::insert($task)) 64 | { 65 | $response['info'] = '任务添加失败'; 66 | } 67 | else 68 | { 69 | $response['status'] = 1; 70 | $response['info'] = ['msg' => '打印任务添加成功', 'id' => $tid]; 71 | } 72 | } 73 | $this->response = $response; 74 | } 75 | 76 | /** 77 | * 任务详情 78 | * GET /task/1 79 | * @method GET_info 80 | * @author NewFuture 81 | * @todo 更详细的信息 82 | */ 83 | public function GET_infoAction($id) 84 | { 85 | $userid = $this->auth(); 86 | if ($task = TaskModel::where('use_id', '=', $userid)->belongs('printer')->find(intval($id))) 87 | { 88 | $task['url'] = File::get($task['url']); 89 | $this->response(1, $task); 90 | } 91 | else 92 | { 93 | $this->response(0, '你没有设定此任务'); 94 | } 95 | } 96 | 97 | /** 98 | * 任务状态修改 99 | * PUT /task/1 100 | * @method PUT_info 101 | * @author NewFuture 102 | */ 103 | public function PUT_infoAction($id = 0) 104 | { 105 | $userid = $this->auth(); 106 | if ($Task = TaskModel::where('use_id', $userid)->where('status', 1)->find(intval($id))) 107 | { 108 | $task = TaskModel::create('put'); 109 | if ($Task->update($task)) 110 | { 111 | $this->response(1, '成功修改'); 112 | } 113 | else 114 | { 115 | $this->response(0, '修改失败'); 116 | } 117 | } 118 | else 119 | { 120 | $this->response(0, '该任务不存在'); 121 | } 122 | } 123 | 124 | /** 125 | * 删除 126 | * @method DELETE_indexAction 127 | * @param [type] $id [description] 128 | * @author NewFuture 129 | */ 130 | public function DELETE_infoAction($id = 0) 131 | { 132 | $userid = $this->auth(); 133 | $response['status'] = 0; 134 | $Task = TaskModel::where('use_id', $userid)->where('status', '>', 0)->field('status,payed,url')->find(intval($id)); 135 | if (!$Task) 136 | { 137 | $response['info'] = '该任务不存在'; 138 | } 139 | elseif ($Task['status'] > 1 && $Task['status'] < 3) 140 | { 141 | $response['info'] = '打印店已经在处理,不可删除,请联系打印店取消订单任务'; 142 | } 143 | elseif ($Task['status'] == 4 && !$Task['payed']) 144 | { 145 | $response['info'] = '打印店尚未确认付款'; 146 | } 147 | elseif ($Task->set('status', 0)->save($id)) 148 | { 149 | $response['status'] = 1; 150 | $response['info'] = '删除成功'; 151 | } 152 | else 153 | { 154 | $response['info'] = '删除失败'; 155 | } 156 | $this->response = $response; 157 | } 158 | 159 | /** 160 | * 获取下载url 161 | * @method GET_urlAction 162 | * @param $id [description] 163 | * @author NewFuture 164 | */ 165 | public function GET_urlAction($id = 0) 166 | { 167 | $userid = $this->auth(); 168 | $url = TaskModel::where('id', '=', $id)->where('use_id', '=', $userid)->get($url); 169 | Input::get('alias', $alias, 'title'); 170 | if ($url && $url = File::get($url, $alias)) 171 | { 172 | $this->response(1, $url); 173 | } 174 | else 175 | { 176 | $this->response(0, '你没有设定此任务'); 177 | } 178 | } 179 | } -------------------------------------------------------------------------------- /app/controllers/Test.php: -------------------------------------------------------------------------------- 1 | $method, 23 | 'agent' => $agent, 24 | 'token'=> $token, 25 | 'data' => $_REQUEST, 26 | 'param' => $GLOBALS['_' . $method], 27 | ]; 28 | $this->response = $reponse; 29 | } 30 | 31 | public function GET_requestAction() 32 | { 33 | $reponse = [ 34 | 'method' => $_SERVER['REQUEST_METHOD'], 35 | 'uri' => $_SERVER['REQUEST_URI'], 36 | 'param' => $_GET, 37 | ]; 38 | $this->response = $reponse; 39 | } 40 | 41 | public function POST_requestAction() 42 | { 43 | $reponse = [ 44 | 'method' => $_SERVER['REQUEST_METHOD'], 45 | 'uri' => $_SERVER['REQUEST_URI'], 46 | 'param' => $_POST, 47 | ]; 48 | $this->response = $reponse; 49 | } 50 | 51 | public function PUT_requestAction() 52 | { 53 | $reponse = [ 54 | 'method' => $_SERVER['REQUEST_METHOD'], 55 | 'uri' => $_SERVER['REQUEST_URI'], 56 | 'param' => $GLOBALS['_PUT'], 57 | ]; 58 | $this->response = $reponse; 59 | } 60 | 61 | public function DELETE_requestAction() 62 | { 63 | $reponse = [ 64 | 'method' => $_SERVER['REQUEST_METHOD'], 65 | 'uri' => $_SERVER['REQUEST_URI'], 66 | ]; 67 | $this->response = $reponse; 68 | } 69 | } 70 | ?> -------------------------------------------------------------------------------- /app/email/pwd.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 云印服务密码找回邮件 7 | 8 | 9 | 10 | 11 | 12 | 13 | 37 | 38 | 39 |
14 |
15 | 16 | 17 | 33 | 34 |
18 |

亲爱的

19 |

这是来自云印南天yunyin.org密码找回邮件

20 |

请确定这是您的个人操作

21 |

输入以下验证码完成验证然后重置密码

22 | 23 | 24 | 27 | 28 |
25 |

26 |
29 |
30 |

关注新浪微博@云印南天

31 |

关注项目最新进度Github

32 |
35 |
36 |
40 | 41 | 42 | 43 | 44 | 55 | 56 | 57 |
45 |
46 | 47 | 48 | 51 | 52 |
49 |

Copyright©2014-2015云印南天

50 |
53 |
54 |
58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/email/verify.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 云印服务验证邮件 7 | 8 | 9 | 10 | 11 | 12 | 13 | 38 | 39 | 40 |
14 |
15 | 16 | 17 | 34 | 35 |
18 |

亲爱的

19 |

这是来自云印南天yunyin.org绑定邮箱的验证邮件

20 |

请确定这是您的个人操作,将绑定您的邮箱

21 |

输入验证码或者点击一下链接完成验证

22 | 23 | 24 | 27 | 28 |
25 |

点击以验证邮箱

26 |
29 |

如果无法正常打开请复制到浏览器

30 |
31 |

关注新浪微博@云印南天

32 |

关注项目最新进度Github

33 |
36 |
37 |
41 | 42 | 43 | 44 | 45 | 56 | 57 | 58 |
46 |
47 | 48 | 49 | 52 | 53 |
50 |

Copyright©2014-2015云印南天

51 |
54 |
55 |
59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /app/models/Book.php: -------------------------------------------------------------------------------- 1 | insert($array)) 9 | { 10 | return $id; 11 | } 12 | else 13 | { 14 | return false; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /app/models/Cardlog.php: -------------------------------------------------------------------------------- 1 | 1]);//查找所有school值为1的用户 9 | * 10 | * UserModel::set('pwd','1234')->save(1);//将id为1的用户密码设置为1234 11 | * UserModel::where('id','=','1')->update(['pwd'=>'1234']);//同上,也可以使用save 12 | * 13 | * UserModel::set(['pwd'=>'mypwd','name'=>'test'])->add();//添加新用户 14 | * UserModel::add(['pwd'=>'mypwd','name'=>'test']);//同上,也可以使用insert() 15 | * 16 | * UserModel::where('id','>','10')->where('id','<','100')->select();//查找所有id在10到100之间的用户 17 | * UserModel::where('id','=','1')->get('name');//获取id为一的用户的name 18 | * UserModel::where('id','>','1')->limit(10)->select('id,name');//查询id>1的10个用户的id和name 19 | * UserModel::where('id','>','1')->field('id','uid')->field('name','uname')->select();//查询id>1的用户的uid和uname(表示id和name) 20 | * UserModel::where('name','LIKE','%future%')->count();//统计name中包含future的字数 21 | * 22 | * 也可以实例化操作 $user=new UserModel; 23 | * $user->find(1);// 24 | */ 25 | abstract class FacadeModel 26 | { 27 | protected $table = null; //数据库表 28 | protected $pk = 'id'; //主键 29 | protected $error = ''; //错误信息 30 | protected $_model = null; //底层model实体 31 | protected static $_instance = null; //接口实体 32 | 33 | /** 34 | * 构造函数 35 | * @method __construct 36 | * @param array $data [description] 37 | * @access private 38 | * @author NewFuture 39 | */ 40 | public function __construct($data = array()) 41 | { 42 | if (null === $this->table) 43 | { 44 | $this->table = strtolower(strstr(get_called_class(), 'Model', true)); 45 | } 46 | $this->_model = new Model($this->table, $this->pk); 47 | if (!empty($data)) 48 | { 49 | $this->_model->set($data); 50 | } 51 | } 52 | 53 | /*获取错误信息33*/ 54 | public function getError() 55 | { 56 | return $this->error; 57 | } 58 | 59 | /** 60 | * 获取模型实例 61 | * @method getModel 62 | * @return [type] [description] 63 | * @author NewFuture 64 | */ 65 | protected function getModel() 66 | { 67 | if (null === $this->_model) 68 | { 69 | $this->_model = new Model($this->table, $this->pk); 70 | } 71 | return $this->_model; 72 | } 73 | 74 | /** 75 | * 获取实现的实体 76 | * @method getInstance 77 | * @return [type] [description] 78 | * @author NewFuture 79 | */ 80 | public static function getInstance() 81 | { 82 | if (null === static::$_instance) 83 | { 84 | static::$_instance = new static; 85 | } 86 | return static::$_instance; 87 | } 88 | 89 | /** 90 | * 直接修改字段 91 | * @method __set 92 | * @param [type] $name [description] 93 | * @param [type] $value [description] 94 | * @access public 95 | * @author NewFuture 96 | */ 97 | public function __set($name, $value) 98 | { 99 | return $this->_model->set($name, $value); 100 | } 101 | 102 | /** 103 | * 直接读取字段 104 | * @method __get 105 | * @return [type] [description] 106 | * @access public 107 | * @author NewFuture 108 | */ 109 | public function __get($name) 110 | { 111 | return $this->_model->get($name, false); 112 | } 113 | 114 | /** 115 | * 直接调用model的操作 116 | * @author NewFuture 117 | */ 118 | public function __call($method, $params) 119 | { 120 | return call_user_func_array(array($this->getModel(), $method), $params); 121 | } 122 | 123 | /** 124 | * 静态调用model的操作 125 | * @author NewFuture 126 | */ 127 | public static function __callStatic($method, $params) 128 | { 129 | $instance = new static; //::getInstance(); 130 | return call_user_func_array(array($instance->getModel(), $method), $params); 131 | } 132 | } -------------------------------------------------------------------------------- /app/models/File.php: -------------------------------------------------------------------------------- 1 | set('name', $name)->save($fid); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /app/models/Printer.php: -------------------------------------------------------------------------------- 1 | select($field)) 41 | { 42 | $school_array = []; 43 | foreach ($schools as $school) 44 | { 45 | $id = $school['id']; 46 | if ($id > 0) 47 | { 48 | $school_array[$id] = $school; 49 | } 50 | } 51 | Cache::set('sch_all'.$t, $school_array, 259200); 52 | return $school_array; 53 | } 54 | else 55 | { 56 | //TO DO exception 57 | return null; 58 | } 59 | } 60 | } 61 | 62 | /** 63 | * 查找学校 64 | * @method find 65 | * @param [type] $id [description] 66 | * @return [type] [description] 67 | * @author NewFuture 68 | */ 69 | public static function find($id) 70 | { 71 | $id = intval($id); 72 | if ((($schools = self::all()) && isset($schools[$id])) 73 | || (($schools = self::all(false)) && isset($schools[$id]))) 74 | { 75 | return $schools[$id]; 76 | } 77 | else 78 | { 79 | return false; 80 | } 81 | } 82 | 83 | /** 84 | * 静态调用model的操作 85 | * @author NewFuture 86 | */ 87 | public static function __callStatic($method, $params) 88 | { 89 | return call_user_func_array(array(new Model('school'), $method), $params); 90 | } 91 | } -------------------------------------------------------------------------------- /app/models/Share.php: -------------------------------------------------------------------------------- 1 | error = '姓名有误!'; 22 | return false; 23 | } 24 | else 25 | { 26 | $userInfo['name'] = $data['name']; 27 | } 28 | /*学号*/ 29 | if (!(isset($data['number']) && is_numeric($data['number']))) 30 | { 31 | $this->error = '学号必须'; 32 | return false; 33 | } 34 | else 35 | { 36 | $userInfo['number'] = $data['number']; 37 | } 38 | /*密码*/ 39 | if (!isset($data['password'])) 40 | { 41 | $this->error = '密码必须'; 42 | return false; 43 | } 44 | else 45 | { 46 | $userInfo['password'] = Encrypt::encryptPwd($data['password'], $data['number']); 47 | } 48 | /*学校*/ 49 | if (isset($data['sch_id'])) 50 | { 51 | $userInfo['sch_id'] = intval($data['sch_id']); 52 | } 53 | 54 | /*存入数据库*/ 55 | if ($uid = parent::getModel()->insert($userInfo)) 56 | { 57 | return $uid; 58 | } 59 | else 60 | { 61 | $this->error = '保存失败'; 62 | return false; 63 | } 64 | } 65 | 66 | /*关联用户学校*/ 67 | public function school() 68 | { 69 | /*用户属于一所学校*/ 70 | parent::getModel()->belongs('school'); 71 | return $this; 72 | } 73 | 74 | /** 75 | * 用户数据打码 76 | * @method mask 77 | * @param [type] &$user [description] 78 | * @return [type] [description] 79 | * @author NewFuture 80 | */ 81 | public static function mask(&$user) 82 | { 83 | if (isset($user['phone']) && $phone = $user['phone']) 84 | { 85 | $user['phone'] = substr_replace($phone, '********', -8); 86 | } 87 | if (isset($user['email']) && $email = $user['email']) 88 | { 89 | $user['email'] = $email[0] . '***' . strrchr($email, '@'); 90 | } 91 | return $user; 92 | } 93 | 94 | /** 95 | * 用户数据解码 96 | * @method mask 97 | * @param [type] &$user [description] 98 | * @return [type] [description] 99 | * @author NewFuture 100 | */ 101 | public static function decrypt(&$user) 102 | { 103 | if (isset($user['phone']) && $user['phone'] && $user['number'] && $user['id']) 104 | { 105 | $user['phone'] = Encrypt::decryptPhone($user['phone'], $user['number'], $user['id']); 106 | } 107 | 108 | if (isset($user['email']) && $email = $user['email']) 109 | { 110 | $user['email'] = Encrypt::decryptEmail($email); 111 | } 112 | return $user; 113 | } 114 | 115 | /** 116 | * 保存手机 117 | * @method savePhone 118 | * @param [type] $id [description] 119 | * @param [type] $number [description] 120 | * @param [type] $phone [description] 121 | * @return [type] [description] 122 | * @author NewFuture 123 | */ 124 | public static function savePhone($phone) 125 | { 126 | if (!$user = Auth::getUser()) 127 | { 128 | //无法获取用户 129 | return false; 130 | } 131 | elseif (self::getByPhone($phone)) 132 | { 133 | //手机绑定过 134 | return false; 135 | } 136 | else 137 | { 138 | //加密 139 | $phone = Encrypt::encryptPhone($phone, $user['number'], $user['id']); 140 | return self::set('phone', $phone)->save($user['id']); 141 | } 142 | } 143 | 144 | /** 145 | * 根据手机获取用户 146 | * @method getByPhone 147 | * @param [type] $phone [description] 148 | * @return [type] [description] 149 | * @author NewFuture 150 | */ 151 | public static function getByPhone($phone) 152 | { 153 | $tail = Encrypt::encryptPhoneTail(substr($phone, -4)); 154 | if ($users = self::where('phone', 'LIKE', '%%' . $tail)->select('id,number,phone')) 155 | { 156 | foreach ($users as $user) 157 | { 158 | if ($phone == Encrypt::decryptPhone($user['phone'], $user['number'], $user['id'])) 159 | { 160 | return $user; 161 | } 162 | } 163 | } 164 | } 165 | 166 | public static function saveEmail($email, $id) 167 | { 168 | 169 | if (!($id || $id = Auth::id())) 170 | { 171 | //无法获取用户 172 | return false; 173 | } 174 | elseif (self::getByEmail($email)) 175 | { 176 | //手机绑定过 177 | return false; 178 | } 179 | else 180 | { 181 | //加密 182 | $email = Encrypt::encryptEmail($email); 183 | return self::set('email', $email)->save($id); 184 | } 185 | } 186 | 187 | /** 188 | * 邮箱获取用户 189 | * @method getByEmail 190 | * @param [type] $email [description] 191 | * @return [type] [description] 192 | * @author NewFuture 193 | */ 194 | public static function getByEmail($email) 195 | { 196 | if (strrpos($email, '@') == 1) 197 | { 198 | /*单字母邮箱*/ 199 | return self::where('email', 'LIKE', substr_replace($email, '%', 0, 1)) 200 | ->where('length(`email`)<' . (strlen($email) + 23)) 201 | ->find(); 202 | } 203 | else 204 | { 205 | /*正常邮箱*/ 206 | $email = Encrypt::encryptEmail($email); 207 | return self::where('email', $email)->find(); 208 | } 209 | } 210 | } -------------------------------------------------------------------------------- /app/modules/Printer/controllers/Auth.php: -------------------------------------------------------------------------------- 1 | field('id,sch_id,password,status,name')->find()) 29 | { 30 | $response['info'] = '账号错误'; 31 | } 32 | elseif (Encrypt::encryptPwd($password, $account) != $Printer['password']) 33 | { 34 | $response['info'] = '密码错误'; 35 | } 36 | else 37 | { 38 | Safe::del('printer_auth_' . $account); 39 | unset($Printer['password']); 40 | $sid = Session::start(); 41 | Session::set('printer', ['id' => $Printer['id'], 'sch_id' => $Printer['sch_id']]); 42 | $response['status'] = 1; 43 | $response['info'] = ['sid' => $sid, 'printer' => $Printer]; 44 | } 45 | $this->response = $response; 46 | } 47 | 48 | /** 49 | * 注销 50 | * @method logout 51 | */ 52 | public function logoutAction() 53 | { 54 | Session::flush(); 55 | Cookie::flush(); 56 | $this->response(1, '登录信息已注销!'); 57 | } 58 | } 59 | ?> -------------------------------------------------------------------------------- /app/modules/Printer/controllers/Books.php: -------------------------------------------------------------------------------- 1 | authPrinter(); 14 | Input::get('page', $page, 'int', 1); 15 | $Book = BookModel::where('pri_id', '=', $pid)->page($page); 16 | if (Input::get('key', $key)) 17 | { 18 | $key = '%' . strtr($key, ' ', '%') . '%'; 19 | $Book->where('name', 'LIKE', $key)->orWhere('detail', 'LIKE', $key); 20 | } 21 | $books = $Book->select('id,name,price,image'); 22 | $this->response(1, $books); 23 | } 24 | 25 | /** 26 | * 添加资源 27 | * @method POST_indexAction 28 | * @author NewFuture 29 | */ 30 | public function POST_indexAction() 31 | { 32 | $pid = $this->authPrinter(); 33 | if (Input::post('books', $books)) 34 | { 35 | /*批量插入*/ 36 | $books = explode("\n", $books); 37 | $books = array_map(array('\\Parse\\Filter', 'title'), $books); 38 | $books = array_filter($books); 39 | $data = array(); 40 | foreach ($books as $key => $name) 41 | { 42 | $data[] = [$pid, $name]; 43 | } 44 | /*全部插入*/ 45 | if (BookModel::insertAll(['pri_id', 'name'], $data)) 46 | { 47 | $this->response(1, $books); 48 | } 49 | else 50 | { 51 | $this->response(0, '批量插入失败'); 52 | } 53 | } 54 | elseif (Input::post('name', $name, 'title')) 55 | { 56 | /*单个插入*/ 57 | $book['name'] = $name; 58 | $book['pri_id'] = $pid; 59 | if (Input::post('price', $price, 'float')) 60 | { 61 | $book['price'] = $price; 62 | } 63 | if (Input::post('detail', $detail, 'text')) 64 | { 65 | $book['detail'] = $detail; 66 | } 67 | 68 | if ($book['id'] = BookModel::insert($book)) 69 | { 70 | $this->response(1, $book); 71 | } 72 | else 73 | { 74 | $this->response(0, '添加失败'); 75 | } 76 | } 77 | else 78 | { 79 | $this->response(0, '数据无效'); 80 | } 81 | } 82 | 83 | /** 84 | * 获取详情 85 | * GET /books/123 86 | * @method GET_infoAction 87 | * @param integer $id [资源id] 88 | * @author NewFuture 89 | */ 90 | public function GET_infoAction($id = 0) 91 | { 92 | $pid = $this->authPrinter(); 93 | if ($book = BookModel::where('pri_id', '=', $pid)->find($id)) 94 | { 95 | $this->response(1, $book); 96 | } 97 | else 98 | { 99 | $this->response(0, '信息不存在或者无权访问'); 100 | } 101 | } 102 | 103 | /** 104 | * 删除 105 | * DELETE /books/123 106 | * @method GET_infoAction 107 | * @param integer $id [资源id] 108 | * @author NewFuture 109 | */ 110 | public function DELETE_infoAction($id = 0) 111 | { 112 | $pid = $this->authPrinter(); 113 | if (BookModel::delete($id)) 114 | { 115 | $this->response(1, '删除成功!'); 116 | } 117 | else 118 | { 119 | $this->response(0, '信息不存在或者无权访问'); 120 | } 121 | } 122 | 123 | /** 124 | * 获取详情 125 | * PUT /books/123 126 | * @method GET_infoAction 127 | * @param integer $id [资源id] 128 | * @author NewFuture 129 | */ 130 | public function PUT_infoAction($id = 0) 131 | { 132 | $pid = $this->authPrinter(); 133 | $book = []; 134 | if (Input::put('name', $name, 'title')) 135 | { 136 | $book['name'] = $name; 137 | } 138 | 139 | if (Input::put('detail', $detail, 'text')) 140 | { 141 | $book['detail'] = $detail; 142 | } 143 | 144 | if (Input::put('price', $price, 'float')) 145 | { 146 | $book['price'] = $price; 147 | } 148 | 149 | if (empty($book)) 150 | { 151 | $this->response(0, '无修改内容'); 152 | } 153 | elseif (BookModel::where('id', $id)->where('pri_id', $pid)->update($book)) 154 | { 155 | $this->response(1, $book); 156 | } 157 | else 158 | { 159 | $this->response(0, '修改失败'); 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /app/modules/Printer/controllers/Info.php: -------------------------------------------------------------------------------- 1 | authPrinter($id); 15 | $field = 'id,name,sch_id,account,address,email,phone,qq,wechat,profile,image,open,status,price,other'; 16 | if ($printer = PrinterModel::field($field)->find($id)) 17 | { 18 | $printer['price'] = json_decode($printer['price']); 19 | $this->response(1, $printer); 20 | } 21 | else 22 | { 23 | $this->response(0, '无效用户'); 24 | } 25 | } 26 | 27 | /** 28 | * 修改信息 29 | * @param [type] $id [description] 30 | * @todo 价格 31 | */ 32 | public function PUT_infoAction($id) 33 | { 34 | $this->authPrinter($id); 35 | $info = []; 36 | /*店名*/ 37 | Input::put('name', $var, 'title') AND $info['name'] = $var; 38 | /*邮箱*/ 39 | Input::put('email', $var, 'email') AND $info['email'] = $var; 40 | /*手机*/ 41 | Input::put('phone', $var, 'phone') AND $info['phone'] = $var; 42 | /*qq号*/ 43 | Input::put('qq', $var, 'int') AND $info['qq'] = $var; 44 | /*微信号*/ 45 | Input::put('wechat', $var, 'char_num') AND $info['wechat'] = $var; 46 | /*地址*/ 47 | Input::put('address', $var, 'text') AND $info['address'] = $var; 48 | /*简介*/ 49 | Input::put('profile', $var, 'text') AND $info['profile'] = $var; 50 | /*营业时间*/ 51 | Input::put('open', $var, 'text') AND $info['open'] = $var; 52 | /*营业时间*/ 53 | Input::put('other', $var, 'text') AND $info['other'] = $var; 54 | /*价格*/ 55 | $price = []; 56 | Input::put('price_s', $price['s'], 'float'); 57 | Input::put('price_d', $price['d'], 'float'); 58 | Input::put('price_c_s', $price['c_s'], 'float'); 59 | Input::put('price_c_d', $price['c_d'], 'float'); 60 | if (!empty(array_filter($price))) 61 | { 62 | if ($oldprice = PrinterModel::where('id', $id)->get('price')) 63 | { 64 | if ($oldprice = @json_decode($oldprice, true)) 65 | { 66 | $price = array_merge($oldprice, array_filter($price)); 67 | } 68 | } 69 | $info['price'] = json_encode($price); 70 | } 71 | if (empty($info)) 72 | { 73 | $this->response(0, '无有效参数'); 74 | } 75 | elseif (PrinterModel::where('id', $id)->update($info) !== false) 76 | { 77 | $this->response(1, $info); 78 | } 79 | else 80 | { 81 | $this->response(0, '修改失败'); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /app/modules/Printer/controllers/Password.php: -------------------------------------------------------------------------------- 1 | field('id,phone')->find()) 25 | { 26 | $response['info'] = '尚未注册'; 27 | } 28 | elseif (!Safe::checkTry('pwd_phone_' . $account)) 29 | { 30 | $response['info'] = '尝试次数过多,临时封禁!'; 31 | } 32 | elseif (!$Printer['phone'] || ($Printer['phone'] != $phone)) 33 | { 34 | $response['info'] = '绑定手机不一致,或者手机号错误'; 35 | } 36 | elseif (!Sms::findPwd($phone, $code = Random::number(6))) 37 | { 38 | $response['info'] = '短信发送出错,请联系我们!'; 39 | } 40 | else 41 | { 42 | /*发送成功*/ 43 | $find = ['id' => $Printer['id'], 'account' => $account, 'code' => strtoupper($code)]; 44 | Session::set('find_info_p', $find); 45 | Safe::del('pwd_phone_' . $account); 46 | $response['status'] = 1; 47 | $response['info'] = '验证短信已发送'; 48 | } 49 | $this->response = $response; 50 | } 51 | 52 | /** 53 | * 通过邮箱找回密码 54 | * @method POST_emailAction 55 | * @author NewFuture 56 | */ 57 | public function POST_emailAction() 58 | { 59 | 60 | $response['status'] = 0; 61 | if (!Input::post('email', $email, 'email')) 62 | { 63 | $response['info'] = '邮箱格式有误或者不支持!'; 64 | } 65 | elseif (!Input::post('account', $account, Config::get('regex.account'))) 66 | { 67 | $response['info'] = '学号格式有误!'; 68 | } 69 | elseif (!Safe::checkTry('pwd_email_' . $account)) 70 | { 71 | $response['info'] = '尝试次数过多,临时封禁!'; 72 | } 73 | elseif (!$Printer = PrinterModel::where('account', $account)->field('id,email')->find()) 74 | { 75 | $response['info'] = '尚未注册,或者账号错误'; 76 | } 77 | elseif (empty($Printer['email'])) 78 | { 79 | $response['info'] = '未绑定邮箱,或邮箱不存在'; 80 | } 81 | elseif ($Printer['email'] != $email) 82 | { 83 | $response['info'] = '绑定邮箱不一致,或者邮箱错误'; 84 | } 85 | elseif (!Mail::findPwd($email, $code = Random::code(6))) 86 | { 87 | $response['info'] = '邮件发送出错,请联系我们!'; 88 | } 89 | else 90 | { 91 | /*发送成功*/ 92 | $find = ['id' => $user['id'], 'account' => $account, 'code' => strtoupper($code)]; 93 | Session::set('find_info_p', $find); 94 | Safe::del('pwd_email_' . $account); 95 | $response['status'] = 1; 96 | $response['info'] = '验证邮件已发送!'; 97 | } 98 | $this->response = $response; 99 | } 100 | 101 | /** 102 | * 验证验证码 103 | * @method POST_codeAction 104 | * @author NewFuture 105 | */ 106 | public function POST_codeAction() 107 | { 108 | $response['status'] = 0; 109 | if (!Input::post('code', $code, 'char_num')) 110 | { 111 | $response['info'] = '验证码无效'; 112 | } 113 | elseif (!$info = Session::get('find_info_p')) 114 | { 115 | $response['info'] = '验证信息已失效,请重新发送验证码'; 116 | } 117 | elseif ($info['code'] != strtoupper($code)) 118 | { 119 | $response['info'] = '验证码错误'; 120 | $times = isset($info['t']) ? $info['t'] + 1 : 1; 121 | if ($times > 3) 122 | { 123 | /*一个验证码尝试超过三次强制过期*/ 124 | Session::del('find_info_p'); 125 | } 126 | else 127 | { 128 | $info['t'] = $times; 129 | Session::set('find_info_p', $info); 130 | } 131 | } 132 | else 133 | { 134 | Session::del('find_info_p'); 135 | Session::set('find_printer', ['id' => $info['id'], 'account' => $info['account']]); 136 | $response['status'] = 1; 137 | $response['info'] = '验证成功,请重置密码'; 138 | } 139 | $this->response = $response; 140 | } 141 | 142 | /** 143 | * 重置密码 144 | * @method POST_indexAction 145 | * @author NewFuture 146 | */ 147 | public function POST_indexAction() 148 | { 149 | $response['status'] = 0; 150 | if (!Input::post('password', $password, 'isMd5')) 151 | { 152 | $response['info'] = '密码无效'; 153 | } 154 | elseif (!$printer = Session::get('find_printer')) 155 | { 156 | $response['info'] = '未验证或者验证信息过期'; 157 | } 158 | else 159 | { 160 | $printer['password'] = Encrypt::encryptPwd($password, $printer['account']); 161 | if (PrinterModel::where('id', $printer['id'])->update($printer) >= 0) 162 | { 163 | $response['status'] = 1; 164 | $response['info'] = '重置成功'; 165 | } 166 | else 167 | { 168 | $response['info'] = '新密码保存失败'; 169 | } 170 | } 171 | $this->response = $response; 172 | } 173 | 174 | /** 175 | * 重置密码 176 | * @method POST_printerAction 177 | * @author NewFuture 178 | */ 179 | public function PUT_indexAction($id) 180 | { 181 | $this->auth($id); 182 | $response['status'] = 0; 183 | if (!Input::put('password', $password, 'isMd5')) 184 | { 185 | $response['info'] = '新的密码格式不对'; 186 | } 187 | elseif (!Input::put('old', $old_pwd, 'isMd5')) 188 | { 189 | $response['info'] = '请输入原密码'; 190 | } 191 | else 192 | { 193 | /*数据库中读取用户数据*/ 194 | $printer = PrinterModel::field('password,account')->find($id); 195 | $account = $printer['account']; 196 | if (!$printer || Encrypt::encryptPwd($old_pwd, $account) != $printer['password']) 197 | { 198 | $response['info'] = '原密码错误'; 199 | } 200 | elseif ($printer->update(['password' => Encrypt::encryptPwd($password, $account)]) >= 0) //修改数据 201 | { 202 | $response['info'] = '修改成功'; 203 | $response['status'] = 1; 204 | } 205 | else 206 | { 207 | $response['info'] = '修改失败'; 208 | } 209 | } 210 | $this->response = $response; 211 | } 212 | } 213 | ?> -------------------------------------------------------------------------------- /app/modules/Printer/controllers/Task.php: -------------------------------------------------------------------------------- 1 | authPrinter(); 16 | Input::get('page', $page, 'int', 1); 17 | $Task = TaskModel::where('pri_id', '=', $pid)->belongs('user')->page($page)->order('id', true); 18 | if (Input::get('status', $status, 'int')) 19 | { 20 | $Task->where('status', '=', $status); 21 | } 22 | else 23 | { 24 | //所有未完成订单 25 | $Task->where('status', '>', 0); 26 | } 27 | $tasks = $Task->select('name,id,color,format,double,copies,status,name,time,requirements,payed'); 28 | $this->response(1, $tasks); 29 | } 30 | 31 | /** 32 | * 获取详情 33 | * @param [type] $id [description] 34 | */ 35 | public function GET_infoAction($id) 36 | { 37 | $pid = $this->authPrinter(); 38 | if (!$task = TaskModel::where('pri_id', '=', $pid)->find(intval($id))) 39 | { 40 | $this->response(0, '无此文件'); 41 | } 42 | else 43 | { 44 | $task['url'] = File::get($task['url']); 45 | $this->response(1, $task); 46 | } 47 | 48 | } 49 | 50 | /** 51 | * 修改状态 52 | * @param [type] $id [description] 53 | */ 54 | public function PUT_infoAction($id) 55 | { 56 | $pid = $this->authPrinter(); 57 | $response['status'] = 0; 58 | if (!Input::put('status', $status, 'int')) 59 | { 60 | $response['info'] = '无效状态'; 61 | } 62 | elseif ($status < -1 || $status > 5) 63 | { 64 | $response['info'] = '此状态不允许设置'; 65 | } 66 | elseif($status==-1&&TaskModel::where('id',intval($id))->where('pri_id',$pri_id)->get('payed')) 67 | {//取消订单 68 | 69 | $response['info']='已支付暂不支持线上取消'; 70 | } 71 | elseif (TaskModel::where('id', intval($id))->where('pri_id', $pid)->update(['status' => $status])) 72 | { 73 | $response['status'] = 1; 74 | $response['info'] = '修改成功'; 75 | } 76 | else 77 | { 78 | $response['info'] = '状态设置失败'; 79 | } 80 | $this->response = $response; 81 | } 82 | 83 | /** 84 | * 确认支付 85 | * @method POST_payAction 86 | * @param [type] $id [description] 87 | * @author NewFuture 88 | */ 89 | public function POST_payAction($id) 90 | { 91 | $pid = $this->authPrinter(); 92 | if (TaskModel::where('id', intval($id))->where('pri_id', $pid)->update(['payed' => 1])) 93 | { 94 | $this->response(1, '已确认支付!'); 95 | } 96 | else 97 | { 98 | $this->response(0, '状态修改失败'); 99 | } 100 | } 101 | 102 | /** 103 | * 获取源文件 104 | * 在转码出问题可用此接口 105 | * @param [type] $id [description] 106 | */ 107 | public function GET_fileAction($id) 108 | { 109 | $pid = $this->authPrinter(); 110 | if ($url = TaskModel::where('id', intval($id))->where('pri_id', '=', $pid)->get('url')) 111 | { 112 | $this->response(1, File::source($url)); 113 | } 114 | else 115 | { 116 | $this->response(0, '无此文件'); 117 | } 118 | } 119 | } 120 | ?> -------------------------------------------------------------------------------- /app/modules/Printer/controllers/User.php: -------------------------------------------------------------------------------- 1 | authPrinter(); 19 | if (TaskModel::where('use_id', $id)->where('pri_id', $pid)->find()) 20 | { 21 | $user = UserModel::field('name,number,phone,email,sch_id')->find($id); 22 | $user = UserModel::mask($user); 23 | $this->response(1, $user); 24 | } 25 | else 26 | { 27 | $this->response(0, '此同学未在此打印过'); 28 | } 29 | } 30 | 31 | /** 32 | * 获取用户真实手机 33 | * GET /user/1/phone 34 | * @method GET_infoAction 35 | * @param integer $id [description] 36 | * @author NewFuture 37 | */ 38 | public function GET_phoneAction($id = 0) 39 | { 40 | $pid = $this->authPrinter(); 41 | if (TaskModel::where('use_id', $id)->where('pri_id', $pid)->get('id')) 42 | { 43 | $user = UserModel::field('number,phone')->find($id); 44 | $phone = $user ? Encrypt::decryptPhone($user['phone'], $user['number'], $id) : null; 45 | $this->response(1, $phone); 46 | } 47 | else 48 | { 49 | $this->response(0, '此同学未在此打印过'); 50 | } 51 | 52 | } 53 | 54 | /** 55 | * 获取用户真实手机 56 | * GET /user/1/email 57 | * @method GET_infoAction 58 | * @param integer $id [description] 59 | * @author NewFuture 60 | */ 61 | public function GET_emailAction($id = 0) 62 | { 63 | $pid = $this->authPrinter(); 64 | if (TaskModel::where('use_id', $id)->where('pri_id', $pid)->get('id')) 65 | { 66 | $email = UserModel::where('id', '=', $id)->get('email'); 67 | $email = $email ? Encrypt::decryptEmail($email) : null; 68 | $this->response(1, $email); 69 | } 70 | else 71 | { 72 | $this->response(0, '此同学未在此打印过'); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /app/plugins/Tracer.php: -------------------------------------------------------------------------------- 1 | time['request'] = $start; 15 | $this->mem['start'] = memory_get_usage() / 1024; //启动内存,包括调试插件占用 16 | } 17 | 18 | //在路由之前触发,这个是7个事件中, 最早的一个. 但是一些全局自定的工作, 还是应该放在Bootstrap中去完成 19 | public function routerStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) 20 | { 21 | $this->time['routerstartup'] = self::mtime(); 22 | } 23 | 24 | //路由结束之后触发,此时路由一定正确完成, 否则这个事件不会触发 25 | public function routerShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) 26 | { 27 | $this->time['routershutdown'] = self::mtime(); 28 | } 29 | 30 | //分发循环开始之前被触发 31 | public function dispatchLoopStartup(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) 32 | { 33 | $this->time['dispatchloopstartup'] = self::mtime(); 34 | $this->mem['dispatch'] = memory_get_usage() / 1024; 35 | } 36 | 37 | // //分发之前触发 如果在一个请求处理过程中, 发生了forward, 则这个事件会被触发多次 38 | // public function preDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) 39 | // { 40 | // $this->time['predispatch'] = self::mtime(); 41 | // } 42 | 43 | //分发结束之后触发,此时动作已经执行结束, 视图也已经渲染完成. 和preDispatch类似, 此事件也可能触发多次 44 | public function postDispatch(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) 45 | { 46 | $this->time['postdispatch'] = self::mtime(); 47 | } 48 | 49 | //分发循环结束之后触发,此时表示所有的业务逻辑都已经运行完成, 但是响应还没有发送 50 | public function dispatchLoopShutdown(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) 51 | { 52 | $this->time['dispatchloopshutdown'] = self::mtime(); 53 | } 54 | 55 | // public function preResponse(Yaf_Request_Abstract $request, Yaf_Response_Abstract $response) 56 | // { 57 | // echo 1; 58 | // $this->time['preresponse'] = self::mtime(); 59 | // } 60 | 61 | /** 62 | * 获取当前毫秒数 63 | * @method mtime 64 | * @return [type] [description] 65 | * @author NewFuture 66 | */ 67 | public static function mtime() 68 | { 69 | return microtime(true) * 1000; 70 | } 71 | 72 | public function __destruct() 73 | { 74 | 75 | $included_files = get_included_files(); 76 | $file_msg = '文件加载[' . count($included_files) . ']' . print_r($included_files, true); 77 | 78 | $mem = $this->mem; 79 | $mem_end = memory_get_usage() / 1024; 80 | $mem_msg = PHP_EOL . '[内存消耗统计]'; 81 | $mem_msg .= PHP_EOL . '启动消耗内存:' . $mem['start'] . 'Kb'; 82 | $mem_msg .= PHP_EOL . '路由消耗内存:' . ($mem['dispatch'] - $mem['start']) . 'Kb'; 83 | $mem_msg .= PHP_EOL . '处理消耗内存:' . ($mem_end - $mem['dispatch']) . 'Kb'; 84 | $mem_msg .= PHP_EOL . '总共消耗内存:' . $mem_end . 'Kb'; 85 | 86 | $time = $this->time; 87 | $end = self::mtime(); 88 | $time_msg = '启动时间:' . $time['request']; 89 | $time_msg .= PHP_EOL . '结束时间:' . $end; 90 | $time_msg .= PHP_EOL . '框架启动耗时:' . ($time['routerstartup'] - $time['request']) . 'ms'; 91 | $time_msg .= PHP_EOL . '路由处理耗时:' . ($time['routershutdown'] - $time['routerstartup']) . 'ms'; 92 | $time_msg .= PHP_EOL . '分发准备耗时:' . ($time['dispatchloopstartup'] - $time['routershutdown']) . 'ms'; 93 | 94 | if (isset($time['dispatchloopshutdown'])) 95 | { 96 | $time_msg .= PHP_EOL . '处理过程耗时:' . ($time['dispatchloopshutdown'] - $time['dispatchloopstartup']) . 'ms'; 97 | $time_msg .= PHP_EOL . '输出关闭耗时:' . ($end - $time['dispatchloopshutdown']) . 'ms'; 98 | } 99 | else 100 | { 101 | $time_msg .= PHP_EOL . '处理过程耗时:' . ($end - $time['dispatchloopstartup']) . 'ms'; 102 | } 103 | 104 | $time_msg .= PHP_EOL . '总耗时:' . ($end - $time['request']) . 'ms'; 105 | Log::write($file_msg . $time_msg . $mem_msg . PHP_EOL, 'TRACER'); 106 | } 107 | } -------------------------------------------------------------------------------- /app/views/api/choice.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 云印API接口 5 | 6 | 7 | 54 | 55 | 56 |
57 |

云印南天API

58 | 60 |
61 |

您已经登录,请选择服务

62 | 云印服务 63 | 招领服务 64 |
65 |
退出登录
66 | 67 | 68 | -------------------------------------------------------------------------------- /app/views/jump.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <?=$msg?> 5 | 6 | 10 | 11 |

12 |

s后自动 跳转

13 | 14 | 23 | 24 | -------------------------------------------------------------------------------- /backup.php: -------------------------------------------------------------------------------- 1 | fileExists(DOMAIN, $filename)) 12 | { 13 | $dj = new SaeDeferredJob(); 14 | $taskID = $dj->addTask('export', 'mysql', DOMAIN, $filename, SAE_MYSQL_DB, '', ''); 15 | if ($taskID === false) 16 | { 17 | var_dump($dj->errno(), $dj->errmsg()); 18 | } 19 | else 20 | { 21 | echo $taskID; 22 | } 23 | } 24 | 25 | /*旧备份清理*/ 26 | /*保留最近7天和每周1和每月1日的数据备份*/ 27 | $week_ago = date('Y-m-d', strtotime('-1 week')); 28 | $ninety_days_ago = date('Y-m-d', strtotime('-90 day')); 29 | if (date('N', time()) != '1' && date('d') != '8' && $stor->fileExists(DOMAIN, $week_ago.'.sql.zip')) 30 | { 31 | //if ( today != monday && today != 8.th), delete 7 days ago backup 32 | $stor->delete(DOMAIN, $week_ago.'.sql.zip'); 33 | } 34 | if (date('d', strtotime('-90 day')) != '1' && $stor->fileExists(DOMAIN, $ninety_days_ago.'.sql.zip')) 35 | { 36 | //if ( $90daysago != 1.st ), delete 3 months ago backup 37 | $stor->delete(DOMAIN, $ninety_days_ago.'.sql.zip'); 38 | } 39 | ?> -------------------------------------------------------------------------------- /conf/app.ini: -------------------------------------------------------------------------------- 1 | [common];公用配置 2 | application.directory = APP_PATH "/app/" 3 | application.library = APP_PATH"/library" 4 | application.modules = "Index,Printer";模块 5 | application.dispatcher.defaultController = "Api";默认控制器名称 6 | 7 | 8 | ;配置路径 9 | secret_config_path = APP_PATH "/conf/secret.common.ini" 10 | tempdir = APP_PATH "/temp/";临时文件目录和日志,缓存存于此处 11 | 12 | ;路由 13 | ;printer缺省路由 14 | routes.default.type = "rewrite" 15 | routes.default.match = "/printer/:_c" 16 | routes.default.route.module = "Printer" 17 | routes.default.route.controller = :_c 18 | routes.default.route.action = "index" 19 | ;printer完整路由 20 | routes.prifull.type = "rewrite" 21 | routes.prifull.match = "/printer/:_c/:_a" 22 | routes.prifull.route.module = "Printer" 23 | routes.prifull.route.controller = :_c 24 | routes.prifull.route.action = :_a 25 | 26 | ;正则验证 27 | regex.number.all = "/^(\d{6,7}|\d{10,12})$/"; //学号正则 28 | regex.number.nku = "/^((1[1-6]\d{5})|([1|2]1201[1-6]\d{4}))$/";南开7或10 29 | regex.number.tju = "/^[1-4]01[1-6]\d{6}$/";天大10 30 | regex.number.tifert = "/^((0[1-5][01][0-9])|(1[139][05][1-4]))1[2-5]\d{4}$/"; 天商职10 31 | regex.number.hebut = "/^(([1][1-5]\d{4})|(201[0-5]\d{8}))$/";河工大6或12 32 | regex.number.gzpyp = "/^1[3-6][0,1]\d{3}0\d{3}$/";广州番职院11 33 | regex.number.hnist = "/^((1[2,4,5])|(24))1[2-6][0-6]\d{6}$/";湖南理工学院11 34 | regex.account = "/^\w{3,16}$/";打印店账号正则 35 | regex.token = "/^\w{38,48}$/" 36 | regex.phone = "/^1[34578]\d{9}$/";//手机号 37 | regex.email = "/^[\w\.\-]{1,17}@[A-Za-z,0-9,\-,\.]{1,30}\.[A-Za-z]{2,6}$/" 38 | regex.name = "/^[\x{4E00}-\x{9FA5}]{2,5}(·[\x{4E00}-\x{9FA5}]{2,8})?$/u";姓名支持少数民族 39 | regex.zh = "/^[\x{4E00}-\x{9FA5}]*$/u" 40 | 41 | ;上传通用配置 42 | upload.type = "qiniu" 43 | upload.max = 52428800; //50 * 1024 * 1024,文件大小限制 44 | upload.exts = "pdf,doc,docx,odt,rtf,wps,ppt,pptx,odp,dps,xls,xlsx,ods,csv,et,jpg,png,jpeg";后缀名限制 45 | 46 | ;cookie配置 47 | cookie.path = "/" 48 | cookie.expire = 259200 ;3天 49 | cookie.domain = ".yunyin.org" 50 | cookie.secure = 0 51 | cookie.httponly = 1; 52 | 53 | ;尝试限制 54 | try.times = 5 55 | try.expire = 18000 56 | 57 | ;cors 跨域设置 58 | cors.Access-Control-Allow-Credentials = "true" 59 | cors.Access-Control-Allow-Headers = "Token,Session-ID" 60 | cors.Access-Control-Allow-Methods = "GET,POST,PUT,DELETE" 61 | cors.Access-Control-Max-Age = 3628800 62 | 63 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 | [dev:common];开发调试配置 65 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 66 | application.bootstrap = APP_PATH "/app/Debug.php" 67 | application.system.cache_config = 0 68 | 69 | ;特殊配置path 70 | secret_config_path = APP_PATH "/conf/secret.local" 71 | 72 | ;开启调试 73 | isdebug = 1 74 | debug.auth = "" 75 | 76 | ;缓存日志相关 77 | cache.type = "file" 78 | kv.type = "file" 79 | log.type = "file" 80 | log.allow = "ERROR,WARN,DEBUG,INFO,SQL,TRACER" 81 | 82 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 83 | [product:common];线上配置 84 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 85 | application.dispatcher.throwException = 1 86 | application.dispatcher.catchException = 1 87 | application.system.cache_config = 1 88 | 89 | ;特殊配置path 90 | secret_config_path = APP_PATH "/conf/secret.product.ini" 91 | 92 | ;调试和日志相关 93 | isdebug = 0 94 | debug.auth = "yunyindebug"; 95 | log.allow = "ERROR,WARN" 96 | log.type = "file";sae设置成SAE,使用系统og 97 | cache.type = "file";缓存类型SAE设置SAE使用memcache 98 | kv.type = "file";SAE设置为sae使用KVDB 99 | -------------------------------------------------------------------------------- /conf/secret.common.ini: -------------------------------------------------------------------------------- 1 | [encrypt] 2 | ;加密密钥32位字符 3 | key_email = "123e#Pe65qg2ARw9asf3*KelRM74j42a";邮箱加密密钥 4 | key_phone_mid = "asdyfadusihahke123&*@asdas123131";手机中间号码加密密钥 5 | key_phone_end = "shjdkadadlaksddakl213adsjjasjadf";尾号加密密钥 6 | 7 | [mail] 8 | ;系统邮箱相关配置 9 | server.smtp = "smtp.yunyin.org" 10 | server.port = 465 11 | server.secure = "ssl" 12 | verify.name = "云小印[验证]" 13 | verify.email = "verify@mail.yunyin.org" 14 | verify.pwd = "邮箱密码" 15 | verify.baseuri = "http://localhost/api/email/code/" 16 | notify.name = "云小印[通知]" 17 | notify.email = "notify@mail.yunyin.org" 18 | notify.pwd = "邮箱密码" 19 | 20 | [sms] 21 | ;短信接口相关配置 22 | account = "" 23 | appid = "" 24 | token = "" 25 | template.bind = 3620 26 | template.pwd = 4003 27 | template.card = 4134 28 | template.printed = 4698 29 | 30 | [qiniu] 31 | ;七牛上传配置 32 | secretkey = "8nfzvI5ontAmER33n40O6U2LGCj1wVHUcEAlmByS" 33 | accesskey = "EfZW44Kjkjp8T92qMqLkkt4awRTRP1ucd-n6wUhn" 34 | expire = 86400;超时时间 35 | ;bucket配置 36 | file = "uploadbucket" 37 | task = "taskbucket" 38 | share = "sharebucket" 39 | ;bucket对应域名 40 | domain.uploadbucket = "http://1.qiniudn.com/" 41 | domain.taskbucket = "http://2.qiniudn.com/" 42 | domain.sharebucket = "http://3.qiniudn.com/" 43 | 44 | [api] 45 | ;开放API 46 | card = "yunyincard" 47 | 48 | [database] 49 | ;数据库配置 50 | driver = "mysql" 51 | charset = "utf8" 52 | collation = "utf8_unicode_ci" 53 | prefix = "" 54 | ;账号信息 55 | host = "127.0.0.1" 56 | database = "yunyin" ;数据库名 57 | username = "root" 58 | password = "" 59 | port = 3306 60 | ;FOR SAE JUST LIKE FOLLOW 61 | ;host = SAE_MYSQL_HOST_M;//从数据库SAE_MYSQL_HOST_S 62 | ;port = SAE_MYSQL_PORT 63 | ;database = SAE_MYSQL_DB 64 | ;username = SAE_MYSQL_USER 65 | ;password = SAE_MYSQL_PASS -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | name: yunyin 2 | handle: 3 | - rewrite: if(!is_file() && path~"^(.*)$") goto "index.php/$1" 4 | 5 | - hostaccess: if(path == "/backup.php") allow "10.0.0.0/8" 6 | - hostaccess: if (%{REQUEST_URI} ~*"/conf/") allow "0.0" 7 | - hostaccess: if (%{REQUEST_URI} ~*"/app/") allow "0.0" 8 | - hostaccess: if (path ~*"/.htacesss") allow "0.0" 9 | 10 | cron: 11 | - description: backup 12 | url: /backup.php 13 | schedule: every day of month 04:32 14 | timezone: Beijing 15 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | copy ./conf/secret.common.ini ./conf/secret.local 4 | 5 | mkdir -m 555 temp 6 | 7 | sudo rm -R temp/* 8 | 9 | -------------------------------------------------------------------------------- /library/Auth.php: -------------------------------------------------------------------------------- 1 | $_SERVER['REQUEST_TIME'] 52 | && $user = self::checkToken($uid, $token)) 53 | { 54 | /*token有效*/ 55 | Session::set('user', $user); 56 | return $user; 57 | } 58 | } 59 | } 60 | } 61 | 62 | /** 63 | * 生成token 64 | * @method token 65 | * @param [type] $user [id或者包括用户id,number,password(加密后的),$sch_id的数组] 66 | * @return [type] [description] 67 | * @author NewFuture 68 | */ 69 | public static function token($user) 70 | { 71 | 72 | if (!$user) 73 | { 74 | return false; 75 | } 76 | elseif (is_numeric($user) && $data = UserModel::field('id,number,password,sch_id')->find($user)->get()) 77 | { 78 | $token = self::createBaseToken($data); 79 | } 80 | elseif (isset($user['id']) && ($data['id'] = $user['id']) 81 | && isset($user['number']) && ($data['number'] = $user['number']) 82 | && isset($user['password']) && ($data['password'] = $user['password']) 83 | && isset($user['sch_id']) && ($data['sch_id'] = $user['sch_id'])) 84 | { 85 | $token = self::createBaseToken($data); 86 | } 87 | else 88 | { 89 | return false; 90 | } 91 | $token = $data['id'] . ':' . $token . ':' . $_SERVER['REQUEST_TIME']; 92 | return Encrypt::aesEncode($token, Cookie::key(), true); 93 | } 94 | 95 | /** 96 | * 验证token 97 | * @method checkToken 98 | * @param [type] $uid [description] 99 | * @param [type] $token [description] 100 | * @return [type] [description] 101 | * @author NewFuture 102 | */ 103 | public static function checkToken($uid, $token) 104 | { 105 | if ($user = UserModel::field('id,number,password,sch_id')->find(intval($uid))->get()) 106 | { 107 | $base_token = self::createBaseToken($user); 108 | return $token == $base_token ? $user : null; 109 | } 110 | } 111 | 112 | /** 113 | * 获取当前登录的打印店 114 | * @method getPrinter 115 | * @return [type] [description] 116 | * @author NewFuture 117 | */ 118 | public static function getPrinter() 119 | { 120 | if ($printer = Session::get('printer')) 121 | { 122 | /*session中的信息*/ 123 | return $printer; 124 | } 125 | // elseif ($token = Cookie::get('token') || Input::I('SERVER.HTTP_TOKEN', $token, 'token')) 126 | // { 127 | // /*解析cookie*/ 128 | // if ($token = Encrypt::aesDecode($token, Cookie::key(), true)) 129 | // { 130 | // list($pid, $token, $time) = explode(':', $token); 131 | // if ($time + Config::get('cookie.expire') > $_SERVER['REQUEST_TIME'] 132 | // && $printer = self::checkToken($pid, $token)) 133 | // { 134 | // /*token有效*/ 135 | // Session::set('printer', $printer); 136 | // return $printer; 137 | // } 138 | // } 139 | // } 140 | } 141 | 142 | /** 143 | * 获取打印店ID 144 | * @method priId 145 | * @return [type] [description] 146 | * @author NewFuture 147 | */ 148 | public static function priId() 149 | { 150 | if ($printer = self::getPrinter()) 151 | { 152 | return $printer['id']; 153 | } 154 | } 155 | 156 | /** 157 | * printer 生成token 158 | * @method printerToken 159 | * @param [type] $printer [description] 160 | * @return [type] [description] 161 | * @author NewFuture 162 | */ 163 | public static function printerToken($printer) 164 | { 165 | if ($printer && 166 | (is_numeric($printer) && $data = PrinterModel::field('id,name,password,sch_id')->find($printer)) 167 | || (isset($printer['id']) && $data['id'] = $printer['id'] 168 | && isset($printer['name']) && $data['name'] = $printer['name'] 169 | && isset($printer['password']) && $data['password'] = $printer['password'] 170 | && isset($printer['sch_id']) && $data['sch_id'] = $printer['sch_id'])) 171 | { 172 | return self::createBaseToken($data); 173 | } 174 | } 175 | 176 | // /** 177 | // * checkPrinterToken description 178 | // * @method checkPrinterToken 179 | // * @param [type] $id [description] 180 | // * @param [type] $token [description] 181 | // * @return [type] [description] 182 | // * @author NewFuture 183 | // */ 184 | // public static function checkPrinterToken($id, $token) 185 | // { 186 | // if ($p = printerModel::field('id,name,password,sch_id')->find(intval($id))) 187 | // { 188 | // $base_token = self::createBaseToken($p); 189 | // return $token == $base_token ? $p : null; 190 | // } 191 | // } 192 | 193 | /*根据用户信息生成基础token*/ 194 | private static function createBaseToken(&$user) 195 | { 196 | $token = hash_hmac('md5', implode('|', $user), $user['password'], true); 197 | return Encrypt::base64Encode($token); 198 | } 199 | } -------------------------------------------------------------------------------- /library/Cache.php: -------------------------------------------------------------------------------- 1 | set($name, $value, 0, $expire); 26 | } 27 | 28 | /** 29 | * 读取缓存数据 30 | * @method get 31 | * @param [type] $name [description] 32 | * @return [type] [description] 33 | * @author NewFuture 34 | */ 35 | public static function get($name) 36 | { 37 | return self::Handler()->get($name); 38 | } 39 | 40 | /** 41 | * 删除缓存数据 42 | * @method del 43 | * @param [type] $name [description] 44 | * @return [bool] 45 | * @author NewFuture 46 | */ 47 | public static function del($name) 48 | { 49 | return self::Handler()->delete($name); 50 | } 51 | 52 | /** 53 | * 清空缓存 54 | * @method fush 55 | * @return [type] [description] 56 | * @author NewFuture 57 | */ 58 | public static function flush() 59 | { 60 | return self::Handler()->flush(); 61 | } 62 | 63 | /** 64 | * 获取处理方式 65 | * @param [type] $name [description] 66 | * @return $_handler 67 | * @author NewFuture 68 | */ 69 | protected static function Handler() 70 | { 71 | if (null === self::$_handler) 72 | { 73 | switch (Config::get('cache.type')) 74 | { 75 | case 'sae': //sae_memcache 76 | self::$_handler = memcache_init(); 77 | break; 78 | 79 | case 'file': //文件缓存 80 | self::$_handler = new Storage\File(Config::get('tempdir') . 'cache', true); 81 | break; 82 | 83 | default: 84 | throw new Exception('未知缓存方式' . Config::get('cahce.type')); 85 | } 86 | } 87 | return self::$_handler; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /library/Config.php: -------------------------------------------------------------------------------- 1 | get($key)) 21 | { 22 | return is_object($value) ? $value->toArray() : $value; 23 | } 24 | else 25 | { 26 | return $default; 27 | } 28 | } 29 | 30 | /** 31 | * 获取私密配置 32 | * @method secret 33 | * @param [string] $name [配置名] 34 | * @param [string] $key [键值] 35 | * @return [midex] [description] 36 | * @author NewFuture 37 | * @example 38 | * Config::getSecrect('encrypt') 获取取私密配置中的encrypt所有配置 39 | * Config::getSecrect('encrypt','key') 获取取私密配置中的encrypt配置的secret值 40 | */ 41 | public static function getSecret($name = '', $key = null) 42 | { 43 | if ($path = self::getConfig()->get('secret_config_path')) 44 | { 45 | $secretConfig = new Yaf_Config_Ini($path, $name); 46 | return $key ? $secretConfig->get($key) : $secretConfig->toArray(); 47 | } 48 | } 49 | 50 | /*获取配置*/ 51 | private static function getConfig() 52 | { 53 | if (null === self::$_config) 54 | { 55 | self::$_config = $GLOBALS['app']->getConfig(); 56 | } 57 | return self::$_config; 58 | } 59 | } -------------------------------------------------------------------------------- /library/Cookie.php: -------------------------------------------------------------------------------- 1 | $val) 79 | { 80 | self::del($key); 81 | } 82 | } 83 | 84 | } 85 | 86 | /** 87 | * Cookie数据加密编码 88 | * @method encode 89 | * @param [type] $data [description] 90 | * @return [type] [description] 91 | * @author NewFuture 92 | */ 93 | private static function encode($data) 94 | { 95 | return Encrypt::aesEncode(json_encode($data), self::config('key'), true); 96 | } 97 | 98 | /** 99 | * Cookie数据解密 100 | * @method encode 101 | * @param [type] $data [description] 102 | * @return [type] [description] 103 | * @author NewFuture 104 | */ 105 | private static function decode($data) 106 | { 107 | if ($data = Encrypt::aesDecode($data, self::config('key'), true)) 108 | { 109 | return @json_decode($data); 110 | } 111 | } 112 | 113 | /** 114 | * 获取cookie配置 115 | * @method config 116 | * @param [string] $name [配置变量名] 117 | * @return [mixed] [description] 118 | * @author NewFuture 119 | */ 120 | private static function config($name) 121 | { 122 | if (!$config = self::$_config) 123 | { 124 | $config = Config::get('cookie'); 125 | 126 | $config['key'] = self::key(); 127 | self::$_config = $config; 128 | } 129 | return isset($config[$name]) ? $config[$name] : null; 130 | } 131 | 132 | /** 133 | * 获取加密密钥 134 | * @method key 135 | * @return [type] [description] 136 | * @author NewFuture 137 | */ 138 | public static function key() 139 | { 140 | if (!$key = Kv::get('COOKIE_aes_key')) 141 | { 142 | /*重新生成加密密钥*/ 143 | $key = Random::word(32); 144 | Kv::set('COOKIE_aes_key', $key); 145 | } 146 | return $key; 147 | } 148 | } -------------------------------------------------------------------------------- /library/File.php: -------------------------------------------------------------------------------- 1 | mb_substr($name, 0, $end), 169 | 'ext' => substr($ext, 1), 170 | ); 171 | } 172 | } -------------------------------------------------------------------------------- /library/Input.php: -------------------------------------------------------------------------------- 1 | set($name, $value); 26 | } 27 | 28 | /** 29 | * 读取缓存数据 30 | * @method get 31 | * @param [string] $name [缓存名称] 32 | * @return [mixed] [获取值] 33 | * @author NewFuture 34 | */ 35 | public static function get($name) 36 | { 37 | return self::Handler()->get($name); 38 | } 39 | 40 | /** 41 | * 删除缓存数据 42 | * @method del 43 | * @param [string] $name [缓存名称] 44 | * @return [bool] 45 | * @author NewFuture 46 | */ 47 | public static function del($name) 48 | { 49 | return self::Handler()->delete($name); 50 | } 51 | 52 | /** 53 | * 清空存储 54 | * @method fush 55 | * @author NewFuture 56 | */ 57 | public static function flush() 58 | { 59 | if (Config::get('kv.type') == 'sae') 60 | { 61 | /*sae kvdb 逐个删除*/ 62 | $kv = self::Handler(); 63 | while ($ret = $kv->pkrget('', 100)) 64 | { 65 | foreach ($ret as $k => $v) 66 | { 67 | $kv->delete(key($k)); 68 | } 69 | } 70 | } 71 | else 72 | { 73 | return self::Handler()->flush(); 74 | } 75 | 76 | } 77 | 78 | /** 79 | * 获取处理方式 80 | * @return $_handler 81 | * @author NewFuture 82 | */ 83 | protected static function Handler() 84 | { 85 | if (null === self::$_handler) 86 | { 87 | switch (Config::get('kv.type')) 88 | { 89 | case 'sae': //sae_memcache 90 | self::$_handler = memcache_init(); 91 | break; 92 | case 'file': //文件缓存 93 | self::$_handler = new Storage\File(Config::get('tempdir') . 'kv', false); 94 | break; 95 | 96 | default: 97 | throw new Exception('未定义方式' . Config::get('kv.type')); 98 | } 99 | } 100 | return self::$_handler; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /library/Log.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /library/Mail.php: -------------------------------------------------------------------------------- 1 | _config['verify']; 30 | $to = ['email' => $email, 'name' => $name ?: $email]; 31 | $url = $instance->_config['verify']['baseuri'] . $code; 32 | 33 | $msg['title'] = '云印验证邮件'; 34 | $msg['body'] = $instance->getView() 35 | ->assign('name', $name) 36 | ->assign('url', $url) 37 | ->assign('code', substr($code, -6)) 38 | ->assign('email', $email) 39 | ->render('verify.tpl'); 40 | return $instance->send($from, $to, $msg); 41 | } 42 | 43 | /** 44 | * 发送验证邮件 45 | * @method sendVerify 46 | * @param [string] $email [邮箱] 47 | * @param [string] $name [姓名] 48 | * @param [string] $link [验证链接] 49 | * @return [type] [发送结果] 50 | * @author NewFuture 51 | */ 52 | public static function findPwd($email, $code, $name = '云印南天用户') 53 | { 54 | $instance = self::getInstance(); 55 | $from = $instance->_config['verify']; 56 | $to = ['email' => $email, 'name' => $name ?: $email]; 57 | $msg['title'] = '云印验证邮件'; 58 | $msg['body'] = $instance->getView() 59 | ->assign('name', $name) 60 | ->assign('code', $code) 61 | ->render('pwd.tpl'); 62 | return $instance->send($from, $to, $msg); 63 | } 64 | 65 | /** 66 | * 发送通知邮件 67 | * @method sendNotify 68 | * @param [type] $email [邮箱] 69 | * @param [type] $name [姓名] 70 | * @param [type] $body [内容] 71 | * @return [bool] [发送状态] 72 | * @author NewFuture 73 | */ 74 | public static function sendNotify($email, $name, $body) 75 | { 76 | $instance = self::getInstance(); 77 | 78 | $from = $instance->_config['notify']; 79 | $to = ['email' => $email]; 80 | $to['name'] = $name ?: $email; 81 | $msg['title'] = '云印通知邮件'; 82 | $msg['body'] = $body; //TODO 渲染模板 83 | return $instance->send($from, $to, $msg); 84 | } 85 | 86 | /** 87 | * 发送邮件 88 | * @method send 89 | * @param [string] $from [发送方邮箱] 90 | * @param [string] $to [接收方邮箱] 91 | * @param [array] $msg [发送信息] 92 | * @return [bool] [发送结果] 93 | * @author NewFuture 94 | */ 95 | public function send($from, $to, $msg) 96 | { 97 | $Message = new Message(); 98 | $Message->setFrom($from['name'], $from['email']) 99 | ->addTo($to['name'], $to['email']) 100 | ->setSubject($msg['title']) 101 | ->setBody($msg['body']); 102 | return $this->_smtp 103 | ->setAuth($from['email'], $from['pwd']) 104 | ->send($Message); 105 | } 106 | 107 | public static function getInstance() 108 | { 109 | return self::$_instance ?: (self::$_instance = new self()); 110 | } 111 | 112 | //获取模板引擎 113 | private function getView() 114 | { 115 | return $this->_view ?: ($this->_view = new Yaf_View_Simple(self::TPL_DIR)); 116 | } 117 | 118 | private function __construct() 119 | { 120 | $this->_config = Config::getSecret('mail'); 121 | $this->_smtp = new Smtp(); 122 | $server = $this->_config['server']; 123 | $this->_smtp->setServer($server['smtp'], $server['port'], $server['secure']); 124 | } 125 | } -------------------------------------------------------------------------------- /library/Parse/Filter.php: -------------------------------------------------------------------------------- 1 | &/\\%|{} ,; ,;、') === false) ? $str : false; 30 | } 31 | } -------------------------------------------------------------------------------- /library/Parse/Xml.php: -------------------------------------------------------------------------------- 1 | '; 15 | $xml .= ''; 16 | $xml .= self::data_to_xml($data); 17 | $xml .= ''; 18 | return $xml; 19 | } 20 | 21 | /** 22 | * 数据XML编码 23 | * @param mixed $data 数据 24 | * @param string $item 数字索引时的节点名称 25 | * @param string $id 数字索引key转换为的属性名 26 | * @return string 27 | */ 28 | private static function data_to_xml($data, $item = 'item', $id = 'id') 29 | { 30 | $xml = $attr = ''; 31 | foreach ($data as $key => $val) 32 | { 33 | if (is_numeric($key)) 34 | { 35 | $id && $attr = " {$id}=\"{$key}\""; 36 | $key = $item; 37 | } 38 | $xml .= "<{$key}{$attr}>"; 39 | $xml .= (is_array($val) || is_object($val)) ? self::data_to_xml($val, $item, $id) : $val; 40 | $xml .= ""; 41 | } 42 | return $xml; 43 | } 44 | } -------------------------------------------------------------------------------- /library/PhpConsole/Auth.php: -------------------------------------------------------------------------------- 1 | publicKeyByIp = $publicKeyByIp; 28 | $this->passwordHash = $this->getPasswordHash($password); 29 | } 30 | 31 | protected final function hash($string) { 32 | return hash('sha256', $string); 33 | } 34 | 35 | /** 36 | * Get password hash like on client 37 | * @param $password 38 | * @return string 39 | */ 40 | protected final function getPasswordHash($password) { 41 | return $this->hash($password . self::PASSWORD_HASH_SALT); 42 | } 43 | 44 | /** 45 | * Get authorization result data for client 46 | * @param ClientAuth|null $clientAuth 47 | * @return ServerAuthStatus 48 | */ 49 | public final function getServerAuthStatus(ClientAuth $clientAuth = null) { 50 | $serverAuthStatus = new ServerAuthStatus(); 51 | $serverAuthStatus->publicKey = $this->getPublicKey(); 52 | $serverAuthStatus->isSuccess = $clientAuth && $this->isValidAuth($clientAuth); 53 | return $serverAuthStatus; 54 | } 55 | 56 | /** 57 | * Check if client authorization data is valid 58 | * @param ClientAuth $clientAuth 59 | * @return bool 60 | */ 61 | public final function isValidAuth(ClientAuth $clientAuth) { 62 | return $clientAuth->publicKey === $this->getPublicKey() && $clientAuth->token === $this->getToken(); 63 | } 64 | 65 | /** 66 | * Get client unique identification 67 | * @return string 68 | */ 69 | protected function getClientUid() { 70 | $clientUid = ''; 71 | if($this->publicKeyByIp) { 72 | if(isset($_SERVER['REMOTE_ADDR'])) { 73 | $clientUid .= $_SERVER['REMOTE_ADDR']; 74 | } 75 | if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 76 | $clientUid .= $_SERVER['HTTP_X_FORWARDED_FOR']; 77 | } 78 | } 79 | return $clientUid; 80 | } 81 | 82 | /** 83 | * Get authorization session public key for current client 84 | * @return string 85 | */ 86 | protected function getPublicKey() { 87 | return $this->hash($this->getClientUid() . $this->passwordHash); 88 | } 89 | 90 | /** 91 | * Get string signature for current password & public key 92 | * @param $string 93 | * @return string 94 | */ 95 | public final function getSignature($string) { 96 | return $this->hash($this->passwordHash . $this->getPublicKey() . $string); 97 | } 98 | 99 | /** 100 | * Get expected valid client authorization token 101 | * @return string 102 | */ 103 | private final function getToken() { 104 | return $this->hash($this->passwordHash . $this->getPublicKey()); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /library/PhpConsole/Dispatcher.php: -------------------------------------------------------------------------------- 1 | connector = $connector; 28 | $this->setDumper($dumper); 29 | } 30 | 31 | /** 32 | * Override default dumper 33 | * @param Dumper $dumper 34 | */ 35 | public function setDumper(Dumper $dumper) { 36 | $this->dumper = $dumper; 37 | } 38 | 39 | /** 40 | * Check if dispatcher is active to send messages 41 | * @return bool 42 | */ 43 | public function isActive() { 44 | return $this->connector->isActiveClient(); 45 | } 46 | 47 | /** 48 | * Send message to PHP Console connector 49 | * @param Message $message 50 | */ 51 | protected function sendMessage(Message $message) { 52 | $this->connector->sendMessage($message); 53 | } 54 | 55 | /** 56 | * Convert backtrace to array of TraceCall with source file & line detection 57 | * @param array $trace Standard PHP backtrace array 58 | * @param null|string $file Reference to var that will contain source file path 59 | * @param null|string $line Reference to var that will contain source line number 60 | * @param int|array $ignoreTraceCalls Ignore tracing classes by name prefix `array('PhpConsole')` or fixed number of calls to ignore 61 | * @return TraceCall[] 62 | */ 63 | protected function fetchTrace(array $trace, &$file = null, &$line = null, $ignoreTraceCalls = 0) { 64 | $ignoreByNumber = is_numeric($ignoreTraceCalls) ? $ignoreTraceCalls : 0; 65 | $ignoreByClassPrefixes = is_array($ignoreTraceCalls) ? array_merge($ignoreTraceCalls, array(__NAMESPACE__)) : null; 66 | 67 | foreach($trace as $i => $call) { 68 | if(!$file && $i == $ignoreTraceCalls && isset($call['file'])) { 69 | $file = $call['file']; 70 | $line = $call['line']; 71 | } 72 | if($ignoreByClassPrefixes && isset($call['class'])) { 73 | foreach($ignoreByClassPrefixes as $classPrefix) { 74 | if(strpos($call['class'], $classPrefix) !== false) { 75 | unset($trace[$i]); 76 | continue; 77 | } 78 | } 79 | } 80 | if($i < $ignoreByNumber || (isset($call['file']) && $call['file'] == $file && $call['line'] == $line)) { 81 | unset($trace[$i]); 82 | } 83 | } 84 | 85 | $traceCalls = array(); 86 | foreach(array_reverse($trace) as $call) { 87 | $args = array(); 88 | if(isset($call['args'])) { 89 | foreach($call['args'] as $arg) { 90 | if(is_object($arg)) { 91 | $args[] = get_class($arg); 92 | } 93 | elseif(is_array($arg)) { 94 | $args[] = 'Array[' . count($arg) . ']'; 95 | } 96 | else { 97 | $arg = var_export($arg, 1); 98 | $args[] = strlen($arg) > 15 ? substr($arg, 0, 15) . '...\'' : $arg; 99 | } 100 | } 101 | } 102 | 103 | $traceCall = new TraceCall(); 104 | $traceCall->call = (isset($call['class']) ? $call['class'] . $call['type'] : '') . $call['function'] . '(' . implode(', ', $args) . ')'; 105 | if(isset($call['file'])) { 106 | $traceCall->file = $call['file']; 107 | } 108 | if(isset($call['line'])) { 109 | $traceCall->line = $call['line']; 110 | } 111 | $traceCalls[] = $traceCall; 112 | } 113 | return $traceCalls; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /library/PhpConsole/Dispatcher/Debug.php: -------------------------------------------------------------------------------- 1 | isActive()) { 28 | $message = new \PhpConsole\DebugMessage(); 29 | $message->data = $this->dumper->dump($data); 30 | if($tags) { 31 | $message->tags = explode('.', $tags); 32 | } 33 | if($this->detectTraceAndSource && $ignoreTraceCalls !== null) { 34 | $message->trace = $this->fetchTrace(debug_backtrace(), $message->file, $message->line, $ignoreTraceCalls); 35 | } 36 | $this->sendMessage($message); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /library/PhpConsole/Dispatcher/Errors.php: -------------------------------------------------------------------------------- 1 | names(will be initialized in first call) */ 18 | protected static $errorsConstantsValues = array(); 19 | /** @var array PHP errors constants names */ 20 | protected static $errorsConstantsNames = array( 21 | 'E_STRICT', 22 | 'E_DEPRECATED', 23 | 'E_RECOVERABLE_ERROR', 24 | 'E_NOTICE', 25 | 'E_WARNING', 26 | 'E_ERROR', 27 | 'E_PARSE', 28 | 'E_USER_DEPRECATED', 29 | 'E_USER_NOTICE', 30 | 'E_USER_WARNING', 31 | 'E_USER_ERROR', 32 | 'E_CORE_WARNING', 33 | 'E_CORE_ERROR', 34 | 'E_COMPILE_ERROR', 35 | 'E_COMPILE_WARNING', 36 | ); 37 | 38 | /** @var bool Don't send errors messages with same file, line & class */ 39 | public $ignoreRepeatedSource = true; 40 | /** @var bool Dispatch $exception->getPrevious() if not empty */ 41 | public $dispatchPreviousExceptions = true; 42 | 43 | /** @var \PhpConsole\ErrorMessage[] */ 44 | protected $sentMessages = array(); 45 | 46 | /** 47 | * Send error message to client 48 | * @param null|integer $code 49 | * @param null|string $text 50 | * @param null|string $file 51 | * @param null|integer $line 52 | * @param int|array $ignoreTraceCalls Ignore tracing classes by name prefix `array('PhpConsole')` or fixed number of calls to ignore 53 | */ 54 | public function dispatchError($code = null, $text = null, $file = null, $line = null, $ignoreTraceCalls = 0) { 55 | if($this->isActive()) { 56 | $message = new \PhpConsole\ErrorMessage(); 57 | $message->code = $code; 58 | $message->class = $this->getErrorTypeByCode($code); 59 | $message->data = $this->dumper->dump($text); 60 | $message->file = $file; 61 | $message->line = $line; 62 | if($ignoreTraceCalls !== null) { 63 | $message->trace = $this->fetchTrace(debug_backtrace(), $file, $line, is_array($ignoreTraceCalls) ? $ignoreTraceCalls : $ignoreTraceCalls + 1); 64 | } 65 | $this->sendMessage($message); 66 | } 67 | } 68 | 69 | /** 70 | * Send exception message to client 71 | * @param \Exception $exception 72 | */ 73 | public function dispatchException(\Exception $exception) { 74 | if($this->isActive()) { 75 | if($this->dispatchPreviousExceptions && $exception->getPrevious()) { 76 | $this->dispatchException($exception->getPrevious()); 77 | } 78 | $message = new \PhpConsole\ErrorMessage(); 79 | $message->code = $exception->getCode(); 80 | $message->class = get_class($exception); 81 | $message->data = $this->dumper->dump($exception->getMessage()); 82 | $message->file = $exception->getFile(); 83 | $message->line = $exception->getLine(); 84 | $message->trace = self::fetchTrace($exception->getTrace(), $message->file, $message->line); 85 | $this->sendMessage($message); 86 | } 87 | } 88 | 89 | /** 90 | * Send message to PHP Console connector 91 | * @param \PhpConsole\Message $message 92 | */ 93 | protected function sendMessage(\PhpConsole\Message $message) { 94 | if(!$this->isIgnored($message)) { 95 | parent::sendMessage($message); 96 | $this->sentMessages[] = $message; 97 | } 98 | } 99 | 100 | /** 101 | * Get PHP error constant name by value 102 | * @param int $code 103 | * @return string 104 | */ 105 | protected function getErrorTypeByCode($code) { 106 | if(!static::$errorsConstantsValues) { 107 | foreach(static::$errorsConstantsNames as $constantName) { 108 | if(defined($constantName)) { 109 | static::$errorsConstantsValues[constant($constantName)] = $constantName; 110 | } 111 | } 112 | } 113 | if(isset(static::$errorsConstantsValues[$code])) { 114 | return static::$errorsConstantsValues[$code]; 115 | } 116 | return (string)$code; 117 | } 118 | 119 | /** 120 | * Return true if message with same file, line & class was already sent 121 | * @param \PhpConsole\ErrorMessage $message 122 | * @return bool 123 | */ 124 | protected function isIgnored(\PhpConsole\ErrorMessage $message) { 125 | if($this->ignoreRepeatedSource && $message->file) { 126 | foreach($this->sentMessages as $sentMessage) { 127 | if($message->file == $sentMessage->file && $message->line == $sentMessage->line && $message->class == $sentMessage->class) { 128 | return true; 129 | } 130 | } 131 | } 132 | return false; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /library/PhpConsole/Dispatcher/Evaluate.php: -------------------------------------------------------------------------------- 1 | evalProvider = $evalProvider; 27 | parent::__construct($connector, $dumper); 28 | } 29 | 30 | /** 31 | * Override eval provider 32 | * @param \PhpConsole\EvalProvider $evalProvider 33 | */ 34 | public function setEvalProvider(\PhpConsole\EvalProvider $evalProvider) { 35 | $this->evalProvider = $evalProvider; 36 | } 37 | 38 | /** 39 | * Get eval provider 40 | * @return \PhpConsole\EvalProvider 41 | */ 42 | public function getEvalProvider() { 43 | return $this->evalProvider; 44 | } 45 | 46 | /** 47 | * Execute PHP code and send result message in connector 48 | * @param $code 49 | */ 50 | public function dispatchCode($code) { 51 | if($this->isActive()) { 52 | $previousLastError = error_get_last(); 53 | $oldDisplayErrors = ini_set('display_errors', false); 54 | $result = $this->evalProvider->evaluate($code); 55 | ini_set('display_errors', $oldDisplayErrors); 56 | 57 | $message = new \PhpConsole\EvalResultMessage(); 58 | $message->return = $this->dumper->dump($result->return); 59 | $message->output = $this->dumper->dump($result->output); 60 | $message->time = round($result->time, 6); 61 | 62 | $newLastError = error_get_last(); 63 | if($newLastError && $newLastError != $previousLastError) { 64 | $this->connector->getErrorsDispatcher()->dispatchError($newLastError ['type'], $newLastError ['message'], $newLastError ['file'], $newLastError ['line'], 999); 65 | } 66 | if($result->exception) { 67 | $this->connector->getErrorsDispatcher()->dispatchException($result->exception); 68 | } 69 | $this->sendMessage($message); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /library/PhpConsole/Dumper.php: -------------------------------------------------------------------------------- 1 | levelLimit = $levelLimit; 36 | $this->itemsCountLimit = $itemsCountLimit; 37 | $this->itemSizeLimit = $itemSizeLimit; 38 | $this->dumpSizeLimit = $dumpSizeLimit; 39 | } 40 | 41 | /** 42 | * Convert any type of var to string or array applying all actual limits & transformations 43 | * @param mixed $var 44 | * @return string|array 45 | */ 46 | public function dump($var) { 47 | $this->dumpVarData($var, $this->levelLimit); 48 | return $var; 49 | } 50 | 51 | /** 52 | * Recursively convert any type of var to string or array applying all actual limits & transformations 53 | * @param $data 54 | * @param $levelLimit 55 | * @param bool $rootCall 56 | */ 57 | protected function dumpVarData(&$data, $levelLimit, $rootCall = true) { 58 | static $sizeLeft, 59 | $objectsHashes = array(), 60 | $origQueue = array(), 61 | $refQueue = array(), 62 | $levelsQueue = array(); 63 | 64 | if($rootCall) { 65 | $sizeLeft = $this->dumpSizeLimit ? : 999999999; 66 | } 67 | 68 | if(is_object($data)) { 69 | if($data instanceof \Closure) { 70 | $data = '(callback function)'; 71 | return; 72 | } 73 | if($rootCall) { 74 | $data = array('' => $data); 75 | return $this->dumpVarData($data, $levelLimit + 1); 76 | } 77 | $objectsHashes[] = spl_object_hash($data); 78 | $dataArray = array(); 79 | foreach((array)$data as $key => $value) { 80 | $nullPos = strrpos($key, chr(0)); 81 | if($nullPos) { 82 | $dataArray[substr($key, $nullPos + 1)] = $value; 83 | } 84 | else { 85 | $dataArray[$key] = $value; 86 | } 87 | } 88 | $data = $dataArray; 89 | } 90 | 91 | if(is_array($data)) { 92 | 93 | if($this->detectCallbacks && count($data) == 2 && is_callable($data)) { 94 | list($class, $method) = $data; 95 | $data = '(callback ' . (is_object($class) ? get_class($class) : $class) . '::' . $method . ')'; 96 | $sizeLeft -= strlen($data) + 4; 97 | return; 98 | } 99 | 100 | $i = 0; 101 | $dataArray = array(); 102 | foreach($data as $k => &$v) { 103 | if(($this->itemsCountLimit && $i >= $this->itemsCountLimit) || $sizeLeft <= 0) { 104 | break; 105 | } 106 | if(is_array($v) || is_object($v)) { 107 | if($levelLimit > 1) { 108 | $origQueue[] = $v; 109 | $refQueue[] =& $v; 110 | $levelsQueue[] = $levelLimit; 111 | } 112 | if(is_object($v) && !$v instanceof \Closure) { 113 | $k .= ':' . get_class($v); 114 | $hash = spl_object_hash($v); 115 | if(in_array($hash, $objectsHashes)) { 116 | $v = '*RECURSION*'; 117 | } 118 | else { 119 | $v = '(object)'; 120 | $objectsHashes[] = $hash; 121 | } 122 | } 123 | else { 124 | $v = '(array)'; 125 | } 126 | $sizeLeft -= strlen($k) + strlen($v) + 8; 127 | } 128 | else { 129 | $sizeLeft -= strlen($k) + 4; 130 | $this->dumpVarData($v, $levelLimit - 1, false); 131 | } 132 | $dataArray[$k] =& $v; 133 | $i++; 134 | } 135 | 136 | if($i != count($data)) { 137 | $dataArray['...'] = '(displayed ' . $i . ' of ' . count($data) . ')'; 138 | } 139 | $data = $dataArray; 140 | 141 | if(!$rootCall) { 142 | return; 143 | } 144 | 145 | do { 146 | $origData = array_shift($origQueue); 147 | $level = array_shift($levelsQueue); 148 | $refData =& $refQueue[0]; 149 | array_shift($refQueue); 150 | $sizeLeft += strlen($refData); 151 | if($refData !== '*RECURSION*') { 152 | $this->dumpVarData($origData, $level - 1, false); 153 | $refData = $origData; 154 | } 155 | } 156 | while(count($origQueue) && $sizeLeft >= 0); 157 | 158 | if($rootCall) { 159 | $levelsQueue = $origQueue = $refQueue = $objectsHashes = array(); 160 | } 161 | } 162 | // scalar or resource 163 | else { 164 | if(!is_scalar($data) && $data !== null) { 165 | if(is_resource($data)) { 166 | $data = '(' . strtolower((string)$data) . ' ' . get_resource_type($data) . ')'; 167 | $sizeLeft -= strlen($data); 168 | return; 169 | } 170 | $data = var_export($data, true); 171 | } 172 | if(strlen($data) > $this->itemSizeLimit) { 173 | $data = substr($data, 0, $this->itemSizeLimit - 3) . '...'; 174 | } 175 | if(strlen($data) > $sizeLeft) { 176 | $data = substr($data, 0, $sizeLeft - 3) . '...'; 177 | } 178 | $sizeLeft -= strlen($data); 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /library/PhpConsole/Helper.php: -------------------------------------------------------------------------------- 1 | debug($var, 'db') 13 | * 14 | * @package PhpConsole 15 | * @version 3.1 16 | * @link http://php-console.com 17 | * @author Sergey Barbushin http://linkedin.com/in/barbushin 18 | * @copyright © Sergey Barbushin, 2011-2013. All rights reserved. 19 | * @license http://www.opensource.org/licenses/BSD-3-Clause "The BSD 3-Clause License" 20 | */ 21 | class Helper { 22 | 23 | /** @var Connector|null */ 24 | private static $connector; 25 | /** @var Handler|null */ 26 | private static $handler; 27 | /** @var bool */ 28 | protected static $isActive; 29 | 30 | private function __construct() { 31 | } 32 | 33 | /** 34 | * This method must be called to make class "PC" available 35 | * @param Connector|null $connector 36 | * @param Handler|null $handler 37 | * @throws \Exception 38 | * @return Connector 39 | */ 40 | public static function register(Connector $connector = null, Handler $handler = null) { 41 | if(static::$connector) { 42 | throw new \Exception('Helper already registered'); 43 | } 44 | self::$handler = $handler; 45 | self::$connector = $connector ? : Connector::getInstance(); 46 | self::$isActive = self::$connector->isActiveClient(); 47 | return self::$connector; 48 | } 49 | 50 | /** 51 | * Check if method Helper::register() was called before 52 | * @return bool 53 | */ 54 | public static function isRegistered() { 55 | return isset(self::$connector); 56 | } 57 | 58 | /** 59 | * Get actual helper connector instance 60 | * @return Connector 61 | * @throws \Exception 62 | */ 63 | public static function getConnector() { 64 | if(!self::$connector) { 65 | throw new \Exception('Helper is not registered. Call ' . get_called_class() . '::register()'); 66 | } 67 | return self::$connector; 68 | } 69 | 70 | /** 71 | * Get actual handler instance 72 | * @return Handler 73 | * @throws \Exception 74 | */ 75 | public static function getHandler() { 76 | if(!self::$connector) { 77 | throw new \Exception('Helper is not registered. Call ' . get_called_class() . '::register()'); 78 | } 79 | if(!self::$handler) { 80 | self::$handler = Handler::getInstance(); 81 | } 82 | return self::$handler; 83 | } 84 | 85 | /** 86 | * Analog of Handler::getInstance()->debug(...) method 87 | * @param mixed $data 88 | * @param string|null $tags Tags separated by dot, e.g. "low.db.billing" 89 | * @param int|array $ignoreTraceCalls Ignore tracing classes by name prefix `array('PhpConsole')` or fixed number of calls to ignore 90 | */ 91 | public static function debug($data, $tags = null, $ignoreTraceCalls = 0) { 92 | if(self::$isActive) { 93 | self::$connector->getDebugDispatcher()->dispatchDebug($data, $tags, is_numeric($ignoreTraceCalls) ? $ignoreTraceCalls + 1 : $ignoreTraceCalls); 94 | } 95 | } 96 | 97 | /** 98 | * Short access to analog of Handler::getInstance()->debug(...) method 99 | * You can access it like PC::tagName($debugData, $additionalTags = null) 100 | * @param string $tags 101 | * @param $args 102 | */ 103 | public static function __callStatic($tags, $args) { 104 | if(isset($args[1])) { 105 | $tags .= '.' . $args[1]; 106 | } 107 | static::debug(isset($args[0]) ? $args[0] : null, $tags, 1); 108 | } 109 | } 110 | } 111 | 112 | namespace { 113 | if(!class_exists('PC', false)) { 114 | /** 115 | * Helper short class name in global namespace 116 | */ 117 | class PC extends \PhpConsole\Helper { 118 | 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /library/PhpConsole/LICENSE: -------------------------------------------------------------------------------- 1 | PHP Console 2 | 3 | Copyright (c) 2011-2013 by Barbushin Sergey . 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following 15 | disclaimer in the documentation and/or other materials provided 16 | with the distribution. 17 | 18 | * The names of the contributors may not be used to endorse or 19 | promote products derived from this software without specific 20 | prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /library/PhpConsole/Storage.php: -------------------------------------------------------------------------------- 1 | keyLifetime = $seconds; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /library/PhpConsole/Storage/AllKeysList.php: -------------------------------------------------------------------------------- 1 | getKeysData(); 36 | if(isset($keysData[$key])) { 37 | $keyData = $keysData[$key]['data']; 38 | unset($keysData[$key]); 39 | $this->saveKeysData($keysData); 40 | return $keyData; 41 | } 42 | } 43 | 44 | /** 45 | * Save postponed data to storage 46 | * @param string $key 47 | * @param string $data 48 | */ 49 | public function push($key, $data) { 50 | $keysData = $this->getKeysData(); 51 | $this->clearExpiredKeys($keysData); 52 | $keysData[$key] = array( 53 | 'time' => time(), 54 | 'data' => $data 55 | ); 56 | $this->saveKeysData($keysData); 57 | } 58 | 59 | /** 60 | * Remove postponed data that is out of limit 61 | * @param array $keysData 62 | */ 63 | protected function clearExpiredKeys(array &$keysData) { 64 | $expireTime = time() - $this->keyLifetime; 65 | foreach($keysData as $key => $item) { 66 | if($item['time'] < $expireTime) { 67 | unset($keysData[$key]); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /library/PhpConsole/Storage/ExpiringKeyValue.php: -------------------------------------------------------------------------------- 1 | get($key); 46 | if($data) { 47 | $this->delete($key); 48 | } 49 | return $data; 50 | } 51 | 52 | /** 53 | * Save postponed data to storage 54 | * @param string $key 55 | * @param string $data 56 | */ 57 | public function push($key, $data) { 58 | $this->set($key, $data, $this->keyLifetime); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /library/PhpConsole/Storage/File.php: -------------------------------------------------------------------------------- 1 | filePath = realpath($filePath); 32 | 33 | if($validatePathNotUnderDocRoot && $this->isPathUnderDocRoot()) { 34 | throw new \Exception('Path ' . $this->filePath . ' is under DOCUMENT_ROOT. It\'s insecure!'); 35 | } 36 | } 37 | 38 | protected function isPathUnderDocRoot() { 39 | return !empty($_SERVER['DOCUMENT_ROOT']) && strpos($this->filePath, $_SERVER['DOCUMENT_ROOT']) === 0; 40 | } 41 | 42 | protected function initFileHandler() { 43 | $this->fileHandler = fopen($this->filePath, 'a+b'); 44 | if(!$this->fileHandler) { 45 | throw new \Exception('Unable to read/write file ' . $this->filePath); 46 | } 47 | while(!flock($this->fileHandler, LOCK_EX | LOCK_NB)) { 48 | usleep(10000); 49 | } 50 | fseek($this->fileHandler, 0); 51 | } 52 | 53 | /** 54 | * @throws \Exception 55 | * @return array 56 | */ 57 | protected function getKeysData() { 58 | return json_decode(fgets($this->fileHandler), true) ? : array(); 59 | } 60 | 61 | /** 62 | * @param array $keysData 63 | */ 64 | protected function saveKeysData(array $keysData) { 65 | ftruncate($this->fileHandler, 0); 66 | fwrite($this->fileHandler, json_encode($keysData, defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : null)); 67 | } 68 | 69 | protected function closeFileHandler() { 70 | if($this->fileHandler) { 71 | flock($this->fileHandler, LOCK_UN); 72 | fclose($this->fileHandler); 73 | $this->fileHandler = null; 74 | } 75 | } 76 | 77 | public function pop($key) { 78 | $this->initFileHandler(); 79 | $result = parent::pop($key); 80 | $this->closeFileHandler(); 81 | return $result; 82 | } 83 | 84 | public function push($key, $data) { 85 | $this->initFileHandler(); 86 | parent::push($key, $data); 87 | $this->closeFileHandler(); 88 | } 89 | 90 | public function __destruct() { 91 | $this->closeFileHandler(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /library/PhpConsole/Storage/Memcache.php: -------------------------------------------------------------------------------- 1 | memcache = new \Memcache(); 22 | if(!$this->memcache->connect($host, $port)) { 23 | throw new \Exception('Unable to connect to Memcache server'); 24 | } 25 | } 26 | 27 | /** 28 | * Save data by auto-expire key 29 | * @param $key 30 | * @param string $data 31 | * @param int $expire 32 | */ 33 | protected function set($key, $data, $expire) { 34 | $this->memcache->set($key, $data, null, $expire); 35 | } 36 | 37 | /** 38 | * Get data by key if not expired 39 | * @param $key 40 | * @return string 41 | */ 42 | protected function get($key) { 43 | return $this->memcache->get($key); 44 | } 45 | 46 | /** 47 | * Remove key in store 48 | * @param $key 49 | * @return mixed 50 | */ 51 | protected function delete($key) { 52 | $this->memcache->delete($key); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /library/PhpConsole/Storage/MongoDB.php: -------------------------------------------------------------------------------- 1 | mongoClient = new \MongoClient($server); 24 | if(!$this->mongoClient) { 25 | throw new \Exception('Unable to connect to MongoDB server'); 26 | } 27 | 28 | $this->mongoCollection = $this->mongoClient->selectCollection($db, $collection); 29 | if(!$this->mongoCollection) { 30 | throw new \Exception('Unable to get collection'); 31 | } 32 | 33 | $this->mongoCollection->ensureIndex(array( 34 | 'expireAt' => 1, 35 | ), array( 36 | 'background' => true, 37 | 'name' => 'TTL', 38 | 'expireAfterSeconds' => 0, 39 | )); 40 | } 41 | 42 | /** 43 | * Save data by auto-expire key 44 | * @param $key 45 | * @param string $data 46 | * @param int $expire 47 | */ 48 | protected function set($key, $data, $expire) { 49 | $this->mongoCollection->update(array( 50 | 'key' => $key 51 | ), array( 52 | 'key' => $key, 53 | 'data' => $data, 54 | 'expireAt' => new \MongoDate(time() + $expire) 55 | ), array( 56 | 'upsert' => true 57 | )); 58 | } 59 | 60 | /** 61 | * Get data by key if not expired 62 | * @param $key 63 | * @return string 64 | */ 65 | protected function get($key) { 66 | $record = $this->mongoCollection->findOne(array('key' => $key)); 67 | if($record && is_array($record) && array_key_exists('data', $record)) { 68 | return $record['data']; 69 | } 70 | } 71 | 72 | /** 73 | * Remove key in store 74 | * @param $key 75 | * @return mixed 76 | */ 77 | protected function delete($key) { 78 | return $this->mongoCollection->remove(array('key' => $key)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /library/PhpConsole/Storage/Session.php: -------------------------------------------------------------------------------- 1 | sessionKey = $sessionKey; 29 | } 30 | 31 | protected function getKeysData() { 32 | return isset($_SESSION[$this->sessionKey]) ? $_SESSION[$this->sessionKey] : array(); 33 | } 34 | 35 | protected function saveKeysData(array $keysData) { 36 | $_SESSION[$this->sessionKey] = $keysData; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /library/PhpConsole/__autoload.php: -------------------------------------------------------------------------------- 1 | find(123);#查找id为123的用户 131 | $User->set('time',time())->save();#保存 132 | $User->Insert(['name'=>'test']);新建用户 133 | 134 | $Book = new Model('book'); #创建book 135 | $Book->where('amount','>',10) #选择amount>10 136 | ->order('amount','DESC') #amount倒序 137 | ->select('id AS NO,name,amount'); #选出id作为NO,name和account 138 | $Book->where('amount',0)->delete(); #删除 139 | ``` 140 | 141 | Random 142 | ------- 143 | 快速随机数生成器 144 | ```php 145 | Random::n($n = 4) #生成随机number[0-9] 146 | Random::w($n = 8) #随机word[0-9|a-Z] 147 | Random::c($n=10) #生成随机char[a-Z] 148 | Random::code($n=6) #随机验证码验证码,去除0,1等不易辨识字符 149 | ``` 150 | 151 | Rest 152 | ------- 153 | REST控制器核心基类 154 | 155 | * 自动把GET,POST,PUT,DELETE 映射到 对应的Action 如get detail 映射到GET_detailAction() 156 | * 自动绑定参数id 157 | * 自动输出xml或者json格式数据 158 | 159 | `private $response_type='json'` 数据格式json和xml 160 | `protected $response `响应的数据 161 | `protected response(status,info)`快速设置响应方法 162 | 163 | Rsa 164 | ------- 165 | Rsa 非对称加密库 166 | ``` 167 | Rsa::pubKey() #获取公钥 168 | Rsa::encode($s) #加密 169 | Rsa::decode($s) #解密 170 | ``` 171 | 172 | 173 | Session 174 | -------- 175 | Session操作管理 176 | 支持数组 177 | ```php 178 | Session::set($name, $data) #设置 179 | Session::get($name) #读取 180 | Session::del($name) #删除 181 | Session::flush() #清空 182 | ``` -------------------------------------------------------------------------------- /library/Random.php: -------------------------------------------------------------------------------- 1 | = 2) 16 | { 17 | return str_pad(mt_rand(1, pow(10, $n)), '0', STR_PAD_LEFT); 18 | } 19 | else 20 | { 21 | $str = str_repeat('1234567890', $n / 2); 22 | return substr(str_shuffle($str), 0, $n); 23 | } 24 | } 25 | 26 | /*数字和字母组合的随机字符串*/ 27 | public static function word($n = 8) 28 | { 29 | return $n < 1 ? '' : substr(str_shuffle(str_repeat('abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', ($n + 3) / 4)), 0, $n); 30 | } 31 | 32 | /*只有字符*/ 33 | public static function char($n = 10) 34 | { 35 | return $n < 1 ? '' : substr(str_shuffle(str_repeat('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ($n + 3) / 4)), 0, $n); 36 | } 37 | 38 | /** 39 | * 验证码生成 40 | * 会过滤掉0O1lL等不易辨识字符 41 | * @method code 42 | * @param [integer] $n [description] 43 | * @return string 44 | * @author NewFuture 45 | */ 46 | public static function code($n = 6) 47 | { 48 | return $n < 1 ? '' : substr(str_shuffle(str_repeat('abcdefghijkmnpqrstuvwxyz23456789ABCDEFGHJKMNPQRSTUVWXYZ', 3)), 0, $n); 49 | } 50 | } -------------------------------------------------------------------------------- /library/Rest.php: -------------------------------------------------------------------------------- 1 | disableView(); //立即输出响应,并关闭视图模板引擎 23 | /*请求来源,跨站响应*/ 24 | $from=isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:(isset($_SERVER['HTTP_ORIGIN'])?$_SERVER['HTTP_ORIGIN']:false); 25 | if ($from) 26 | { 27 | /*跨站请求*/ 28 | $from = parse_url($from); 29 | if (isset($from['host']) && substr($from['host'], -11) == '.yunyin.org') 30 | { 31 | $cors = Config::get('cors'); 32 | foreach ($cors as $key => $value) 33 | { 34 | header($key . ':' . $value); 35 | } 36 | /*允许来自cors跨站响应头*/ 37 | header('Access-Control-Allow-Origin:' . $from['scheme'] . '://' . $from['host']); 38 | } 39 | } 40 | 41 | /*请求操作判断*/ 42 | $request = $this->_request; 43 | $method = $request->getMethod(); 44 | if ($method == 'OPTIONS') 45 | { 46 | /*cors应答*/ 47 | exit(); 48 | } 49 | elseif ($method == 'PUT') 50 | { 51 | //put请求写入GOLBAL中和post get一样 52 | parse_str(file_get_contents('php://input'), $GLOBALS['_PUT']); 53 | } 54 | 55 | /*Action路由*/ 56 | $action = $request->getActionName(); 57 | if (is_numeric($action)) 58 | { 59 | /*数字id映射带infoAction*/ 60 | $request->setParam('id', intval($action)); 61 | $path = substr(strstr($_SERVER['PATH_INFO'], $action), strlen($action) + 1); 62 | $action = $path ? strstr($path . '/', '/', true) : 'info'; 63 | } 64 | 65 | $rest_action = $method . '_' . $action; //对应REST_Action 66 | 67 | /*检查该action操作是否存在,存在则修改为REST接口*/ 68 | if (method_exists($this, $rest_action . 'Action')) 69 | { 70 | /*存在对应的操作*/ 71 | $request->setActionName($rest_action); 72 | } 73 | elseif (!method_exists($this, $action . 'Action')) 74 | { 75 | /*action和REST_action 都不存在*/ 76 | $this->response = array( 77 | 'error' => '未定义操作', 78 | 'method' => $method, 79 | 'action' => $action, 80 | 'controller' => $request->getControllerName(), 81 | 'module' => $request->getmoduleName(), 82 | ); 83 | exit; 84 | } 85 | } 86 | 87 | /** 88 | * 验证用户信息 89 | * 验证用户是否登录或者是否为当前用户 90 | * 如果验证失败,立即返回错误信息并终止执行 91 | * @method auth 92 | * @param int $user_id [有则验证是否为当前用户,否则只验证是否登录] 93 | * @return [type] [description] 94 | * @author NewFuture 95 | */ 96 | protected function auth($user_id = false) 97 | { 98 | if (!$uid = Auth::id()) 99 | { 100 | /*验证是否有效*/ 101 | $this->response(self::AUTH_FAIL, '用户信息验证失效,请重新登录!'); 102 | exit(); 103 | } 104 | elseif ($user_id !== false && $user_id != $uid) 105 | { 106 | /*资源所有权验证*/ 107 | $this->response(self::AUTH_BAN, '账号验证失败无权访问!'); 108 | exit(); 109 | } 110 | else 111 | { 112 | return $uid; 113 | } 114 | } 115 | 116 | /** 117 | * 验证打印店登录信息 118 | * 如果验证失败,立即返回错误信息并终止执行 119 | * @method auth 120 | * @param int $pid [有则验证是否为当前用户,否则只验证是否登录] 121 | * @return [type] [description] 122 | * @author NewFuture 123 | */ 124 | protected function authPrinter($pid = false) 125 | { 126 | if (!$id = Auth::priId()) 127 | { 128 | /*验证是否有效*/ 129 | $this->response(self::AUTH_FAIL, '登陆信息验证失效,请重新登录!'); 130 | exit(); 131 | } 132 | elseif ($pid && $pid != $id) 133 | { 134 | /*资源所有权验证*/ 135 | $this->response(self::AUTH_BAN, '账号验证失败或者无权访问!'); 136 | exit(); 137 | } 138 | else 139 | { 140 | return $id; 141 | } 142 | } 143 | 144 | /** 145 | * 设置返回信息 146 | * @method response 147 | * @param [type] $status [请求结果] 148 | * @param string $info [请求信息] 149 | * @return [type] [description] 150 | * @author NewFuture 151 | */ 152 | protected function response($status, $info = '') 153 | { 154 | $this->response = ['status' => $status, 'info' => $info]; 155 | } 156 | 157 | /** 158 | * 结束时自动输出信息 159 | * @method __destruct 160 | * @access private 161 | * @author NewFuture 162 | */ 163 | public function __destruct() 164 | { 165 | if ($this->response !== false) 166 | { 167 | header('Content-type: application/json;charset=utf-8'); 168 | echo (json_encode($this->response, JSON_UNESCAPED_UNICODE)); //unicode不转码 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /library/Rsa.php: -------------------------------------------------------------------------------- 1 | $_SERVER['REQUEST_TIME'] && $key = kv::get('RSA_pub_key')) ? $key : self::init(); 17 | } 18 | 19 | /** 20 | * 解密 21 | * @method decode 22 | * @return string 23 | * @author NewFuture 24 | */ 25 | public static function decode($str) 26 | { 27 | $str = base64_decode($str); 28 | if ($key = Kv::get('RSA_pri_key')) 29 | { 30 | $pri_key = openssl_pkey_get_private($key); 31 | return openssl_private_decrypt($str, $decrypted, $pri_key) ? $decrypted : false; 32 | } 33 | return false; 34 | } 35 | 36 | /** 37 | * 加密 38 | * @method encode 39 | * @param [type] $str [原文] 40 | * @return string 41 | * @author NewFuture 42 | */ 43 | public static function encode($str) 44 | { 45 | $pub = openssl_pkey_get_public(self::pubKey()); 46 | return openssl_public_encrypt($str, $crypttext, $pub) ? base64_encode($crypttext) : false; 47 | } 48 | 49 | /** 50 | * 生成和保存密钥对 51 | * @method init 52 | * @param boolean $return_pri [返回公钥或者私钥] 53 | * @return [string] [公钥或者私钥] 54 | * @author NewFuture 55 | */ 56 | private static function init($return_pri = false) 57 | { 58 | $res = openssl_pkey_new(); 59 | openssl_pkey_export($res, $pri); 60 | $d = openssl_pkey_get_details($res); 61 | $pub = $d['key']; 62 | 63 | $time = time() + Config::get('rsa.lifetime') ?: 604800; 64 | 65 | kv::set('RSA_life_time', $time); 66 | kv::set('RSA_pri_key', $pri); 67 | Kv::set('RSA_pub_key', $pub); 68 | return $return_pri ? $pri : $pub; 69 | } 70 | } -------------------------------------------------------------------------------- /library/Safe.php: -------------------------------------------------------------------------------- 1 | = $timesLimit) 23 | { 24 | $msg = '多次尝试警告:' . $key . 'IP信息:' . self::ip(); 25 | Log::write($msg, 'WARN'); 26 | return false; 27 | } 28 | else 29 | { 30 | Cache::set($name, ++$times, Config::get('try.expire')); 31 | return $times; 32 | // return self::$_key[$key] = $times; 33 | } 34 | } 35 | 36 | public static function del($key) 37 | { 38 | Cache::del('s_t_' . $key); 39 | } 40 | 41 | public static function ip() 42 | { 43 | $request_ip = getenv('REMOTE_ADDR'); 44 | $orign_ip = getenv('HTTP_X_FORWARDED_FOR') ?: getenv('HTTP_CLIENT_IP'); 45 | return $request_ip . '[client:' . $orign_ip . ']'; 46 | } 47 | } -------------------------------------------------------------------------------- /library/School.php: -------------------------------------------------------------------------------- 1 | $school) 54 | { 55 | $list[$i] = call_user_func_array(array('Verify\\' . strtoupper($school), 'getName'), $param); 56 | } 57 | return $list; 58 | } 59 | } 60 | 61 | /** 62 | * 获取验证码 63 | * @method code 64 | * @param [type] $id [学校id] 65 | * @return [type] [description] 66 | * @author NewFuture 67 | */ 68 | public static function code($id) 69 | { 70 | if ($school = self::getAbbr($id)) 71 | { 72 | return call_user_func(array('Verify\\' . strtoupper($school), 'getCode'), []); 73 | } 74 | } 75 | 76 | /** 77 | * 猜测用户学校 78 | * @method guess 79 | * @param [type] $number [description] 80 | * @param array $black_list [排除的黑名单] 81 | * @param array $white_list [过滤范围] 82 | * @return [type] [description] 83 | * @author NewFuture 84 | */ 85 | public static function guess($number, $black_list = array(), $white_list = null) 86 | { 87 | if (!Validate::card($number)) 88 | { 89 | return false; 90 | } 91 | 92 | if (is_array($white_list)) 93 | { 94 | $list = $white_list; 95 | } 96 | else 97 | { 98 | $list = self::_getList(); 99 | } 100 | 101 | if (!empty($black_list)) 102 | { 103 | $list = array_diff($list, $black_list); 104 | } 105 | 106 | if (!$list = self::filtByNumber($number, $list)) 107 | { 108 | return false; 109 | } 110 | $list = self::filtByIP($list); 111 | return $list; 112 | } 113 | 114 | /** 115 | * 获取学校的缩写 116 | * @method getAbbr 117 | * @param [type] $id [description] 118 | * @return [type] [description] 119 | * @author NewFuture 120 | */ 121 | public static function getAbbr($id) 122 | { 123 | $list = self::_getList(); 124 | return isset($list[$id]) ? $list[$id] : false; 125 | } 126 | 127 | /** 128 | * [_getList description] 129 | * @method _getList 130 | * @return [type] [description] 131 | * @access private 132 | * @author NewFuture 133 | */ 134 | private static function _getList() 135 | { 136 | if (!$list = Cache::get('v_school_list')) 137 | { 138 | $schools = SchoolModel::where('id', '>', 0)->select('id,abbr'); 139 | foreach ($schools as $school) 140 | { 141 | $list[$school['id']] = strtolower($school['abbr']); 142 | } 143 | Cache::set('v_school_list', $list, 864000); 144 | } 145 | return $list; 146 | } 147 | 148 | /** 149 | * 根据学号格式过滤 150 | * @method filtByNumber 151 | * @param [type] $number [description] 152 | * @param [type] &$list [description] 153 | * @return [type] [description] 154 | * @author NewFuture 155 | */ 156 | private static function filtByNumber($number, &$list) 157 | { 158 | $regex = Config::get('regex.number'); 159 | foreach ($list as $i => $school) 160 | { 161 | if (!preg_match($regex[$school], $number)) 162 | { 163 | unset($list[$i]); 164 | } 165 | } 166 | return $list; 167 | } 168 | 169 | /** 170 | * 根据IP过滤 171 | * @method filtByIP 172 | * @param [type] &$list [description] 173 | * @return [type] [description] 174 | * @author NewFuture 175 | */ 176 | private static function filtByIP(&$list) 177 | { 178 | return $list; 179 | } 180 | } -------------------------------------------------------------------------------- /library/Service/Api.php: -------------------------------------------------------------------------------- 1 | _config['bucket']; 38 | $op = '/move/' . self::qiniuEncode($from) . '/' . self::qiniuEncode($to); 39 | return self::opration($op); 40 | } 41 | 42 | /** 43 | * 复制文件 44 | * @method copy 45 | * @param [type] $file [description] 46 | * @param [type] $copyName [description] 47 | * @return [type] [description] 48 | * @author NewFuture 49 | */ 50 | public static function copy($from, $saveas) 51 | { 52 | // $bucket = $this->_config['bucket']; 53 | $op = '/copy/' . self::qiniuEncode($from) . '/' . self::qiniuEncode($saveas); 54 | return self::opration($op); 55 | } 56 | 57 | /** 58 | * 获取token 59 | * @method getToken 60 | * @param [type] $uri [description] 61 | * @param integer $timeout [description] 62 | * @return [type] [description] 63 | * @author NewFuture 64 | */ 65 | public static function getToken($bucket, $key, $max = 10485760, $timeout = 600) 66 | { 67 | $setting = array( 68 | 'scope' => $bucket, 69 | 'saveKey' => $key, 70 | 'deadline' => $timeout + $_SERVER['REQUEST_TIME'], 71 | 'fsizeLimit' => intval($max), 72 | ); 73 | $setting = self::qiniuEncode(json_encode($setting)); 74 | return self::sign($setting) . ':' . $setting; 75 | } 76 | 77 | /** 78 | * 删除 79 | * @method delete 80 | * @param string $file [文件名] 81 | * @return bool [description] 82 | * @author NewFuture 83 | */ 84 | public static function delete($uri) 85 | { 86 | $file = self::qiniuEncode($uri); 87 | return self::opration('/delete/' . $file); 88 | } 89 | 90 | /** 91 | * 判断文件是否存在 92 | * @param [type] $bucket [description] 93 | * @param [type] $key [description] 94 | * @return boolean [description] 95 | */ 96 | public static function has($uri) 97 | { 98 | $op = '/stat/' . self::qiniuEncode($uri); 99 | return self::opration($op); 100 | } 101 | 102 | /** 103 | * 转pdf 104 | * @param [type] $file [description] 105 | * @param [type] $saveName [description] 106 | * @return [type] [description] 107 | */ 108 | public static function toPdf($bucket, $key, $saveas) 109 | { 110 | $API = 'http://api.qiniu.com'; 111 | $op = '/pfop/'; 112 | $data = 'bucket=' . $bucket . '&key=' . $key . '&fops=yifangyun_preview|saveas/' . self::qiniuEncode($saveas); 113 | return self::opration($op, $data, $API); 114 | } 115 | 116 | /** 117 | * 七牛操作 118 | * @method opration 119 | * @param string $op [操作命令] 120 | * @return bool [操作结果] 121 | * @author NewFuture 122 | */ 123 | private static function opration($op, $data = null, $host = self::QINIU_RS) 124 | { 125 | $token = self::sign(is_string($data) ? $op . "\n" . $data : $op . "\n"); 126 | $url = $host . $op; 127 | $header = array('Authorization: QBox ' . $token); 128 | 129 | if ($ch = curl_init($url)) 130 | { 131 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 132 | curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 133 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); 134 | if($data) 135 | { 136 | curl_setopt($ch, CURLOPT_POST, true); 137 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 138 | } 139 | curl_setopt($ch, CURLOPT_HEADER, 1); 140 | $response = curl_exec($ch); 141 | $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 142 | curl_close($ch); 143 | 144 | if ($status == 200) 145 | { 146 | return true; 147 | } 148 | elseif (\Config::get('isdebug')) 149 | { 150 | /*操作出错*/ 151 | \PC::debug($response, '七牛请求出错'); 152 | } 153 | } 154 | \Log::write('[QINIU]七牛错误' . $url . ':' . ($response ?: '请求失败'), 'ERROR'); 155 | return false; 156 | } 157 | 158 | /** 159 | * 获取url签名 160 | * @method sign 161 | * @param [type] $url [description] 162 | * @return [type] [description] 163 | * @author NewFuture 164 | */ 165 | private static function sign($url) 166 | { 167 | $config = self::$_config ?: (self::$_config = \Config::getSecret('qiniu')); 168 | $sign = hash_hmac('sha1', $url, $config['secretkey'], true); 169 | $ak = $config['accesskey']; 170 | return $ak . ':' . self::qiniuEncode($sign); 171 | } 172 | 173 | /** 174 | * 七牛安全编码 175 | */ 176 | private static function qiniuEncode($str) 177 | { 178 | return strtr(base64_encode($str), ['+' => '-', '/' => '_']); 179 | } 180 | } -------------------------------------------------------------------------------- /library/Service/README.MD: -------------------------------------------------------------------------------- 1 | # 第三服务API接口 2 | 3 | ### 文件上传 4 | Flie.php 七牛文件管理接口 5 | ```php 6 | Qiniu::set($file,$new_file) #文件重命名 7 | Qiniu::get($name,$param='') #获取下载链接 8 | Qiniu::del($file) #删除文件 9 | Qiniu::getToken($name) #获取上传token 10 | ``` 11 | 12 | ### 数据库 13 | Db.php 数据库PDO封装的对象 14 | 15 | ### 邮件 16 | Smtp.php 邮件链接类 17 | Message.php 邮件消息 18 | -------------------------------------------------------------------------------- /library/Service/Ucpaas.php: -------------------------------------------------------------------------------- 1 | _appid = $appId; 19 | $this->_url = $baseUrl . $softVersion . '/Accounts/' . $accountSid . '/Messages/templateSMS?sig=' . $sig; 20 | $this->auth = trim(base64_encode($accountSid . ':' . $timestamp)); 21 | } 22 | 23 | /** 24 | * 连接服务器回尝试curl 25 | * @param $data post数据 26 | * @return mixed|string 27 | */ 28 | private function _connection($data) 29 | { 30 | 31 | $ch = curl_init($this->_url); 32 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 33 | curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json;charset=utf-8', 'Authorization:' . $this->auth)); 34 | curl_setopt($ch, CURLOPT_POST, true); 35 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 36 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 37 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 38 | $result = curl_exec($ch); 39 | curl_close($ch); 40 | 41 | return $result; 42 | } 43 | 44 | /** 45 | * 发送短信 46 | * @param $phone 到达手机号 47 | * @param $msg 短信参数 48 | * @param $templateId 短信模板ID 49 | */ 50 | public function send($phone, $msg, $templateId) 51 | { 52 | $body_json = array( 53 | 'templateSMS' => array( 54 | 'appId' => $this->_appid, 55 | 'templateId' => $templateId, 56 | 'to' => $phone, 57 | 'param' => $msg)); 58 | $data = json_encode($body_json); 59 | 60 | $result = $this->_connection($data); 61 | $result = json_decode($result); 62 | return isset($result->resp->respCode) ? ($result->resp->respCode == 0) : false; 63 | } 64 | } -------------------------------------------------------------------------------- /library/Session.php: -------------------------------------------------------------------------------- 1 | send($phone, $msg, self::$_template[$tplName]); 75 | } 76 | } -------------------------------------------------------------------------------- /library/Storage/File.php: -------------------------------------------------------------------------------- 1 | _serialized) 28 | { 29 | //序列化写入文件 30 | $expire = func_num_args() == 4 ? (func_get_arg(3) + time()) : 0; 31 | $cache = array('e' => $expire, 'c' => $value); 32 | $value = serialize($cache); 33 | } 34 | 35 | $filename = $this->_dir . $name . '.php'; 36 | return file_put_contents($filename, $value); 37 | } 38 | 39 | /** 40 | * 读取数据 41 | * @method get 42 | * @param [type] $name [description] 43 | * @return [type] [description] 44 | * @author NewFuture 45 | */ 46 | public function get($name) 47 | { 48 | 49 | $filename = $this->_dir . $name . '.php'; 50 | if (is_file($filename)) 51 | { 52 | $content = file_get_contents($filename); 53 | } 54 | else 55 | { 56 | return null; /*不存在返回null*/ 57 | } 58 | 59 | if ($this->_serialized) 60 | { 61 | /*反序列化的文件*/ 62 | $cache = unserialize($content); 63 | return ($cache['e'] && $_SERVER['REQUEST_TIME'] > $cache['e']) ? null : $cache['c']; 64 | } 65 | else 66 | { 67 | return $content; 68 | } 69 | } 70 | 71 | /** 72 | * 删除数据 73 | * @method del 74 | * @param [type] $name [数据名称] 75 | * @return [bool] [description] 76 | * @author NewFuture 77 | */ 78 | public function delete($name) 79 | { 80 | $filename = $this->_dir . $name . '.php'; 81 | return is_file($filename) ? unlink($filename) : false; 82 | } 83 | 84 | /** 85 | * 删除全部缓存数据 86 | * @method flush 87 | * @return [type] [description] 88 | * @author NewFuture 89 | */ 90 | public function flush() 91 | { 92 | $dir = $this->_dir; 93 | /*获取全部文件*/ 94 | $files = scandir($dir); 95 | unset($files[0]); 96 | unset($files[1]); 97 | foreach ($files as $f) 98 | { 99 | @unlink($dir . $f); 100 | } 101 | } 102 | 103 | /** 104 | * @param [type] $dir [存储目录] 105 | * @param [bool] [是否序列化,用于记录缓存] 106 | * @author NewFuture 107 | */ 108 | public function __construct($dir, $serialized = false) 109 | { 110 | $dir .= DIRECTORY_SEPARATOR; 111 | if (self::mkdir($dir)) 112 | { 113 | $this->_dir = $dir; 114 | } 115 | else 116 | { 117 | throw new \Exception('目录无法创建:' . $dir); 118 | } 119 | $this->_serialized = $serialized; 120 | } 121 | 122 | /** 123 | * 循环创建目录 124 | * @method mkdir 125 | * @param [type] $dir [目录名] 126 | * @param integer $mod [创建模式] 127 | * @return [bool] [是否创建成功] 128 | * @author NewFuture 129 | */ 130 | public static function mkdir($dir, $mod = 0755) 131 | { 132 | return is_dir($dir) || (self::mkdir(dirname($dir), $mod) && mkdir($dir, $mod)); 133 | } 134 | } -------------------------------------------------------------------------------- /library/Validate.php: -------------------------------------------------------------------------------- 1 | &#\\%') === false; 95 | } 96 | } -------------------------------------------------------------------------------- /library/Verify/Connect.php: -------------------------------------------------------------------------------- 1 | (opener || parent).handleLoginSuccessed();'; 13 | 14 | public static function getName($number, $pwd) 15 | { 16 | $data = 'Login.Token1=' . $number . '&Login.Token2=' . $pwd; 17 | $result = parent::getHtml(self::LOGIN_URL, $data); 18 | if ($result && strpos($result, self::SUCC_KEY) !== false) 19 | { 20 | if ($result = parent::getHtml(self::INFO_URL)) 21 | { 22 | return parent::parseName($result, '欢迎您:', ''); 23 | } 24 | } 25 | return false; 26 | } 27 | } -------------------------------------------------------------------------------- /library/Verify/HEBUT.php: -------------------------------------------------------------------------------- 1 | 0) 53 | { 54 | $result = parent::getHtml(self::INFO_URL,null,'GBK'); 55 | if ($result) 56 | { 57 | $name = parent::parseName($result, "当前用户:$number(", ')'); 58 | return trim($name); 59 | } 60 | } 61 | return false; 62 | } 63 | 64 | /** 65 | * 获取验证码 66 | * @method getCode 67 | * @return [type] [description] 68 | */ 69 | public static function getCode() 70 | { 71 | $img = parent::request(self::CODE_URL); 72 | if ($img) 73 | { 74 | Cookie::set('verify_cookie', self::$_cookie, null, null, $_SERVER['HTTP_HOST']); 75 | } 76 | return ['img' => $img, 'verify_cookie' => base64_encode(self::$_cookie)]; 77 | } 78 | } -------------------------------------------------------------------------------- /library/Verify/HNIST.php: -------------------------------------------------------------------------------- 1 |

', '

')) 83 | { 84 | return substr($html, strrpos($html, '>') + 1); 85 | } 86 | 87 | } 88 | return FALSE; 89 | } 90 | } -------------------------------------------------------------------------------- /library/Verify/NKU.php: -------------------------------------------------------------------------------- 1 | 欢迎您:', ''); 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /library/Verify/README.MD: -------------------------------------------------------------------------------- 1 | 2 | # 学校验证 3 | 4 | ### 定义格式 5 | 6 | 以学校缩写命名文件名 `SCHOOLNAME.php` 7 | 8 | ```php 9 | 获取的二进制图像 57 | * cookie 'verify_cookie'=>base64编码的cookie 58 | */ 59 | public static function getCode() 60 | { 61 | return ['img' => $img, 'verify_cookie' => base64_encode($_cookie)]; 62 | } 63 | } 64 | ``` 65 | 66 | ### 文件说明 67 | 68 | * NKU.php 南开大学验证 69 | * TJU.php 天津大学验证 70 | * HEBUT.php 河北工业大学验证 71 | * TIFERT.php 天津商职验证 72 | .... -------------------------------------------------------------------------------- /library/Verify/TIFERT.php: -------------------------------------------------------------------------------- 1 | '); 23 | } 24 | } 25 | return false; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /library/Verify/TJU.php: -------------------------------------------------------------------------------- 1 | $img, 'verify_cookie' => base64_encode(self::$_cookie)]; 73 | } 74 | } -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Options +FollowSymlinks 3 | RewriteEngine On 4 | RewriteBase / 5 | RewriteCond %{REQUEST_FILENAME} !-d 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 8 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YunYinORG/YunYinService/e11405007ec1e16b6c5087216fda25ea8aa028a8/public/favicon.ico -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | bootstrap()->run(); 5 | ?> -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: /index.php 3 | Disallow: / --------------------------------------------------------------------------------