├── .gitignore ├── CODESTYLE.md ├── LICENSE ├── LazyRest4minibook.pdf ├── README.md ├── _build.php ├── _lp ├── config │ ├── core.php │ └── exception.php ├── lib │ ├── Lazyphp │ │ ├── Core │ │ │ ├── Application.php │ │ │ ├── Database.php │ │ │ ├── Datameta.php │ │ │ ├── Dispatcher.php │ │ │ ├── Ldo.php │ │ │ ├── LpObject.php │ │ │ └── Object.php │ │ └── Doc │ │ │ ├── Builder.php │ │ │ ├── Extractor.php │ │ │ └── Resources │ │ │ └── views │ │ │ └── template │ │ │ └── index.html │ ├── flight │ │ ├── Engine.php │ │ ├── Flight.php │ │ ├── autoload.php │ │ ├── core │ │ │ ├── Dispatcher.php │ │ │ └── Loader.php │ │ ├── net │ │ │ ├── Request.php │ │ │ ├── Response.php │ │ │ ├── Route.php │ │ │ └── Router.php │ │ ├── template │ │ │ └── View.php │ │ └── util │ │ │ └── Collection.php │ └── functions.php └── lp.init.php ├── assets ├── css │ ├── app.css │ ├── app.less │ ├── bootstrap.min.css │ ├── stylish-portfolio.css │ └── toastr.min.css ├── fonts │ ├── lrfont.eot │ ├── lrfont.svg │ ├── lrfont.ttf │ └── lrfont.woff ├── image │ ├── logo.lr4.png │ └── news.jpg ├── script │ ├── app.js │ ├── jquery.base64.min.js │ └── toastr.min.js └── template │ ├── inputcode.tpl.php │ ├── logiccode.tpl.php │ └── outputcode.tpl.php ├── auth.demo.txt ├── behat.yml ├── bower.json ├── coderemote.demo.txt ├── codetpl ├── cache │ └── 77 │ │ └── 77ab97689b8f8003b5f352979c1d248abc1b30032a8d71bb7ecc1bc186ab613c.php └── code │ ├── controller.tpl.code │ ├── custom.tpl.code │ ├── delete.tpl.code │ ├── insert.tpl.code │ ├── list.tpl.code │ └── update.tpl.code ├── compiled └── route.php ├── composer.full.json ├── composer.json ├── composer.lock ├── config.yaml ├── config ├── app.php ├── database.php └── exception.php ├── controller ├── AuthedController.php ├── Controller.php └── LazyphpController.php ├── docs └── index.html ├── features ├── bootstrap │ └── FeatureContext.php └── user.feature ├── index.php ├── lib └── functions.php ├── migrations └── 20140422224730_lazy_php_db.php ├── mink.txt ├── phinx.yml ├── phpunit.xml ├── route.php ├── sample.bowerrc ├── sample.htaccess ├── tests ├── app │ └── dbTest.php ├── data │ └── dev.sql ├── framework │ ├── dbtClass.php │ ├── functionTest.php │ └── sampleTest.php └── loader.php ├── upload2sae.php └── view ├── ajax ├── default.tpl.php └── main │ ├── lazyphp_code_functions.tpl.php │ ├── lazyphp_field_add.tpl.php │ └── lazyphp_settings.tpl.php └── web ├── default.tpl.php ├── footer.lr.tpl.php ├── footer.tpl.php ├── header.lr.tpl.php ├── header.tpl.php ├── info.tpl.php ├── lazyrest.tpl.php └── main ├── lazyphp_index.tpl.php ├── lazyphp_interface_create.tpl.php ├── lazyphp_interface_list.tpl.php ├── lazyphp_login.tpl.php └── lazyphp_projects.tpl.php /.gitignore: -------------------------------------------------------------------------------- 1 | composer.phar 2 | /vendor/ 3 | assets/bower_components/ 4 | # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file 5 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file 6 | composer.lock 7 | -------------------------------------------------------------------------------- /CODESTYLE.md: -------------------------------------------------------------------------------- 1 | 编码规范 2 | ======== 3 | 4 | ## 自动加载及PSR4 5 | LP4采用Composer PSR4进行自动加载,第三方组件请使用自己的Namespace,做成独立的包即可。 6 | 7 | ## 函数命名 8 | my_method 9 | 10 | ## 方法命名 11 | myFirstMethod 12 | 13 | 14 | ## 文件和目录名 15 | 以.php结尾,目录和文件名采用驼峰写法分隔单词。 16 | 17 | ## 括号对齐 18 | ``` 19 | function name() 20 | { 21 | 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /LazyRest4minibook.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/LazyRest4/42b99dc4f39ff14cd7ebaf10727cb60c409859a8/LazyRest4minibook.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LazyRest4 完全手册 2 | 3 | [TOC] 4 | 5 | ## 简介 6 | LazyRest,是一个基于Web的类Rest风格API生成器。LazyRest4(以下简称LR4)是为LazyPHP4专门定制的全新设计的版本,但只要简单的修改代码模板,就可以为其他的框架生成代码。 7 | 8 | 和之前的版本相比,LR4具有以下特性: 9 | 10 | - 直接生成最终代码,更好调试、更高性能。 11 | - 全新的交互界面,更漂亮和便捷。 12 | - 按接口而非数据表设计界面,具有更大的灵活性。 13 | - 本身不需要数据库,项目配置直接保存成文件,方便分享。 14 | 15 | 请使用Chrome浏览器访问本应用,其他浏览器并未做兼容性处理。 16 | 17 | ## 安装 18 | 19 | ### 获取源文件 20 | 下载安装包,并解压。或者直接Git Clone。 21 | Repo地址: https://github.com/easychen/LazyRest4 22 | 23 | ### 将apache指定到对应目录 24 | 25 | 注意,必须将Document Root指定到LR4的根目录,否则会出现路径问题。 26 | 27 | ### 初始化项目 28 | #### 使用composer安装PHP依赖 29 | 30 | ``` 31 | composer install --no-dev 32 | ``` 33 | 34 | #### 使用Bower安装JS依赖 35 | 36 | ``` 37 | cp sample.bowerrc .bowerrc 38 | bower install 39 | ``` 40 | 41 | #### 修改URL重写规则 42 | 43 | ``` 44 | cp sample.htaccess .htaccess 45 | ``` 46 | 47 | #### 设置默认管理帐号 48 | 49 | 打开 /config/app.php 50 | 修改以下内容 51 | 52 | ``` 53 | $GLOBALS['lpconfig']['admin_email'] = 'your email'; 54 | $GLOBALS['lpconfig']['admin_password'] = 'your password'; 55 | ``` 56 | 57 | 如果配置正常,这时候访问Web根目录,LazyRest就已经可以使用了。 58 | 59 | ## 实战指南 60 | 61 | 为了更好的演示,我们选择一个真实需求来看看LR4到底怎么用。 62 | ### 需求 63 | 我们需要一个公司部门内使用的函数共享库。这个共享库位于公司内网,公司员工可以注册帐号,登入帐号以后可以添加、下载、修改和删除函数。添加函数时可以将其设置为私有,这样别人就无法浏览和下载该函数了。 64 | 65 | ### 设计MySQL表 66 | 67 | 我们使用PHPMyAdmin来设计数据表。新建一个库,coderemote。总共两张表,一张user表用来存放开发者帐号、领一张code表,用来存放函数。 68 | 69 | user表结构如下: 70 | 71 | ![](http://ww2.sinaimg.cn/large/40dfde6fjw1f354o4k1dsj20i003vjsh.jpg) 72 | 73 | 设计数据表时需要注意以下两点: 74 | 75 | - 每个表需要有id字段,这个字段在查询接口中用于since_id,这个后文详细讲。 76 | - 每个字段需要添加注释,注释的内容是字段的中文名。 77 | 78 | code表结构如下: 79 | 80 | ![](http://ww4.sinaimg.cn/large/40dfde6fjw1f2yh6pgkhsj20hr053myk.jpg) 81 | 82 | 为了方便显示,我们对账户名做了冗余(uname)字段,同时通过private字段来标识是否私有。 83 | 84 | 索引一般在整个API完成后,根据SQL来添加,这里就暂时跳过了。 85 | 86 | ### 创建新项目 87 | 88 | LR4采用项目文件保存数据,所以使用方式类似软件。已有项目可以直接上传项目文件,然后继续,这里我们直接「创建新项目」。 89 | 90 | ![](http://ww3.sinaimg.cn/large/40dfde6fjw1f2yh78a9m6j20is0gpdgb.jpg) 91 | 92 | 在设计接口之前,我们需要把数据库配置下。这样在添加字段时,可以便捷的使用数据库的信息。点击顶导航右侧的⚙图标,设置好Mysql信息。注意这个数据库可以是远程的,并不要一定和LR在一台机器上。 93 | 94 | ![](http://ww1.sinaimg.cn/large/40dfde6fjw1f2yh7h5ehpj20qs0j6jsn.jpg) 95 | 96 | 点击保存后,LR会连接数据库,并把数据表信息缓存起来。所以如果后续有数据库变动,请再到设置页面,点一遍保存来刷新数据表信息。 97 | 98 | ### 创建接口 99 | 100 | 然后我们来创建接口。首先是帐号注册接口。 101 | 102 | ![](http://ww3.sinaimg.cn/large/40dfde6fjw1f2yh7vv78nj20pz0j5jsi.jpg) 103 | 104 | 一般我会把写操作设置为POST,把读操作设置为GET。这里我并不严格遵守RESTful的规范,因为觉得这样更简单一些。 105 | 106 | 目标数据表是我们生成SQL时需要操作的数据表,如果要使用联表操作,则目标数据表可以不选。 107 | 108 | ![](http://ww4.sinaimg.cn/large/40dfde6fjw1f2yh8zqorpj20ls0jdmya.jpg) 109 | 110 | 然后是输入字段和输入过滤代码。简单的说,「输入字段」部分,会帮你自动生成输入过滤代码,包括输入检查,类型转换等。而如果你觉得生成的代码不好用,或者没有把事情做完时,可以在「输入过滤代码」部分进行补充。 111 | 112 | 然后我们来添加字段,点击「添加新字段」,然后会出现字段设置界面。因为是LazyRest,所以当然不会让你挨个手工去填写,我们在右边做了快速输入。在「来自数据库」tab下,选择「user」表,然后选上Email字段,点「填至左侧」,LR会根据数据表信息自动填上一部分信息。 113 | 114 | ![](http://ww3.sinaimg.cn/large/40dfde6fjw1f2yh9lgsoqj20oy0duq3s.jpg) 115 | 116 | 因为email字段设置为了not null,所以检查函数默认启用了check_not_empty。但是则会这个函数不够强,我们需要检查是否为email,所以我们自己写一个,先把名字写上(注意LP4中的检查函数必须以check_开头,过滤函数则没有限制): 117 | 118 | ![](http://ww4.sinaimg.cn/large/40dfde6fjw1f2yha1mmvqj20ox0dut9h.jpg) 119 | 120 | 保存好。LR也直接提供了公共函数的在线编写界面,点击顶导航第二个图标🖋,会弹出代码编辑图层。 121 | 122 | ![](http://ww4.sinaimg.cn/large/40dfde6fjw1f2yhaiohm7j20ox0g6wf9.jpg) 123 | 124 | 125 | 保存后,点右上角关掉。接着再把其他帐号注册接口需要的字段添进来。 126 | 我们不希望密码明文存储,所以我们在输入过滤代码中对它进行sha1编码(生产环境需要更强的密码策略)。 127 | 128 | ``` 129 | 134 | ``` 135 | 136 | 这样输入部分就完成。接下来看业务逻辑代码。LR预置了添加、修改、列表、删除四大内业务逻辑模板,这些模板你都可以在```/codetpl/code```目录下进行修改。 137 | 138 | 这里我们选添加,添加模板预置了唯一字段检查逻辑。在我们的需求里,email字段是唯一的。于是把email字段加上。 139 | 140 | 这样核心逻辑就完成了。为了方便使用,在预置逻辑里,添加、修改和删除都会返回对应的那条数据的信息(用于提示,某某数据已经删除之类)。 141 | 142 | 所以这里还用到输出字段和输出过滤代码。这输入很像,但记住password字段其实是不需要返回的。 143 | 144 | 选完以后我们就可以保存接口了。 145 | 146 | ### 生成和测试代码 147 | 148 | 点击顶导航右三图标,代码会生成到controller目录下的LazyRestController.php。为了调试和部署方便,LR目前所有代码都放到这个文件里。 149 | 150 | 这时候就可以开始测试了。 151 | 152 | ``` 153 | 如果生成代码中有语法错,会导致LR整体报错,只需要删除生成的文件就好。 154 | ``` 155 | 156 | 如果路由没有更新,请记得把LazyPHP4的自动重建路由开关打开。在/config/app.php中 157 | 158 | ``` 159 | $GLOBALS['lpconfig']['buildeverytime'] = true; 160 | ``` 161 | 162 | ### 测试接口 163 | 164 | 我一般使用[PostMan](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop)来测试API,所以以下以它为例。 165 | 166 | ![](http://ww4.sinaimg.cn/large/40dfde6fjw1f2yhayug9dj20lt0bvdh8.jpg) 167 | 168 | 注意几个点: 169 | 170 | - 我们设置了这个接口只支持POST,所以用GET会提示404 171 | - LazyPHP4.5开始因为支持了Web界面,所以要在添加一个特殊的Header才能强制返回json。 172 | 173 | ``` 174 | 'LP4-Request-Type':'json' 175 | ``` 176 | 177 | 填好参数,接口已经正常工作了。 178 | 179 | ![](http://ww2.sinaimg.cn/large/40dfde6fjw1f2yhb7ujgsj20ln0jz773.jpg) 180 | 181 | ### 授权机制 182 | 183 | 在这个项目里,我们采用token机制:通过email和密码换取一个token,需要授权的接口,带上这个token来访问。 184 | 185 | 首先我们来做这个接口,在LR中再新建一个。顺便说句,点击这个图标就可以返回接口列表。 186 | 187 | ![](http://ww1.sinaimg.cn/large/40dfde6fjw1f2yhbm258tj202101xjr7.jpg) 188 | 189 | 将email和password添加为输入字段,设置为必填。 190 | 191 | ![](http://ww4.sinaimg.cn/large/40dfde6fjw1f2yhbuigduj20go05474k.jpg) 192 | 193 | 然后我们这次直接自定义业务逻辑代码 194 | 195 | ``` 196 | auth(); 269 | lazyrest_auth_check(); 270 | } 271 | } 272 | } 273 | ``` 274 | 275 | 可以看到,所有授权控制的「任意访问」设置为否的接口,都会通过lazyrest_auth_check函数进行权限检查。但是lazyrest_auth_check函数默认是没定义的,所以默认不生效。我们只需要在公共函数中把这个函数实现了,就完成了权限控制。 276 | 277 | 先看看$this->auth()的实现,在/controller/AuthedContrllor.php里边: 278 | 279 | ``` 280 | protected function auth() 281 | { 282 | $token = t(v('_token')); 283 | if( strlen( $token ) > 0 ) 284 | { 285 | session_id( $token ); 286 | } 287 | 288 | session_start(); 289 | } 290 | ``` 291 | 它接受_token参数,并把其作为session id,自动enable了session。所以我们只需要在lazyrest_auth_check里边简单的检查下$_SESSION数据是否正常就OK了。 292 | 293 | ``` 294 | function lazyrest_auth_check() 295 | { 296 | if( intval( $_SESSION['level'] ) < 1 ) 297 | { 298 | send_error( 'AUTH' , '当前权限不足以访问本接口' ); 299 | exit; 300 | } 301 | } 302 | ``` 303 | 304 | 同时,如果对auth函数的实现不满意,可以直接覆盖它的实现。 305 | 保存后Build下代码,就可以测试了: 306 | 307 | ![](http://ww2.sinaimg.cn/large/40dfde6fjw1f2yhfcporbj20ld0an40c.jpg) 308 | 309 | 带上token,已经可以访问了。 310 | 311 | ![](http://ww2.sinaimg.cn/large/40dfde6fjw1f2yhfjtv8hj20li0egwgv.jpg) 312 | 313 | ### 其他预置接口 314 | 315 | #### 修改接口 316 | id和code作为输入字段;业务逻辑代码选「 修改 」,WHERE子句添加id,选完全匹配。 317 | 318 | ![](http://ww4.sinaimg.cn/large/40dfde6fjw1f2yhfsjjtvj20ow0dswf6.jpg) 319 | 320 | 然后因为只有自己才能修改自己的代码,所以在业务逻辑代码中加上权限检查: 321 | 322 | ``` 323 | if( $last['uid'] != uid() ) return send_error( 'AUTH' , '只能修改自己发布的函数' ); 324 | ``` 325 | 注意在UPDATE和DELETE预置模块中,会查询对应的记录,并保存到$last中供使用。 326 | 327 | #### 列表接口 328 | 329 | 列表接口很简单,预置的业务逻辑也是WHERE匹配,和前文一样处理就好。 330 | 331 | ![](http://ww2.sinaimg.cn/large/40dfde6fjw1f2yhg3om7ej20lh0iaad8.jpg) 332 | 333 | 下边是列表接口支持的参数: 334 | 335 | - _order:asc/dsec。 336 | - _order_by:字段名。 337 | - _since_id:从某个id开始返回。 338 | - _count:每次返回的数据条数,最多1000条。 339 | 340 | 但上文我们发现了一个问题,私有函数也被列出来。所以我们需要在业务逻辑处,进行调整,给where子句再加一个条件: 341 | 342 | ``` 343 | $add_where = " (`private` != 1 OR `uid` = '" . intval( $uid ) . "' ) "; 344 | 345 | if( strlen( t( $where_sql ) ) < 1 ) $where_sql = 'WHERE ' . $add_where; 346 | else $where_sql .= ' AND (' . $add_where . ')'; 347 | ``` 348 | 349 | 要了解如何调整sql的拼接,直接查看生成好的代码是最好的办法。 350 | 351 | 另外,为了让查询的实现更简单点,LR预置的删除是直接删除,而非标记删除。 352 | 353 | CodeRemote项目的LR文件,可以 [点击这里查看](./coderemote.demo.txt) ;我还准备了一个[只有用户注册和授权验证的LR文件](./auth.demo.txt),方便大家直接开始做业务逻辑。 354 | 355 | 356 | ## 部署 357 | 首先你要有一个可以运行的LazyPHP4环境,然后把LazyRestController.php放到controller目录下,再php _build.php 更新下路由就能用了。 358 | 359 | ## 其他 360 | ### 继续开发和贡献代码 361 | 362 | 如果你有兴趣给LR贡献代码,有几个我觉得很值得做的地方供参考: 363 | 364 | - 自动生成API的JS SDK。 365 | - 自动打包LazyRestController.php,并发布到云平台。可以生成phing文件来完成。 366 | - 整理并分享LR项目文件,让有同样需求的同学不用重复开发(记得分享的文件要干点数据库信息)。 367 | - 根据LR项目文件里边的数据库信息,在数据表不存在时,自动创建数据表。 368 | 369 | #### 几个开发Tips 370 | 371 | - 访问 ```/session``` 页面可以查看全部元数据。 372 | - 代码模板使用Twig引擎,挺好用的。 373 | - css使用less完成,php _build.php的时候会自动编译app.less到app.css 374 | 375 | ### 捐助 376 | 本来只是做来给自己用的,但因为很多同学表示也想用,就放出来了。写文档解释如何使用什么的挺费事,所以当LazyRest帮你节省了时间和精力之后,可以考虑打赏我一点零花钱 😁 377 | 378 | 微信 379 | 380 | ![](http://ww3.sinaimg.cn/large/40dfde6fjw1f2yhu86w8kj206r06e0t6.jpg) 381 | 382 | 支付宝 383 | 384 | ![](http://ww3.sinaimg.cn/large/40dfde6fjw1f2yhuhxpxij20740730tm.jpg) 385 | 386 | 387 | -------------------------------------------------------------------------------- /_build.php: -------------------------------------------------------------------------------- 1 | generate(); 56 | } catch (Exception $e) { 57 | echo 'There was an error generating the documentation: ', $e->getMessage(); 58 | } 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /_lp/config/core.php: -------------------------------------------------------------------------------- 1 | '10000' , 'message' => 'route error' ); 4 | $GLOBALS['rest_errors']['INPUT'] = array( 'code' => '10001' , 'message' => 'input error' ); 5 | $GLOBALS['rest_errors']['DATABASE'] = array( 'code' => '30001' , 'message' => 'database error' ); 6 | $GLOBALS['rest_errors']['DATA'] = array( 'code' => '40001' , 'message' => 'data error' ); 7 | $GLOBALS['rest_errors']['AUTH'] = array( 'code' => '20001' , 'message' => 'auth error' ); 8 | $GLOBALS['rest_errors']['TMPLATE'] = array( 'code' => '50001' , 'message' => 'template error' ); 9 | -------------------------------------------------------------------------------- /_lp/lib/Lazyphp/Core/Application.php: -------------------------------------------------------------------------------- 1 | request = new Request(); 21 | $this->response = new Response(); 22 | $this->router = new Router(); 23 | $this->dispatcher = new Dispatcher(); // LP自己的Dispatcher 24 | 25 | } 26 | 27 | public function run() 28 | { 29 | $dispatched = false; 30 | 31 | if ($this->request->ajax) 32 | { 33 | $this->response->cache(false); 34 | } 35 | 36 | while ($route = $this->router->route($this->request)) 37 | { 38 | $params = array_values($route->params); 39 | //TODO 修复参数顺序和meta不一致 40 | 41 | $continue = $this->dispatcher->execute( 42 | $route->callback, 43 | $params 44 | ); 45 | 46 | $dispatched = true; 47 | 48 | if (!$continue) break; 49 | 50 | $this->router->next(); 51 | } 52 | 53 | if (!$dispatched) { 54 | $this->notFound(); 55 | } 56 | 57 | } 58 | 59 | public function notFound() 60 | { 61 | $code=404; 62 | if('OPTIONS'==$_SERVER['REQUEST_METHOD']) 63 | { 64 | //ajax跨域请求之前的options请求,为了避免如上传失败,返回200 65 | $code=200; 66 | } 67 | $this->response 68 | ->status($code) 69 | ->write( 70 | '

404 Not Found

'. 71 | '

The page you have requested could not be found.

'. 72 | str_repeat(' ', 512) 73 | ) 74 | ->send(); 75 | } 76 | 77 | public function route($pattern, $callback) 78 | { 79 | $this->router->map($pattern, $callback); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /_lp/lib/Lazyphp/Core/Database.php: -------------------------------------------------------------------------------- 1 | pdo = $dsn; 14 | } 15 | else 16 | { 17 | if( $dsn == null ) 18 | { 19 | $dsn = c('database','dsn'); 20 | //echo $dsn; 21 | $user = c('database','user'); 22 | $password = c('database','password'); 23 | } 24 | $this->pdo = new PDO( $dsn , $user , $password ); 25 | } 26 | 27 | if( is_devmode() || c('allow_pdo_exception') ) 28 | $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 29 | 30 | $this->pdo->exec("SET NAMES 'utf8';"); 31 | } 32 | 33 | // get data to result set 34 | 35 | public function getData( $sql ) 36 | { 37 | $args = func_get_args(); 38 | array_unshift($args, 'getdata'); 39 | return call_user_func_array(array($this, 'bindData'),$args ); 40 | } 41 | 42 | 43 | 44 | 45 | public function runSql() 46 | { 47 | $args = func_get_args(); 48 | array_unshift($args, 'runsql'); 49 | return call_user_func_array(array($this, 'bindData'),$args ); 50 | } 51 | 52 | /** 53 | * bindData 用于处理带绑定支持的SQL 54 | * 第一个参数为 TYPE , 当 TYPE = getdata 时,产生返回内容。否则为执行语句。 55 | */ 56 | protected function bindData() 57 | { 58 | $this->result=false; 59 | $arg_num = func_num_args(); 60 | $arg_num = $arg_num - 1; 61 | $args = func_get_args(); 62 | $type = array_shift($args); 63 | 64 | if( $arg_num < 1 ) 65 | { 66 | throw new \PdoException("NO SQL PASSBY"); 67 | return $this; 68 | } 69 | else 70 | { 71 | if( $arg_num == 1 ) 72 | { 73 | $sql = $args[0]; 74 | } 75 | else 76 | { 77 | // 绑定 78 | 79 | $sql = array_shift($args); 80 | if( $params = get_bind_params($sql) ) 81 | { 82 | //$sth = $this->pdo->prepare( $sql ); 83 | $meta = $GLOBALS['meta'][$GLOBALS['meta_key']]; 84 | 85 | if( isset( $meta['table'][0]['fields'] ) ) 86 | $fields = $meta['table'][0]['fields']; 87 | 88 | $replace = array(); 89 | 90 | foreach( $params as $param ) 91 | { 92 | $value = array_shift( $args ); 93 | if( isset( $fields[$param] ) && type2pdo($fields[$param]['type']) == PDO::PARAM_INT ) 94 | { 95 | 96 | $replace[':'.$param] = intval($value); 97 | //$sth->bindValue(':'.$param, $value , type2pdo($fields[$param]['type'])); 98 | } 99 | else 100 | { 101 | $replace[':'.$param] = "'" . s($value) . "'"; 102 | //$sth->bindValue(':'.$param, $value , PDO::PARAM_STR); 103 | } 104 | } 105 | 106 | $sql = str_replace( array_keys($replace), array_values($replace), $sql ); 107 | } 108 | } 109 | 110 | if( 'getdata' == $type ) 111 | { 112 | foreach( $this->pdo->query( $sql , PDO::FETCH_ASSOC ) as $item ) 113 | { 114 | 115 | if( is_array($this->result) ) $this->result[] = $item; 116 | else $this->result = array( '0' => $item ); 117 | } 118 | 119 | } 120 | else 121 | { 122 | $this->result = $this->pdo->exec( $sql ); 123 | } 124 | 125 | //print_r( $this->result ); 126 | 127 | 128 | 129 | return $this; 130 | } 131 | 132 | return $this; 133 | 134 | } 135 | 136 | 137 | 138 | // export 139 | public function toLine() 140 | { 141 | if( !isset($this->result) ) return false; 142 | 143 | $ret = $this->result; 144 | $this->result = null; 145 | return first($ret); 146 | } 147 | 148 | public function toVar( $field = null ) 149 | { 150 | if( !isset($this->result) ) return false; 151 | 152 | $ret = $this->result; 153 | $this->result = null; 154 | 155 | if( $field == null ) 156 | return first(first($ret)); 157 | else 158 | return isset($ret[0][$field])?$ret[0][$field]:false; 159 | } 160 | 161 | public function toArray() 162 | { 163 | if( !isset($this->result) ) return false; 164 | 165 | $ret = $this->result; 166 | $this->result = null; 167 | return $ret; 168 | } 169 | 170 | public function col( $name ) 171 | { 172 | return $this->toColumn($name); 173 | } 174 | 175 | public function toColumn( $name ) 176 | { 177 | if( !isset($this->result) ) return false; 178 | 179 | $rs = $this->result; 180 | $this->result = null; 181 | 182 | if( !isset( $rs ) || !is_array($rs) ) return false; 183 | foreach( $rs as $line ) 184 | if( isset($line[$name]) ) $ret[] = $line[$name]; 185 | 186 | return isset($ret)?$ret:false; 187 | } 188 | 189 | public function index( $name ) 190 | { 191 | return $this->toIndexedArray($name); 192 | } 193 | 194 | public function toIndexedArray( $name ) 195 | { 196 | if( !isset($this->result) ) return false; 197 | 198 | $rs = $this->result; 199 | $this->result = null; 200 | 201 | if( !isset( $rs ) || !is_array($rs) ) return false; 202 | foreach( $rs as $line ) 203 | $ret[$line[$name]] = $line; 204 | 205 | return isset($ret)?$ret:false; 206 | } 207 | 208 | public function quote( $string ) 209 | { 210 | return $this->pdo->quote( $string ); 211 | } 212 | 213 | public function lastId() 214 | { 215 | return $this->pdo->lastInsertId(); 216 | } 217 | 218 | 219 | 220 | 221 | 222 | 223 | } 224 | -------------------------------------------------------------------------------- /_lp/lib/Lazyphp/Core/Datameta.php: -------------------------------------------------------------------------------- 1 | db = new Database($pdo); 13 | $this->quote_name_prefix = "`"; 14 | $this->quote_name_suffix = "`"; 15 | } 16 | 17 | public function getFields($table) 18 | { 19 | if( !isset($this->fields) ) 20 | $this->getTableCols( $table ); 21 | 22 | return $this->fields; 23 | } 24 | 25 | public function getTableCols( $table ) 26 | { 27 | $table = $this->quoteName($table); 28 | $sql = "SHOW FULL COLUMNS FROM " . $table . " " ; 29 | if( $data = $this->db->getData($sql)->toArray() ) 30 | foreach( $data as $item ) 31 | { 32 | $name = $item['Field']; 33 | $default = $this->getDefault($item['Default']); 34 | list($type, $size, $scale) = $this->getTypeSizeScope($item['Type']); 35 | 36 | $array = array 37 | ( 38 | 'name' => $name, 39 | 'default' => $default, 40 | 'type' => $type , 41 | 'size' => ($size ? (int) $size : null) , 42 | 'scale' => ($scale ? (int) $scale : null) , 43 | 'notnull' => (bool) ($item['Null'] != 'YES') , 44 | 'auto' => (bool) (strpos($item['Extra'], 'auto_increment') !== false) , 45 | 'primary' => (bool) ($item['Key'] == 'PRI'), 46 | 'comment' => $item['Comment'] , 47 | ); 48 | 49 | $ret[$name] = $array; 50 | $this->fields[] = $name; 51 | } 52 | 53 | 54 | return isset( $ret ) ? $ret : false; 55 | } 56 | 57 | protected function getDefault($default) 58 | { 59 | $upper = strtoupper($default); 60 | if ($upper == 'NULL' || $upper == 'CURRENT_TIMESTAMP') { 61 | // the only non-literal allowed by MySQL is "CURRENT_TIMESTAMP" 62 | return null; 63 | } else { 64 | // return the literal default 65 | return $default; 66 | } 67 | } 68 | 69 | protected function getTypeSizeScope($spec) 70 | { 71 | $spec = strtolower($spec); 72 | $type = null; 73 | $size = null; 74 | $scale = null; 75 | 76 | // find the parens, if any 77 | $pos = strpos($spec, '('); 78 | if ($pos === false) { 79 | // no parens, so no size or scale 80 | $type = $spec; 81 | } else { 82 | // find the type first. 83 | $type = substr($spec, 0, $pos); 84 | 85 | // there were parens, so there's at least a size. 86 | // remove parens to get the size. 87 | $size = trim(substr($spec, $pos), '()'); 88 | 89 | // a comma in the size indicates a scale. 90 | $pos = strpos($size, ','); 91 | if ($pos !== false) { 92 | $scale = substr($size, $pos + 1); 93 | $size = substr($size, 0, $pos); 94 | } 95 | } 96 | 97 | return array($type, $size, $scale); 98 | } 99 | 100 | protected function splitName($name) 101 | { 102 | $pos = strpos($name, '.'); 103 | if ($pos === false) { 104 | return array(null, $name); 105 | } else { 106 | return array(substr($name, 0, $pos), substr($name, $pos+1)); 107 | } 108 | } 109 | 110 | public function quoteName($name) 111 | { 112 | // remove extraneous spaces 113 | $name = trim($name); 114 | 115 | // "name"."name" 116 | $pos = strrpos($name, '.'); 117 | if ($pos) { 118 | $one = $this->quoteName(substr($name, 0, $pos)); 119 | $two = $this->quoteName(substr($name, $pos + 1)); 120 | return "{$one}.{$two}"; 121 | } 122 | 123 | // "name" 124 | return $this->quote_name_prefix . $name . $this->quote_name_suffix; 125 | } 126 | } -------------------------------------------------------------------------------- /_lp/lib/Lazyphp/Core/Dispatcher.php: -------------------------------------------------------------------------------- 1 | $item ) 84 | { 85 | if( isset($item['filters']) && is_array( $item['filters'] ) ) 86 | { 87 | foreach( $item['filters'] as $check_function ) 88 | { 89 | $tinfo = explode( '_' , $check_function ); 90 | $type = reset( $tinfo ); 91 | $type = strtolower(trim($type)); 92 | if( $type == 'check' ) 93 | { 94 | // 当函数调用为false时直接输出错误信息 95 | if( function_exists( $check_function ) ) 96 | { 97 | //echo $item['name'] . '~' . print_r( $meta['route'][0]['params'] , 1 ); 98 | // 如果是路由器自带变量 99 | if( $route_parmas && isset($meta['route'][0]['params']) && in_array( $item['name'] , $route_parmas ) ) 100 | $vv = $params[array_search( $item['name'] , $route_parmas )]; // 按顺序从参数中获取 101 | else 102 | $vv = v($item['name']); // 按名字从REQUEST中获取 103 | 104 | $ret = call_user_func( $check_function , $vv ); 105 | if( !$ret ) 106 | { 107 | // 抛出异常 108 | if( is_devmode() ) 109 | throw new InputException($item['cnname']."(" . $item['name'] . ")未提供或格式不正确 via ".$check_function." return $ret"); 110 | else 111 | throw new InputException($item['cnname']."(" . $item['name'] . ")未提供或格式不正确"); 112 | 113 | } 114 | } 115 | 116 | } 117 | else 118 | { 119 | // filter 120 | // 修改request数值 121 | if( function_exists( $check_function ) ) 122 | { 123 | if( $route_parmas && isset($meta['route'][0]['params']) && in_array( $item['name'] , $route_parmas ) ) 124 | { 125 | $params[array_search( $item['name'] , $route_parmas )] = 126 | call_user_func( $check_function , $params[array_search( $item['name'] , $route_parmas )] ); 127 | } 128 | elseif( isset( $_REQUEST[$item['name']] ) ) 129 | { 130 | $php_uri_type = '_'.strtoupper($route_type); 131 | switch ($php_uri_type) { 132 | case '_GET': 133 | $_GET[$item['name']] = call_user_func( $check_function , $_REQUEST[$item['name']] ); 134 | break; 135 | case '_POST': 136 | $_POST[$item['name']] = call_user_func( $check_function , $_REQUEST[$item['name']] ); 137 | break; 138 | case '_PUT': 139 | $_PUT[$item['name']] = call_user_func( $check_function , $_REQUEST[$item['name']] ); 140 | break; 141 | case '_DELETE': 142 | $_DELETE[$item['name']] = call_user_func( $check_function , $_REQUEST[$item['name']] ); 143 | break; 144 | } 145 | } 146 | } 147 | } 148 | } 149 | } 150 | 151 | // 如果写入了参数绑定 152 | // 注意这个地方是依赖于参数顺序的 153 | 154 | // 如果在路由中 155 | if( !($route_parmas && in_array( $item['name'] , $route_parmas ))) 156 | if( isset($meta['binding'][$item['name']]) ) 157 | { 158 | // 变量顺序按绑定顺序排序 159 | $index = array_key_index( $item['name'],$meta['binding'] ); 160 | $request_params[$index] = (isset($meta['binding'][$item['name']]['default']) && !isset($_REQUEST[$item['name']]))? 161 | $meta['binding'][$item['name']]['default']: 162 | v($item['name']); 163 | } 164 | // slog($request_params); 165 | } 166 | //slog($meta['binding']); 167 | 168 | } 169 | 170 | // 强制request变量按function参数顺序进行绑定 171 | if( isset($request_params) && is_array( $request_params ) ) 172 | { 173 | ksort( $request_params ); 174 | $params = array_merge( $params , $request_params ); 175 | } 176 | return call_user_func_array(array( $instance , $method ) , $params); 177 | } 178 | 179 | } 180 | -------------------------------------------------------------------------------- /_lp/lib/Lazyphp/Core/Ldo.php: -------------------------------------------------------------------------------- 1 | getAllById('1')->toLine(); 11 | * $member->getNameById('1')->toVar(); 12 | * $member->getDataById(array('name','avatar') , 1)->toLine(); 13 | * $member->getAllByArray(array('name'=>'easy'))->toLine(); 14 | * $member->findNameByNothing()->col('name'); 15 | * $member->findNameByNothingLimit(array(2,5))->col('name'); 16 | */ 17 | class Ldo extends LpObject 18 | { 19 | public function __construct( $table ) 20 | { 21 | $this->table = $table; 22 | $this->db = db(); 23 | } 24 | 25 | public function __call( $name, $arguments ) 26 | { 27 | if( !isset($this->table) ) throw new \Exception("LDO未绑定数据表"); 28 | 29 | 30 | $reg = '/(get|find)([A-Z_]+[a-z0-9_]*)By([A-Z_]+[a-z0-9_]*)(Limit)*/s'; 31 | if( preg_match( $reg , $name , $out ) ) 32 | { 33 | //print_r($out); 34 | 35 | $type = strtolower( t($out[1]) ); 36 | $select = strtolower( t($out[2]) ); 37 | 38 | if( isset($out[3]) ) 39 | $where = strtolower( t($out[3]) ); 40 | else 41 | $where = ''; 42 | 43 | if( isset($out[4]) && strtolower( t($out[4])) == 'limit' ) 44 | $limit = true; 45 | else 46 | $limit = false; 47 | 48 | 49 | 50 | switch( $select ) 51 | { 52 | case 'data': 53 | $array = array_shift($arguments); 54 | if( is_array($array) ) 55 | { 56 | foreach ($array as $value) 57 | { 58 | $select_array[] = '`' . $value . '`'; 59 | } 60 | 61 | if( isset( $select_array ) ) 62 | $select_sql = join( ' , ' , $select_array ) ; 63 | else 64 | $select_sql = ' * '; 65 | } 66 | else 67 | $select_sql = ' * '; 68 | 69 | break; 70 | case 'all': 71 | $select_sql = ' * '; 72 | break; 73 | default: 74 | $select_sql = ' `' . $select . '` '; 75 | 76 | break; 77 | } 78 | 79 | if( ne($where) ) 80 | { 81 | if( $where == 'nothing' ) 82 | $where_sql = " 1 "; 83 | elseif( $where == 'array' ) 84 | { 85 | $array = array_shift($arguments); 86 | if( is_array($array) ) 87 | { 88 | foreach ($array as $key => $value) 89 | { 90 | $where_array[] = "`" . $key . "` = '" . s($value) . "'"; 91 | } 92 | 93 | if( isset( $where_array ) ) 94 | $where_sql = join( ' AND ' , $where_array ) ; 95 | else 96 | $where_sql = ' 1 '; 97 | } 98 | else 99 | $where_sql = ' 1 '; 100 | } 101 | else 102 | { 103 | $value = array_shift($arguments); 104 | $where_sql = " `" . $where . "` = '" . s( $value ) . "' "; 105 | } 106 | 107 | } 108 | 109 | 110 | if( $limit ) 111 | { 112 | if($limit_info = array_shift($arguments)) 113 | { 114 | if( is_array( $limit_info ) ) 115 | $limit_sql = " LIMIT ".$limit_info[0] . " , " . $limit_info[1]; 116 | elseif( ne( $limit_info ) ) $limit_sql = " LIMIT ".$limit_info; 117 | else $limit_sql = " "; 118 | } 119 | else $limit_sql = " "; 120 | }else $limit_sql = " "; 121 | 122 | $sql = "SELECT {$select_sql} FROM `{$this->table}` WHERE {$where_sql} {$limit_sql}"; 123 | //echo $sql . "
"; 124 | return $this->db->getData($sql); 125 | 126 | } 127 | else throw new \Exception("Method not exists".$name); 128 | 129 | 130 | } 131 | 132 | public function runSql() 133 | { 134 | $args = func_get_args(); 135 | return call_user_func_array(array($this->db, 'runSql'),$args ); 136 | } 137 | 138 | public function lastId() 139 | { 140 | $args = func_get_args(); 141 | return call_user_func_array(array($this->db, 'lastId'),$args ); 142 | } 143 | 144 | public function getData() 145 | { 146 | $args = func_get_args(); 147 | return call_user_func_array(array($this->db, 'getData'),$args ); 148 | } 149 | } -------------------------------------------------------------------------------- /_lp/lib/Lazyphp/Core/LpObject.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | php-apidoc v {{ version }} 10 | 11 | 25 | 26 | 27 | 28 | 54 | 55 |
56 |
57 |
58 |
Api URL
59 | 60 |
61 |
62 |
63 |
64 | {{ content }} 65 |
66 |
67 | 68 | 76 | 77 |
78 | 79 | 80 | 81 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /_lp/lib/flight/Flight.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | /** 10 | * The Flight class is a static representation of the framework. 11 | * 12 | * Core. 13 | * @method static void start() Starts the framework. 14 | * @method static void path($path) Adds a path for autoloading classes. 15 | * @method static void stop() Stops the framework and sends a response. 16 | * @method static void halt($code = 200, $message = '') Stop the framework with an optional status code and message. 17 | * 18 | * Routing. 19 | * @method static void route($pattern, $callback) Maps a URL pattern to a callback. 20 | * @method static \flight\net\Router router() Returns Router instance. 21 | * 22 | * Extending & Overriding. 23 | * @method static void map($name, $callback) Creates a custom framework method. 24 | * @method static void register($name, $class, array $params = array(), $callback = null) Registers a class to a framework method. 25 | * 26 | * Filtering. 27 | * @method static void before($name, $callback) Adds a filter before a framework method. 28 | * @method static void after($name, $callback) Adds a filter after a framework method. 29 | * 30 | * Variables. 31 | * @method static void set($key, $value) Sets a variable. 32 | * @method static mixed get($key) Gets a variable. 33 | * @method static bool has($key) Checks if a variable is set. 34 | * @method static void clear($key = null) Clears a variable. 35 | * 36 | * Views. 37 | * @method static void render($file, array $data = null, $key = null) Renders a template file. 38 | * @method static \flight\template\View view() Returns View instance. 39 | * 40 | * Request & Response. 41 | * @method static \flight\net\Request request() Returns Request instance. 42 | * @method static \flight\net\Response response() Returns Response instance. 43 | * @method static void redirect($url, $code = 303) Redirects to another URL. 44 | * @method static void json($data, $code = 200, $encode = true, $charset = "utf8", $encodeOption = 0, $encodeDepth = 512) Sends a JSON response. 45 | * @method static void jsonp($data, $param = 'jsonp', $code = 200, $encode = true, $charset = "utf8", $encodeOption = 0, $encodeDepth = 512) Sends a JSONP response. 46 | * @method static void error($exception) Sends an HTTP 500 response. 47 | * @method static void notFound() Sends an HTTP 404 response. 48 | * 49 | * HTTP Caching. 50 | * @method static void etag($id, $type = 'strong') Performs ETag HTTP caching. 51 | * @method static void lastModified($time) Performs last modified HTTP caching. 52 | */ 53 | class Flight { 54 | /** 55 | * Framework engine. 56 | * 57 | * @var \flight\Engine 58 | */ 59 | private static $engine; 60 | 61 | // Don't allow object instantiation 62 | private function __construct() {} 63 | private function __destruct() {} 64 | private function __clone() {} 65 | 66 | /** 67 | * Handles calls to static methods. 68 | * 69 | * @param string $name Method name 70 | * @param array $params Method parameters 71 | * @return mixed Callback results 72 | * @throws \Exception 73 | */ 74 | public static function __callStatic($name, $params) { 75 | $app = Flight::app(); 76 | 77 | return \flight\core\Dispatcher::invokeMethod(array($app, $name), $params); 78 | } 79 | 80 | /** 81 | * @return \flight\Engine Application instance 82 | */ 83 | public static function app() { 84 | static $initialized = false; 85 | 86 | if (!$initialized) { 87 | require_once __DIR__.'/autoload.php'; 88 | 89 | self::$engine = new \flight\Engine(); 90 | 91 | $initialized = true; 92 | } 93 | 94 | return self::$engine; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /_lp/lib/flight/autoload.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | require_once __DIR__.'/core/Loader.php'; 10 | 11 | \flight\core\Loader::autoload(true, dirname(__DIR__)); 12 | -------------------------------------------------------------------------------- /_lp/lib/flight/core/Dispatcher.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\core; 10 | 11 | /** 12 | * The Dispatcher class is responsible for dispatching events. Events 13 | * are simply aliases for class methods or functions. The Dispatcher 14 | * allows you to hook other functions to an event that can modify the 15 | * input parameters and/or the output. 16 | */ 17 | class Dispatcher { 18 | /** 19 | * Mapped events. 20 | * 21 | * @var array 22 | */ 23 | protected $events = array(); 24 | 25 | /** 26 | * Method filters. 27 | * 28 | * @var array 29 | */ 30 | protected $filters = array(); 31 | 32 | /** 33 | * Dispatches an event. 34 | * 35 | * @param string $name Event name 36 | * @param array $params Callback parameters 37 | * @return string Output of callback 38 | * @throws \Exception 39 | */ 40 | public function run($name, array $params = array()) { 41 | $output = ''; 42 | 43 | // Run pre-filters 44 | if (!empty($this->filters[$name]['before'])) { 45 | $this->filter($this->filters[$name]['before'], $params, $output); 46 | } 47 | 48 | // Run requested method 49 | $output = $this->execute($this->get($name), $params); 50 | 51 | // Run post-filters 52 | if (!empty($this->filters[$name]['after'])) { 53 | $this->filter($this->filters[$name]['after'], $params, $output); 54 | } 55 | 56 | return $output; 57 | } 58 | 59 | /** 60 | * Assigns a callback to an event. 61 | * 62 | * @param string $name Event name 63 | * @param callback $callback Callback function 64 | */ 65 | public function set($name, $callback) { 66 | $this->events[$name] = $callback; 67 | } 68 | 69 | /** 70 | * Gets an assigned callback. 71 | * 72 | * @param string $name Event name 73 | * @return callback $callback Callback function 74 | */ 75 | public function get($name) { 76 | return isset($this->events[$name]) ? $this->events[$name] : null; 77 | } 78 | 79 | /** 80 | * Checks if an event has been set. 81 | * 82 | * @param string $name Event name 83 | * @return bool Event status 84 | */ 85 | public function has($name) { 86 | return isset($this->events[$name]); 87 | } 88 | 89 | /** 90 | * Clears an event. If no name is given, 91 | * all events are removed. 92 | * 93 | * @param string $name Event name 94 | */ 95 | public function clear($name = null) { 96 | if ($name !== null) { 97 | unset($this->events[$name]); 98 | unset($this->filters[$name]); 99 | } 100 | else { 101 | $this->events = array(); 102 | $this->filters = array(); 103 | } 104 | } 105 | 106 | /** 107 | * Hooks a callback to an event. 108 | * 109 | * @param string $name Event name 110 | * @param string $type Filter type 111 | * @param callback $callback Callback function 112 | */ 113 | public function hook($name, $type, $callback) { 114 | $this->filters[$name][$type][] = $callback; 115 | } 116 | 117 | /** 118 | * Executes a chain of method filters. 119 | * 120 | * @param array $filters Chain of filters 121 | * @param array $params Method parameters 122 | * @param mixed $output Method output 123 | * @throws \Exception 124 | */ 125 | public function filter($filters, &$params, &$output) { 126 | $args = array(&$params, &$output); 127 | foreach ($filters as $callback) { 128 | $continue = $this->execute($callback, $args); 129 | if ($continue === false) break; 130 | } 131 | } 132 | 133 | /** 134 | * Executes a callback function. 135 | * 136 | * @param callback $callback Callback function 137 | * @param array $params Function parameters 138 | * @return mixed Function results 139 | * @throws \Exception 140 | */ 141 | public static function execute($callback, array &$params = array()) { 142 | if (is_callable($callback)) { 143 | return is_array($callback) ? 144 | self::invokeMethod($callback, $params) : 145 | self::callFunction($callback, $params); 146 | } 147 | else { 148 | throw new \Exception('Invalid callback specified.'); 149 | } 150 | } 151 | 152 | /** 153 | * Calls a function. 154 | * 155 | * @param string $func Name of function to call 156 | * @param array $params Function parameters 157 | * @return mixed Function results 158 | */ 159 | public static function callFunction($func, array &$params = array()) { 160 | // Call static method 161 | if (is_string($func) && strpos($func, '::') !== false) { 162 | return call_user_func_array($func, $params); 163 | } 164 | 165 | switch (count($params)) { 166 | case 0: 167 | return $func(); 168 | case 1: 169 | return $func($params[0]); 170 | case 2: 171 | return $func($params[0], $params[1]); 172 | case 3: 173 | return $func($params[0], $params[1], $params[2]); 174 | case 4: 175 | return $func($params[0], $params[1], $params[2], $params[3]); 176 | case 5: 177 | return $func($params[0], $params[1], $params[2], $params[3], $params[4]); 178 | default: 179 | return call_user_func_array($func, $params); 180 | } 181 | } 182 | 183 | /** 184 | * Invokes a method. 185 | * 186 | * @param mixed $func Class method 187 | * @param array $params Class method parameters 188 | * @return mixed Function results 189 | */ 190 | public static function invokeMethod($func, array &$params = array()) { 191 | list($class, $method) = $func; 192 | 193 | $instance = is_object($class); 194 | 195 | switch (count($params)) { 196 | case 0: 197 | return ($instance) ? 198 | $class->$method() : 199 | $class::$method(); 200 | case 1: 201 | return ($instance) ? 202 | $class->$method($params[0]) : 203 | $class::$method($params[0]); 204 | case 2: 205 | return ($instance) ? 206 | $class->$method($params[0], $params[1]) : 207 | $class::$method($params[0], $params[1]); 208 | case 3: 209 | return ($instance) ? 210 | $class->$method($params[0], $params[1], $params[2]) : 211 | $class::$method($params[0], $params[1], $params[2]); 212 | case 4: 213 | return ($instance) ? 214 | $class->$method($params[0], $params[1], $params[2], $params[3]) : 215 | $class::$method($params[0], $params[1], $params[2], $params[3]); 216 | case 5: 217 | return ($instance) ? 218 | $class->$method($params[0], $params[1], $params[2], $params[3], $params[4]) : 219 | $class::$method($params[0], $params[1], $params[2], $params[3], $params[4]); 220 | default: 221 | return call_user_func_array($func, $params); 222 | } 223 | } 224 | 225 | /** 226 | * Resets the object to the initial state. 227 | */ 228 | public function reset() { 229 | $this->events = array(); 230 | $this->filters = array(); 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /_lp/lib/flight/core/Loader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\core; 10 | 11 | /** 12 | * The Loader class is responsible for loading objects. It maintains 13 | * a list of reusable class instances and can generate a new class 14 | * instances with custom initialization parameters. It also performs 15 | * class autoloading. 16 | */ 17 | class Loader { 18 | /** 19 | * Registered classes. 20 | * 21 | * @var array 22 | */ 23 | protected $classes = array(); 24 | 25 | /** 26 | * Class instances. 27 | * 28 | * @var array 29 | */ 30 | protected $instances = array(); 31 | 32 | /** 33 | * Autoload directories. 34 | * 35 | * @var array 36 | */ 37 | protected static $dirs = array(); 38 | 39 | /** 40 | * Registers a class. 41 | * 42 | * @param string $name Registry name 43 | * @param string|callable $class Class name or function to instantiate class 44 | * @param array $params Class initialization parameters 45 | * @param callback $callback Function to call after object instantiation 46 | */ 47 | public function register($name, $class, array $params = array(), $callback = null) { 48 | unset($this->instances[$name]); 49 | 50 | $this->classes[$name] = array($class, $params, $callback); 51 | } 52 | 53 | /** 54 | * Unregisters a class. 55 | * 56 | * @param string $name Registry name 57 | */ 58 | public function unregister($name) { 59 | unset($this->classes[$name]); 60 | } 61 | 62 | /** 63 | * Loads a registered class. 64 | * 65 | * @param string $name Method name 66 | * @param bool $shared Shared instance 67 | * @return object Class instance 68 | * @throws \Exception 69 | */ 70 | public function load($name, $shared = true) { 71 | $obj = null; 72 | 73 | if (isset($this->classes[$name])) { 74 | list($class, $params, $callback) = $this->classes[$name]; 75 | 76 | $exists = isset($this->instances[$name]); 77 | 78 | if ($shared) { 79 | $obj = ($exists) ? 80 | $this->getInstance($name) : 81 | $this->newInstance($class, $params); 82 | 83 | if (!$exists) { 84 | $this->instances[$name] = $obj; 85 | } 86 | } 87 | else { 88 | $obj = $this->newInstance($class, $params); 89 | } 90 | 91 | if ($callback && (!$shared || !$exists)) { 92 | $ref = array(&$obj); 93 | call_user_func_array($callback, $ref); 94 | } 95 | } 96 | 97 | return $obj; 98 | } 99 | 100 | /** 101 | * Gets a single instance of a class. 102 | * 103 | * @param string $name Instance name 104 | * @return object Class instance 105 | */ 106 | public function getInstance($name) { 107 | return isset($this->instances[$name]) ? $this->instances[$name] : null; 108 | } 109 | 110 | /** 111 | * Gets a new instance of a class. 112 | * 113 | * @param string|callable $class Class name or callback function to instantiate class 114 | * @param array $params Class initialization parameters 115 | * @return object Class instance 116 | * @throws \Exception 117 | */ 118 | public function newInstance($class, array $params = array()) { 119 | if (is_callable($class)) { 120 | return call_user_func_array($class, $params); 121 | } 122 | 123 | switch (count($params)) { 124 | case 0: 125 | return new $class(); 126 | case 1: 127 | return new $class($params[0]); 128 | case 2: 129 | return new $class($params[0], $params[1]); 130 | case 3: 131 | return new $class($params[0], $params[1], $params[2]); 132 | case 4: 133 | return new $class($params[0], $params[1], $params[2], $params[3]); 134 | case 5: 135 | return new $class($params[0], $params[1], $params[2], $params[3], $params[4]); 136 | default: 137 | try { 138 | $refClass = new \ReflectionClass($class); 139 | return $refClass->newInstanceArgs($params); 140 | } catch (\ReflectionException $e) { 141 | throw new \Exception("Cannot instantiate {$class}", 0, $e); 142 | } 143 | } 144 | } 145 | 146 | /** 147 | * @param string $name Registry name 148 | * @return mixed Class information or null if not registered 149 | */ 150 | public function get($name) { 151 | return isset($this->classes[$name]) ? $this->classes[$name] : null; 152 | } 153 | 154 | /** 155 | * Resets the object to the initial state. 156 | */ 157 | public function reset() { 158 | $this->classes = array(); 159 | $this->instances = array(); 160 | } 161 | 162 | /*** Autoloading Functions ***/ 163 | 164 | /** 165 | * Starts/stops autoloader. 166 | * 167 | * @param bool $enabled Enable/disable autoloading 168 | * @param array $dirs Autoload directories 169 | */ 170 | public static function autoload($enabled = true, $dirs = array()) { 171 | if ($enabled) { 172 | spl_autoload_register(array(__CLASS__, 'loadClass')); 173 | } 174 | else { 175 | spl_autoload_unregister(array(__CLASS__, 'loadClass')); 176 | } 177 | 178 | if (!empty($dirs)) { 179 | self::addDirectory($dirs); 180 | } 181 | } 182 | 183 | /** 184 | * Autoloads classes. 185 | * 186 | * @param string $class Class name 187 | */ 188 | public static function loadClass($class) { 189 | $class_file = str_replace(array('\\', '_'), '/', $class).'.php'; 190 | 191 | foreach (self::$dirs as $dir) { 192 | $file = $dir.'/'.$class_file; 193 | if (file_exists($file)) { 194 | require $file; 195 | return; 196 | } 197 | } 198 | } 199 | 200 | /** 201 | * Adds a directory for autoloading classes. 202 | * 203 | * @param mixed $dir Directory path 204 | */ 205 | public static function addDirectory($dir) { 206 | if (is_array($dir) || is_object($dir)) { 207 | foreach ($dir as $value) { 208 | self::addDirectory($value); 209 | } 210 | } 211 | else if (is_string($dir)) { 212 | if (!in_array($dir, self::$dirs)) self::$dirs[] = $dir; 213 | } 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /_lp/lib/flight/net/Request.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\net; 10 | 11 | use flight\util\Collection; 12 | 13 | /** 14 | * The Request class represents an HTTP request. Data from 15 | * all the super globals $_GET, $_POST, $_COOKIE, and $_FILES 16 | * are stored and accessible via the Request object. 17 | * 18 | * The default request properties are: 19 | * url - The URL being requested 20 | * base - The parent subdirectory of the URL 21 | * method - The request method (GET, POST, PUT, DELETE) 22 | * referrer - The referrer URL 23 | * ip - IP address of the client 24 | * ajax - Whether the request is an AJAX request 25 | * scheme - The server protocol (http, https) 26 | * user_agent - Browser information 27 | * type - The content type 28 | * length - The content length 29 | * query - Query string parameters 30 | * data - Post parameters 31 | * cookies - Cookie parameters 32 | * files - Uploaded files 33 | * secure - Connection is secure 34 | * accept - HTTP accept parameters 35 | * proxy_ip - Proxy IP address of the client 36 | */ 37 | class Request { 38 | /** 39 | * @var string URL being requested 40 | */ 41 | public $url; 42 | 43 | /** 44 | * @var string Parent subdirectory of the URL 45 | */ 46 | public $base; 47 | 48 | /** 49 | * @var string Request method (GET, POST, PUT, DELETE) 50 | */ 51 | public $method; 52 | 53 | /** 54 | * @var string Referrer URL 55 | */ 56 | public $referrer; 57 | 58 | /** 59 | * @var string IP address of the client 60 | */ 61 | public $ip; 62 | 63 | /** 64 | * @var bool Whether the request is an AJAX request 65 | */ 66 | public $ajax; 67 | 68 | /** 69 | * @var string Server protocol (http, https) 70 | */ 71 | public $scheme; 72 | 73 | /** 74 | * @var string Browser information 75 | */ 76 | public $user_agent; 77 | 78 | /** 79 | * @var string Content type 80 | */ 81 | public $type; 82 | 83 | /** 84 | * @var int Content length 85 | */ 86 | public $length; 87 | 88 | /** 89 | * @var \flight\util\Collection Query string parameters 90 | */ 91 | public $query; 92 | 93 | /** 94 | * @var \flight\util\Collection Post parameters 95 | */ 96 | public $data; 97 | 98 | /** 99 | * @var \flight\util\Collection Cookie parameters 100 | */ 101 | public $cookies; 102 | 103 | /** 104 | * @var \flight\util\Collection Uploaded files 105 | */ 106 | public $files; 107 | 108 | /** 109 | * @var bool Whether the connection is secure 110 | */ 111 | public $secure; 112 | 113 | /** 114 | * @var string HTTP accept parameters 115 | */ 116 | public $accept; 117 | 118 | /** 119 | * @var string Proxy IP address of the client 120 | */ 121 | public $proxy_ip; 122 | 123 | /** 124 | * @var string HTTP host name 125 | */ 126 | public $host; 127 | 128 | /** 129 | * Constructor. 130 | * 131 | * @param array $config Request configuration 132 | */ 133 | public function __construct($config = array()) { 134 | // Default properties 135 | if (empty($config)) { 136 | $config = array( 137 | 'url' => str_replace('@', '%40', self::getVar('REQUEST_URI', '/')), 138 | 'base' => str_replace(array('\\',' '), array('/','%20'), dirname(self::getVar('SCRIPT_NAME'))), 139 | 'method' => self::getMethod(), 140 | 'referrer' => self::getVar('HTTP_REFERER'), 141 | 'ip' => self::getVar('REMOTE_ADDR'), 142 | 'ajax' => self::getVar('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest', 143 | 'scheme' => self::getScheme(), 144 | 'user_agent' => self::getVar('HTTP_USER_AGENT'), 145 | 'type' => self::getVar('CONTENT_TYPE'), 146 | 'length' => self::getVar('CONTENT_LENGTH', 0), 147 | 'query' => new Collection($_GET), 148 | 'data' => new Collection($_POST), 149 | 'cookies' => new Collection($_COOKIE), 150 | 'files' => new Collection($_FILES), 151 | 'secure' => self::getScheme() == 'https', 152 | 'accept' => self::getVar('HTTP_ACCEPT'), 153 | 'proxy_ip' => self::getProxyIpAddress(), 154 | 'host' => self::getVar('HTTP_HOST'), 155 | ); 156 | } 157 | 158 | $this->init($config); 159 | } 160 | 161 | /** 162 | * Initialize request properties. 163 | * 164 | * @param array $properties Array of request properties 165 | */ 166 | public function init($properties = array()) { 167 | // Set all the defined properties 168 | foreach ($properties as $name => $value) { 169 | $this->$name = $value; 170 | } 171 | 172 | // Get the requested URL without the base directory 173 | if ($this->base != '/' && strlen($this->base) > 0 && strpos($this->url, $this->base) === 0) { 174 | $this->url = substr($this->url, strlen($this->base)); 175 | } 176 | 177 | // Default url 178 | if (empty($this->url)) { 179 | $this->url = '/'; 180 | } 181 | // Merge URL query parameters with $_GET 182 | else { 183 | $_GET += self::parseQuery($this->url); 184 | 185 | $this->query->setData($_GET); 186 | } 187 | 188 | // Check for JSON input 189 | if (strpos($this->type, 'application/json') === 0) { 190 | $body = $this->getBody(); 191 | if ($body != '') { 192 | $data = json_decode($body, true); 193 | if ($data != null) { 194 | $this->data->setData($data); 195 | } 196 | } 197 | } 198 | } 199 | 200 | /** 201 | * Gets the body of the request. 202 | * 203 | * @return string Raw HTTP request body 204 | */ 205 | public static function getBody() { 206 | static $body; 207 | 208 | if (!is_null($body)) { 209 | return $body; 210 | } 211 | 212 | $method = self::getMethod(); 213 | 214 | if ($method == 'POST' || $method == 'PUT' || $method == 'PATCH') { 215 | $body = file_get_contents('php://input'); 216 | } 217 | 218 | return $body; 219 | } 220 | 221 | /** 222 | * Gets the request method. 223 | * 224 | * @return string 225 | */ 226 | public static function getMethod() { 227 | $method = self::getVar('REQUEST_METHOD', 'GET'); 228 | 229 | if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { 230 | $method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; 231 | } 232 | elseif (isset($_REQUEST['_method'])) { 233 | $method = $_REQUEST['_method']; 234 | } 235 | 236 | return strtoupper($method); 237 | } 238 | 239 | /** 240 | * Gets the real remote IP address. 241 | * 242 | * @return string IP address 243 | */ 244 | public static function getProxyIpAddress() { 245 | static $forwarded = array( 246 | 'HTTP_CLIENT_IP', 247 | 'HTTP_X_FORWARDED_FOR', 248 | 'HTTP_X_FORWARDED', 249 | 'HTTP_X_CLUSTER_CLIENT_IP', 250 | 'HTTP_FORWARDED_FOR', 251 | 'HTTP_FORWARDED' 252 | ); 253 | 254 | $flags = \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE; 255 | 256 | foreach ($forwarded as $key) { 257 | if (array_key_exists($key, $_SERVER)) { 258 | sscanf($_SERVER[$key], '%[^,]', $ip); 259 | if (filter_var($ip, \FILTER_VALIDATE_IP, $flags) !== false) { 260 | return $ip; 261 | } 262 | } 263 | } 264 | 265 | return ''; 266 | } 267 | 268 | /** 269 | * Gets a variable from $_SERVER using $default if not provided. 270 | * 271 | * @param string $var Variable name 272 | * @param string $default Default value to substitute 273 | * @return string Server variable value 274 | */ 275 | public static function getVar($var, $default = '') { 276 | return isset($_SERVER[$var]) ? $_SERVER[$var] : $default; 277 | } 278 | 279 | /** 280 | * Parse query parameters from a URL. 281 | * 282 | * @param string $url URL string 283 | * @return array Query parameters 284 | */ 285 | public static function parseQuery($url) { 286 | $params = array(); 287 | 288 | $args = parse_url($url); 289 | if (isset($args['query'])) { 290 | parse_str($args['query'], $params); 291 | } 292 | 293 | return $params; 294 | } 295 | 296 | public static function getScheme() { 297 | if ( 298 | (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on') 299 | || 300 | (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') 301 | || 302 | (isset($_SERVER['HTTP_FRONT_END_HTTPS']) && $_SERVER['HTTP_FRONT_END_HTTPS'] === 'on') 303 | || 304 | (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') 305 | ) { 306 | return 'https'; 307 | } 308 | return 'http'; 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /_lp/lib/flight/net/Response.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\net; 10 | 11 | /** 12 | * The Response class represents an HTTP response. The object 13 | * contains the response headers, HTTP status code, and response 14 | * body. 15 | */ 16 | class Response { 17 | /** 18 | * @var int HTTP status 19 | */ 20 | protected $status = 200; 21 | 22 | /** 23 | * @var array HTTP headers 24 | */ 25 | protected $headers = array(); 26 | 27 | /** 28 | * @var string HTTP response body 29 | */ 30 | protected $body; 31 | 32 | /** 33 | * @var bool HTTP response sent 34 | */ 35 | protected $sent = false; 36 | 37 | /** 38 | * @var array HTTP status codes 39 | */ 40 | public static $codes = array( 41 | 100 => 'Continue', 42 | 101 => 'Switching Protocols', 43 | 102 => 'Processing', 44 | 45 | 200 => 'OK', 46 | 201 => 'Created', 47 | 202 => 'Accepted', 48 | 203 => 'Non-Authoritative Information', 49 | 204 => 'No Content', 50 | 205 => 'Reset Content', 51 | 206 => 'Partial Content', 52 | 207 => 'Multi-Status', 53 | 208 => 'Already Reported', 54 | 55 | 226 => 'IM Used', 56 | 57 | 300 => 'Multiple Choices', 58 | 301 => 'Moved Permanently', 59 | 302 => 'Found', 60 | 303 => 'See Other', 61 | 304 => 'Not Modified', 62 | 305 => 'Use Proxy', 63 | 306 => '(Unused)', 64 | 307 => 'Temporary Redirect', 65 | 308 => 'Permanent Redirect', 66 | 67 | 400 => 'Bad Request', 68 | 401 => 'Unauthorized', 69 | 402 => 'Payment Required', 70 | 403 => 'Forbidden', 71 | 404 => 'Not Found', 72 | 405 => 'Method Not Allowed', 73 | 406 => 'Not Acceptable', 74 | 407 => 'Proxy Authentication Required', 75 | 408 => 'Request Timeout', 76 | 409 => 'Conflict', 77 | 410 => 'Gone', 78 | 411 => 'Length Required', 79 | 412 => 'Precondition Failed', 80 | 413 => 'Payload Too Large', 81 | 414 => 'URI Too Long', 82 | 415 => 'Unsupported Media Type', 83 | 416 => 'Range Not Satisfiable', 84 | 417 => 'Expectation Failed', 85 | 86 | 422 => 'Unprocessable Entity', 87 | 423 => 'Locked', 88 | 424 => 'Failed Dependency', 89 | 90 | 426 => 'Upgrade Required', 91 | 92 | 428 => 'Precondition Required', 93 | 429 => 'Too Many Requests', 94 | 95 | 431 => 'Request Header Fields Too Large', 96 | 97 | 500 => 'Internal Server Error', 98 | 501 => 'Not Implemented', 99 | 502 => 'Bad Gateway', 100 | 503 => 'Service Unavailable', 101 | 504 => 'Gateway Timeout', 102 | 505 => 'HTTP Version Not Supported', 103 | 506 => 'Variant Also Negotiates', 104 | 507 => 'Insufficient Storage', 105 | 508 => 'Loop Detected', 106 | 107 | 510 => 'Not Extended', 108 | 511 => 'Network Authentication Required' 109 | ); 110 | 111 | /** 112 | * Sets the HTTP status of the response. 113 | * 114 | * @param int $code HTTP status code. 115 | * @return object|int Self reference 116 | * @throws \Exception If invalid status code 117 | */ 118 | public function status($code = null) { 119 | if ($code === null) { 120 | return $this->status; 121 | } 122 | 123 | if (array_key_exists($code, self::$codes)) { 124 | $this->status = $code; 125 | } 126 | else { 127 | throw new \Exception('Invalid status code.'); 128 | } 129 | 130 | return $this; 131 | } 132 | 133 | /** 134 | * Adds a header to the response. 135 | * 136 | * @param string|array $name Header name or array of names and values 137 | * @param string $value Header value 138 | * @return object Self reference 139 | */ 140 | public function header($name, $value = null) { 141 | if (is_array($name)) { 142 | foreach ($name as $k => $v) { 143 | $this->headers[$k] = $v; 144 | } 145 | } 146 | else { 147 | $this->headers[$name] = $value; 148 | } 149 | 150 | return $this; 151 | } 152 | 153 | /** 154 | * Returns the headers from the response 155 | * @return array 156 | */ 157 | public function headers() { 158 | return $this->headers; 159 | } 160 | 161 | /** 162 | * Writes content to the response body. 163 | * 164 | * @param string $str Response content 165 | * @return object Self reference 166 | */ 167 | public function write($str) { 168 | $this->body .= $str; 169 | 170 | return $this; 171 | } 172 | 173 | /** 174 | * Clears the response. 175 | * 176 | * @return object Self reference 177 | */ 178 | public function clear() { 179 | $this->status = 200; 180 | $this->headers = array(); 181 | $this->body = ''; 182 | 183 | return $this; 184 | } 185 | 186 | /** 187 | * Sets caching headers for the response. 188 | * 189 | * @param int|string $expires Expiration time 190 | * @return object Self reference 191 | */ 192 | public function cache($expires) { 193 | if ($expires === false) { 194 | $this->headers['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT'; 195 | $this->headers['Cache-Control'] = array( 196 | 'no-store, no-cache, must-revalidate', 197 | 'post-check=0, pre-check=0', 198 | 'max-age=0' 199 | ); 200 | $this->headers['Pragma'] = 'no-cache'; 201 | } 202 | else { 203 | $expires = is_int($expires) ? $expires : strtotime($expires); 204 | $this->headers['Expires'] = gmdate('D, d M Y H:i:s', $expires) . ' GMT'; 205 | $this->headers['Cache-Control'] = 'max-age='.($expires - time()); 206 | if (isset($this->headers['Pragma']) && $this->headers['Pragma'] == 'no-cache'){ 207 | unset($this->headers['Pragma']); 208 | } 209 | } 210 | return $this; 211 | } 212 | 213 | /** 214 | * Sends HTTP headers. 215 | * 216 | * @return object Self reference 217 | */ 218 | public function sendHeaders() { 219 | // Send status code header 220 | if (strpos(php_sapi_name(), 'cgi') !== false) { 221 | header( 222 | sprintf( 223 | 'Status: %d %s', 224 | $this->status, 225 | self::$codes[$this->status] 226 | ), 227 | true 228 | ); 229 | } 230 | else { 231 | header( 232 | sprintf( 233 | '%s %d %s', 234 | (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'), 235 | $this->status, 236 | self::$codes[$this->status]), 237 | true, 238 | $this->status 239 | ); 240 | } 241 | 242 | // Send other headers 243 | foreach ($this->headers as $field => $value) { 244 | if (is_array($value)) { 245 | foreach ($value as $v) { 246 | header($field.': '.$v, false); 247 | } 248 | } 249 | else { 250 | header($field.': '.$value); 251 | } 252 | } 253 | 254 | // Send content length 255 | $length = $this->getContentLength(); 256 | 257 | if ($length > 0) { 258 | header('Content-Length: '.$length); 259 | } 260 | 261 | return $this; 262 | } 263 | 264 | /** 265 | * Gets the content length. 266 | * 267 | * @return string Content length 268 | */ 269 | public function getContentLength() { 270 | return extension_loaded('mbstring') ? 271 | mb_strlen($this->body, 'latin1') : 272 | strlen($this->body); 273 | } 274 | 275 | /** 276 | * Gets whether response was sent. 277 | */ 278 | public function sent() { 279 | return $this->sent; 280 | } 281 | 282 | /** 283 | * Sends a HTTP response. 284 | */ 285 | public function send() { 286 | if (ob_get_length() > 0) { 287 | ob_end_clean(); 288 | } 289 | 290 | if (!headers_sent()) { 291 | $this->sendHeaders(); 292 | } 293 | 294 | echo $this->body; 295 | 296 | $this->sent = true; 297 | } 298 | } 299 | 300 | -------------------------------------------------------------------------------- /_lp/lib/flight/net/Route.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\net; 10 | 11 | /** 12 | * The Route class is responsible for routing an HTTP request to 13 | * an assigned callback function. The Router tries to match the 14 | * requested URL against a series of URL patterns. 15 | */ 16 | class Route { 17 | /** 18 | * @var string URL pattern 19 | */ 20 | public $pattern; 21 | 22 | /** 23 | * @var mixed Callback function 24 | */ 25 | public $callback; 26 | 27 | /** 28 | * @var array HTTP methods 29 | */ 30 | public $methods = array(); 31 | 32 | /** 33 | * @var array Route parameters 34 | */ 35 | public $params = array(); 36 | 37 | /** 38 | * @var string Matching regular expression 39 | */ 40 | public $regex; 41 | 42 | /** 43 | * @var string URL splat content 44 | */ 45 | public $splat = ''; 46 | 47 | /** 48 | * @var boolean Pass self in callback parameters 49 | */ 50 | public $pass = false; 51 | 52 | /** 53 | * Constructor. 54 | * 55 | * @param string $pattern URL pattern 56 | * @param mixed $callback Callback function 57 | * @param array $methods HTTP methods 58 | * @param boolean $pass Pass self in callback parameters 59 | */ 60 | public function __construct($pattern, $callback, $methods, $pass) { 61 | $this->pattern = $pattern; 62 | $this->callback = $callback; 63 | $this->methods = $methods; 64 | $this->pass = $pass; 65 | } 66 | 67 | /** 68 | * Checks if a URL matches the route pattern. Also parses named parameters in the URL. 69 | * 70 | * @param string $url Requested URL 71 | * @param boolean $case_sensitive Case sensitive matching 72 | * @return boolean Match status 73 | */ 74 | public function matchUrl($url, $case_sensitive = false) { 75 | // Wildcard or exact match 76 | if ($this->pattern === '*' || $this->pattern === $url) { 77 | return true; 78 | } 79 | 80 | $ids = array(); 81 | $last_char = substr($this->pattern, -1); 82 | 83 | // Get splat 84 | if ($last_char === '*') { 85 | $n = 0; 86 | $len = strlen($url); 87 | $count = substr_count($this->pattern, '/'); 88 | 89 | for ($i = 0; $i < $len; $i++) { 90 | if ($url[$i] == '/') $n++; 91 | if ($n == $count) break; 92 | } 93 | 94 | $this->splat = (string)substr($url, $i+1); 95 | } 96 | 97 | // Build the regex for matching 98 | $regex = str_replace(array(')','/*'), array(')?','(/?|/.*?)'), $this->pattern); 99 | 100 | $regex = preg_replace_callback( 101 | '#@([\w]+)(:([^/\(\)]*))?#', 102 | function($matches) use (&$ids) { 103 | $ids[$matches[1]] = null; 104 | if (isset($matches[3])) { 105 | return '(?P<'.$matches[1].'>'.$matches[3].')'; 106 | } 107 | return '(?P<'.$matches[1].'>[^/\?]+)'; 108 | }, 109 | $regex 110 | ); 111 | 112 | // Fix trailing slash 113 | if ($last_char === '/') { 114 | $regex .= '?'; 115 | } 116 | // Allow trailing slash 117 | else { 118 | $regex .= '/?'; 119 | } 120 | 121 | // Attempt to match route and named parameters 122 | if (preg_match('#^'.$regex.'(?:\?.*)?$#'.(($case_sensitive) ? '' : 'i'), $url, $matches)) { 123 | foreach ($ids as $k => $v) { 124 | $this->params[$k] = (array_key_exists($k, $matches)) ? urldecode($matches[$k]) : null; 125 | } 126 | 127 | $this->regex = $regex; 128 | 129 | return true; 130 | } 131 | 132 | return false; 133 | } 134 | 135 | /** 136 | * Checks if an HTTP method matches the route methods. 137 | * 138 | * @param string $method HTTP method 139 | * @return bool Match status 140 | */ 141 | public function matchMethod($method) { 142 | return count(array_intersect(array($method, '*'), $this->methods)) > 0; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /_lp/lib/flight/net/Router.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\net; 10 | 11 | /** 12 | * The Router class is responsible for routing an HTTP request to 13 | * an assigned callback function. The Router tries to match the 14 | * requested URL against a series of URL patterns. 15 | */ 16 | class Router { 17 | /** 18 | * Mapped routes. 19 | * 20 | * @var array 21 | */ 22 | protected $routes = array(); 23 | 24 | /** 25 | * Pointer to current route. 26 | * 27 | * @var int 28 | */ 29 | protected $index = 0; 30 | 31 | /** 32 | * Case sensitive matching. 33 | * 34 | * @var boolean 35 | */ 36 | public $case_sensitive = false; 37 | 38 | /** 39 | * Gets mapped routes. 40 | * 41 | * @return array Array of routes 42 | */ 43 | public function getRoutes() { 44 | return $this->routes; 45 | } 46 | 47 | /** 48 | * Clears all routes in the router. 49 | */ 50 | public function clear() { 51 | $this->routes = array(); 52 | } 53 | 54 | /** 55 | * Maps a URL pattern to a callback function. 56 | * 57 | * @param string $pattern URL pattern to match 58 | * @param callback $callback Callback function 59 | * @param boolean $pass_route Pass the matching route object to the callback 60 | */ 61 | public function map($pattern, $callback, $pass_route = false) { 62 | $url = $pattern; 63 | $methods = array('*'); 64 | 65 | if (strpos($pattern, ' ') !== false) { 66 | list($method, $url) = explode(' ', trim($pattern), 2); 67 | 68 | $methods = explode('|', $method); 69 | } 70 | 71 | $this->routes[] = new Route($url, $callback, $methods, $pass_route); 72 | } 73 | 74 | /** 75 | * Routes the current request. 76 | * 77 | * @param Request $request Request object 78 | * @return Route|bool Matching route or false if no match 79 | */ 80 | public function route(Request $request) { 81 | $url_decoded = urldecode( $request->url ); 82 | while ($route = $this->current()) { 83 | if ($route !== false && $route->matchMethod($request->method) && $route->matchUrl($url_decoded, $this->case_sensitive)) { 84 | return $route; 85 | } 86 | $this->next(); 87 | } 88 | 89 | return false; 90 | } 91 | 92 | /** 93 | * Gets the current route. 94 | * 95 | * @return Route 96 | */ 97 | public function current() { 98 | return isset($this->routes[$this->index]) ? $this->routes[$this->index] : false; 99 | } 100 | 101 | /** 102 | * Gets the next route. 103 | * 104 | * @return Route 105 | */ 106 | public function next() { 107 | $this->index++; 108 | } 109 | 110 | /** 111 | * Reset to the first route. 112 | */ 113 | public function reset() { 114 | $this->index = 0; 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /_lp/lib/flight/template/View.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\template; 10 | 11 | /** 12 | * The View class represents output to be displayed. It provides 13 | * methods for managing view data and inserts the data into 14 | * view templates upon rendering. 15 | */ 16 | class View { 17 | /** 18 | * Location of view templates. 19 | * 20 | * @var string 21 | */ 22 | public $path; 23 | 24 | /** 25 | * File extension. 26 | * 27 | * @var string 28 | */ 29 | public $extension = '.php'; 30 | 31 | /** 32 | * View variables. 33 | * 34 | * @var array 35 | */ 36 | protected $vars = array(); 37 | 38 | /** 39 | * Template file. 40 | * 41 | * @var string 42 | */ 43 | private $template; 44 | 45 | /** 46 | * Constructor. 47 | * 48 | * @param string $path Path to templates directory 49 | */ 50 | public function __construct($path = '.') { 51 | $this->path = $path; 52 | } 53 | 54 | /** 55 | * Gets a template variable. 56 | * 57 | * @param string $key Key 58 | * @return mixed Value 59 | */ 60 | public function get($key) { 61 | return isset($this->vars[$key]) ? $this->vars[$key] : null; 62 | } 63 | 64 | /** 65 | * Sets a template variable. 66 | * 67 | * @param mixed $key Key 68 | * @param string $value Value 69 | */ 70 | public function set($key, $value = null) { 71 | if (is_array($key) || is_object($key)) { 72 | foreach ($key as $k => $v) { 73 | $this->vars[$k] = $v; 74 | } 75 | } 76 | else { 77 | $this->vars[$key] = $value; 78 | } 79 | } 80 | 81 | /** 82 | * Checks if a template variable is set. 83 | * 84 | * @param string $key Key 85 | * @return boolean If key exists 86 | */ 87 | public function has($key) { 88 | return isset($this->vars[$key]); 89 | } 90 | 91 | /** 92 | * Unsets a template variable. If no key is passed in, clear all variables. 93 | * 94 | * @param string $key Key 95 | */ 96 | public function clear($key = null) { 97 | if (is_null($key)) { 98 | $this->vars = array(); 99 | } 100 | else { 101 | unset($this->vars[$key]); 102 | } 103 | } 104 | 105 | /** 106 | * Renders a template. 107 | * 108 | * @param string $file Template file 109 | * @param array $data Template data 110 | * @throws \Exception If template not found 111 | */ 112 | public function render($file, $data = null) { 113 | $this->template = $this->getTemplate($file); 114 | 115 | if (!file_exists($this->template)) { 116 | throw new \Exception("Template file not found: {$this->template}."); 117 | } 118 | 119 | if (is_array($data)) { 120 | $this->vars = array_merge($this->vars, $data); 121 | } 122 | 123 | extract($this->vars); 124 | 125 | include $this->template; 126 | } 127 | 128 | /** 129 | * Gets the output of a template. 130 | * 131 | * @param string $file Template file 132 | * @param array $data Template data 133 | * @return string Output of template 134 | */ 135 | public function fetch($file, $data = null) { 136 | ob_start(); 137 | 138 | $this->render($file, $data); 139 | $output = ob_get_clean(); 140 | 141 | return $output; 142 | } 143 | 144 | /** 145 | * Checks if a template file exists. 146 | * 147 | * @param string $file Template file 148 | * @return bool Template file exists 149 | */ 150 | public function exists($file) { 151 | return file_exists($this->getTemplate($file)); 152 | } 153 | 154 | /** 155 | * Gets the full path to a template file. 156 | * 157 | * @param string $file Template file 158 | * @return string Template file location 159 | */ 160 | public function getTemplate($file) { 161 | $ext = $this->extension; 162 | 163 | if (!empty($ext) && (substr($file, -1 * strlen($ext)) != $ext)) { 164 | $file .= $ext; 165 | } 166 | 167 | if ((substr($file, 0, 1) == '/')) { 168 | return $file; 169 | } 170 | 171 | return $this->path.'/'.$file; 172 | } 173 | 174 | /** 175 | * Displays escaped output. 176 | * 177 | * @param string $str String to escape 178 | * @return string Escaped string 179 | */ 180 | public function e($str) { 181 | echo htmlentities($str); 182 | } 183 | } 184 | 185 | -------------------------------------------------------------------------------- /_lp/lib/flight/util/Collection.php: -------------------------------------------------------------------------------- 1 | 6 | * @license MIT, http://flightphp.com/license 7 | */ 8 | 9 | namespace flight\util; 10 | 11 | /** 12 | * The Collection class allows you to access a set of data 13 | * using both array and object notation. 14 | */ 15 | class Collection implements \ArrayAccess, \Iterator, \Countable { 16 | /** 17 | * Collection data. 18 | * 19 | * @var array 20 | */ 21 | private $data; 22 | 23 | /** 24 | * Constructor. 25 | * 26 | * @param array $data Initial data 27 | */ 28 | public function __construct(array $data = array()) { 29 | $this->data = $data; 30 | } 31 | 32 | /** 33 | * Gets an item. 34 | * 35 | * @param string $key Key 36 | * @return mixed Value 37 | */ 38 | public function __get($key) { 39 | return isset($this->data[$key]) ? $this->data[$key] : null; 40 | } 41 | 42 | /** 43 | * Set an item. 44 | * 45 | * @param string $key Key 46 | * @param mixed $value Value 47 | */ 48 | public function __set($key, $value) { 49 | $this->data[$key] = $value; 50 | } 51 | 52 | /** 53 | * Checks if an item exists. 54 | * 55 | * @param string $key Key 56 | * @return bool Item status 57 | */ 58 | public function __isset($key) { 59 | return isset($this->data[$key]); 60 | } 61 | 62 | /** 63 | * Removes an item. 64 | * 65 | * @param string $key Key 66 | */ 67 | public function __unset($key) { 68 | unset($this->data[$key]); 69 | } 70 | 71 | /** 72 | * Gets an item at the offset. 73 | * 74 | * @param string $offset Offset 75 | * @return mixed Value 76 | */ 77 | public function offsetGet($offset) { 78 | return isset($this->data[$offset]) ? $this->data[$offset] : null; 79 | } 80 | 81 | /** 82 | * Sets an item at the offset. 83 | * 84 | * @param string $offset Offset 85 | * @param mixed $value Value 86 | */ 87 | public function offsetSet($offset, $value) { 88 | if (is_null($offset)) { 89 | $this->data[] = $value; 90 | } 91 | else { 92 | $this->data[$offset] = $value; 93 | } 94 | } 95 | 96 | /** 97 | * Checks if an item exists at the offset. 98 | * 99 | * @param string $offset Offset 100 | * @return bool Item status 101 | */ 102 | public function offsetExists($offset) { 103 | return isset($this->data[$offset]); 104 | } 105 | 106 | /** 107 | * Removes an item at the offset. 108 | * 109 | * @param string $offset Offset 110 | */ 111 | public function offsetUnset($offset) { 112 | unset($this->data[$offset]); 113 | } 114 | 115 | /** 116 | * Resets the collection. 117 | */ 118 | public function rewind() { 119 | reset($this->data); 120 | } 121 | 122 | /** 123 | * Gets current collection item. 124 | * 125 | * @return mixed Value 126 | */ 127 | public function current() { 128 | return current($this->data); 129 | } 130 | 131 | /** 132 | * Gets current collection key. 133 | * 134 | * @return mixed Value 135 | */ 136 | public function key() { 137 | return key($this->data); 138 | } 139 | 140 | /** 141 | * Gets the next collection value. 142 | * 143 | * @return mixed Value 144 | */ 145 | public function next() 146 | { 147 | return next($this->data); 148 | } 149 | 150 | /** 151 | * Checks if the current collection key is valid. 152 | * 153 | * @return bool Key status 154 | */ 155 | public function valid() 156 | { 157 | $key = key($this->data); 158 | return ($key !== NULL && $key !== FALSE); 159 | } 160 | 161 | /** 162 | * Gets the size of the collection. 163 | * 164 | * @return int Collection size 165 | */ 166 | public function count() { 167 | return sizeof($this->data); 168 | } 169 | 170 | /** 171 | * Gets the item keys. 172 | * 173 | * @return array Collection keys 174 | */ 175 | public function keys() { 176 | return array_keys($this->data); 177 | } 178 | 179 | /** 180 | * Gets the collection data. 181 | * 182 | * @return array Collection data 183 | */ 184 | public function getData() { 185 | return $this->data; 186 | } 187 | 188 | /** 189 | * Sets the collection data. 190 | * 191 | * @param array $data New collection data 192 | */ 193 | public function setData(array $data) { 194 | $this->data = $data; 195 | } 196 | 197 | /** 198 | * Removes all items from the collection. 199 | */ 200 | public function clear() { 201 | $this->data = array(); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /_lp/lp.init.php: -------------------------------------------------------------------------------- 1 | getMessage(); 49 | $error['created'] = date("Y-m-d H:i:s"); 50 | 51 | if( is_json_request() || c('api_server_only') ) 52 | send_json( $error ); 53 | elseif( is_ajax_request() ) 54 | render_ajax( $error , 'info' ); 55 | else 56 | render_web( $error , 'info' ); 57 | 58 | } 59 | catch(\Lazyphp\Core\RestException $e) 60 | { 61 | $class_array = explode( '\\' , get_class( $e ) ); 62 | $class = t(end( $class_array )); 63 | $prefix = strtoupper(rremove( $class , 'Exception' )); 64 | 65 | $error = get_error( $prefix ); 66 | $error['message'] = $error['message'] . '- ' .$e->getMessage(); 67 | $error['created'] = date("Y-m-d H:i:s"); 68 | 69 | if( is_json_request() || c('api_server_only') ) 70 | send_json( $error ); 71 | elseif( is_ajax_request() ) 72 | render_ajax( $error , 'info' ); 73 | else 74 | render_web( $error , 'info' ); 75 | 76 | } 77 | catch(\Exception $e) 78 | { 79 | $class_array = explode( '\\' , get_class( $e ) ); 80 | $class = t(end( $class_array )); 81 | $prefix = strtoupper(rremove( $class , 'Exception' )); 82 | 83 | $error = get_error( $prefix ); 84 | $error['message'] = $error['message'] . '- ' .$e->getMessage(); 85 | $error['created'] = date("Y-m-d H:i:s"); 86 | 87 | if( is_json_request() || c('api_server_only') ) 88 | send_json( $error ); 89 | elseif( is_ajax_request() ) 90 | render_ajax( $error , 'info' ); 91 | else 92 | render_web( $error , 'info' ); 93 | } 94 | -------------------------------------------------------------------------------- /assets/css/stylish-portfolio.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - Stylish Portfolio Bootstrap Theme (http://startbootstrap.com) 3 | * Code licensed under the Apache License v2.0. 4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0. 5 | */ 6 | 7 | /* Global Styles */ 8 | 9 | html, 10 | body { 11 | width: 100%; 12 | height: 100%; 13 | } 14 | 15 | body { 16 | font-family: "Helvetica Neue",Helvetica,"Hiragino Sans GB","STHeitiSC-Light","Microsoft YaHei","微软雅黑",Arial,sans-serif; 17 | } 18 | 19 | .text-vertical-center { 20 | display: table-cell; 21 | text-align: center; 22 | vertical-align: middle; 23 | } 24 | 25 | .text-vertical-center h1 { 26 | margin: 0; 27 | padding: 0; 28 | font-size: 4.5em; 29 | font-weight: 700; 30 | } 31 | 32 | /* Custom Button Styles */ 33 | 34 | .btn-dark { 35 | border-radius: 0; 36 | color: #fff; 37 | background-color: rgba(0,0,0,0.4); 38 | } 39 | 40 | .btn-dark:hover, 41 | .btn-dark:focus, 42 | .btn-dark:active { 43 | color: #fff; 44 | background-color: rgba(0,0,0,0.7); 45 | } 46 | 47 | .btn-light { 48 | border-radius: 0; 49 | color: #333; 50 | background-color: rgb(255,255,255); 51 | } 52 | 53 | .btn-light:hover, 54 | .btn-light:focus, 55 | .btn-light:active { 56 | color: #333; 57 | background-color: rgba(255,255,255,0.8); 58 | } 59 | 60 | /* Custom Horizontal Rule */ 61 | 62 | hr.small { 63 | max-width: 100px; 64 | } 65 | 66 | /* Side Menu */ 67 | 68 | #sidebar-wrapper { 69 | z-index: 1000; 70 | position: fixed; 71 | right: 0; 72 | width: 250px; 73 | height: 100%; 74 | margin-right: -250px; 75 | overflow-y: auto; 76 | background: #222; 77 | -webkit-transition: all 0.4s ease 0s; 78 | -moz-transition: all 0.4s ease 0s; 79 | -ms-transition: all 0.4s ease 0s; 80 | -o-transition: all 0.4s ease 0s; 81 | transition: all 0.4s ease 0s; 82 | } 83 | 84 | .sidebar-nav { 85 | position: absolute; 86 | top: 0; 87 | width: 250px; 88 | margin: 0; 89 | padding: 0; 90 | list-style: none; 91 | } 92 | 93 | .sidebar-nav li { 94 | text-indent: 20px; 95 | line-height: 40px; 96 | } 97 | 98 | .sidebar-nav li a { 99 | display: block; 100 | text-decoration: none; 101 | color: #999; 102 | } 103 | 104 | .sidebar-nav li a:hover { 105 | text-decoration: none; 106 | color: #fff; 107 | background: rgba(255,255,255,0.2); 108 | } 109 | 110 | .sidebar-nav li a:active, 111 | .sidebar-nav li a:focus { 112 | text-decoration: none; 113 | } 114 | 115 | .sidebar-nav > .sidebar-brand { 116 | height: 55px; 117 | font-size: 18px; 118 | line-height: 55px; 119 | } 120 | 121 | .sidebar-nav > .sidebar-brand a { 122 | color: #999; 123 | } 124 | 125 | .sidebar-nav > .sidebar-brand a:hover { 126 | color: #fff; 127 | background: none; 128 | } 129 | 130 | #menu-toggle { 131 | z-index: 1; 132 | position: fixed; 133 | top: 0; 134 | right: 0; 135 | /* 136 | background-color: rgba(255,255,255,.8); 137 | height:40px; 138 | width:40px; 139 | */ 140 | } 141 | 142 | #sidebar-wrapper.active { 143 | right: 250px; 144 | width: 250px; 145 | -webkit-transition: all 0.4s ease 0s; 146 | -moz-transition: all 0.4s ease 0s; 147 | -ms-transition: all 0.4s ease 0s; 148 | -o-transition: all 0.4s ease 0s; 149 | transition: all 0.4s ease 0s; 150 | } 151 | 152 | .toggle { 153 | margin: 5px 5px 0 0; 154 | } 155 | 156 | /* Header */ 157 | 158 | .header { 159 | color:rgba(255,255,255,1); 160 | text-shadow: 2px 2px 2px rgba(0,0,0,.6); 161 | display: table; 162 | position: relative; 163 | width: 100%; 164 | height: 100%; 165 | background: url(http://ww1.sinaimg.cn/large/40dfde6fjw1exdczmyl8nj215o0s718t.jpg) no-repeat center center scroll; 166 | -webkit-background-size: cover; 167 | -moz-background-size: cover; 168 | background-size: cover; 169 | -o-background-size: cover; 170 | } 171 | 172 | /* About */ 173 | 174 | .about { 175 | padding: 50px 0; 176 | } 177 | 178 | /* Services */ 179 | 180 | .services { 181 | padding: 50px 0; 182 | } 183 | 184 | .service-item { 185 | margin-bottom: 30px; 186 | } 187 | 188 | 189 | /* Footer */ 190 | 191 | footer { 192 | padding: 100px 0; 193 | } -------------------------------------------------------------------------------- /assets/css/toastr.min.css: -------------------------------------------------------------------------------- 1 | .toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#fff;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8;-ms-filter:alpha(Opacity=80);filter:alpha(opacity=80)}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;-ms-filter:alpha(Opacity=40);filter:alpha(opacity=40)}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{position:relative;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#fff;opacity:.8;-ms-filter:alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;-ms-filter:alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{width:300px;margin:auto}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin:auto}.toast{background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-warning{background-color:#f89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4;-ms-filter:alpha(Opacity=40);filter:alpha(opacity=40)}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}} -------------------------------------------------------------------------------- /assets/fonts/lrfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/LazyRest4/42b99dc4f39ff14cd7ebaf10727cb60c409859a8/assets/fonts/lrfont.eot -------------------------------------------------------------------------------- /assets/fonts/lrfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /assets/fonts/lrfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/LazyRest4/42b99dc4f39ff14cd7ebaf10727cb60c409859a8/assets/fonts/lrfont.ttf -------------------------------------------------------------------------------- /assets/fonts/lrfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/LazyRest4/42b99dc4f39ff14cd7ebaf10727cb60c409859a8/assets/fonts/lrfont.woff -------------------------------------------------------------------------------- /assets/image/logo.lr4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/LazyRest4/42b99dc4f39ff14cd7ebaf10727cb60c409859a8/assets/image/logo.lr4.png -------------------------------------------------------------------------------- /assets/image/news.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/LazyRest4/42b99dc4f39ff14cd7ebaf10727cb60c409859a8/assets/image/news.jpg -------------------------------------------------------------------------------- /assets/script/jquery.base64.min.js: -------------------------------------------------------------------------------- 1 | (function($){ 2 | 3 | var keyString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 4 | 5 | var uTF8Encode = function(string) { 6 | string = string.replace(/\x0d\x0a/g, "\x0a"); 7 | var output = ""; 8 | for (var n = 0; n < string.length; n++) { 9 | var c = string.charCodeAt(n); 10 | if (c < 128) { 11 | output += String.fromCharCode(c); 12 | } else if ((c > 127) && (c < 2048)) { 13 | output += String.fromCharCode((c >> 6) | 192); 14 | output += String.fromCharCode((c & 63) | 128); 15 | } else { 16 | output += String.fromCharCode((c >> 12) | 224); 17 | output += String.fromCharCode(((c >> 6) & 63) | 128); 18 | output += String.fromCharCode((c & 63) | 128); 19 | } 20 | } 21 | return output; 22 | }; 23 | 24 | var uTF8Decode = function(input) { 25 | var string = ""; 26 | var i = 0; 27 | var c = c1 = c2 = 0; 28 | while ( i < input.length ) { 29 | c = input.charCodeAt(i); 30 | if (c < 128) { 31 | string += String.fromCharCode(c); 32 | i++; 33 | } else if ((c > 191) && (c < 224)) { 34 | c2 = input.charCodeAt(i+1); 35 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 36 | i += 2; 37 | } else { 38 | c2 = input.charCodeAt(i+1); 39 | c3 = input.charCodeAt(i+2); 40 | string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 41 | i += 3; 42 | } 43 | } 44 | return string; 45 | } 46 | 47 | $.extend({ 48 | base64Encode: function(input) { 49 | var output = ""; 50 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 51 | var i = 0; 52 | input = uTF8Encode(input); 53 | while (i < input.length) { 54 | chr1 = input.charCodeAt(i++); 55 | chr2 = input.charCodeAt(i++); 56 | chr3 = input.charCodeAt(i++); 57 | enc1 = chr1 >> 2; 58 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 59 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 60 | enc4 = chr3 & 63; 61 | if (isNaN(chr2)) { 62 | enc3 = enc4 = 64; 63 | } else if (isNaN(chr3)) { 64 | enc4 = 64; 65 | } 66 | output = output + keyString.charAt(enc1) + keyString.charAt(enc2) + keyString.charAt(enc3) + keyString.charAt(enc4); 67 | } 68 | return output; 69 | }, 70 | base64Decode: function(input) { 71 | var output = ""; 72 | var chr1, chr2, chr3; 73 | var enc1, enc2, enc3, enc4; 74 | var i = 0; 75 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 76 | while (i < input.length) { 77 | enc1 = keyString.indexOf(input.charAt(i++)); 78 | enc2 = keyString.indexOf(input.charAt(i++)); 79 | enc3 = keyString.indexOf(input.charAt(i++)); 80 | enc4 = keyString.indexOf(input.charAt(i++)); 81 | chr1 = (enc1 << 2) | (enc2 >> 4); 82 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 83 | chr3 = ((enc3 & 3) << 6) | enc4; 84 | output = output + String.fromCharCode(chr1); 85 | if (enc3 != 64) { 86 | output = output + String.fromCharCode(chr2); 87 | } 88 | if (enc4 != 64) { 89 | output = output + String.fromCharCode(chr3); 90 | } 91 | } 92 | output = uTF8Decode(output); 93 | return output; 94 | } 95 | }); 96 | })(jQuery); -------------------------------------------------------------------------------- /assets/script/toastr.min.js: -------------------------------------------------------------------------------- 1 | !function(e){e(["jquery"],function(e){return function(){function t(e,t,n){return f({type:O.error,iconClass:g().iconClasses.error,message:e,optionsOverride:n,title:t})}function n(t,n){return t||(t=g()),v=e("#"+t.containerId),v.length?v:(n&&(v=c(t)),v)}function i(e,t,n){return f({type:O.info,iconClass:g().iconClasses.info,message:e,optionsOverride:n,title:t})}function o(e){w=e}function s(e,t,n){return f({type:O.success,iconClass:g().iconClasses.success,message:e,optionsOverride:n,title:t})}function a(e,t,n){return f({type:O.warning,iconClass:g().iconClasses.warning,message:e,optionsOverride:n,title:t})}function r(e){var t=g();v||n(t),l(e,t)||u(t)}function d(t){var i=g();return v||n(i),t&&0===e(":focus",t).length?void h(t):void(v.children().length&&v.remove())}function u(t){for(var n=v.children(),i=n.length-1;i>=0;i--)l(e(n[i]),t)}function l(t,n){return t&&0===e(":focus",t).length?(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0):!1}function c(t){return v=e("
").attr("id",t.containerId).addClass(t.positionClass).attr("aria-live","polite").attr("role","alert"),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",target:"body",closeHtml:'',newestOnTop:!0,preventDuplicates:!1,progressBar:!1}}function m(e){w&&w(e)}function f(t){function i(t){return!e(":focus",l).length||t?(clearTimeout(O.intervalId),l[r.hideMethod]({duration:r.hideDuration,easing:r.hideEasing,complete:function(){h(l),r.onHidden&&"hidden"!==b.state&&r.onHidden(),b.state="hidden",b.endTime=new Date,m(b)}})):void 0}function o(){(r.timeOut>0||r.extendedTimeOut>0)&&(u=setTimeout(i,r.extendedTimeOut),O.maxHideTime=parseFloat(r.extendedTimeOut),O.hideEta=(new Date).getTime()+O.maxHideTime)}function s(){clearTimeout(u),O.hideEta=0,l.stop(!0,!0)[r.showMethod]({duration:r.showDuration,easing:r.showEasing})}function a(){var e=(O.hideEta-(new Date).getTime())/O.maxHideTime*100;f.width(e+"%")}var r=g(),d=t.iconClass||r.iconClass;if("undefined"!=typeof t.optionsOverride&&(r=e.extend(r,t.optionsOverride),d=t.optionsOverride.iconClass||d),r.preventDuplicates){if(t.message===C)return;C=t.message}T++,v=n(r,!0);var u=null,l=e("
"),c=e("
"),p=e("
"),f=e("
"),w=e(r.closeHtml),O={intervalId:null,hideEta:null,maxHideTime:null},b={toastId:T,state:"visible",startTime:new Date,options:r,map:t};return t.iconClass&&l.addClass(r.toastClass).addClass(d),t.title&&(c.append(t.title).addClass(r.titleClass),l.append(c)),t.message&&(p.append(t.message).addClass(r.messageClass),l.append(p)),r.closeButton&&(w.addClass("toast-close-button").attr("role","button"),l.prepend(w)),r.progressBar&&(f.addClass("toast-progress"),l.prepend(f)),l.hide(),r.newestOnTop?v.prepend(l):v.append(l),l[r.showMethod]({duration:r.showDuration,easing:r.showEasing,complete:r.onShown}),r.timeOut>0&&(u=setTimeout(i,r.timeOut),O.maxHideTime=parseFloat(r.timeOut),O.hideEta=(new Date).getTime()+O.maxHideTime,r.progressBar&&(O.intervalId=setInterval(a,10))),l.hover(s,o),!r.onclick&&r.tapToDismiss&&l.click(i),r.closeButton&&w&&w.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),i(!0)}),r.onclick&&l.click(function(){r.onclick(),i()}),m(b),r.debug&&console&&console.log(b),l}function g(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),C=void 0))}var v,w,C,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:d,error:t,getContainer:n,info:i,options:{},subscribe:o,success:s,version:"2.1.0",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)}); 2 | //# sourceMappingURL=toastr.js.map 3 | -------------------------------------------------------------------------------- /assets/template/inputcode.tpl.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/template/logiccode.tpl.php: -------------------------------------------------------------------------------- 1 | \t\t\t\t\t\t\t","unique-fileds":[{"field_enname":"email","field_cnname":"电子邮件"}],"mwhere-fileds":[],"lwhere-fileds":[],"dwhere-fileds":[],"logiccode":"\t\t\t\t\t\t\t","unique-fileds":[],"mwhere-fileds":[],"lwhere-fileds":[],"dwhere-fileds":[],"logiccode":"" 6 | ], 7 | "description": "", 8 | "main": "", 9 | "license": "MIT", 10 | "private": true, 11 | "ignore": [ 12 | "**/.*", 13 | "node_modules", 14 | "bower_components", 15 | "assets/bower_components/", 16 | "test", 17 | "tests" 18 | ], 19 | "dependencies": { 20 | "bootstrap": "~3.3.6", 21 | "font-awesome": "fontawesome#^4.6.1", 22 | "ace-builds": "^1.2.3", 23 | "jquery": "~2.2.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /codetpl/cache/77/77ab97689b8f8003b5f352979c1d248abc1b30032a8d71bb7ecc1bc186ab613c.php: -------------------------------------------------------------------------------- 1 | parent = false; 11 | 12 | $this->blocks = array( 13 | ); 14 | } 15 | 16 | protected function doDisplay(array $context, array $blocks = array()) 17 | { 18 | // line 1 19 | echo "env, $this->getAttribute((isset($context["settings"]) ? $context["settings"] : null), "target_table_list", array()), "html", null, true); 25 | echo "添加记录 26 | * @ApiDescription(section=\""; 27 | // line 5 28 | echo twig_escape_filter($this->env, $this->getAttribute((isset($context["settings"]) ? $context["settings"] : null), "target_table_list", array()), "html", null, true); 29 | echo "\", description=\""; 30 | echo twig_escape_filter($this->env, $this->getAttribute((isset($context["settings"]) ? $context["settings"] : null), "iname", array()), "html", null, true); 31 | echo "\") 32 | * @ApiLazyRoute(uri=\""; 33 | // line 6 34 | echo twig_escape_filter($this->env, $this->getAttribute((isset($context["settings"]) ? $context["settings"] : null), "iuri", array()), "html", null, true); 35 | echo "\",method=\"POST\") 36 | 37 | "; 38 | // line 8 39 | $context['_parent'] = $context; 40 | $context['_seq'] = twig_ensure_traversable(($this->getAttribute((isset($context["settings"]) ? $context["settings"] : null), "input", array()) - (isset($context["fileds"]) ? $context["fileds"] : null))); 41 | foreach ($context['_seq'] as $context["_key"] => $context["item"]) { 42 | // line 9 43 | echo " 44 | * @ApiParams(name=\""; 45 | // line 10 46 | echo twig_escape_filter($this->env, (isset($context["field_enname"]) ? $context["field_enname"] : null), "html", null, true); 47 | echo "\", type=\"string\", 48 | "; 49 | // line 11 50 | if (((isset($context["field_cannull"]) ? $context["field_cannull"] : null) == 0)) { 51 | echo "nullable=false"; 52 | } else { 53 | echo "nullable=true"; 54 | } 55 | echo ",description=\""; 56 | echo twig_escape_filter($this->env, (isset($context["field_cnname"]) ? $context["field_cnname"] : null), "html", null, true); 57 | echo "\", check=\""; 58 | echo twig_escape_filter($this->env, (isset($context["field_checkfunction"]) ? $context["field_checkfunction"] : null), "html", null, true); 59 | echo "\", cnname=\""; 60 | echo twig_escape_filter($this->env, (isset($context["field_cnname"]) ? $context["field_cnname"] : null), "html", null, true); 61 | echo "\") 62 | 63 | "; 64 | } 65 | $_parent = $context['_parent']; 66 | unset($context['_seq'], $context['_iterated'], $context['_key'], $context['item'], $context['_parent'], $context['loop']); 67 | $context = array_intersect_key($context, $_parent) + $_parent; 68 | // line 14 69 | echo " 70 | * @ApiReturn(type=\"object\", sample=\"{'code': 0,'message': 'success'}\") 71 | */ 72 | function insert_data( ) 73 | { 74 | 75 | } 76 | 77 | ?>"; 78 | } 79 | 80 | public function getTemplateName() 81 | { 82 | return "insert.tpl.code"; 83 | } 84 | 85 | public function isTraitable() 86 | { 87 | return false; 88 | } 89 | 90 | public function getDebugInfo() 91 | { 92 | return array ( 69 => 14, 50 => 11, 46 => 10, 43 => 9, 39 => 8, 34 => 6, 28 => 5, 24 => 4, 19 => 1,); 93 | } 94 | } 95 | /* */ 117 | -------------------------------------------------------------------------------- /codetpl/code/controller.tpl.code: -------------------------------------------------------------------------------- 1 | 0 %} 7 | $GLOBALS['lpconfig']['database']['dsn'] = 'mysql:host={{mysql.mysql_host}};port={{mysql.mysql_port}};dbname={{mysql.mysql_database}};charset=UTF8'; 8 | $GLOBALS['lpconfig']['database']['user'] = '{{mysql.mysql_user}}'; 9 | $GLOBALS['lpconfig']['database']['password'] = '{{mysql.mysql_password}}'; 10 | {% endif %} 11 | } 12 | 13 | namespace Lazyphp\Controller 14 | { 15 | class LazyRestController extends AuthedController 16 | { 17 | public function __construct() 18 | { 19 | {% for aitem in noauth %} 20 | $noauth[] = '{{aitem}}'; 21 | {% endfor %} 22 | 23 | if( function_exists('lazyrest_auth_check') ) 24 | { 25 | if( !in_array( g('a') , $noauth ) ) 26 | { 27 | $this->auth(); 28 | lazyrest_auth_check(); 29 | } 30 | } 31 | } 32 | 33 | {% for theadd in lcadd %} 34 | {{theadd|clean_ptag|raw}} 35 | 36 | {% endfor %} 37 | 38 | {% for themodify in lcmodify %} 39 | {{themodify|clean_ptag|raw}} 40 | 41 | {% endfor %} 42 | 43 | {% for thedelete in lcdelete %} 44 | {{thedelete|clean_ptag|raw}} 45 | 46 | {% endfor %} 47 | 48 | {% for thelist in lclist %} 49 | {{thelist|clean_ptag|raw}} 50 | 51 | {% endfor %} 52 | 53 | {% for thecustom in lccustom %} 54 | {{thecustom|clean_ptag|raw}} 55 | 56 | {% endfor %} 57 | 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /codetpl/code/custom.tpl.code: -------------------------------------------------------------------------------- 1 | /** 2 | * 自定义查询数据表{{settings.target_table_list}}的记录 3 | * @ApiDescription(section="{{settings.target_table_list}}", description="{{settings.iname}}") 4 | * @ApiLazyRoute(uri="{{settings.iuri}}",method="{% if( settings.iget ==1 and settings.ipost == 1 ) %}GET|POST{% else %}{% if( settings.iget ==1 ) %}GET{% else %}POST{% endif %}{% endif %}") 5 | {% for item in settings['input-fileds'] %} 6 | * @ApiParams(name="{{item.field_enname}}", type="string",{% if( item.field_cannull == 0 ) %}nullable=false,check="{{item.field_checkfunction}}", {% else %}nullable=true,check="", {% endif %},description="{{item.field_cnname}}", cnname="{{item.field_cnname}}") 7 | {% endfor %} 8 | * @ApiReturn(type="object", sample="{'code': 0,'message': 'success'}") 9 | */ 10 | function {{method}}( {{ settings['input-fileds'] | join_names }} ) 11 | { 12 | {% if( settings.ipublic != 1 ) %}return send_error( 'AUTH' , '此接口已暂停服务' );{% endif %} 13 | 14 | 15 | // 输入过滤 16 | {% for item in settings['input-fileds'] %} 17 | 18 | {# 检查可选参数的格式 #} 19 | {% if item.field_cannull == 1 and item.field_checkfunction | length > 0 %} 20 | if( isset( $_REQUEST['{{item.field_enname}}'] ) && !{{item.field_checkfunction}}( ${{item.field_enname}} ) ) 21 | { 22 | return send_error( 'INPUT' , '字段{{item.field_cnname}}({{item.field_enname}})格式错误' ); 23 | } 24 | {% endif %} 25 | 26 | {# 过滤输入参数 #} 27 | {% if( item.field_table != '-phpfunction-' ) %} 28 | ${{item.field_enname}} = {{item.field_filterfunction}}( ${{item.field_enname}} ); 29 | {% else %} 30 | ${{item.field_enname}} = {{item.field_filterfunction}}(); 31 | {% endif %} 32 | 33 | {% endfor %} 34 | 35 | // 输入控制代码 36 | {{settings.inputcode|clean_ptag|raw}} 37 | 38 | 39 | // 业务逻辑控制代码 40 | {{settings.logiccode|clean_ptag|raw}} 41 | 42 | 43 | // 输出控制代码 44 | {{settings.outputcode|clean_ptag|raw}} 45 | 46 | 47 | } -------------------------------------------------------------------------------- /codetpl/code/delete.tpl.code: -------------------------------------------------------------------------------- 1 | /** 2 | * 删除数据表{{settings.target_table_list}}的记录 3 | * @ApiDescription(section="{{settings.target_table_list}}", description="{{settings.iname}}") 4 | * @ApiLazyRoute(uri="{{settings.iuri}}",method="{% if( settings.iget ==1 and settings.ipost == 1 ) %}GET|POST{% else %}{% if( settings.iget ==1 ) %}GET{% else %}POST{% endif %}{% endif %}") 5 | {% for item in settings['input-fileds'] %} 6 | * @ApiParams(name="{{item.field_enname}}", type="string",{% if( item.field_cannull == 0 ) %}nullable=false,check="{{item.field_checkfunction}}", {% else %}nullable=true,check="", {% endif %},description="{{item.field_cnname}}", cnname="{{item.field_cnname}}") 7 | {% endfor %} 8 | * @ApiReturn(type="object", sample="{'code': 0,'message': 'success'}") 9 | */ 10 | function {{method}}( {{ settings['input-fileds'] | join_names }} ) 11 | { 12 | $where_logic = ' AND '; 13 | 14 | // 输入过滤 15 | {% for item in settings['input-fileds'] %} 16 | {% if( item.field_filterfunction | length > 0 ) %} 17 | {% if( item.field_table != '-phpfunction-' ) %} 18 | ${{item.field_enname}} = {{item.field_filterfunction}}( ${{item.field_enname}} ); 19 | {% else %} 20 | ${{item.field_enname}} = {{item.field_filterfunction}}(); 21 | {% endif %} 22 | {% endif %} 23 | {% endfor %} 24 | 25 | // 输入控制代码 26 | {{settings.inputcode|clean_ptag|raw}} 27 | 28 | 29 | // 拼接SQL准备 30 | 31 | {% for item in settings['dwhere-fileds'] %} 32 | $dwhere_field = '`{{item.field_enname}}` = '; 33 | 34 | {% if( item.field_table == '-phpfunction-' ) %} 35 | $dwhere_field .= "'" . s( {{item.field_filterfunction}}() ) . "'"; 36 | {% endif %} 37 | 38 | {% if( item.field_table == settings.target_table_list ) %} 39 | $dwhere_field .= "'" . s( ${{item.field_enname}} ) . "'"; 40 | {% endif %} 41 | 42 | $dwhere_fields[] = $dwhere_field; 43 | {% endfor %} 44 | 45 | // 检查该记录是否存在 46 | // 处理返回值 47 | {% for item in settings['output-fileds']%} 48 | $out_field[] = '`{{item.field_enname}}`'; 49 | {% endfor %} 50 | 51 | $sql = "SELECT " . join( ' , ' , $out_field ) . " FROM `{{settings.target_table_list}}` WHERE " . join( $where_logic , $dwhere_fields ) . " LIMIT 1"; 52 | if( !$last = get_line( $sql ) ) return send_error( 'INPUT' , '记录不存在,可能您权限不足或已被删除' ); 53 | 54 | // 业务逻辑控制代码 55 | {{settings.logiccode|clean_ptag|raw}} 56 | 57 | // 拼接SQL 58 | $sql = "DELETE FROM `{{settings.target_table_list}}` WHERE " . join( ' AND ' , $dwhere_fields ) . " LIMIT 1"; 59 | 60 | 61 | run_sql( $sql ); 62 | 63 | $return_item = $last; 64 | 65 | // 输出控制代码 66 | {{settings.outputcode|clean_ptag|raw}} 67 | 68 | if( $return_item ) 69 | { 70 | return render_json( $return_item ); 71 | } 72 | else 73 | { 74 | return send_error('DATABASE' , '数据删除失败'); 75 | }; 76 | } -------------------------------------------------------------------------------- /codetpl/code/insert.tpl.code: -------------------------------------------------------------------------------- 1 | /** 2 | * 向数据表{{settings.target_table_list}}添加记录 3 | * @ApiDescription(section="{{settings.target_table_list}}", description="{{settings.iname}}") 4 | * @ApiLazyRoute(uri="{{settings.iuri}}",method="{% if( settings.iget ==1 and settings.ipost == 1 ) %}GET|POST{% else %}{% if( settings.iget ==1 ) %}GET{% else %}POST{% endif %}{% endif %}") 5 | {% for item in settings['input-fileds'] %} 6 | * @ApiParams(name="{{item.field_enname}}", type="string",{% if( item.field_cannull == 0 ) %}nullable=false{% else %}nullable=true{% endif %},description="{{item.field_cnname}}", check="{{item.field_checkfunction}}", cnname="{{item.field_cnname}}") 7 | {% endfor %} 8 | * @ApiReturn(type="object", sample="{'code': 0,'message': 'success'}") 9 | */ 10 | function {{method}}( {{ settings['input-fileds'] | join_names }} ) 11 | { 12 | // 输入函数过滤 13 | {% for item in settings['input-fileds'] %} 14 | {% if( item.field_filterfunction | length > 0 ) %} 15 | {% if( item.field_table != '-phpfunction-' ) %} 16 | ${{item.field_enname}} = {{item.field_filterfunction}}( ${{item.field_enname}} ); 17 | {% else %} 18 | ${{item.field_enname}} = {{item.field_filterfunction}}(); 19 | {% endif %} 20 | {% endif %} 21 | {% endfor %} 22 | 23 | // 输入控制代码 24 | {{settings.inputcode|clean_ptag|raw}} 25 | 26 | // 检查唯一 27 | {%for item in settings['unique-fileds'] %} 28 | if( get_var("SELECT COUNT(*) FROM `{{settings.target_table_list}}` WHERE `{{item.field_enname}}` = '" . s( ${{item.field_enname}} ) . "'") > 0 ) 29 | { 30 | return send_error('INPUT' , '{{item.field_cnname}}字段不能重复'); 31 | } 32 | 33 | {% endfor %} 34 | 35 | 36 | // 拼接SQL 37 | {% for item in settings['input-fileds']%} 38 | 39 | {# 数据来自REQUEST的字段 #} 40 | {% if( item.field_table == settings.target_table_list ) %} 41 | $pre_field[] = '`{{item.field_enname}}`'; 42 | $post_field[] = "'" . s( ${{item.field_enname}} ) . "'"; 43 | {% endif %} 44 | 45 | {# 数据来自php函数的字段 #} 46 | {% if( item.field_table == '-phpfunction-' ) %} 47 | $pre_field[] = '`{{item.field_enname}}`'; 48 | $post_field[] = "'" . s( {{item.field_filterfunction}}() ) . "'"; 49 | {% endif %} 50 | 51 | {% endfor %} 52 | 53 | // 业务逻辑控制代码 54 | {{settings.logiccode|clean_ptag|raw}} 55 | 56 | 57 | $sql = "INSERT INTO `{{settings.target_table_list}}` ( " . join( ' , ' , $pre_field ) . " ) VALUES ( " . join( ' , ' , $post_field ) . " ) "; 58 | 59 | run_sql( $sql ); 60 | $theid = last_id(); 61 | 62 | {% for item in settings['output-fileds']%} 63 | {# if( item.field_table == settings.target_table_list ) #} 64 | $out_field[] = '`{{item.field_enname}}`'; 65 | {# endif #} 66 | {% endfor %} 67 | 68 | $return_item = get_line("SELECT " . join( ' , ' , $out_field ) . " FROM `{{settings.target_table_list}}` WHERE `id` = '" . intval( $theid ) . "' LIMIT 1"); 69 | 70 | // 输出控制代码 71 | {{settings.outputcode|clean_ptag|raw}} 72 | 73 | if( $return_item ) 74 | { 75 | return render_json( $return_item ); 76 | } 77 | else 78 | { 79 | return send_error('DATABASE' , '数据插入失败'); 80 | }; 81 | 82 | 83 | } -------------------------------------------------------------------------------- /codetpl/code/list.tpl.code: -------------------------------------------------------------------------------- 1 | /** 2 | * 查询数据表{{settings.target_table_list}}的记录 3 | * @ApiDescription(section="{{settings.target_table_list}}", description="{{settings.iname}}") 4 | * @ApiLazyRoute(uri="{{settings.iuri}}",method="{% if( settings.iget ==1 and settings.ipost == 1 ) %}GET|POST{% else %}{% if( settings.iget ==1 ) %}GET{% else %}POST{% endif %}{% endif %}") 5 | {% for item in settings['input-fileds'] %} 6 | * @ApiParams(name="{{item.field_enname}}", type="string",{% if( item.field_cannull == 0 ) %}nullable=false,check="{{item.field_checkfunction}}", {% else %}nullable=true,check="", {% endif %},description="{{item.field_cnname}}", cnname="{{item.field_cnname}}") 7 | {% endfor %} 8 | * @ApiReturn(type="object", sample="{'code': 0,'message': 'success'}") 9 | */ 10 | function {{method}}( {{ settings['input-fileds'] | join_names }} ) 11 | { 12 | {% if( settings.ipublic != 1 ) %}return send_error( 'AUTH' , '此接口已暂停服务' );{% endif %} 13 | 14 | $page_count = 10; 15 | $where_logic = ' AND '; 16 | 17 | // 输入过滤 18 | {% for item in settings['input-fileds'] %} 19 | 20 | {# 检查可选参数的格式 #} 21 | {% if item.field_checkfunction | length > 0 %} 22 | if( isset( $_REQUEST['{{item.field_enname}}'] ) && !{{item.field_checkfunction}}( ${{item.field_enname}} ) ) 23 | { 24 | return send_error( 'INPUT' , '字段{{item.field_cnname}}({{item.field_enname}})格式错误' ); 25 | } 26 | {% endif %} 27 | 28 | {% if( item.field_filterfunction | length > 0 ) %} 29 | {% if( item.field_table != '-phpfunction-' ) %} 30 | ${{item.field_enname}} = {{item.field_filterfunction}}( ${{item.field_enname}} ); 31 | {% else %} 32 | ${{item.field_enname}} = {{item.field_filterfunction}}(); 33 | {% endif %} 34 | {% endif %} 35 | 36 | {% endfor %} 37 | 38 | // 输入控制代码 39 | {{settings.inputcode|clean_ptag|raw}} 40 | 41 | 42 | // 拼接SQL准备 43 | 44 | {% for item in settings['lwhere-fileds'] %} 45 | if( strlen( ${{item.field_enname}} ) > 0 ) 46 | { 47 | {# 匹配类型 = #} 48 | {% if( item.field_eq == 1 ) %} 49 | $lwhere_field = '`{{item.field_enname}}` = '; 50 | 51 | {% if( item.field_table == '-phpfunction-' ) %} 52 | $lwhere_field .= "'" . s( {{item.field_filterfunction}}() ) . "'"; 53 | {% endif %} 54 | 55 | {% if( item.field_table == settings.target_table_list ) %} 56 | $lwhere_field .= "'" . s( ${{item.field_enname}} ) . "'"; 57 | {% endif %} 58 | {% endif %} 59 | 60 | {# 匹配类型 % #} 61 | {% if( item.field_eq == 2 ) %} 62 | $lwhere_field = '`{{item.field_enname}}` '; 63 | 64 | {% if( item.field_table == '-phpfunction-' ) %} 65 | $lwhere_field .= "LIKE '%" . s( {{item.field_filterfunction}}() ) . "%'"; 66 | {% endif %} 67 | 68 | {% if( item.field_table == settings.target_table_list ) %} 69 | $lwhere_field .= "LIKE '%" . s( ${{item.field_enname}} ) . "%'"; 70 | {% endif %} 71 | {% endif %} 72 | 73 | $lwhere_fields[] = $lwhere_field; 74 | } 75 | {% endfor %} 76 | 77 | if( isset( $lwhere_fields ) ) 78 | $list_where = join( $where_logic , $lwhere_fields ) . " "; 79 | else 80 | $list_where = ""; 81 | 82 | 83 | 84 | // 检查该记录是否存在 85 | // 处理返回值 86 | {% for item in settings['output-fileds']%} 87 | $out_field[] = '`{{item.field_enname}}`'; 88 | {% endfor %} 89 | 90 | // sinceID 91 | $sid = intval(v('_since_id')); 92 | 93 | if( intval(v('_count')) > 0 ) $page_count = intval(v('_count')); 94 | if( $page_count > 1000 ) $page_count = 1000; 95 | $limit_sql = " LIMIT " . $page_count; 96 | 97 | // 排序 98 | $by = z(t(v('_order_by'))); 99 | if( strlen( $by ) < 1 ) $by = 'id'; 100 | 101 | $table_fields = array(); 102 | {% for fitem in table_fields %} 103 | $table_fields[] = '{{fitem}}'; 104 | {% endfor %} 105 | if( !in_array( $by , $table_fields ) ) return send_error('INPUT' , '错误的字段名称'); 106 | 107 | if( strtolower(t(v('_order'))) == 'asc' ) 108 | { 109 | $order_sql = " ORDER BY `" . $by . "` ASC "; 110 | 111 | if( $sid > 0 ) 112 | $where_fields[] = " `id` >= '" . intval( $sid ) . "' "; 113 | } 114 | else 115 | { 116 | $order_sql = " ORDER BY `" . $by . "` DESC "; 117 | if( $sid > 0 ) 118 | $where_fields[] = " `id` <= '" . intval( $sid ) . "' "; 119 | } 120 | 121 | 122 | if( isset($where_fields) ) 123 | $main_where = join( " AND " , $where_fields ); 124 | else 125 | $main_where = ""; 126 | 127 | 128 | if( strlen( $list_where ) > 0 && strlen( $main_where ) > 0 ) 129 | $where_sql = " WHERE " . $main_where . " AND " . $list_where ; 130 | elseif( strlen( $list_where ) > 0 ) 131 | $where_sql = " WHERE " . $list_where ; 132 | elseif( strlen( $main_where ) > 0 ) 133 | $where_sql = " WHERE " . $main_where ; 134 | else 135 | $where_sql = ""; 136 | 137 | // 业务逻辑控制代码 138 | {{settings.logiccode|clean_ptag|raw}} 139 | 140 | $sql = "SELECT " . join( ' , ' , $out_field ) . " FROM `{{settings.target_table_list}}` " . $where_sql . " " . $order_sql . " " . $limit_sql ; 141 | 142 | 143 | $return_item = get_data( $sql ); 144 | 145 | // 输出控制代码 146 | {{settings.outputcode|clean_ptag|raw}} 147 | 148 | if( $return_item ) 149 | { 150 | foreach( $return_item as $item ) 151 | $iid[] = $item['id']; 152 | 153 | $return_item['max_id'] = max( $iid ); 154 | $return_item['min_id'] = min( $iid ); 155 | 156 | return render_json( $return_item ); 157 | } 158 | else 159 | { 160 | return send_error('NODATA' , '没有对应的记录,可能数据表为空'); 161 | }; 162 | } -------------------------------------------------------------------------------- /codetpl/code/update.tpl.code: -------------------------------------------------------------------------------- 1 | /** 2 | * 修改数据表{{settings.target_table_list}}的记录 3 | * @ApiDescription(section="{{settings.target_table_list}}", description="{{settings.iname}}") 4 | * @ApiLazyRoute(uri="{{settings.iuri}}",method="{% if( settings.iget ==1 and settings.ipost == 1 ) %}GET|POST{% else %}{% if( settings.iget ==1 ) %}GET{% else %}POST{% endif %}{% endif %}") 5 | {% for item in settings['input-fileds'] %} 6 | * @ApiParams(name="{{item.field_enname}}", type="string",{% if( item.field_cannull == 0 ) %}nullable=false,check="{{item.field_checkfunction}}", {% else %}nullable=true,check="", {% endif %},description="{{item.field_cnname}}", cnname="{{item.field_cnname}}") 7 | {% endfor %} 8 | * @ApiReturn(type="object", sample="{'code': 0,'message': 'success'}") 9 | */ 10 | function {{method}}( {{ settings['input-fileds'] | join_names }} ) 11 | { 12 | $where_logic = ' AND '; 13 | 14 | // 输入过滤 15 | {% for item in settings['input-fileds'] %} 16 | {% if( item.field_filterfunction | length > 0 ) %} 17 | {% if( item.field_table != '-phpfunction-' ) %} 18 | ${{item.field_enname}} = {{item.field_filterfunction}}( ${{item.field_enname}} ); 19 | {% else %} 20 | ${{item.field_enname}} = {{item.field_filterfunction}}(); 21 | {% endif %} 22 | {% endif %} 23 | {% endfor %} 24 | 25 | // 输入控制代码 26 | {{settings.inputcode|clean_ptag|raw}} 27 | 28 | 29 | // 拼接SQL准备 30 | 31 | {% for item in settings['input-fileds'] %} 32 | // 如果参与了请求,就放进来,不用strlen,以处理值为空的情况 33 | 34 | {# if( strlen(${{item.field_enname}}) > 0 )#} 35 | if( isset($_REQUEST['{{item.field_enname}}']) ) 36 | { 37 | {% if item.field_checkfunction | length > 0 %} 38 | if( {{item.field_checkfunction}}( ${{item.field_enname}} ) ) 39 | { 40 | {% endif %} 41 | 42 | $update_field = '`{{item.field_enname}}` = '; 43 | 44 | {% if( item.field_table == '-phpfunction-' ) %} 45 | $update_field .= "'" . s( {{item.field_filterfunction}}() ) . "'"; 46 | {% endif %} 47 | 48 | {% if( item.field_table == settings.target_table_list ) %} 49 | $update_field .= "'" . s( ${{item.field_enname}} ) . "'"; 50 | {% endif %} 51 | 52 | $update_fields[] = $update_field; 53 | 54 | {% if item.field_checkfunction | length > 0 %} 55 | } 56 | else 57 | { 58 | return send_error( 'INPUT' , '参数{{item.field_cnname}}({{item.field_enname}})的格式不正确' ); 59 | } 60 | {% endif %} 61 | 62 | } 63 | {% endfor %} 64 | 65 | {% for item in settings['mwhere-fileds'] %} 66 | $mwhere_field = '`{{item.field_enname}}` = '; 67 | 68 | {% if( item.field_table == '-phpfunction-' ) %} 69 | $mwhere_field .= "'" . s( {{item.field_filterfunction}}() ) . "'"; 70 | {% endif %} 71 | 72 | {% if( item.field_table == settings.target_table_list ) %} 73 | $mwhere_field .= "'" . s( ${{item.field_enname}} ) . "'"; 74 | {% endif %} 75 | 76 | $mwhere_fields[] = $mwhere_field; 77 | {% endfor %} 78 | 79 | // 检查该记录是否存在 80 | $sql = "SELECT * FROM `{{settings.target_table_list}}` WHERE " . join( ' AND ' , $mwhere_fields ) . " LIMIT 1"; 81 | if( !$last = get_line( $sql )) return send_error( 'INPUT' , '记录不存在,可能您权限不足或已被删除' ); 82 | 83 | // 业务逻辑控制代码 84 | {{settings.logiccode|clean_ptag|raw}} 85 | 86 | // 拼接SQL 87 | $sql = "UPDATE `{{settings.target_table_list}}` SET " . join( ' , ' , $update_fields ) . " WHERE " . join( ' AND ' , $mwhere_fields ) . " LIMIT 1"; 88 | 89 | 90 | run_sql( $sql ); 91 | 92 | // 处理返回值 93 | {% for item in settings['output-fileds']%} 94 | $out_field[] = '`{{item.field_enname}}`'; 95 | {% endfor %} 96 | 97 | $return_item = get_line("SELECT " . join( ' , ' , $out_field ) . " FROM `{{settings.target_table_list}}` WHERE " . join( $where_logic , $mwhere_fields ) . " LIMIT 1"); 98 | 99 | // 输出控制代码 100 | {{settings.outputcode|clean_ptag|raw}} 101 | 102 | if( $return_item ) 103 | { 104 | return render_json( $return_item ); 105 | } 106 | else 107 | { 108 | return send_error('DATABASE' , '数据更新失败'); 109 | }; 110 | } -------------------------------------------------------------------------------- /composer.full.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": 3 | { 4 | "php":">=5.3.3" 5 | }, 6 | "require-dev": 7 | { 8 | "behat/behat": "2.4.*@stable", 9 | "behat/mink": "1.4@stable", 10 | "behat/mink-extension": "*", 11 | "behat/mink-goutte-driver": "1.0.*@dev", 12 | "crada/php-apidoc": "@dev" 13 | }, 14 | "autoload": 15 | { 16 | "psr-4": 17 | { 18 | "Lazyphp\\": "_lp/lib/Lazyphp/", 19 | "Lazyphp\\Controller\\": "controller/" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": 3 | { 4 | "php":">=5.3.3", 5 | "twig/twig": ">=3.0.1" 6 | }, 7 | "autoload": 8 | { 9 | "psr-4": 10 | { 11 | "Lazyphp\\": "_lp/lib/Lazyphp/", 12 | "Lazyphp\\Controller\\": "controller/" 13 | } 14 | }, 15 | "config": { 16 | "secure-http": false 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | handle: 2 | - rewrite: if (!is_file() && !is_dir() && path ~ "^/(.*)") goto "index.php/$1" -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | 'mysql', 9 | 'host' => SAE_MYSQL_HOST_M, 10 | 'name' => SAE_MYSQL_DB, 11 | 'user' => SAE_MYSQL_USER , 12 | 'password' => SAE_MYSQL_PASS, 13 | 'port' => SAE_MYSQL_PORT, 14 | 'charset' => 'utf8' 15 | ); 16 | 17 | $GLOBALS['lpconfig']['database']['dsn'] = $GLOBALS['lpconfig']['database']['adapter'] 18 | .':host=' . $GLOBALS['lpconfig']['database']['host'] 19 | . ';port=' . $GLOBALS['lpconfig']['database']['port'] 20 | . ';dbname=' . $GLOBALS['lpconfig']['database']['name'] 21 | . ';charset=' . $GLOBALS['lpconfig']['database']['charset']; 22 | } 23 | else 24 | { 25 | $GLOBALS['lpconfig']['database'] = array 26 | ( 27 | 'adapter' => 'mysql', 28 | 'host' => 'localhost', 29 | 'name' => $db_name, 30 | 'user' => 'root', 31 | 'password' => 'root', 32 | 'port' => 8889, 33 | 'charset' => 'utf8' 34 | ); 35 | 36 | $GLOBALS['lpconfig']['database']['dsn'] = $GLOBALS['lpconfig']['database']['adapter'] 37 | .':host=' . $GLOBALS['lpconfig']['database']['host'] 38 | . ';port=' . $GLOBALS['lpconfig']['database']['port'] 39 | . ';dbname=' . $GLOBALS['lpconfig']['database']['name'] 40 | . ';charset=' . $GLOBALS['lpconfig']['database']['charset']; 41 | } 42 | 43 | $GLOBALS['lpconfig']['database_dev'] = array 44 | ( 45 | 'adapter' => 'mysql', 46 | 'host' => 'localhost', 47 | 'name' => $db_name, 48 | 'user' => 'root', 49 | 'password' => 'root', 50 | 'port' => 8889, 51 | 'charset' => 'utf8' 52 | ); 53 | 54 | $GLOBALS['lpconfig']['database_dev']['dsn'] = $GLOBALS['lpconfig']['database_dev']['adapter'] 55 | .':host=' . $GLOBALS['lpconfig']['database_dev']['host'] 56 | . ';port=' . $GLOBALS['lpconfig']['database_dev']['port'] 57 | . ';dbname=' . $GLOBALS['lpconfig']['database_dev']['name'] 58 | . ';charset=' . $GLOBALS['lpconfig']['database_dev']['charset']; 59 | 60 | 61 | -------------------------------------------------------------------------------- /config/exception.php: -------------------------------------------------------------------------------- 1 | '90000' , 'message' => 'RP error' ); 5 | $GLOBALS['rest_errors']['REMOTE'] = array( 'code' => '50001' , 'message' => 'Remote API Error' ); 6 | -------------------------------------------------------------------------------- /controller/AuthedController.php: -------------------------------------------------------------------------------- 1 | 0 ) 14 | { 15 | session_id( $token ); 16 | } 17 | 18 | session_start(); 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /controller/Controller.php: -------------------------------------------------------------------------------- 1 | getSession()->getPage()->getContent() ) != trim( (string)$string ) ) 41 | throw new Exception("Return data is ".$string); 42 | } 43 | 44 | // 45 | // Place your definition and hook methods here: 46 | // 47 | // /** 48 | // * @Given /^I have done something with "([^"]*)"$/ 49 | // */ 50 | // public function iHaveDoneSomethingWith($argument) 51 | // { 52 | // doSomethingWith($argument); 53 | // } 54 | // 55 | } 56 | -------------------------------------------------------------------------------- /features/user.feature: -------------------------------------------------------------------------------- 1 | Feature: User 2 | In order to know a user well 3 | As a api interface 4 | I need to get info via uid 5 | 6 | Scenario: get user info via uid 7 | Given I go to "/user/1" 8 | Then the response status code should be 200 9 | And I see the Json 10 | """ 11 | {"code":0,"message":"","data":{"id":"1","name":"easy","email":"easychen@gmail.com"}} 12 | """ -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | = 1 ; 25 | } 26 | 27 | function ss( $key ) 28 | { 29 | if( isset( $_SESSION[$key] ) ) return $_SESSION[$key]; 30 | else return false; 31 | } 32 | 33 | 34 | function checked( $value1 , $value2 ) 35 | { 36 | if( intval($value1) == intval( $value2 ) ) echo " checked "; 37 | else echo " "; 38 | } 39 | 40 | function selected( $value1 , $value2 ) 41 | { 42 | if( intval($value1) == intval( $value2 ) ) echo " selected "; 43 | else echo " "; 44 | } 45 | 46 | function twig() 47 | { 48 | if( !isset( $GLOBALS['__LR_TNG'] ) ) 49 | { 50 | $loader = new \Twig\Loader\FilesystemLoader( AROOT . DS . 'codetpl' . DS . 'code' ); 51 | 52 | $GLOBALS['__LR_TNG'] = new \Twig\Environment($loader); 53 | 54 | $filter = new \Twig\TwigFilter('join_names', function ( $array) 55 | { 56 | $ret = array(); 57 | foreach( $array as $item ) 58 | { 59 | $ret[] = '$'.$item['field_enname']; 60 | } 61 | return join(',' , $ret ); 62 | }); 63 | 64 | $filter2 = new \Twig\TwigFilter('clean_ptag', function ( $string ) 65 | { 66 | $string = trim( $string ); 67 | if( substr( $string , 0 , 5 ) == '<'.'?php' ) $string = substr( $string , 5 ); 68 | if( substr( $string , -2 ) == '?'.'>' ) $string = substr( $string , 0 , -2 ); 69 | return $string; 70 | }); 71 | 72 | $GLOBALS['__LR_TNG']->addFilter( $filter ); 73 | $GLOBALS['__LR_TNG']->addFilter( $filter2 ); 74 | 75 | } 76 | 77 | return $GLOBALS['__LR_TNG']; 78 | } 79 | 80 | // ====================================== 81 | // function now() 82 | // { 83 | // return date("Y-m-d H:i:s"); 84 | // } 85 | 86 | // function check_mobile( $str ) 87 | // { 88 | // return preg_match('/1\d{10}/',$str); 89 | // } 90 | 91 | -------------------------------------------------------------------------------- /migrations/20140422224730_lazy_php_db.php: -------------------------------------------------------------------------------- 1 | table('lptest'); 18 | $table->addColumn('name', 'string' , array('limit' => 20) ) 19 | ->addColumn('password', 'string' , array('limit' => 20) ) 20 | ->addColumn('avatar', 'string' , array('limit' => 255) ) 21 | ->addColumn('created', 'datetime') 22 | ->create(); 23 | } 24 | 25 | 26 | 27 | /** 28 | * Migrate Up. 29 | */ 30 | public function up() 31 | { 32 | 33 | } 34 | 35 | /** 36 | * Migrate Down. 37 | */ 38 | public function down() 39 | { 40 | 41 | } 42 | } -------------------------------------------------------------------------------- /mink.txt: -------------------------------------------------------------------------------- 1 | Given /^(?:|I )am on (?:|the )homepage$/ 2 | - Opens homepage. 3 | # FeatureContext::iAmOnHomepage() 4 | 5 | When /^(?:|I )go to (?:|the )homepage$/ 6 | - Opens homepage. 7 | # FeatureContext::iAmOnHomepage() 8 | 9 | Given /^(?:|I )am on "(?P[^"]+)"$/ 10 | - Opens specified page. 11 | # FeatureContext::visit() 12 | 13 | When /^(?:|I )go to "(?P[^"]+)"$/ 14 | - Opens specified page. 15 | # FeatureContext::visit() 16 | 17 | When /^(?:|I )reload the page$/ 18 | - Reloads current page. 19 | # FeatureContext::reload() 20 | 21 | When /^(?:|I )move backward one page$/ 22 | - Moves backward one page in history. 23 | # FeatureContext::back() 24 | 25 | When /^(?:|I )move forward one page$/ 26 | - Moves forward one page in history 27 | # FeatureContext::forward() 28 | 29 | When /^(?:|I )press "(?P
"; 5 | ?> -------------------------------------------------------------------------------- /view/ajax/main/lazyphp_code_functions.tpl.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 |
5 |
6 |
7 |
8 | 9 |
10 | -------------------------------------------------------------------------------- /view/ajax/main/lazyphp_field_add.tpl.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 |
5 |
6 |
7 |
8 |
9 | 10 |
11 | 12 |
13 |
14 | 15 | 16 |
17 | 18 |
19 | 20 |
21 |
22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 |
30 |
31 | 32 | 33 | 34 |
35 | 36 |
37 | 38 |
39 |
40 | 41 | 42 | 43 |
44 | 45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 |
54 | 55 |
56 |
57 | 61 |
62 | 63 |
64 | 68 |
69 |
70 |
71 | 72 | 73 | 74 |
75 | 76 |
77 |
78 | 82 |
83 | 84 |
85 | 89 |
90 |
91 |
92 | 93 | 94 |
95 |
96 | 97 | 98 | 99 |
100 |
101 | 102 | 103 |
104 |
105 |
106 | 113 | 114 |
115 |
116 | 119 | 120 | 122 | 123 | 124 |
125 | 126 |
127 | 128 | 130 | 131 | 132 |
133 |
134 | 135 | 136 | 137 |
138 |
139 | 140 | 147 | 148 | 149 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /view/ajax/main/lazyphp_settings.tpl.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 |
5 |

数据库设置

6 |
7 |
8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 | 16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 | 24 |
25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 | 42 |
43 |
44 |
45 |
-------------------------------------------------------------------------------- /view/web/default.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <?=$data['title'] . ' | ' . c('site_name');?> 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 46 | 47 | 48 | 49 | 没有设置模板文件,如需获取JSON,请将Header的Content-Type设置为application/json
"; 58 | 59 | 60 | $footer_file = dirname( __FILE__ ) . DS . 'footer.lr.tpl.php'; 61 | if( file_exists( $footer_file ) ) include( $footer_file ); 62 | 63 | ?> 64 | 65 | 66 | -------------------------------------------------------------------------------- /view/web/footer.lr.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /view/web/footer.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /view/web/header.lr.tpl.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
    5 |
  • 6 |
  • 7 |
  • 8 |
  • 9 |
  • 10 |
  • 11 |
12 |
13 |
14 | 32 | -------------------------------------------------------------------------------- /view/web/header.tpl.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easychen/LazyRest4/42b99dc4f39ff14cd7ebaf10727cb60c409859a8/view/web/header.tpl.php -------------------------------------------------------------------------------- /view/web/info.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <?='系统提示 | ' . c('site_name');?> 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 35 |
36 |

系统提示

37 | 38 |
39 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /view/web/lazyrest.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <?=$data['title'] . ' | ' . c('site_name');?> 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 47 | 48 | 49 | 50 | 没有设置模板文件,如需获取JSON,请将Header的Content-Type设置为application/json
"; 59 | 60 | 61 | $footer_file = dirname( __FILE__ ) . DS . 'footer.lr.tpl.php'; 62 | if( file_exists( $footer_file ) ) include( $footer_file ); 63 | 64 | ?> 65 | 66 | 67 | -------------------------------------------------------------------------------- /view/web/main/lazyphp_index.tpl.php: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

LazyPHP 4.5

5 |

API first this time

6 |
7 | Find Out More 8 |
9 |
10 | 11 | 12 |
13 |
14 |
15 |
16 |

What's new in 4.5?

17 |

Document

18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | -------------------------------------------------------------------------------- /view/web/main/lazyphp_interface_list.tpl.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

接口设置

5 | 6 |
7 |
    8 | 9 | 10 | 16 |
  • 17 |
    18 |
    19 | 20 |
    21 |
    22 |   23 | 24 | 25 | 26 |
    27 | 28 | 29 |
  • 30 | 31 |
32 | 33 |
34 |

还没有接口呢,点这里创建一个

35 |
36 | 37 | 38 | 39 |
40 | -------------------------------------------------------------------------------- /view/web/main/lazyphp_login.tpl.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /view/web/main/lazyphp_projects.tpl.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | 7 | 8 |
9 | 12 |
13 |
14 |
15 |
16 | 17 |
18 | 19 |
20 |
21 | 22 |
23 | --------------------------------------------------------------------------------