From d6f3082110cc29da9c54af4c3dafcd5cd40a9ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=B0=E5=B0=91Pakey?= Date: Tue, 30 Dec 2014 08:36:25 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=91=E6=9C=9F=E4=BF=AE=E6=94=B9=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 - .htaccess | 8 - 404.html | 26 - README.md | 4 + application/ad/controller/manage.php | 107 - application/ad/view/manage_add.html | 76 - application/ad/view/manage_edit.html | 83 - application/ad/view/manage_index.html | 106 - application/admin/controller/config.php | 70 - application/admin/controller/group.php | 55 - application/admin/controller/index.php | 47 - application/admin/controller/node.php | 93 - application/admin/controller/public.php | 46 - application/admin/controller/theme.php | 58 - application/admin/controller/user.php | 87 - application/admin/model/theme.php | 21 - application/admin/view/config_add.html | 120 - application/admin/view/config_index.html | 66 - application/admin/view/css/admin.css | 2155 -------------- .../view/css/glyphicons-halflings-regular.eot | Bin 20290 -> 0 bytes .../view/css/glyphicons-halflings-regular.svg | 229 -- .../view/css/glyphicons-halflings-regular.ttf | Bin 41236 -> 0 bytes .../css/glyphicons-halflings-regular.woff | Bin 23292 -> 0 bytes application/admin/view/group_add.html | 65 - application/admin/view/group_edit.html | 73 - application/admin/view/group_index.html | 51 - .../admin/view/image/bg-button-green.gif | Bin 169 -> 0 bytes application/admin/view/image/container_bg.gif | Bin 197 -> 0 bytes application/admin/view/image/error.png | Bin 280 -> 0 bytes application/admin/view/image/jia.png | Bin 977 -> 0 bytes application/admin/view/image/jian.png | Bin 589 -> 0 bytes application/admin/view/image/left_bg.gif | Bin 162 -> 0 bytes application/admin/view/image/line_x.gif | Bin 44 -> 0 bytes application/admin/view/image/loading.gif | Bin 1553 -> 0 bytes application/admin/view/image/login_bg.png | Bin 1887 -> 0 bytes application/admin/view/image/login_logo.png | Bin 4095 -> 0 bytes application/admin/view/image/login_t.png | Bin 352 -> 0 bytes application/admin/view/image/logo.png | Bin 48915 -> 0 bytes application/admin/view/image/message_bg.gif | Bin 419 -> 0 bytes application/admin/view/image/nav_bg.png | Bin 957 -> 0 bytes application/admin/view/image/onLoad.gif | Bin 781 -> 0 bytes application/admin/view/image/order_bg.gif | Bin 93 -> 0 bytes application/admin/view/image/range-line.gif | Bin 45 -> 0 bytes application/admin/view/image/right.png | Bin 419 -> 0 bytes .../admin/view/image/sidebar_title_bg.gif | Bin 154 -> 0 bytes application/admin/view/image/skin_list_bg.gif | Bin 434 -> 0 bytes .../admin/view/image/skin_list_urrent.gif | Bin 130 -> 0 bytes application/admin/view/image/skin_tab_bg.gif | Bin 44 -> 0 bytes application/admin/view/image/td_title_bg.gif | Bin 54 -> 0 bytes .../admin/view/image/validator_default.png | Bin 424 -> 0 bytes application/admin/view/image/white.gif | Bin 4480 -> 0 bytes application/admin/view/image/win_bg.png | Bin 298 -> 0 bytes application/admin/view/image/x_bg.png | Bin 234 -> 0 bytes application/admin/view/image/y_bg.png | Bin 127 -> 0 bytes application/admin/view/index_index.html | 59 - application/admin/view/index_welcome.html | 205 -- application/admin/view/node_add.html | 70 - application/admin/view/node_edit.html | 76 - application/admin/view/node_index.html | 59 - application/admin/view/public_angular.html | 34 - application/admin/view/public_layout.html | 46 - application/admin/view/public_login.html | 70 - application/admin/view/script/admin.js | 255 -- application/admin/view/script/tongji.js | 0 application/admin/view/theme_config.html | 53 - application/admin/view/theme_index.html | 47 - application/admin/view/user_add.html | 53 - application/admin/view/user_edit.html | 58 - application/admin/view/user_index.html | 60 - application/common/block/friendlink.php | 9 - application/common/block/pagelist.php | 53 - application/common/config.php | 31 - application/common/controller/admin.php | 56 - application/common/controller/common.php | 8 - application/common/controller/public.php | 8 - application/common/function.php | 144 - application/common/library/tree.php | 101 - application/common/model/ad.php | 46 - application/common/model/admin_group.php | 43 - application/common/model/admin_node.php | 69 - application/common/model/admin_user.php | 71 - application/common/model/friendlink.php | 58 - application/common/model/passport.php | 12 - application/common/ptf.coding.io.config.php | 19 - application/friendlink/controller/manage.php | 111 - application/friendlink/view/manage_add.html | 76 - application/friendlink/view/manage_edit.html | 83 - application/friendlink/view/manage_index.html | 62 - application/index/controller/index.php | 13 - index.php | 10 - mind.md | 26 - ptcms.sql | 157 - ptcms/core/api.php | 70 + ptcms/core/block.php | 58 +- ptcms/core/cache.php | 36 +- ptcms/core/config.php | 82 + ptcms/core/controller.php | 126 +- ptcms/core/cookie.php | 60 + ptcms/core/db.php | 77 + ptcms/core/dispatcher.php | 50 +- ptcms/core/filter.php | 135 + ptcms/core/input.php | 53 + ptcms/core/log.php | 6 +- ptcms/core/model.php | 762 +---- ptcms/core/plugin.php | 65 +- ptcms/core/request.php | 109 + ptcms/core/response.php | 215 ++ ptcms/core/session.php | 123 + ptcms/core/storage.php | 19 +- ptcms/core/view.php | 472 +-- ptcms/driver/api/ptcms.php | 50 + ptcms/driver/cache/file.php | 26 +- ptcms/driver/cache/memcache.php | 40 +- ptcms/driver/db/dao.php | 829 ++++++ ptcms/driver/db/mysql/dao.php | 4 + ptcms/driver/{model => db/mysql}/pdo.php | 17 +- ptcms/driver/model/mysqi.php | 0 ptcms/driver/model/mysql.php | 0 ptcms/driver/storage/file.php | 12 +- ptcms/driver/storage/ftp.php | 37 - ptcms/driver/storage/sae.php | 10 +- ptcms/driver/view/mc.php | 313 ++ ptcms/library/apiclient.php | 24 +- ptcms/library/bae/BaeImageService.class.php | 1399 +++++++++ ptcms/library/bae/BaeMemcache.class.php | 256 ++ .../bae/images/BaeImageAnnotate.class.php | 254 ++ .../bae/images/BaeImageComposite.class.php | 246 ++ .../bae/images/BaeImageConstant.class.php | 99 + .../bae/images/BaeImageQRCode.class.php | 235 ++ .../bae/images/BaeImageTransform.class.php | 355 +++ .../bae/images/BaeImageVCode.class.php | 173 ++ ptcms/library/bae/lib/BaeBase.class.php | 78 + ptcms/library/bae/lib/BaeException.class.php | 21 + .../bae/lib/BaeTaskQueueException.class.php | 6 + .../bae/lib/BccsServerException.class.php | 6 + ptcms/library/bae/lib/BcmsException.class.php | 6 + .../bae/lib/ChannelException.class.php | 6 + ptcms/library/bae/lib/CronException.class.php | 6 + ptcms/library/bae/lib/RequestCore.class.php | 773 +++++ ptcms/library/bae/zcache/memcache_errno.php | 26 + ptcms/library/bae/zcache/memcached_api.php | 683 +++++ ptcms/library/bae/zcache/zcache_api.php | 486 +++ ptcms/library/bae/zcache/zcache_conf.php | 20 + ptcms/library/bae/zcache/zcache_errno.php | 40 + ptcms/library/bae/zcache/zcache_nshead.php | 186 ++ ptcms/library/bae/zcache/zcache_socket.php | 277 ++ ptcms/library/bae/zcache/zcache_util.php | 95 + ptcms/library/collect.php | 77 +- ptcms/library/dc.php | 103 - ptcms/library/html.php | 15 +- ptcms/library/http.php | 135 +- ptcms/library/image.php | 3 +- ptcms/library/oauth.php | 4 +- ptcms/library/pinyin.php | 6 +- ptcms/library/steal.php | 182 -- ptcms/library/upload.php | 8 +- ptcms/library/verify.php | 2 +- ptcms/library/yarclient.php | 8 +- ptcms/ptcms.php | 839 ++---- ptcms_ad.sql | 35 - ptcms_friendlink.sql | 35 - public/image/114.png | Bin 4616 -> 0 bytes public/image/144.png | Bin 6439 -> 0 bytes public/image/57.png | Bin 1631 -> 0 bytes public/image/72.png | Bin 2352 -> 0 bytes public/image/error.gif | Bin 1709 -> 0 bytes public/image/favicon.ico | Bin 3262 -> 0 bytes public/image/loading.gif | Bin 1821 -> 0 bytes public/image/loading2.gif | Bin 1787 -> 0 bytes public/image/logo.png | Bin 4772 -> 0 bytes public/image/success.gif | Bin 678 -> 0 bytes public/plugin/datepicker/WdatePicker.js | 360 --- public/plugin/datepicker/calendar.js | 22 - public/plugin/datepicker/lang/zh-cn.js | 14 - public/plugin/datepicker/skin/WdatePicker.css | 9 - public/plugin/datepicker/skin/datePicker.gif | Bin 1043 -> 0 bytes .../datepicker/skin/default/datepicker.css | 211 -- public/plugin/datepicker/skin/default/img.gif | Bin 1578 -> 0 bytes .../plugin/datepicker/skin/ext/datepicker.css | 304 -- .../plugin/datepicker/skin/ext/dateselect.gif | Bin 190 -> 0 bytes .../plugin/datepicker/skin/ext/glass-bg.gif | Bin 873 -> 0 bytes .../plugin/datepicker/skin/ext/hd-sprite.gif | Bin 1099 -> 0 bytes public/plugin/datepicker/skin/ext/img.gif | Bin 1604 -> 0 bytes .../plugin/datepicker/skin/ext/left-btn.gif | Bin 870 -> 0 bytes .../plugin/datepicker/skin/ext/left-btn2.gif | Bin 113 -> 0 bytes public/plugin/datepicker/skin/ext/readme.txt | 19 - .../plugin/datepicker/skin/ext/right-btn.gif | Bin 871 -> 0 bytes .../plugin/datepicker/skin/ext/right-btn2.gif | Bin 113 -> 0 bytes public/plugin/layer/layer.js | 766 ----- public/plugin/layer/skin/default/Thumbs.db | Bin 37376 -> 0 bytes public/plugin/layer/skin/default/textbg.png | Bin 210 -> 0 bytes .../plugin/layer/skin/default/xubox_ico0.png | Bin 31945 -> 0 bytes .../layer/skin/default/xubox_loading0.gif | Bin 5793 -> 0 bytes .../layer/skin/default/xubox_loading1.gif | Bin 701 -> 0 bytes .../layer/skin/default/xubox_loading2.gif | Bin 1787 -> 0 bytes .../layer/skin/default/xubox_loading3.gif | Bin 2364 -> 0 bytes .../layer/skin/default/xubox_title0.png | Bin 221 -> 0 bytes public/plugin/layer/skin/layer.css | 58 - public/plugin/layer/skin/layer.ext.css | 22 - public/plugin/validator/change.txt | 1 - public/plugin/validator/images/loading.gif | Bin 457 -> 0 bytes .../validator/images/validator_default.png | Bin 424 -> 0 bytes .../validator/images/validator_simple.png | Bin 1075 -> 0 bytes public/plugin/validator/jquery.validator.css | 64 - public/plugin/validator/jquery.validator.js | 1526 ---------- public/plugin/zclip/zclip.js | 397 --- public/plugin/zclip/zclip.min.js | 314 -- public/plugin/zclip/zclip.swf | Bin 1071 -> 0 bytes public/script/angular.init.js | 28 - public/script/angular.min.js | 221 -- public/script/jquery.cookie.js | 103 - public/script/jquery.form.js | 1183 -------- public/script/jquery.min.js | 2647 ----------------- public/script/jquery.superslide.js | 346 --- public/script/jquery.validform.js | 8 - public/script/pt.common.js | 9 - template/README.md | 1 - template/default/common/message.html | 60 - template/default/config.ini | 6 - template/default/config.php | 28 - template/default/demo.jpg | Bin 19610 -> 0 bytes template/default/index/index_index.html | 9 - 222 files changed, 8810 insertions(+), 17049 deletions(-) delete mode 100644 .gitignore delete mode 100644 .htaccess delete mode 100644 404.html delete mode 100644 application/ad/controller/manage.php delete mode 100644 application/ad/view/manage_add.html delete mode 100644 application/ad/view/manage_edit.html delete mode 100644 application/ad/view/manage_index.html delete mode 100644 application/admin/controller/config.php delete mode 100644 application/admin/controller/group.php delete mode 100644 application/admin/controller/index.php delete mode 100644 application/admin/controller/node.php delete mode 100644 application/admin/controller/public.php delete mode 100644 application/admin/controller/theme.php delete mode 100644 application/admin/controller/user.php delete mode 100644 application/admin/model/theme.php delete mode 100644 application/admin/view/config_add.html delete mode 100644 application/admin/view/config_index.html delete mode 100644 application/admin/view/css/admin.css delete mode 100644 application/admin/view/css/glyphicons-halflings-regular.eot delete mode 100644 application/admin/view/css/glyphicons-halflings-regular.svg delete mode 100644 application/admin/view/css/glyphicons-halflings-regular.ttf delete mode 100644 application/admin/view/css/glyphicons-halflings-regular.woff delete mode 100644 application/admin/view/group_add.html delete mode 100644 application/admin/view/group_edit.html delete mode 100644 application/admin/view/group_index.html delete mode 100644 application/admin/view/image/bg-button-green.gif delete mode 100644 application/admin/view/image/container_bg.gif delete mode 100644 application/admin/view/image/error.png delete mode 100644 application/admin/view/image/jia.png delete mode 100644 application/admin/view/image/jian.png delete mode 100644 application/admin/view/image/left_bg.gif delete mode 100644 application/admin/view/image/line_x.gif delete mode 100644 application/admin/view/image/loading.gif delete mode 100644 application/admin/view/image/login_bg.png delete mode 100644 application/admin/view/image/login_logo.png delete mode 100644 application/admin/view/image/login_t.png delete mode 100644 application/admin/view/image/logo.png delete mode 100644 application/admin/view/image/message_bg.gif delete mode 100644 application/admin/view/image/nav_bg.png delete mode 100644 application/admin/view/image/onLoad.gif delete mode 100644 application/admin/view/image/order_bg.gif delete mode 100644 application/admin/view/image/range-line.gif delete mode 100644 application/admin/view/image/right.png delete mode 100644 application/admin/view/image/sidebar_title_bg.gif delete mode 100644 application/admin/view/image/skin_list_bg.gif delete mode 100644 application/admin/view/image/skin_list_urrent.gif delete mode 100644 application/admin/view/image/skin_tab_bg.gif delete mode 100644 application/admin/view/image/td_title_bg.gif delete mode 100644 application/admin/view/image/validator_default.png delete mode 100644 application/admin/view/image/white.gif delete mode 100644 application/admin/view/image/win_bg.png delete mode 100644 application/admin/view/image/x_bg.png delete mode 100644 application/admin/view/image/y_bg.png delete mode 100644 application/admin/view/index_index.html delete mode 100644 application/admin/view/index_welcome.html delete mode 100644 application/admin/view/node_add.html delete mode 100644 application/admin/view/node_edit.html delete mode 100644 application/admin/view/node_index.html delete mode 100644 application/admin/view/public_angular.html delete mode 100644 application/admin/view/public_layout.html delete mode 100644 application/admin/view/public_login.html delete mode 100644 application/admin/view/script/admin.js delete mode 100644 application/admin/view/script/tongji.js delete mode 100644 application/admin/view/theme_config.html delete mode 100644 application/admin/view/theme_index.html delete mode 100644 application/admin/view/user_add.html delete mode 100644 application/admin/view/user_edit.html delete mode 100644 application/admin/view/user_index.html delete mode 100644 application/common/block/friendlink.php delete mode 100644 application/common/block/pagelist.php delete mode 100644 application/common/config.php delete mode 100644 application/common/controller/admin.php delete mode 100644 application/common/controller/common.php delete mode 100644 application/common/controller/public.php delete mode 100644 application/common/function.php delete mode 100644 application/common/library/tree.php delete mode 100644 application/common/model/ad.php delete mode 100644 application/common/model/admin_group.php delete mode 100644 application/common/model/admin_node.php delete mode 100644 application/common/model/admin_user.php delete mode 100644 application/common/model/friendlink.php delete mode 100644 application/common/model/passport.php delete mode 100644 application/common/ptf.coding.io.config.php delete mode 100644 application/friendlink/controller/manage.php delete mode 100644 application/friendlink/view/manage_add.html delete mode 100644 application/friendlink/view/manage_edit.html delete mode 100644 application/friendlink/view/manage_index.html delete mode 100644 application/index/controller/index.php delete mode 100644 index.php delete mode 100644 mind.md delete mode 100644 ptcms.sql create mode 100644 ptcms/core/api.php create mode 100644 ptcms/core/config.php create mode 100644 ptcms/core/cookie.php create mode 100644 ptcms/core/db.php create mode 100644 ptcms/core/filter.php create mode 100644 ptcms/core/input.php create mode 100644 ptcms/core/request.php create mode 100644 ptcms/core/response.php create mode 100644 ptcms/core/session.php create mode 100644 ptcms/driver/api/ptcms.php create mode 100644 ptcms/driver/db/dao.php create mode 100644 ptcms/driver/db/mysql/dao.php rename ptcms/driver/{model => db/mysql}/pdo.php (96%) delete mode 100644 ptcms/driver/model/mysqi.php delete mode 100644 ptcms/driver/model/mysql.php delete mode 100644 ptcms/driver/storage/ftp.php create mode 100644 ptcms/driver/view/mc.php create mode 100644 ptcms/library/bae/BaeImageService.class.php create mode 100644 ptcms/library/bae/BaeMemcache.class.php create mode 100644 ptcms/library/bae/images/BaeImageAnnotate.class.php create mode 100644 ptcms/library/bae/images/BaeImageComposite.class.php create mode 100644 ptcms/library/bae/images/BaeImageConstant.class.php create mode 100644 ptcms/library/bae/images/BaeImageQRCode.class.php create mode 100644 ptcms/library/bae/images/BaeImageTransform.class.php create mode 100644 ptcms/library/bae/images/BaeImageVCode.class.php create mode 100644 ptcms/library/bae/lib/BaeBase.class.php create mode 100644 ptcms/library/bae/lib/BaeException.class.php create mode 100644 ptcms/library/bae/lib/BaeTaskQueueException.class.php create mode 100644 ptcms/library/bae/lib/BccsServerException.class.php create mode 100644 ptcms/library/bae/lib/BcmsException.class.php create mode 100644 ptcms/library/bae/lib/ChannelException.class.php create mode 100644 ptcms/library/bae/lib/CronException.class.php create mode 100644 ptcms/library/bae/lib/RequestCore.class.php create mode 100644 ptcms/library/bae/zcache/memcache_errno.php create mode 100644 ptcms/library/bae/zcache/memcached_api.php create mode 100644 ptcms/library/bae/zcache/zcache_api.php create mode 100644 ptcms/library/bae/zcache/zcache_conf.php create mode 100644 ptcms/library/bae/zcache/zcache_errno.php create mode 100644 ptcms/library/bae/zcache/zcache_nshead.php create mode 100644 ptcms/library/bae/zcache/zcache_socket.php create mode 100644 ptcms/library/bae/zcache/zcache_util.php delete mode 100644 ptcms/library/dc.php delete mode 100644 ptcms/library/steal.php delete mode 100644 ptcms_ad.sql delete mode 100644 ptcms_friendlink.sql delete mode 100644 public/image/114.png delete mode 100644 public/image/144.png delete mode 100644 public/image/57.png delete mode 100644 public/image/72.png delete mode 100644 public/image/error.gif delete mode 100644 public/image/favicon.ico delete mode 100644 public/image/loading.gif delete mode 100644 public/image/loading2.gif delete mode 100644 public/image/logo.png delete mode 100644 public/image/success.gif delete mode 100644 public/plugin/datepicker/WdatePicker.js delete mode 100644 public/plugin/datepicker/calendar.js delete mode 100644 public/plugin/datepicker/lang/zh-cn.js delete mode 100644 public/plugin/datepicker/skin/WdatePicker.css delete mode 100644 public/plugin/datepicker/skin/datePicker.gif delete mode 100644 public/plugin/datepicker/skin/default/datepicker.css delete mode 100644 public/plugin/datepicker/skin/default/img.gif delete mode 100644 public/plugin/datepicker/skin/ext/datepicker.css delete mode 100644 public/plugin/datepicker/skin/ext/dateselect.gif delete mode 100644 public/plugin/datepicker/skin/ext/glass-bg.gif delete mode 100644 public/plugin/datepicker/skin/ext/hd-sprite.gif delete mode 100644 public/plugin/datepicker/skin/ext/img.gif delete mode 100644 public/plugin/datepicker/skin/ext/left-btn.gif delete mode 100644 public/plugin/datepicker/skin/ext/left-btn2.gif delete mode 100644 public/plugin/datepicker/skin/ext/readme.txt delete mode 100644 public/plugin/datepicker/skin/ext/right-btn.gif delete mode 100644 public/plugin/datepicker/skin/ext/right-btn2.gif delete mode 100644 public/plugin/layer/layer.js delete mode 100644 public/plugin/layer/skin/default/Thumbs.db delete mode 100644 public/plugin/layer/skin/default/textbg.png delete mode 100644 public/plugin/layer/skin/default/xubox_ico0.png delete mode 100644 public/plugin/layer/skin/default/xubox_loading0.gif delete mode 100644 public/plugin/layer/skin/default/xubox_loading1.gif delete mode 100644 public/plugin/layer/skin/default/xubox_loading2.gif delete mode 100644 public/plugin/layer/skin/default/xubox_loading3.gif delete mode 100644 public/plugin/layer/skin/default/xubox_title0.png delete mode 100644 public/plugin/layer/skin/layer.css delete mode 100644 public/plugin/layer/skin/layer.ext.css delete mode 100644 public/plugin/validator/change.txt delete mode 100644 public/plugin/validator/images/loading.gif delete mode 100644 public/plugin/validator/images/validator_default.png delete mode 100644 public/plugin/validator/images/validator_simple.png delete mode 100644 public/plugin/validator/jquery.validator.css delete mode 100644 public/plugin/validator/jquery.validator.js delete mode 100644 public/plugin/zclip/zclip.js delete mode 100644 public/plugin/zclip/zclip.min.js delete mode 100644 public/plugin/zclip/zclip.swf delete mode 100644 public/script/angular.init.js delete mode 100644 public/script/angular.min.js delete mode 100644 public/script/jquery.cookie.js delete mode 100644 public/script/jquery.form.js delete mode 100644 public/script/jquery.min.js delete mode 100644 public/script/jquery.superslide.js delete mode 100644 public/script/jquery.validform.js delete mode 100644 public/script/pt.common.js delete mode 100644 template/README.md delete mode 100644 template/default/common/message.html delete mode 100644 template/default/config.ini delete mode 100644 template/default/config.php delete mode 100644 template/default/demo.jpg delete mode 100644 template/default/index/index_index.html diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 4cea788..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.idea/ -/runtime/ \ No newline at end of file diff --git a/.htaccess b/.htaccess deleted file mode 100644 index 73c58fe..0000000 --- a/.htaccess +++ /dev/null @@ -1,8 +0,0 @@ - -RewriteEngine on -RewriteRule ^.git - [F,L] -RewriteRule ^.svn - [F,L] -RewriteCond %{REQUEST_FILENAME} !-d -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule (.*) index.php?s=$1 [QSA,PT,L] - diff --git a/404.html b/404.html deleted file mode 100644 index c7a1fb3..0000000 --- a/404.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - {$sitename} - Power By Ptcms - - - -

404页面未找到

-

很抱歉!这个页面已经找不到了.

-

你可以返回首页 {$siteurl}

-
- - \ No newline at end of file diff --git a/README.md b/README.md index 2809795..c3bba37 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +//模版设置 +增加pc设置与wap模版设置 +增加wap模版配置 + #PTFrameWork 开源,不只是一种行为,更是一种信仰! diff --git a/application/ad/controller/manage.php b/application/ad/controller/manage.php deleted file mode 100644 index caa0b50..0000000 --- a/application/ad/controller/manage.php +++ /dev/null @@ -1,107 +0,0 @@ -tableName='ad'; - parent::init(); - } - - public function indexAction() { - $this->list=$this->model->getlist(); - $this->display(); - } - - public function addAction() { - if (IS_POST){ - $param['name']=I('name','str',''); - if (!$param['name']){ - $this->error('请输入链接名称'); - } - $param['key']=I('key','en',''); - if (!$param['key']){ - $this->error('请输入链接地址'); - } - $param['width']=I('width','int',0); - $param['height']=I('height','int',0); - $param['code']=I('code','str',''); - $param['intro']=I('intro','str',''); - $param['status']=I('status','int',1); - $param['type']=I('isblod','int',1); - $param['create_user_id']=$_SESSION['admin']['userid']; - $param['create_time']=NOW_TIME; - if($this->model->add($param)){ - $this->success('添加成功',U('index')); - }else{ - $this->error('添加失败'); - } - } - $this->display(); - } - - public function editAction() { - $id=I('request.id','int',0); - $info=$this->model->where(array('id'=>$id))->find(); - if (IS_POST){ - $param['name']=I('name','str',''); - if (!$param['name']){ - $this->error('请输入链接名称'); - } - $param['width']=I('width','int',0); - $param['height']=I('height','int',0); - $param['code']=I('code','str',''); - $param['intro']=I('intro','str',''); - $param['status']=I('status','int',1); - $param['type']=I('isblod','int',1); - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - $param['id']=$id; - if ($this->model->edit($param)){ - $this->success('修改成功',U('index')); - }else{ - $this->error('修改失败'); - } - } - $this->info=$info; - $this->display(); - } - - public function ajaxAction() { - $id=I('request.id','int',0); - $value=I('param','username',''); - if ($value){ - if ($passport_id=M('passport')->where(array('name'=>$value))->getfield('id')){ - $oid=$this->model->where(array('passport_id'=>$passport_id))->getfield('id'); - if ($oid && $oid!=$id){ - $data=array('status'=>'n','info'=>'您输入的用户名已经使用了'); - }else{ - $data=array('status'=>'y','info'=>'帐号可以使用'); - } - }else{ - $data=array('status'=>'n','info'=>'您输入的用户名不存在'); - } - }else{ - $data=array('status'=>'n','info'=>'输入的用户名有误'); - } - $this->ajax($data); - } - - public function multiAction() { - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - if (isset($_POST['changestatus'])){ - foreach($_POST['id'] as $k=>$v){ - $param['id']=$v; - $param['status']=$_POST['value'][$k]; - $this->model->edit($param); - } - $this->success('修改状态成功'); - }elseif(isset($_POST['reorder'])){ - foreach($_POST['ordernum'] as $k=>$v){ - $param['id']=$k; - $param['ordernum']=$v; - $this->model->edit($param); - } - $this->success('排序成功'); - }else{ - } - } -} \ No newline at end of file diff --git a/application/ad/view/manage_add.html b/application/ad/view/manage_add.html deleted file mode 100644 index 085655f..0000000 --- a/application/ad/view/manage_add.html +++ /dev/null @@ -1,76 +0,0 @@ -
-

添加广告

-
-
-
-
-
- 广告名称: - -
-
-
-
- 广告标识: - -
-
-
-
- 广告代码: - -
-
-
-
- 广告宽: - -
-
-
-
- 广告高: - -
-
-
-
- 广告描述: - -
-
-
-
广告类型: - - -
-
- -
-
广告状态: - - -
-
-
-
-
-
- -     -
-
-
-
-
-
- - diff --git a/application/ad/view/manage_edit.html b/application/ad/view/manage_edit.html deleted file mode 100644 index 742a70d..0000000 --- a/application/ad/view/manage_edit.html +++ /dev/null @@ -1,83 +0,0 @@ -
-

修改广告

-
-
-
-
-
- 广告名称: - -
-
-
-
- 广告标识: - -
-
-
-
- 广告代码: - -
-
-
-
- 广告宽: - -
-
-
-
- 广告高: - -
-
-
-
- 广告描述: - -
-
-
-
广告类型: - - -
-
- -
-
广告状态: - - -
-
-
-
-
-
- - -     -
-
-
-
-
-
- - - \ No newline at end of file diff --git a/application/ad/view/manage_index.html b/application/ad/view/manage_index.html deleted file mode 100644 index 303b1d9..0000000 --- a/application/ad/view/manage_index.html +++ /dev/null @@ -1,106 +0,0 @@ -
-

{$menuinfo.menu.name}

-
-
-
-
- 添加 -
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
广告名称创建人创建时间修改人修改时间状态操作
{{loop.name}}({{loop.key}}){{loop.width}}{{loop.height}}{{loop.create_username}}{{loop.create_time}}{{loop.update_username}}{{loop.update_time}} - 禁用 - 正常 - - 预览 - 调用 - 编辑 - 删除 -
- -
-
-
-
-
-
-
调用代码: - -
-
-
-
- - 复制代码 -
-
-
-
-{include file="/application/admin/view/public_angular.html"} - - \ No newline at end of file diff --git a/application/admin/controller/config.php b/application/admin/controller/config.php deleted file mode 100644 index 05cce1f..0000000 --- a/application/admin/controller/config.php +++ /dev/null @@ -1,70 +0,0 @@ -tableName='admin_user'; - parent::init(); - } - - public function indexAction() { - $this->list=$this->model->getlist(); - $this->pagestr=''; - $this->display(); - } - - public function addAction() { - if (IS_POST){ - var_dump($_POST);exit;; - $param['create_user_id']=$_SESSION['admin']['userid']; - $param['create_time']=NOW_TIME; - if($this->model->add($param)){ - $this->success('添加成功',U('index')); - }else{ - $this->error('添加失败'); - } - } - $this->display(); - } - - public function editAction() { - $id=I('request.id','int',0); - $info=$this->model->field('id,passport_id,group_id,intro,status')->where(array('id'=>$id))->find(); - if (IS_POST){ - $param['intro']=I('intro','str'); - $param['group_id']=I('groupid','int',0); - $param['status']=I('status','int',0); - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - $param['id']=$id; - if ($this->model->edit($param)){ - $this->success('修改成功',U('index')); - }else{ - $this->error('修改失败'); - } - } - $this->grouplist=M('admin_group')->field('id,name')->select(); - $info['name']=dc::get('passport',$info['passport_id'],'name'); - $this->info=$info; - $this->display(); - } - - public function ajaxAction() { - $id=I('request.id','int',0); - $value=I('param','username',''); - if ($value){ - if ($passport_id=M('passport')->where(array('name'=>$value))->getfield('id')){ - $oid=$this->model->where(array('passport_id'=>$passport_id))->getfield('id'); - if ($oid && $oid!=$id){ - $data=array('status'=>'n','info'=>'您输入的用户名已经使用了'); - }else{ - $data=array('status'=>'y','info'=>'帐号可以使用'); - } - }else{ - $data=array('status'=>'n','info'=>'您输入的用户名不存在'); - } - }else{ - $data=array('status'=>'n','info'=>'输入的用户名有误'); - } - $this->ajax($data); - } -} \ No newline at end of file diff --git a/application/admin/controller/group.php b/application/admin/controller/group.php deleted file mode 100644 index db6fcfa..0000000 --- a/application/admin/controller/group.php +++ /dev/null @@ -1,55 +0,0 @@ -tableName='admin_group'; - parent::init(); - } - - public function indexAction() { - $this->list=$this->model->order('id asc')->getlist(); - $this->display(); - } - - public function addAction() { - if (IS_POST){ - $param['name']=I('name','str'); - $param['intro']=I('intro','str'); - $param['node']=implode(',',M('admin_node')->toNodeAuth(I('node','arr',array()))); - $param['create_user_id']=$_SESSION['admin']['userid']; - $param['create_time']=NOW_TIME; - if($this->model->add($param)){ - $this->success('添加成功',U('index')); - }else{ - $this->error('添加失败'); - } - } - $tree=new Tree(M('admin_node')); - $this->menu=$tree->getAuthList(0,'id,name'); - $this->display(); - } - - public function editAction() { - $id=I('request.id','int',0); - $info=$this->model->field('id,name,node,intro')->where(array('id'=>$id))->find(); - if (IS_POST){ - $param['name']=I('name','str'); - $param['intro']=I('intro','str'); - $param['node']=implode(',',M('admin_node')->toNodeAuth(I('node','arr',array()))); - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - $param['id']=$id; - if ($this->model->edit($param)){ - $this->success('修改成功',U('index')); - }else{ - $this->error('修改失败'); - } - } - $info['node']=explode(',',$info['node']); - $tree=new Tree(M('admin_node')); - $this->menu=$tree->getAuthList(0,'id,name'); - $this->info=$info; - $this->display(); - } - -} \ No newline at end of file diff --git a/application/admin/controller/index.php b/application/admin/controller/index.php deleted file mode 100644 index 2a2b3e5..0000000 --- a/application/admin/controller/index.php +++ /dev/null @@ -1,47 +0,0 @@ -menu=$tree->getSonList(0,'id,name,module,controller,action',array('status'=>1)); - }else{ - //其他 - $this->menu=$tree->getSonList(0,'id,name,module,controller,action',array('status'=>1,'id'=>array('in',dc::get('admin_group',$_SESSION['admin']['groupid'],'node')))); - } - $this->display(); - } - - //欢迎页 - public function welcomeAction() { - $tips = array(); - // success info warning danger - if (C('appid') == 'test') { - $tips[] = array('type' => 'danger', 'content' => '您当前使用的APPID为test,请抓紧时间申请正式APPID,否则您可能会无法使用我们的API服务!点击这里更换'); - } - if (C('adminpath') == 'admin') { - $tips[] = array('type' => 'warning', 'content' => '您后台目录为默认的admin,为安全考虑,请您更改目录地址!点击这里更换'); - } - $usernum = M('passport')->count(); - $this->sitenum = 1; - $this->usernum = $usernum; - $this->adnum = 1; - $this->friendlinknum = count(C('friendlink')); - $this->tips = $tips; - $this->display(); - } -} \ No newline at end of file diff --git a/application/admin/controller/node.php b/application/admin/controller/node.php deleted file mode 100644 index e107008..0000000 --- a/application/admin/controller/node.php +++ /dev/null @@ -1,93 +0,0 @@ -tableName='admin_node'; - parent::init(); - } - - public function indexAction() { - $tree=new Tree($this->model); - $list=$tree->getIconList($tree->getList(0,'id,name,module,controller,action,ordernum,status'),2); - foreach($list as &$v){ - $v['url_edit']=U('admin.node.edit',array('id'=>$v['id'])); - $v['url_son']=U('admin.node.add',array('pid'=>$v['id'])); - } - $this->list=$list; - $this->assign('totalnum', count($this->list)); - $this->display(); - } - - public function addAction() { - if(IS_POST){ - $param['name']=I('name','str',''); - $param['pid']=I('pid','int',0); - $param['module']=I('module','str',''); - $param['controller']=I('controller','str',''); - $param['action']=I('action','str',''); - $param['status']=I('status','int',1); - $param['ordernum']=I('ordernum','int',1); - $param['create_user_id']=$_SESSION['admin']['userid']; - $param['create_time']=NOW_TIME; - if($this->model->add($param)){ - $this->success('添加成功'); - }else{ - $this->error('添加失败'); - } - } - $tree=new Tree($this->model); - $this->parentlist=$tree->getIconList($tree->getList(0,'id,name')); - $this->display(); - } - - public function editAction() { - $id=I('request.id','int',0); - $info=$this->model->field('id,name,pid,module,controller,action,status,ordernum')->where(array('id'=>$id))->find(); - if (IS_POST){ - if ($info['id']==$_POST['pid']){ - $this->error('不能设置自己为上级节点'); - } - $param['name']=I('name','str',''); - $param['pid']=I('pid','int',0); - $param['module']=I('module','str',''); - $param['controller']=I('controller','str',''); - $param['action']=I('action','str',''); - $param['status']=I('status','int',1); - $param['ordernum']=I('ordernum','int',1); - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - $param['id']=$id; - if ($this->model->edit($param)){ - $this->success('修改成功'); - }else{ - $this->error('修改失败'); - } - } - $tree=new Tree($this->model); - $this->parentlist=$tree->getIconList($tree->getList(0,'id,name')); - $this->info=$info; - $this->display(); - } - - public function multiAction() { - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - if (isset($_POST['changestatus'])){ - foreach($_POST['id'] as $k=>$v){ - $param['id']=$v; - $param['status']=$_POST['value'][$k]; - $this->model->edit($param); - } - $this->success('修改状态成功'); - }elseif(isset($_POST['reorder'])){ - foreach($_POST['ordernum'] as $k=>$v){ - $param['id']=$k; - $param['ordernum']=$v; - $this->model->edit($param); - } - $this->success('排序成功'); - }else{ - } - } -} \ No newline at end of file diff --git a/application/admin/controller/public.php b/application/admin/controller/public.php deleted file mode 100644 index fd935e6..0000000 --- a/application/admin/controller/public.php +++ /dev/null @@ -1,46 +0,0 @@ -checkInfo($username, $password)) { - if (M('admin_user')->checkUserStatus($userid)) { - M('admin_user')->setLoginStatus($userid); - $this->success('登录成功',U('admin.index.index')); - } else { - $this->error('您没有权限进入后台!'); - } - } else { - $this->error('帐号和密码输入错误'); - } - } else { - $this->error('验证码输入错误'); - } - } - $this->display(); - } - - // 退出操作 - public function logoutAction() { - M('admin_user')->delLoginStatus(); - $this->success('已经成功退出系统',U('Admin.Index.index')); - } - - /** - * 验证码 - */ - public function verifyAction() { - verify::buildImageVerify(6, 1, 'png', 70, 30); - } -} \ No newline at end of file diff --git a/application/admin/controller/theme.php b/application/admin/controller/theme.php deleted file mode 100644 index a8c1ccd..0000000 --- a/application/admin/controller/theme.php +++ /dev/null @@ -1,58 +0,0 @@ -defaulttpl = $config['tpl_theme']; - $this->list = M('theme')->getlist(); - $this->display(); - } - - public function setAction() { - $key = I('get.tpl', 'str', ''); - cookie('THEME_' . MODULE_NAME, null); - $this->saveconfig(array('tpl_theme' => $key)); - $this->success('设置默认模版成功'); - } - - public function configAction() { - $key = I('get.tpl', 'str', ''); - $file = TPL_PATH . '/' . $key . '/config.php'; - if (!$this->config = pt::import($file)) { - $this->config = array(); - } - if (IS_POST) { - $data = array(); - foreach ($_POST as $k => $v) { - if ($v['name'] && $v['key']) { - $data[$v['key']] = array( - 'name' => $v['name'], - 'value' => $v['value'], - ); - } - } - F($file, $data); - $this->success('修改成功'); - } - $this->tpl = I('get.tpl', 'str'); - $this->display(); - } - - public function delAction() { - $key = I('get.tpl', 'str', ''); - $id = I('get.id', 'str', ''); - $file = TPL_PATH . '/' . $key . '/config.php'; - $data = pt::import($file); - if (isset($data[$id])) { - unset($data[$id]); - F($file, $data); - $this->success('删除成功'); - } - $this->error('没有找到对应的配置项'); - } -} \ No newline at end of file diff --git a/application/admin/controller/user.php b/application/admin/controller/user.php deleted file mode 100644 index 627fa29..0000000 --- a/application/admin/controller/user.php +++ /dev/null @@ -1,87 +0,0 @@ -tableName='admin_user'; - parent::init(); - } - - public function indexAction() { - $this->list=$this->model->getlist(); - $this->display(); - } - - public function addAction() { - if (IS_POST){ - $param['passport_id']=M('passport')->where(array('name'=>I('name','username','')))->getfield('id'); - $param['intro']=I('intro','str'); - $param['group_id']=I('groupid','int',0); - $param['status']=I('status','int',0); - $param['create_user_id']=$_SESSION['admin']['userid']; - $param['create_time']=NOW_TIME; - $param['login_num']=0; - if($this->model->add($param)){ - $this->success('添加成功',U('index')); - }else{ - $this->error('添加失败'); - } - } - $this->grouplist=M('admin_group')->field('id,name')->select(); - $this->display(); - } - - public function editAction() { - $id=I('request.id','int',0); - $info=$this->model->field('id,passport_id,group_id,intro,status')->where(array('id'=>$id))->find(); - if (IS_POST){ - $param['intro']=I('intro','str'); - $param['group_id']=I('groupid','int',0); - $param['status']=I('status','int',0); - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - $param['id']=$id; - if ($this->model->edit($param)){ - $this->success('修改成功',U('index')); - }else{ - $this->error('修改失败'); - } - } - $this->grouplist=M('admin_group')->field('id,name')->select(); - $info['name']=dc::get('passport',$info['passport_id'],'name'); - $this->info=$info; - $this->display(); - } - - public function multiAction() { - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - if (isset($_POST['changestatus'])){ - foreach($_POST['id'] as $k=>$v){ - $param['id']=$v; - $param['status']=$_POST['value'][$k]; - $this->model->edit($param); - } - $this->success('修改状态成功'); - } - } - - public function ajaxAction() { - $id=I('request.id','int',0); - $value=I('param','username',''); - if ($value){ - if ($passport_id=M('passport')->where(array('name'=>$value))->getfield('id')){ - $oid=$this->model->where(array('passport_id'=>$passport_id))->getfield('id'); - if ($oid && $oid!=$id){ - $data=array('status'=>'n','info'=>'您输入的用户名已经使用了'); - }else{ - $data=array('status'=>'y','info'=>'帐号可以使用'); - } - }else{ - $data=array('status'=>'n','info'=>'您输入的用户名不存在'); - } - }else{ - $data=array('status'=>'n','info'=>'输入的用户名有误'); - } - $this->ajax($data); - } -} \ No newline at end of file diff --git a/application/admin/model/theme.php b/application/admin/model/theme.php deleted file mode 100644 index e4bc1ad..0000000 --- a/application/admin/model/theme.php +++ /dev/null @@ -1,21 +0,0 @@ - -

添加配置项

-
-
-
-
-
- 配置名称: - -
-
-
-
- 配置Key: - -
-
-
-
- 配置说明: - -
-
-
-
- 配置值: - -
-
-
-
- 配置类型: - -
-
-
-
- 配置分组: - -
-
-
-
- 配置选项: - -
-
-
-
- 排序序号: - -
-
-
-
配置级别: - - - - 核心配置生成在主配置文件,扩展配置生成在扩展文件,辅助配置不生成到文件 -
-
- -
-
配置状态: - - -
-
-
-
-
-
- -     -
-
-
-
-
- - - - \ No newline at end of file diff --git a/application/admin/view/config_index.html b/application/admin/view/config_index.html deleted file mode 100644 index 9c14935..0000000 --- a/application/admin/view/config_index.html +++ /dev/null @@ -1,66 +0,0 @@ -
-

{$menuinfo.menu.name}

-
-
-
-
- 添加 -
-
- - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
用户名用户组创建人创建时间修改人修改时间登录数登录时间状态操作
{{loop.username}}{{loop.groupname}}{{loop.create_username}}{{loop.create_time}}{{loop.update_username}}{{loop.update_time}}{{loop.login_num}}{{loop.login_time}} - 禁用 - 正常 - - 编辑 - 删除 -
- -
-
-
-{include file="public_angular"} \ No newline at end of file diff --git a/application/admin/view/css/admin.css b/application/admin/view/css/admin.css deleted file mode 100644 index fedbbff..0000000 --- a/application/admin/view/css/admin.css +++ /dev/null @@ -1,2155 +0,0 @@ -/* reset*/ -html, body, h1, h2, h3, h4, h5, h6, div, dl, dt, dd, ul, ol, li, p, blockquote, pre, hr, figure, table, caption, th, td, form, fieldset, legend, input, button, textarea, menu { margin: 0; padding: 0; } -header, footer, section, article, aside, nav, hgroup, address, figure, figcaption, menu, details { display: block; } -table { border-collapse: collapse; border-spacing: 0; } -caption, th { text-align: left; font-weight: normal; } -html, body, fieldset, img, iframe, abbr { border: 0; } -i, cite, em, var, address, dfn { font-style: normal; } -[hidefocus], summary { outline: 0; } -li { list-style: none; } -h1, h2, h3, h4, h5, h6, small { font-size: 100%; } -sup, sub { font-size: 83%; } -pre, code, kbd, samp { font-family: inherit; } -q:before, q:after { content: none; } -textarea { overflow: auto; resize: none; } -label, summary { cursor: default; } -a, button { cursor: pointer; } -h1, h2, h3, h4, h5, h6, em, strong, b { font-weight: bold; } -del, ins, u, s, a, a:hover { text-decoration: none; } -body, textarea, input, button, select, keygen, legend { font: 14px/20px 'microsoft Yahei', Tahoma, Geneva, sans-serif; color: #333; outline: 0; } -a:link { color: #0082cb; text-decoration: none; } -a:visited { color: #0082cb; text-decoration: none; } -a:hover { color: #0082cb; text-decoration: underline; } -a:active { color: #0082cb; text-decoration: none; } -/* function */ -.f-cb:after, .f-cbli li:after { display: block; clear: both; visibility: hidden; height: 0; overflow: hidden; content: "."; } -.f-cb, .f-cbli li { zoom: 1; } -.f-ib { display: inline-block; *display: inline; *zoom: 1; } -.f-dn { display: none; } -.f-db { display: block; } -.f-fl { float: left; } -.f-fr { float: right; } -.f-pr { position: relative; } -.f-prz { position: relative; zoom: 1; } -.f-oh { overflow: hidden; } -.f-fwn { font-weight: normal; } -.f-fwb { font-weight: bold; } -.f-tal { text-align: left; } -.f-tac { text-align: center; } -.f-tar { text-align: right; } -.f-taj { text-align: justify; text-justify: inter-ideograph; } -.f-vam, .f-vama * { vertical-align: middle; } -.f-wsn { word-wrap: normal; white-space: nowrap; } -.f-pre { overflow: hidden; text-align: left; white-space: pre-wrap; word-wrap: break-word; word-break: break-all; } -.f-wwb { white-space: normal; word-wrap: break-word; word-break: break-all; } -.f-ti { overflow: hidden; text-indent: -30000px; } -.f-ti2 { text-indent: 2em; } -.f-lhn { line-height: normal; } -.f-tdu, .f-tdu:hover { text-decoration: underline; } -.f-tdn, .f-tdn:hover { text-decoration: none; } -.f-toe { overflow: hidden; word-wrap: normal; white-space: nowrap; text-overflow: ellipsis; } -.f-csp { cursor: pointer; } -.f-csd { cursor: default; } -.f-csh { cursor: help; } -.f-csm { cursor: move; } -.f-usn { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } -.f-clear { clear: both } -/* 颜色 */ -.c-red { color: red } -.w160 { width: 160px } -.w320 { width: 320px; } -.w450 { width: 450px; !important; } -.w640 { width: 640px; } -label { cursor: pointer } -/* 公共 */ -.input-text { - padding: 3px; - font-size: 14px; - vertical-align: middle; - height: 22px; - color: #555; - vertical-align: middle; - border: 1px solid #ccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} -.input-box { - padding: 3px; - font-size: 14px; - line-height: 25px; - vertical-align: middle; - border: 1px solid #ccc; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} -.input-box:focus, .input-text:focus { - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); -} -.input-box:-moz-placeholder, .input-text:-moz-placeholder { - color: #999999; -} -.input-box:-moz-placeholder, .input-text:-moz-placeholder { - color: #999999; - opacity: 1; -} -.input-box:-ms-input-placeholder, .input-text:-ms-input-placeholder { - color: #999999; -} -.input-box:-webkit-input-placeholder, .input-text:-webkit-input-placeholder { - color: #999999; -} -.input-text[disabled], .input-text[readonly] { - cursor: not-allowed; - background-color: #eeeeee; -} -.pt-set-wrap input[type=radio], .pt-set-wrap input[type=checkbox] { - margin-right: 5px; - vertical-align: -2px; -} -a.box { - display: inline-block; - margin-left: 6px; - margin-bottom: 1px; - width: 70px; - height: 23px; - line-height: 23px; - border-width: 1px; - border-style: solid; - border-color: #ccc; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - background: #F9FBFD; - text-align: center; - vertical-align: middle; -} -a.box:hover { - background: #f6f6f6; - color: #333; - text-decoration: none; -} -/*登录用户*/ -#pt-login .pt-login-wrap { - margin: 80px auto 0; - padding: 20px; - width: 650px; - height: 350px; - background: url(../image/login_bg.png) no-repeat; -} -#pt-login .pt-login-wrap .pt-login-title { - position: relative; - height: 60px; - background: url(../image/login_t.png) repeat-x; -} -#pt-login .pt-login-wrap .pt-login-title .pt-title-logo { - background: url(../image/login_logo.png) no-repeat; - position: absolute; - top: 14px; - left: 35px; - width: 137px; - height: 32px; -} -#pt-login .pt-login-wrap .pt-login-content { - padding: 40px 0 0 156px; - line-height: 28px; -} -#pt-login .pt-login-wrap .pt-login-content .pt-login-form-line { - margin-bottom: 25px; -} -#pt-login .pt-login-wrap .pt-login-content .pt-login-form-btn { - margin-left: 72px; -} -#pt-login .pt-login-wrap .pt-login-content label { - display: block; - float: left; - width: 74px; - font-size: 14px; - text-align: right; -} -#pt-login .pt-login-wrap .pt-login-content .verify-input { - width: 80px; -} -#pt-login .pt-login-wrap .pt-login-content .verify { - margin-left: 5px; - margin-right: 5px; - vertical-align: bottom; cursor: pointer; -} -/*头部菜单*/ -#pt-header { - position: relative; - border-bottom: #ccc 1px solid; - height: 89px; - min-width: 990px; - background: #f5f5f5; - background: -webkit-linear-gradient(top, #fff 0%, #f1f1f1 100%); - background: -moz-linear-gradient(top, #fff 0%, #f1f1f1 100%); - background: linear-gradient(top, #fff 0%, #f1f1f1 100%); -} -#pt-header .logo { - position: absolute; - left: 20px; - top: 20px; - width: 240px; - height: 36px; - background: url(../image/logo.png) no-repeat; -} -#pt-header .menu { - position: absolute; - left: 300px; - bottom: -1px; - _bottom: -2px; -} -#pt-header .menu a { - float: left; - height: 35px; - margin-left: 7px; - text-decoration: none; - font-size: 15px; - line-height: 35px; - text-align: center; - font-weight: bold; - letter-spacing: 0.6em; - padding-left: 1.5em; - padding-right: 0.9em; -} -#pt-header .menu .current { - color: #000000; -} -#pt-header .menu .link { - color: #333; - border: #ccc 1px solid; - border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - -webkit-border-radius: 6px 6px 0 0; - background: #eee; - background: -webkit-linear-gradient(top, #fafafa 0%, #e0e0e0 100%); - background: -moz-linear-gradient(top, #fafafa 0%, #e0e0e0 100%); - background: linear-gradient(top, #fafafa 0%, #e0e0e0 100%); -} -#pt-header .menu .link:hover { - background: #f3f3f3; - cursor: pointer; -} -#pt-header .menu .link.current { - background: #fff; - background: -webkit-linear-gradient(top, #fafafa 0%, #fff 100%); - background: -moz-linear-gradient(top, #fafafa 0%, #fff 100%); - background: linear-gradient(top, #fafafa 0%, #fff 100%); - border-bottom-color: #fff; -} -#pt-header .menu .link.current:hover { - background: #f9f9f9; - background: #fff; - background: -webkit-linear-gradient(top, #eee 0%, #fff 100%); - background: -moz-linear-gradient(top, #eee 0%, #fff 100%); - background: linear-gradient(top, #eee 0%, #fff 100%); - cursor: pointer; -} -#pt-header .login-info { - position: absolute; - top: 15px; - right: 20px; - color: #7a7a7a; -} -#pt-header .login-info a { - color: #7a7a7a; -} -#pt-header .login-info em { - margin: 0 5px; -} -/** 主体**/ -#container { - padding: 10px 10px 0; - overflow: hidden; - min-width: 820px; -} -.pt-sidebar { - float: left; - width: 171px; - border: 1px solid #ccc; - background: #FFF; - overflow: hidden; -} -.pt-sidebar .pt-sidebar-menu li i { - width: 40px; - height: 40px; - text-align: center; - position: relative; - float: right; - display: inline-block; - top: 1px; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - border-bottom: 0px; -} -.pt-sidebar .pt-sidebar-menu li i:before { - content: "\2b"; - before: "\2b"; -} -.pt-sidebar .pt-sidebar-menu li div { - display: none; -} -.pt-sidebar .pt-sidebar-menu li.open { - border-bottom: 1px #ccc solid; -} -.pt-sidebar .pt-sidebar-menu li.open h3 { - cursor: default; -} -.pt-sidebar .pt-sidebar-menu li.open i:before { - content: "\2212"; - before: "\2212"; -} -.pt-sidebar .pt-sidebar-menu li h3 { - padding-left: 15px; - border-bottom: 1px #ccc solid; - line-height: 39px; - font-size: 15px; - cursor: pointer; - background: #fafafa; - background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%); - background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%); - background: linear-gradient(top, #fafafa 0%, #eee 100%); -} -.pt-sidebar .pt-sidebar-menu-info a { - display: block; - margin: 10px; - height: 25px; - line-height: 25px; - color: #0082cb; - font-size: 14px; - text-indent: 25px; -} -.pt-sidebar .pt-sidebar-menu-info a:hover { - background: #d4e5ff; - text-decoration: none; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} -.pt-sidebar .pt-sidebar-menu-info a.current { - background-color: #0082cb; - color: #FFF; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} -.pt-sidebar .pt-sidebar-menu-info a.current:hover { - background-color: #0082cb; - color: #FFF; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} -/* 右侧主内容 */ -.pt-main { - margin-left: 181px; - border-width: 1px; - border-style: solid; - border-color: #ccc; - min-width: 800px; - _zoom: 1; -} -#mainframe { - overflow-x: hidden; - overflow-y: auto; -} -/*弹出层*/ -.pt-pop { - padding: 20px 20px 0; - width: 460px; -} -/* 内容 */ -.pt-main-wrap .pt-set-wrap, .pt-main-wrap .pt-table-wrap, .pt-main-wrap .pt-wrap { - position: relative; - padding: 20px 20px 20px; - background: #fff; - _zoom: 1; -} -.pt-main-wrap .pt-set-wrap .pt-set-box { - margin: 20px 0; -} -.pt-main-wrap .pt-path { - background: #fafafa; - background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%); - background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%); - background: linear-gradient(top, #fafafa 0%, #eee 100%); - height: 40px; - line-height: 40px; - color: #444; - position: relative; - padding-left: 20px; - font-size: 15px; - border-bottom: 1px #ccc solid; -} -.pt-main-wrap .pt-path .pt-path-icon { - width: 25px; - height: 40px; - top: 2px; - text-align: left; - position: relative; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; -} -.pt-main-wrap .pt-msg-title { - padding-left: 10px; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; - border-radius: 10px; - background: #eaf3fa; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - height: 38px; - line-height: 38px; - font-size: 15px; - color: #333; -} -.pt-msg-title span { - float: right; -} -.pt-msg-title span a.btn { - color: #fff; - margin: 4px 10px 4px; - font-size: 14px; - height: 18px; - line-height: 18px; -} -.pt-main-wrap .pt-msg-box { - margin: 15px 20px; -} -.pt-msg-box .tips { - margin-bottom: 5px; - color: #555; - text-indent: 2em; -} -.pt-msg-box .tipsbottom { - margin-top: 15px; - color: #555; -} -.pt-msg-box .quote { - padding: 10px; - border: #F6EAD2 1px solid; - color: #666; - background: #FFFCF4; - line-height: 24px; - margin-top: 10px; -} -.pt-main-wrap .pt-set-content { - /*padding: 15px 20px 0;*/ - _zoom: 1; - position: relative -} -.pt-set-content .pt-set-info { - margin-bottom: 15px; - padding-bottom: 15px; - border-bottom: 1px #ccc dashed; -} -.pt-set-content .pt-set-info:last-child { - border-bottom: none; -} -.pt-set-info .name { - width: 6em; - text-align: right; - display: inline-block -} -.pt-set-info .title { - padding-bottom: 8px; -} -.pt-set-info .line { -} -.pt-set-info .line b { - width: 10em; - text-align: right; - display: inline-block -} -.pt-set-info .auth b { - width: 8em; - text-align: right; - display: inline-block -} -.pt-set-info .auth label { - width: 100px; -} -.pt-set-info p { -} -.pt-set-info label { - display: inline-block; -} -.pt-set-info p span { - color: #666; - margin-left: 15px; -} -.pt-set-info .tips { - margin-top: 10px; - margin-left: 15px; - color: #666; -} -/*选项卡*/ -.pt-tab { - margin: 20px 0; -} -.pt-tab-nav { - font-weight: bold; -} -.pt-tab-nav a { - position: relative; - top: 1px; - cursor: pointer; - font-size: 15px; - height: 38px; - line-height: 38px; - margin-right: 5px; - color: #222; - border: #ccc 1px solid; - border-radius: 8px 8px 0 0; - -moz-border-radius: 8px 8px 0 0; - -webkit-border-radius: 8px 8px 0 0; - background: #f1f1f1; - text-decoration: none; - display: inline-block; - padding: 0 15px; -} -.pt-tab-nav .current { - border: #ccc 1px solid; - border-radius: 8px 8px 0 0; - -moz-border-radius: 8px 8px 0 0; - -webkit-border-radius: 8px 8px 0 0; - border-bottom-color: #fff; - background: #fff; -} -.pt-tab-content { - padding: 15px 10px 10px; - border: 1px solid #ccc; - clear: both; -} -.pt-tab-item { - display: none; -} -.pt-tab-button { - padding-left: 20px -} -/*列表展示*/ -.pt-table-wrap .pt-search-area, .pt-table-wrap .pt-list { - margin: 15px 0; -} -.pt-table-wrap .tips { - font-size: 15px; - line-height: 2em; - margin-bottom: 10px; -} -.pt-search-area .pt-search-box { - padding: 10px 10px 0; - border: #d9e7f4 1px solid; - height: 40px; - background: #f4f8fc; - overflow: hidden; - zoom: 1; - _zoom: 1; -} -.pt-search-box strong { - font-size: 15px; -} -.pt-list-title { - height: 30px; - line-height: 30px; -} -.pt-list-table { - width: 100%; - border-spacing: 0; - border: 1px #ccc solid; -} -.pt-list-table td { - padding: 5px 10px; - overflow: hidden; -} -.pt-list-table thead th { - background: #f9f9f9; - text-transform: uppercase; - font-size: 16px; - font-weight: 600; - border-bottom: 1px solid #ccc; - text-shadow: -1px -1px #fff; - padding: 5px 10px; - text-align: left; - height: 30px; - border-right: #CCC 1px solid; - text-align: center; -} -.pt-list-table thead th.f-tal, .pt-list-table tbody td.f-tal { - text-align: left; -} -.pt-list-table thead th.f-tar, .pt-list-table tbody td.f-tar { - text-align: right; -} -.pt-list-table thead th:hover { - cursor: pointer; -} -.pt-list-table tbody { - border-top: 1px solid #fff; - background: #fff; -} -.pt-list-table tbody tr:hover.odd td, .pt-list-table tr:hover td { - background: #eaeaea; -} -.pt-list-table tbody tr:nth-child(2n) { - background: #f4f4f4; -} -.pt-list-table tbody td { - font-size: 11px; - vertical-align: middle; - height: 25px; - border-right: #CCC 1px solid; - font-size: 14px; - text-align: center; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} -.pt-list-table .operate a { - margin-right: 5px; - color: #333; -} -.pt-list-table .operate a:hover { - color: #000; -} -.pt-list-table .operate a:last-child, .pt-list-table .operate a.last { - margin-right: 0; -} -.pt-list-table .operate .icon { - margin-right: 2px; -} -.pt-list-table .w-checkbox { width: 10px; } -.pt-list-table .w-id { width: 50px; } -.pt-list-table .w-fulltime { width: 134px; } -.pt-list-table .w-time { width: 96px; } -.pt-list-table .w-smalltime { width: 77px; } -.pt-list-table .w-word4 { width: 68px; } -.pt-list-table .w-word5 { width: 85px; } -.pt-list-table .w-word4td { width: 56px; } -.pt-list-table .w-word5 { width: 85px; } -.pt-list-table .w-word4 { width: 68px; } -.pt-list-table .w-word3 { width: 51px; } -.pt-list-table .w-word2 { width: 34px; } -.pt-list-table .w-operate1 { width: 45px; } -.pt-list-table .w-operate2 { width: 100px; } -.pt-list-table .w-operate3 { width: 150px; } -.pt-list-table .w-operate4 { width: 200px; } -.pt-list-table .w-operate5 { width: 256px; } -.pt-list-footer { - margin-top: 10px; line-height: 35px; -} -.pt-list-header { - margin-bottom: 10px; line-height: 35px; -} -.pt-list-operate a { - color: #fff; - margin-right: 3px; -} -.pt-list-operate input { - margin-right: 3px; -} -/* 分页 */ -/* 普通翻页器-默认居中 */ -.pt-page { margin: 1px; text-align: center; height: 30px; line-height: 28px; font-size: 0; letter-spacing: -0.307em; word-wrap: normal; white-space: nowrap; color: #999; } -.pt-page a, .pt-page i { display: inline-block; vertical-align: text-bottom; margin: 0 3px; border-radius: 5px; padding: 0 10px; border: 1px solid #ddd; font-size: 14px; letter-spacing: normal; text-shadow: 0 1px #fff; background: #fff; -webkit-transition: background-color 0.3s; -moz-transition: background-color 0.3s; -ms-transition: background-color 0.3s; transition: background-color 0.3s; } -.pt-page i { border: 0; } -.pt-page a, .pt-page a:hover { text-decoration: none; color: #39c; } -.pt-page a:first-child { margin-left: 0; border-radius: 5px; } -.pt-page a:last-child { margin-right: 0; border-radius: 5px; } -.pt-page a:hover { background: #f5f5f5; } -.pt-page a:active { background: #f0f0f0; } -.pt-page a.current, .pt-page a.current:hover, .pt-page a.current:active { cursor: default; color: #999; background: #f5f5f5; } -.pt-page a.disable, .pt-page a.disable:hover, .pt-page a.disable:active { cursor: default; color: #ccc; background: #fff; } -/* 分栏 */ -.pt-col { - margin-top: 20px; - padding: 0 20px; -} -.pt-col-2 { width: 49.5% } -.pt-col-3 { width: 32.65% } -.pt-col-4 { width: 24.25% } -.pt-col-5 { width: 19.2% } -.pt-col-item { - float: left; - min-height: 50px; - margin-right: 1%; -} -.pt-col-item-last { - margin-right: 0; - float: right -} -/* widget */ -.pt-widget { - border: 1px solid #CDCDCD; - width: 100%; -} -.pt-widget a { - color: #333; -} -.pt-widget-title { - background-color: #f4f4f4; - border-bottom: 1px solid #CDCDCD; - height: 35px; - line-height: 35px; -} -.pt-widget-title span { - width: 35px; - border-right: 1px solid #CDCDCD; - float: left; - text-align: center; -} -.pt-widget-title h5 { - float: left; - margin-left: 10px; -} -.pt-widget-content { - min-height: 50px; - background: #FaFaFa; -} -.pt-wcon-text, .pt-wcon-list, .pt-wcon-piclist { - padding: 10px; -} -.pt-wcon-text p { - text-indent: 2em; - line-height: 1.5em; -} -.pt-wcon-list ul { - line-height: 30px; - padding: 0 10px; -} -.pt-wcon-list li { border-bottom: 1px #cecece dotted; height: 30px } -.pt-wcon-list li:first-child { border-top: 1px #cecece dotted; } -.pt-wcon-list i { width: 30px; text-align: center } -.pt-wcon-list strong { width: 150px; display: inline-block; } -.pt-wcon-list li a { display: inline-block } -.pt-wcon-piclist li { - height: 60px; - border-bottom: 1px #cecece dotted; -} -.pt-wcon-piclist li:last-child { - border-bottom-width: 0px; -} -.pt-wcon-piclist .picbox { - background: none repeat scroll 0 0 #FFFFFF; - float: left; - height: 40px; - margin-right: 10px; - margin-top: 5px; - padding: 2px; - width: 40px; -} -.pt-wcon-piclist .textbox { - margin: 5px 0; - position: relative; - font-size: 12px; -} -.pt-wcon-piclist .textbox .info { - color: #999; - line-height: 18px; - height: 18px; - overflow: hidden; -} -.pt-wcon-piclist .textbox .content { - height: 38px; - line-height: 19px; - overflow: hidden; -} -.pt-wcon-infobox { -} -.pt-wcon-infobox .iconbox { - border-right: 1px solid #CDCDCD; - width: 60px; - height: 60px; - line-height: 60px; - font-size: 40px; - padding: 10px; - float: left; -} -.pt-wcon-infobox .infobox { - padding: 10px; -} -.pt-wcon-infobox .infobox strong { - height: 35px; - line-height: 35px; - display: block; - font-size: 20px; - overflow: hidden; -} -.pt-wcon-infobox .infobox span { - height: 25px; - line-height: 25px; -} -.pt-wcon-chart { - margin-top: 20px; - padding: 0 20px; - height: 300px; -} -.pt-wcon-chart .chartbox { - float: left; - width: 74%; -} -.pt-wcon-chart .infobox { - float: right; - width: 24%; -} -.pt-wcon-chart .chartbox .chart { - height: 300px; - width: 100%; -} -.pt-wcon-chart .site-stats { - margin: 0; - padding: 0; text-align: center; - list-style: none; -} -.pt-wcon-chart .site-stats li { - cursor: pointer; - display: inline-block; - margin: 0 5px 10px; - text-align: center; - width: 42%; - height: 65px; - padding: 10px 0; - color: #fff; - position: relative; - background: #b6b3b3; - float: left; -} -.pt-wcon-chart .site-stats li i { - font-size: 24px; - clear: both -} -.pt-wcon-chart .site-stats li:hover { - background: #2E363F; -} -.pt-wcon-chart .site-stats li i { - vertical-align: baseline; -} -.pt-wcon-chart .site-stats li strong { - font-weight: bold; - font-size: 20px; width: 100%; float: left; - margin-left: 0px; -} -.pt-wcon-chart .site-stats li small { - margin-left: 0px; - font-size: 11px; - width: 100%; float: left; -} -/* bootstrap */ - -.label { - padding: 5px 8px 5px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - font-size: 12px; - line-height: 14px; - color: #333333; - vertical-align: baseline; - white-space: nowrap; - background-color: #ffffff; - border: 1px solid transparent; - cursor: pointer; - border-color: #cccccc; -} -.label:hover { - color: #333333; - background-color: #ebebeb; - border-color: #adadad; -} -.btn { - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-size: 14px; - font-weight: normal; - line-height: 1.428571429; - text-align: center; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} -.btn:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.btn:hover, .btn:focus { - color: #333333; - text-decoration: none; -} -.btn:active, .btn.active { - background-image: none; - outline: 0; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn.disabled, .btn[disabled], fieldset[disabled] .btn { - pointer-events: none; - cursor: not-allowed; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} -.btn-default, .label-default { - color: #333333; - background-color: #ffffff; - border-color: #cccccc; -} -.btn-default:hover, .label-default:hover, .btn-default:focus, .btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { - color: #333333; - background-color: #ebebeb; - border-color: #adadad; -} -.btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { - background-image: none; -} -.btn-default.disabled, .btn-default[disabled], fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, .btn-default.disabled:focus, .btn-default[disabled]:focus, fieldset[disabled] .btn-default:focus, .btn-default.disabled:active, .btn-default[disabled]:active, fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { - background-color: #ffffff; - border-color: #cccccc; -} -.btn-default .badge { - color: #ffffff; - background-color: #fff; -} -.btn-primary, .label-primary { - color: #ffffff; - background-color: #428bca; - border-color: #357ebd; -} -.btn-primary:hover, .label-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #3276b1; - border-color: #285e8e; -} -.btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { - background-image: none; -} -.btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { - background-color: #428bca; - border-color: #357ebd; -} -.btn-primary .badge { - color: #428bca; - background-color: #fff; -} -.btn-warning, .label-warning { - color: #ffffff; - background-color: #f0ad4e; - border-color: #eea236; -} -.btn-warning:hover, .label-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #ed9c28; - border-color: #d58512; -} -.btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { - background-image: none; -} -.btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, .btn-warning.disabled:focus, .btn-warning[disabled]:focus, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled:active, .btn-warning[disabled]:active, fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { - background-color: #f0ad4e; - border-color: #eea236; -} -.btn-warning .badge { - color: #f0ad4e; - background-color: #fff; -} -.btn-danger, .label-danger { - color: #ffffff; - background-color: #d9534f; - border-color: #d43f3a; -} -.btn-danger:hover, .label-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #d2322d; - border-color: #ac2925; -} -.btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { - background-image: none; -} -.btn-danger.disabled, .btn-danger[disabled], fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, .btn-danger.disabled:focus, .btn-danger[disabled]:focus, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled:active, .btn-danger[disabled]:active, fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { - background-color: #d9534f; - border-color: #d43f3a; -} -.btn-danger .badge { - color: #d9534f; - background-color: #fff; -} -.btn-success, .label-success { - color: #ffffff; - background-color: #5cb85c; - border-color: #4cae4c; -} -.btn-success:hover, .label-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #47a447; - border-color: #398439; -} -.btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { - background-image: none; -} -.btn-success.disabled, .btn-success[disabled], fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, .btn-success.disabled:focus, .btn-success[disabled]:focus, fieldset[disabled] .btn-success:focus, .btn-success.disabled:active, .btn-success[disabled]:active, fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { - background-color: #5cb85c; - border-color: #4cae4c; -} -.btn-success .badge { - color: #5cb85c; - background-color: #fff; -} -.btn-info, .label-info { - color: #ffffff; - background-color: #5bc0de; - border-color: #46b8da; -} -.btn-info:hover, .label-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #39b3d7; - border-color: #269abc; -} -.btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { - background-image: none; -} -.btn-info.disabled, .btn-info[disabled], fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, .btn-info.disabled:focus, .btn-info[disabled]:focus, fieldset[disabled] .btn-info:focus, .btn-info.disabled:active, .btn-info[disabled]:active, fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { - background-color: #5bc0de; - border-color: #46b8da; -} -.btn-info .badge { - color: #5bc0de; - background-color: #fff; -} -.btn-link { - font-weight: normal; - color: #428bca; - cursor: pointer; - border-radius: 0; -} -.btn-link, .btn-link:active, .btn-link[disabled], fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; -} -.btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { - border-color: transparent; -} -.btn-link:hover, .btn-link:focus { - color: #2a6496; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { - color: #999999; - text-decoration: none; -} -.btn-lg { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; - border-radius: 6px; -} -.btn-sm { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -.btn-xs { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -.btn-block { - display: block; - width: 100%; - padding-right: 0; - padding-left: 0; -} -.btn-block + .btn-block { - margin-top: 5px; -} -input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { - width: 100%; -} -@font-face { - font-family: 'Glyphicons Halflings'; - src: url('./glyphicons-halflings-regular.eot'); - src: url('./glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('./glyphicons-halflings-regular.woff') format('woff'), url('./glyphicons-halflings-regular.ttf') format('truetype'), url('./glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); -} -.icon { - position: relative; - display: inline-block; - top: 1px; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - -moz-osx-font-smoothing: grayscale; -} -.icon-asterisk:before { - content: "\2a"; - before: "\2a"; -} -.icon-plus:before { - content: "\2b"; - before: "\2b"; -} -.icon-euro:before { - content: "\20ac"; - before: "\20ac"; -} -.icon-minus:before { - content: "\2212"; - before: "\2212"; -} -.icon-cloud:before { - content: "\2601"; - before: "\2601"; -} -.icon-envelope:before { - content: "\2709"; - before: "\2709"; -} -.icon-pencil:before { - content: "\270f"; - before: "\270f"; -} -.icon-glass:before { - content: "\e001"; - before: "\e001"; -} -.icon-music:before { - content: "\e002"; - before: "\e002"; -} -.icon-search:before { - content: "\e003"; - before: "\e003"; -} -.icon-heart:before { - content: "\e005"; - before: "\e005"; -} -.icon-star:before { - content: "\e006"; - before: "\e006"; -} -.icon-star-empty:before { - content: "\e007"; - before: "\e007"; -} -.icon-user:before { - content: "\e008"; - before: "\e008"; -} -.icon-film:before { - content: "\e009"; - before: "\e009"; -} -.icon-th-large:before { - content: "\e010"; - before: "\e010"; -} -.icon-th:before { - content: "\e011"; - before: "\e011"; -} -.icon-th-list:before { - content: "\e012"; - before: "\e012"; -} -.icon-ok:before { - content: "\e013"; - before: "\e013"; -} -.icon-remove:before { - content: "\e014"; - before: "\e014"; -} -.icon-zoom-in:before { - content: "\e015"; - before: "\e015"; -} -.icon-zoom-out:before { - content: "\e016"; - before: "\e016"; -} -.icon-off:before { - content: "\e017"; - before: "\e017"; -} -.icon-signal:before { - content: "\e018"; - before: "\e018"; -} -.icon-cog:before { - content: "\e019"; - before: "\e019"; -} -.icon-trash:before { - content: "\e020"; - before: "\e020"; -} -.icon-home:before { - content: "\e021"; - before: "\e021"; -} -.icon-file:before { - content: "\e022"; - before: "\e022"; -} -.icon-time:before { - content: "\e023"; - before: "\e023"; -} -.icon-road:before { - content: "\e024"; - before: "\e024"; -} -.icon-download-alt:before { - content: "\e025"; - before: "\e025"; -} -.icon-download:before { - content: "\e026"; - before: "\e026"; -} -.icon-upload:before { - content: "\e027"; - before: "\e027"; -} -.icon-inbox:before { - content: "\e028"; - before: "\e028"; -} -.icon-play-circle:before { - content: "\e029"; - before: "\e029"; -} -.icon-repeat:before { - content: "\e030"; - before: "\e030"; -} -.icon-refresh:before { - content: "\e031"; - before: "\e031"; -} -.icon-list-alt:before { - content: "\e032"; - before: "\e032"; -} -.icon-lock:before { - content: "\e033"; - before: "\e033"; -} -.icon-flag:before { - content: "\e034"; - before: "\e034"; -} -.icon-headphones:before { - content: "\e035"; - before: "\e035"; -} -.icon-volume-off:before { - content: "\e036"; - before: "\e036"; -} -.icon-volume-down:before { - content: "\e037"; - before: "\e037"; -} -.icon-volume-up:before { - content: "\e038"; - before: "\e038"; -} -.icon-qrcode:before { - content: "\e039"; - before: "\e039"; -} -.icon-barcode:before { - content: "\e040"; - before: "\e040"; -} -.icon-tag:before { - content: "\e041"; - before: "\e041"; -} -.icon-tags:before { - content: "\e042"; - before: "\e042"; -} -.icon-book:before { - content: "\e043"; - before: "\e043"; -} -.icon-bookmark:before { - content: "\e044"; - before: "\e044"; -} -.icon-print:before { - content: "\e045"; - before: "\e045"; -} -.icon-camera:before { - content: "\e046"; - before: "\e046"; -} -.icon-font:before { - content: "\e047"; - before: "\e047"; -} -.icon-bold:before { - content: "\e048"; - before: "\e048"; -} -.icon-italic:before { - content: "\e049"; - before: "\e049"; -} -.icon-text-height:before { - content: "\e050"; - before: "\e050"; -} -.icon-text-width:before { - content: "\e051"; - before: "\e051"; -} -.icon-align-left:before { - content: "\e052"; - before: "\e052"; -} -.icon-align-center:before { - content: "\e053"; - before: "\e053"; -} -.icon-align-right:before { - content: "\e054"; - before: "\e054"; -} -.icon-align-justify:before { - content: "\e055"; - before: "\e055"; -} -.icon-list:before { - content: "\e056"; - before: "\e056"; -} -.icon-indent-left:before { - content: "\e057"; - before: "\e057"; -} -.icon-indent-right:before { - content: "\e058"; - before: "\e058"; -} -.icon-facetime-video:before { - content: "\e059"; - before: "\e059"; -} -.icon-picture:before { - content: "\e060"; - before: "\e060"; -} -.icon-map-marker:before { - content: "\e062"; - before: "\e062"; -} -.icon-adjust:before { - content: "\e063"; - before: "\e063"; -} -.icon-tint:before { - content: "\e064"; - before: "\e064"; -} -.icon-edit:before { - content: "\e065"; - before: "\e065"; -} -.icon-share:before { - content: "\e066"; - before: "\e066"; -} -.icon-check:before { - content: "\e067"; - before: "\e067"; -} -.icon-move:before { - content: "\e068"; - before: "\e068"; -} -.icon-step-backward:before { - content: "\e069"; - before: "\e069"; -} -.icon-fast-backward:before { - content: "\e070"; - before: "\e070"; -} -.icon-backward:before { - content: "\e071"; - before: "\e071"; -} -.icon-play:before { - content: "\e072"; - before: "\e072"; -} -.icon-pause:before { - content: "\e073"; - before: "\e073"; -} -.icon-stop:before { - content: "\e074"; - before: "\e074"; -} -.icon-forward:before { - content: "\e075"; - before: "\e075"; -} -.icon-fast-forward:before { - content: "\e076"; - before: "\e076"; -} -.icon-step-forward:before { - content: "\e077"; - before: "\e077"; -} -.icon-eject:before { - content: "\e078"; - before: "\e078"; -} -.icon-chevron-left:before { - content: "\e079"; - before: "\e079"; -} -.icon-chevron-right:before { - content: "\e080"; - before: "\e080"; -} -.icon-plus-sign:before { - content: "\e081"; - before: "\e081"; -} -.icon-minus-sign:before { - content: "\e082"; - before: "\e082"; -} -.icon-remove-sign:before { - content: "\e083"; - before: "\e083"; -} -.icon-ok-sign:before { - content: "\e084"; - before: "\e084"; -} -.icon-question-sign:before { - content: "\e085"; - before: "\e085"; -} -.icon-info-sign:before { - content: "\e086"; - before: "\e086"; -} -.icon-screenshot:before { - content: "\e087"; - before: "\e087"; -} -.icon-remove-circle:before { - content: "\e088"; - before: "\e088"; -} -.icon-ok-circle:before { - content: "\e089"; - before: "\e089"; -} -.icon-ban-circle:before { - content: "\e090"; - before: "\e090"; -} -.icon-arrow-left:before { - content: "\e091"; - before: "\e091"; -} -.icon-arrow-right:before { - content: "\e092"; - before: "\e092"; -} -.icon-arrow-up:before { - content: "\e093"; - before: "\e093"; -} -.icon-arrow-down:before { - content: "\e094"; - before: "\e094"; -} -.icon-share-alt:before { - content: "\e095"; - before: "\e095"; -} -.icon-resize-full:before { - content: "\e096"; - before: "\e096"; -} -.icon-resize-small:before { - content: "\e097"; - before: "\e097"; -} -.icon-exclamation-sign:before { - content: "\e101"; - before: "\e101"; -} -.icon-gift:before { - content: "\e102"; - before: "\e102"; -} -.icon-leaf:before { - content: "\e103"; - before: "\e103"; -} -.icon-fire:before { - content: "\e104"; - before: "\e104"; -} -.icon-eye-open:before { - content: "\e105"; - before: "\e105"; -} -.icon-eye-close:before { - content: "\e106"; - before: "\e106"; -} -.icon-warning-sign:before { - content: "\e107"; - before: "\e107"; -} -.icon-plane:before { - content: "\e108"; - before: "\e108"; -} -.icon-calendar:before { - content: "\e109"; - before: "\e109"; -} -.icon-random:before { - content: "\e110"; - before: "\e110"; -} -.icon-comment:before { - content: "\e111"; - before: "\e111"; -} -.icon-magnet:before { - content: "\e112"; - before: "\e112"; -} -.icon-chevron-up:before { - content: "\e113"; - before: "\e113"; -} -.icon-chevron-down:before { - content: "\e114"; - before: "\e114"; -} -.icon-retweet:before { - content: "\e115"; - before: "\e115"; -} -.icon-shopping-cart:before { - content: "\e116"; - before: "\e116"; -} -.icon-folder-close:before { - content: "\e117"; - before: "\e117"; -} -.icon-folder-open:before { - content: "\e118"; - before: "\e118"; -} -.icon-resize-vertical:before { - content: "\e119"; - before: "\e119"; -} -.icon-resize-horizontal:before { - content: "\e120"; - before: "\e120"; -} -.icon-hdd:before { - content: "\e121"; - before: "\e121"; -} -.icon-bullhorn:before { - content: "\e122"; - before: "\e122"; -} -.icon-bell:before { - content: "\e123"; - before: "\e123"; -} -.icon-certificate:before { - content: "\e124"; - before: "\e124"; -} -.icon-thumbs-up:before { - content: "\e125"; - before: "\e125"; -} -.icon-thumbs-down:before { - content: "\e126"; - before: "\e126"; -} -.icon-hand-right:before { - content: "\e127"; - before: "\e127"; -} -.icon-hand-left:before { - content: "\e128"; - before: "\e128"; -} -.icon-hand-up:before { - content: "\e129"; - before: "\e129"; -} -.icon-hand-down:before { - content: "\e130"; - before: "\e130"; -} -.icon-circle-arrow-right:before { - content: "\e131"; - before: "\e131"; -} -.icon-circle-arrow-left:before { - content: "\e132"; - before: "\e132"; -} -.icon-circle-arrow-up:before { - content: "\e133"; - before: "\e133"; -} -.icon-circle-arrow-down:before { - content: "\e134"; - before: "\e134"; -} -.icon-globe:before { - content: "\e135"; - before: "\e135"; -} -.icon-wrench:before { - content: "\e136"; - before: "\e136"; -} -.icon-tasks:before { - content: "\e137"; - before: "\e137"; -} -.icon-filter:before { - content: "\e138"; - before: "\e138"; -} -.icon-briefcase:before { - content: "\e139"; - before: "\e139"; -} -.icon-fullscreen:before { - content: "\e140"; - before: "\e140"; -} -.icon-dashboard:before { - content: "\e141"; - before: "\e141"; -} -.icon-paperclip:before { - content: "\e142"; - before: "\e142"; -} -.icon-heart-empty:before { - content: "\e143"; - before: "\e143"; -} -.icon-link:before { - content: "\e144"; - before: "\e144"; -} -.icon-phone:before { - content: "\e145"; - before: "\e145"; -} -.icon-pushpin:before { - content: "\e146"; - before: "\e146"; -} -.icon-usd:before { - content: "\e148"; - before: "\e148"; -} -.icon-gbp:before { - content: "\e149"; - before: "\e149"; -} -.icon-sort:before { - content: "\e150"; - before: "\e150"; -} -.icon-sort-by-alphabet:before { - content: "\e151"; - before: "\e151"; -} -.icon-sort-by-alphabet-alt:before { - content: "\e152"; - before: "\e152"; -} -.icon-sort-by-order:before { - content: "\e153"; - before: "\e153"; -} -.icon-sort-by-order-alt:before { - content: "\e154"; - before: "\e154"; -} -.icon-sort-by-attributes:before { - content: "\e155"; - before: "\e155"; -} -.icon-sort-by-attributes-alt:before { - content: "\e156"; - before: "\e156"; -} -.icon-unchecked:before { - content: "\e157"; - before: "\e157"; -} -.icon-expand:before { - content: "\e158"; - before: "\e158"; -} -.icon-collapse-down:before { - content: "\e159"; - before: "\e159"; -} -.icon-collapse-up:before { - content: "\e160"; - before: "\e160"; -} -.icon-log-in:before { - content: "\e161"; - before: "\e161"; -} -.icon-flash:before { - content: "\e162"; - before: "\e162"; -} -.icon-log-out:before { - content: "\e163"; - before: "\e163"; -} -.icon-new-window:before { - content: "\e164"; - before: "\e164"; -} -.icon-record:before { - content: "\e165"; - before: "\e165"; -} -.icon-save:before { - content: "\e166"; - before: "\e166"; -} -.icon-open:before { - content: "\e167"; - before: "\e167"; -} -.icon-saved:before { - content: "\e168"; - before: "\e168"; -} -.icon-import:before { - content: "\e169"; - before: "\e169"; -} -.icon-export:before { - content: "\e170"; - before: "\e170"; -} -.icon-send:before { - content: "\e171"; - before: "\e171"; -} -.icon-floppy-disk:before { - content: "\e172"; - before: "\e172"; -} -.icon-floppy-saved:before { - content: "\e173"; - before: "\e173"; -} -.icon-floppy-remove:before { - content: "\e174"; - before: "\e174"; -} -.icon-floppy-save:before { - content: "\e175"; - before: "\e175"; -} -.icon-floppy-open:before { - content: "\e176"; - before: "\e176"; -} -.icon-credit-card:before { - content: "\e177"; - before: "\e177"; -} -.icon-transfer:before { - content: "\e178"; - before: "\e178"; -} -.icon-cutlery:before { - content: "\e179"; - before: "\e179"; -} -.icon-header:before { - content: "\e180"; - before: "\e180"; -} -.icon-compressed:before { - content: "\e181"; - before: "\e181"; -} -.icon-earphone:before { - content: "\e182"; - before: "\e182"; -} -.icon-phone-alt:before { - content: "\e183"; - before: "\e183"; -} -.icon-tower:before { - content: "\e184"; - before: "\e184"; -} -.icon-stats:before { - content: "\e185"; - before: "\e185"; -} -.icon-sd-video:before { - content: "\e186"; - before: "\e186"; -} -.icon-hd-video:before { - content: "\e187"; - before: "\e187"; -} -.icon-subtitles:before { - content: "\e188"; - before: "\e188"; -} -.icon-sound-stereo:before { - content: "\e189"; - before: "\e189"; -} -.icon-sound-dolby:before { - content: "\e190"; - before: "\e190"; -} -.icon-sound-5-1:before { - content: "\e191"; - before: "\e191"; -} -.icon-sound-6-1:before { - content: "\e192"; - before: "\e192"; -} -.icon-sound-7-1:before { - content: "\e193"; - before: "\e193"; -} -.icon-copyright-mark:before { - content: "\e194"; - before: "\e194"; -} -.icon-registration-mark:before { - content: "\e195"; - before: "\e195"; -} -.icon-cloud-download:before { - content: "\e197"; - before: "\e197"; -} -.icon-cloud-upload:before { - content: "\e198"; - before: "\e198"; -} -.icon-tree-conifer:before { - content: "\e199"; - before: "\e199"; -} -.icon-tree-deciduous:before { - content: "\e200"; - before: "\e200"; -} -#tooltip { - position: absolute; - display: none; - border: none; - padding: 3px 8px; - border-radius: 3px; - font-size: 10px; - background-color: #222222; - color: #ffffff; - z-index: 25; -} -/*验证*/ -.n-invalid { - border-color: #a94442; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.n-valid { - border-color: #3c763d; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.n-warning { - border-color: #8a6d3b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.msg-box { - display: inline-block; position: relative; *zoom: 1; margin-left: 5px; -} -.n-tip { - color: grey; -} -.n-error { - color: #a94442 -} -.n-ok { - color: #3c763d -} -.n-icon { - width: 17px; - top: 2px; - position: relative; - display: inline-block; - font-family: 'Glyphicons Halflings'; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - -moz-osx-font-smoothing: grayscale; -} -.n-ok .n-icon:before { - content: "\e013"; - before: "\e013"; -} -.n-error .n-icon:before { - content: "\e014"; - before: "\e014"; -} -.n-tip .n-icon:before { - content: "\e101"; - before: "\e101"; -} -.alert { - padding: 15px; - margin-top: 20px; - border: 1px solid transparent; - border-radius: 4px; -} -.alert p { - line-height: 1.6; -} -.alert h4 { - margin-top: 0; - color: inherit; -} -.alert .alert-link { - font-weight: bold; -} -.alert-dismissable { - padding-right: 35px; -} -.alert-dismissable .close { - position: relative; - top: -2px; - right: -21px; - float: right; - font-size: 21px; - font-weight: bold; - line-height: 1; - color: #000; - text-shadow: 0 1px 0 #fff; - opacity: .2; -} -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.alert-success { - color: #3c763d; - background-color: #dff0d8; - border-color: #d6e9c6; -} -.alert-success .alert-link { - color: #2b542c; -} -.alert-info { - color: #31708f; - background-color: #d9edf7; - border-color: #bce8f1; -} -.alert-info .alert-link { - color: #245269; -} -.alert-warning { - color: #8a6d3b; - background-color: #faebcc; - border-color: orange; -} -.alert-warning .alert-link { - color: #66512c; -} -.alert-danger { - color: #a94442; - background-color: #f2dede; - border-color: #ebccd1; -} -.alert-danger .alert-link { - color: #843534; -} -.ke-container { - margin-left: 15px; -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -.progress { - height: 20px; - margin-bottom: 20px; - overflow: hidden; - background-color: #f5f5f5; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} -.progress-bar { - float: left; - width: 0; - height: 100%; - font-size: 12px; - line-height: 20px; - color: #ffffff; - text-align: center; - background-color: #428bca; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - transition: width 0.6s ease; -} -.progress-striped .progress-bar { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 40px 40px; -} -.progress.active .progress-bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} -.progress-bar-success { - background-color: #5cb85c; -} -.progress-striped .progress-bar-success { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-info { - background-color: #5bc0de; -} -.progress-striped .progress-bar-info { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-warning { - background-color: #f0ad4e; -} -.progress-striped .progress-bar-warning { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-danger { - background-color: #d9534f; -} -.progress-striped .progress-bar-danger { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.pt-time-list li span { float: right } -/*==========以下部分是Validform必须的===========*/ -.Validform_checktip { - margin-left: 8px; - line-height: 20px; - height: 20px; - overflow: hidden; - color: #999; - font-size: 14px; -} -.Validform_right { - color: #71b83d; - padding-left: 20px; - background: url(../image/right.png?1) no-repeat left center; -} -.Validform_wrong { - color: red; - padding-left: 20px; - white-space: nowrap; - background: url(../image/error.png?1) no-repeat left center; -} -.Validform_loading { - padding-left: 20px; - background: url(../image/onLoad.gif) no-repeat left center; -} -.Validform_error { - background-color: #ffe7e7; -} -.footinfo{ - text-align: center; - margin-top: 20px; - border-top: 1px #ccc dashed; - line-height: 40px; - height: 40px; - color: #666; -} \ No newline at end of file diff --git a/application/admin/view/css/glyphicons-halflings-regular.eot b/application/admin/view/css/glyphicons-halflings-regular.eot deleted file mode 100644 index 423bd5d3a20b804f596e04e5cd02fb4f16cfcbc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20290 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/application/admin/view/css/glyphicons-halflings-regular.ttf b/application/admin/view/css/glyphicons-halflings-regular.ttf deleted file mode 100644 index a498ef4e7c8b556fc36f580c5ff524025bb11c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41236 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 -

添加用户组

-
-
-
- -
-
-
-
-
- 用户组名称: - -
-
-
-
- 用户组备注: - -
-
-
-
-
-
- - {section loop=menu} -

{$loop.name}

- {section loop=loop.sons item=submenu} -
-
- {$submenu.name}: -
- {section loop=submenu.sons item=submenulist name=k} - {if !$k.first && $submenulist.level==3}
{/if} - - {/section} -
-
-
-
- {/section} - {/section} -
-
-
-
-
- -     -
-
-
-
-
-
-
- - - \ No newline at end of file diff --git a/application/admin/view/group_edit.html b/application/admin/view/group_edit.html deleted file mode 100644 index a85b16d..0000000 --- a/application/admin/view/group_edit.html +++ /dev/null @@ -1,73 +0,0 @@ -
-

修改用户组

-
-
-
- -
-
-
-
-
- 用户组名称: - -
-
-
-
- 用户组备注: - -
-
-
-
-
-
- - {section loop=menu} -

{$loop.name}

- {section loop=loop.sons item=submenu} -
-
- {$submenu.name}: -
- {section loop=submenu.sons item=submenulist name=k} - {if !$k.first && $submenulist.level==3}
{/if} - - {/section} -
-
-
-
- {/section} - {/section} -
-
-
-
-
- - -     -
-
-
-
-
-
-
-
- - - \ No newline at end of file diff --git a/application/admin/view/group_index.html b/application/admin/view/group_index.html deleted file mode 100644 index 80f14c3..0000000 --- a/application/admin/view/group_index.html +++ /dev/null @@ -1,51 +0,0 @@ -
-

{$menuinfo.menu.name}

-
-
-
-
- 添加 -
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - -
用户组名称备注信息创建人创建时间修改人修改时间操作
{{loop.name}}{{loop.intro}}{{loop.create_username}}{{loop.create_time}}{{loop.update_username}}{{loop.update_time}} - 编辑 - 删除 -
- -
-
-
-{include file="public_angular"} \ No newline at end of file diff --git a/application/admin/view/image/bg-button-green.gif b/application/admin/view/image/bg-button-green.gif deleted file mode 100644 index c58a9bcc41a764961d01a7594146196fa0f68bd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmZ?wbhEHbWMU9!IKsf-HiaQ&6@%X_29K!>fpZvKCo`06WhmRuu;hYQ)FKA2=?t+; z8NwGZ6l`YjnZb~?j-g^FL+u`hka-Nb8yV8qFeEN#sM^JV2Ppnz0n6%uNRXWjtZE8P rE)!E7FBD3+UG};BIUqzJZ`!0NOhS*Ih&hTYl0_sKrK z29;-rIWAn-H&Iz{3Cr3xFV3(DG0DfXf4Q^?PH36IDSE@<;g=V3`+7d~I{3|E-<4W? KHm{9=!5RQfyI4*D diff --git a/application/admin/view/image/error.png b/application/admin/view/image/error.png deleted file mode 100644 index 044ba766b246425c949f146e995c8f3be140fb71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkQ1Fze zi(`mI@6ljGu4V&~+J&t83U4o6az4^+VOhb&u72HOXC=!)#mV9u%QtN4zQmpKu{3B= zgof4^M}^9tl|SGAcbRZROvZdJ8^ff>FM1PoRi&3^d{()raWu;7+cBSSEx8ZhRX%v?3+fmvqneowfT@Hzg+ b{sZjM+qY@|o}oSs=qm diff --git a/application/admin/view/image/jia.png b/application/admin/view/image/jia.png deleted file mode 100644 index 88cb694d72999bf498188ec56def2829c69209a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 977 zcmV;?11|iDP);@{r>&^`u6+&_xk+y`u+9#{q_6)_WAwv`Th3! z`}O$y_4xht`1+tmJ@bl^J@#*gJ)ZX#Z-0{%Y@59)@4x6SId z%;~et=&{V|w9M$T%IBfT>8i%*smAH3#^;vG?5oA)tHb4~!{w;M<)*^sr@`c+!sVgC z<)Xmmqrl^!z~!L6$DD~Q%9 zgwra7)GLJ3B8SjHeak_6%P4}!4+V^7Gc2-W5W<&!Vh7>2V%hqU%&)kzy(~u16#lW zS-${Sz5!Ld093u#coW+I000SaNLh0L01CqZ01CqaG$|yj0000SbVXQnQ*UN;cVTj6 z06}DLVr3vkX>w(EZ*psMAVX6%akb+%0004ONkl@! zhX?^*acyOw`lNN_t{mj@AH^4Qe#d^LW?zn;e`K;t9F?f(Ynw}lF9v3w2Fpw)y@HPr zhl=ZA>u7Vbdv?v?a9p{Rd_=a@-kzG3QP{sUUXq^HVHZVYTUUFAmd)lltJPwe-dIra z5mcxgzC6CU4|Z0z-5$^9zM7AqM#a!jmDhLLJ9XWaZ!{W25!u!NLGf9|#A`15W@-3{ zYpX^eY1+#fd#;qQo3Eh3BwiqCyzQKSuaU5uuei2q1+t>!^~K!+8N2z4YwO=YO9v#- z;os^VkVuDrt9L*W9gs{1q|gDebolZwp#S;;k~B+YY>ZHB00000NkvXXu0mjfY?&An diff --git a/application/admin/view/image/jian.png b/application/admin/view/image/jian.png deleted file mode 100644 index 91e10b96e7d24c9d9bb4dfd8997c8e6c7a8f8bda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 589 zcmV-T0+tjI@bu~K@#*gJ z)ZX#Z-0{QG?ZVOQxX|mi&grbi=Bvf!sKe!{!{wsF<)Ojlqrl^!z~!I5<(<9cle6KD zuis>;-B_jHGmF+Th}A)T%P4`p!j#w&2fC~w9YW5Et% z!xmw|317ekT)+lgzyn*r093uK<*GFR000SaNLh0L01CqZ01CqaG$|yj0000SbVXQn zQ*UN;cVTj606}DLVr3vkX>w(EZ*psMAVX6%akb+%0002wNklL6hzT7 zqN1YXm~%i3V8SeB)c^k@MaRW!P;eo>0?)QKcejp!*aQD z?6#I1m9@_Mnb99Af5rT)t{mCEg5urg=A(g z{C|6SPb~9Xage|wB`SrZk2FOMYM!buln2sX?5Y+T78iB(Zu9cS7|LZyZ++}u$^oi1 z_j@S}bW9OzU2R+RMy&~OT>X-oZ98$jq#ogNfJ!BM-42wHGZk*6s2KD}U*IA%epmxb zm}|6BK9YoIF;*xSL!+z@<64lB7->LTW2Vi4ostCA(z&2XniwNIv}fFo-`MbG;)u4G z^p@F!)|9HhZprHd_vXjDoxs6WkK-6P0@lfxnGT>*p(QHoUV=u1FAqb@b%*W=a3{`LsH5k^AvQNL>6fPpy#oU(&MuH(*aEX4b35*} zn4n7)`I2U%=+Z=?BVZQ?vjQFW4gD@~XSOO6b{qu81`4&LFuU2(ilxW+1|ZkNMnWe79C$gs zWT?Ele|HR{JGPe)5BTW>0Ey?-Ls6S#GoV0tbt6ku7B&*0 z;i9QM$W1Rj*rRIdceL)rAOSl+sDe3LkB87<%){;ZdHp6|SNlopDXRx< zxBDF9-lTo&v`8$humFygUij@qgT=Qzhj8{ym2-{Xciwqq_Xwk%=O3B-MNAL_6e`3U zyxwmXex4`g0^1RYw~Dth3av3Dl^AAlpO3mG!nLr#&ZZ7c_wUboI+deC+&%TFjK2Lm z!Y&f1h|T_On%RCV&=4bx`!>(YezqGVhl&QpED?N6GV)HmzJ9&rh$x*i?*@o9#6QI< z5ZI_MRX;0+pY8$`j)eF#TlUyG(eE%E7S!rj;mj^M5vhUicPm zVWQ2z+imFyg}SRABmOBY_@osR!>7Ov!ioK`NB6_Rv}7Ud?35ed5Sb@?yND?kv~RCa wqs^a3Sh>&&L4)!LKI?D2&k@))k(LESaga|C278ChSzn3NWVkcuNoY&{0f?~U_5c6? diff --git a/application/admin/view/image/login_bg.png b/application/admin/view/image/login_bg.png deleted file mode 100644 index b8ece1a5abe072c58d9f0b12f3049865fdd46fc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1887 zcma)7c~BE~6pm+$;OJ-zBB&^d43J>O5eF3z3PLy(6)AxM1U3m`A_K)>hz<@^9gSiV zFdnJ29%U3vGOiHXMntqlSI{gj*e)z|T^*J80EMw8xPvRJJKlUWICjHW?@X>i11 zL5$|^z5#>5FgQ49G#ZD7hD;_Cf*`}g!y_XjI-O3h*IUqft5vJj>I~-5(NQ@z>M8~^ zKbaUD7<2d)ELX&~#w|XvYm?1uo8^jntdhA>nbSVnHB^FKB=>%^hOl>^n$_{MK^R}V zb;!Zr({<-DAP{sRVQqQypf#j0F6?Nhf}lK)CDbjO9bwO9FHWV0w$-%+Fc%go#Kt>7 zb&XHJmXm=n=$FBGL4wO#Y?u92)>=dfJ^A;+LPD+d*4e9}QHP==(sXHYo4r$wM3@w$ zewBUwRVQT;uk9PB8vZX{r)?0A@(L+Irn)>3F7X9_lV_*8%5PScM_qM`%97Dn(0waq zu=Uc470wEYd*?aXg}*W2hH zX&l*FMC-csB*jPgwy_?aiE-CUHt))FY(yzQZF0kIF~tBxhSx`3IQTGor~p+e z%pO%L1Qm>f=NV#9iw)q|WB%B&&?Mti-aNFDi#9;R6QoAfMthvckLy0cm?`%&{B)QP zn4g}|=iCXSPKQ}T`V!3Wv8}nc$H#}J8tnU6|i_MbBE3T%4wNnR2F*B!Nj_=5Ytn+3dV4b(ZG!=7XsdTdO#Pl^zZUlef*@8P2$Ovup#z zb5)qnRm7hO;K9Kl5YEuWf#QEM`)cj55k-JNEY?07>@S9r&ZISl^PQpR)b-@f0Fer4 zRg0k*5Fkq6g6{tQ9Po}^`#n>iMIEeu%d?07L*^JEjwT%$zaoq;9Ee$CAxqh z+g?@Wi(FF*k@x~STX+sV4~xdVxK?tBt>tE+V7nM67p0=7aHEr~rTK(Aa>HGOEU!~J zw4SH^NV%>6sr~5@RWbtNUM{^|D9oj~Ge)1F2a7HVPAC^jkC%opaSzxvspxgxm~f5I zyj?>7RA@*Op?j)9Z1?N8*EP=5eH+~{^A@FS(om^R2ndksYUKj Q(VroP7_uW+6tu74f01OTwEzGB diff --git a/application/admin/view/image/login_logo.png b/application/admin/view/image/login_logo.png deleted file mode 100644 index fc8babeac4bb5b83d2afd3d744f86a25641f3558..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4095 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 N09UN|K(JsC06TuN5qJOq diff --git a/application/admin/view/image/nav_bg.png b/application/admin/view/image/nav_bg.png deleted file mode 100644 index 0798cd0ef503086cc5dd0e5dd88beab15ef83343..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 957 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu@pObhHwBu4M$1`kk47*5n0T@ zz;zge8BH`*Rs#iPN?apKg7ec#$`gxH85~pclTsDjGK*5n^NX^J6`X@j3%5QtV_;x5 z_jGX#shIQju3_Gz42gz^^2b8C{5I&SfB4(~KsewW=K{~o6SsFvP?LHZo6D5VX6w(| z`gVQg*P8(q+t?0n;jz0kcKbX=xoOcl988T00zkq*_w=T(JRd~uk4ey<;;j{d5=4;6Z-p?xc{WdLoz3bjzr4JnU?%lg~{rYvoV-mmr*6rD|=gq&j z5{(WYc$gd&1X!37rIKqZI3lN|E)IO~(FYX#ea9cC9X_yl=CO)?XNeEi=M@CLZDX%F z#|8-na8OW#xGa%8$8Y)C=MC*9y$_Gh{UEtL0_YsDn}EchGu(;5WO2>-z~Q29R+#9r z)W~h~7~efyZ+Ptd|Edc%=jHdkKll9eTDB(lPfH!v)mO$i3v!%)<=q%F*KfJu`OWD9 z8fHL#v~)_(cikjvCZ7)_eC>zNo>LXzxO|QIz}}eq=09Ya9%jn+AJ3P4&l_yB^z_rB z&BdJX==RzELz8FT)x6m2YttLrpNetA(!n3*)4EkIws$69W&i?DS3j3^P6 diff --git a/application/admin/view/image/onLoad.gif b/application/admin/view/image/onLoad.gif deleted file mode 100644 index 5e28c953c14f48c0a5b44d3b68cc7ffee07e371e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 781 zcmZ?wbhEHb6krfwxN6IA`SRuO-@jkHc=7u6>nBg1Jay{Sv17;n{Q2|Y!-p3yUR=F; z_4n`JKYsi;fByW@qeqV%Ir8YyqnkHxzJLGz^XJc3u3R~B;>4FPU!FaC_W1GRTeog~ z{rdIe$B&mTUHbX+=aVN-9zJ~d?c2B4uV0@&efrItH-`@&zHs5f^XJdcoH_II<;y#F z?mT_^^u~=F=gyrwc<|uu+qYl6diCzzySsPq-oJnU-o1O*u3h`|>C@Y{Z-4#z_29vS zfB*jd{rmU$@#Fu&fB_5?|8x7fh6Fo12DlpO889;f1r>j?ure^%GU$L5fV|1TcGzKF z!1j|LSwy_l$_1>f9LWR(|Ggehh4U>Uw_571Wq{nV8iS zoEF%ybBU^0%PhAP>$0)5WR%y@-6#!zD&>zoweS(ERS6KU<`U*S|5QDkFLkzAW2;M1^RVY7z+GFI^x*CtPIXGd%S zyASAq?FRxycpti%i?A{6xsts60V|iqu?d17Kj^f~4d1%hsB}WC>*Qt&6PwoNBaMDq zPeuC!uZH?b1O$jlFoiCdm!m7q1BxTVzl1JXO0L}V0nGK5$dtO2NRLVy4O diff --git a/application/admin/view/image/order_bg.gif b/application/admin/view/image/order_bg.gif deleted file mode 100644 index 97d040158bd663a946b5b7cec3699cce643b0e3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93 zcmZ?wbhEHbWM|-KSj50^=gyr?n>MXqzy9XUoB#j+XMh34pDbXe4u}M)bzoNVF!5U8 mv-fIJjBTQ$I)oaTNXzf*_)X8fudpB5WuST5>9gpoVI@C4?HH zKM-zhZB9952N^BlbRZ219q1Clg(eu0QNw9b98{8&P+9RcDIIr7UOjm5K{I z1d{kmG&uzxTtungp8_Ns%9l!+p`@RZEHb65je(6)o~z0PC0S&qkRZw5Z*X>_adu~b zk}UG@a*x%zWj#A^rjVd7+($_k89m-G_0%3IUFFj55M$Y}sUfASoZ0H7B#R90&szr6 zRJeP(MzL%lq6KhOJm(5u8zP@_@ z`SpiSZ$5tg^!?ZSFWIKsg2@#Dw8fB*ja^=szLneX1c`~3Oyj~_q2e*OCG+qduEzkm7i z<->;$|Ni~^{rmT)PoLhtef#t0&zm=IzJLGz&!0bM&z}AN|NomeZy0a`#h)x-NgWUg zveSX}zk+ICO6I(bRqGxJ>^&u@U7~Z^*iXJZ?zWxmhhvYQcC>fBPR+EMe_=(5*V>?| z>rbSdep|Kw!3GN%iRAeHFU{`QxOdFR^ZD~mQZHMg|3wRd!OdJ78l z^-o}%Fu8xyl!?=4^i5-%D==wJJvRfx;w4MDSFT*LY|W}=YgepVvwYL~)f*PCt`FP0 zZ~y*12M!-OP~Uapdhw8`myex^wO3mFu@I->v6m;(hV_8Plt0 zFW$X=_4d=7m+!wk|Mczc`+5#ePJut%903asG%*Xy@yrldc&Ld(mM?`v;DJ0lA6Lqe z6@rV8_sUw=U6J^te7sk~SAUj{g3x1mCZVKLb0me;d}o>EpE|R0^Ye2v4|Q?Ma;a)u VTzs@gDfX4O=H=zVQ(71ptO1>t;rRdn diff --git a/application/admin/view/image/skin_list_urrent.gif b/application/admin/view/image/skin_list_urrent.gif deleted file mode 100644 index 15e8b152987916bd6024e2409820f05daa0ec785..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130 zcmZ?wbhEHbbY+lan8?8J;lqcSGiRPTbLRj5|B63Z7(hS=M1bTSn1bi@tvvmfzg2R} zt?teD_Vg=MKJut?>|CZHu979A9Zu5SdB?T+s;L=I00V diff --git a/application/admin/view/image/td_title_bg.gif b/application/admin/view/image/td_title_bg.gif deleted file mode 100644 index 169a1d95bf2d1efddd99db1756f6a825f2c0caa1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmZ?wbhEHbWMq(Gn8?8J_wV1YU%&qU|NqOEFN!}|7(hS=M1bTSnAnf>RSLdR=3=l0 E08c0qguXo?en0eC1jXueEIkY6wZ z&;ndwW%=4bpgPV1kH}&M2Cg|E%=qQfeIc-B*NBqf{Irtt#G+IN$CUh}R0X%pqSW&I zqU>S?=U}rJdp7j|)y?*FaSXBOy&7~{=#T=BPqw^PMyptq`Tzg(Clv)OlRI> zvdo;Nqps_9Z0VYZ3YrDM-)?g*_G*}!zQ}UvqPw~hA%9ZNzKP*_xcT<_9WQ>|wCPvO z_->K2AV!Z diff --git a/application/admin/view/image/white.gif b/application/admin/view/image/white.gif deleted file mode 100644 index e75322cf4722991cc8930c125b7207dc6c77108c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4480 zcmc(iYgAKL8iqkxF&d&l2m}%_kc3=F&Oz%~wN7hyI0uLj1$QYZil7M6SZ|0#K@3Td zKtKo}r4A}!P!f>=MS-fdR8XN7Q7N^n<5XL#wO4Dqrp}t_%-#{EUDNc({F?mFI?wr@ z_q&{^7<$3NG(QhNk5Q+`bI(2Z(n~J^0G2LY8XFrMA0MBXn3$ZLoR*fhe*OCF>};J* zw`I$g+}vEfUZ0Ztv0AN_m6f%%wFeI#Y-ng`YHG6E?X9h?ZEbCxot<4> zT|GTL=g*(Nc=6)Ez`)?(;I(VlMn*V`g3#_#NNf1JPLa8KR%u*1pP=v$f3FZ5% zw5z;VldAA=70k*u9n~f#*}=LDV{r+&jh_Q6D#=~>#;!Vh!{OGWFT2CBjpH1P{T$&a z_DA*0Q>vn!W8y^^r}^O%pYxz9`e7}HIdg!cU%j|{2JOc*&3&Ee#m6`*6#*rFeiEPz z4_Cq&Oy-RJRn=Pd0X9IS7H#mfX~8B3ag>s;m(wRs(1L&fLFXw_C6}wnptC_yr%72@ zSb;=S0i{=C9j{2G$u}KtF)PP0TZg4PbQc!Xu`bJX_Jp>&Fo(WYR%7$YnA>=+-ujba z$ztoV@2`HC^}N-2b7RI2GQVJ06iE<8q8T$pz-)$7Crz4aEr(O8rl>0*-^+_{G@^GX zrlcFUQ}`8Vu7yjVI7xuFVL_qac1bj|Vk<_;~df@(cpBu%zRnAw2nA;XCfrcVVv`J)C zPx0`WQUbinyeh~*PtU;WxWptnHEqiVTKD>q%$TKQj(0AVw`*Daih@GJD*ozMt5KD9;=juXTm#O*TL-R+v zFOFJICVuHq)Iu`O-sD- zTjKC@3ksAQlsh?`-IO>axdV ziFau=YNAbUX{yF)P9|cSBqw(W(>O=6GICJH{L2Er&jWvH_gT*fsi$u}FgAU(PgU!n z{+KaW3gl9$9CByO-~yRxhZcn!C}px0T9oXpow@Su#gu6JbP+A!@dPx})00W_9egs3 z%MBwL?F?E{C?Pphr*g=k$&-U}+5PN8>R=Wtcx1#a<%CzVj&(JsYvt0G@8mfk63JLe2^9H{DA*SGDbh+ zkQ&$YcPcqCp2sPX%pbECt!_JT>WxJW381AC!CGbHVD$V`@yEB1^rvq+JbdfHWbH{> z6b>+;2BQMLnXeI+3IQh6$acS$x6DN-t&=_jbfK~x>}Qm|?Y=aIBVCw?*Q#L*jAP!o z;kKCnE&Ow*8Fbl(A3n(nt%^;0SkvF@|5oa{GF_NMBdHysDm34=!(-L9&QFv8yH3E? z0nfxs5LrY3xh{)E)(i4>x?H=gyJQD62GA@g3kxsfHgaj~84K^i=EsFQe@}SzZ(2v5 zQcgQFb2M!I;>NnN{`B7W-wS=nn%i_U615KKYyD|VUcE4Wl|rEcxIz$j5b!Pbg|f08 zcq61~Q3s{yp{sG^+si3e-?%!6af0!zdH5ZC8vA|LJ(7G$9{URWh^u*S-gH~bi7oQW zz;PW2i1VMi`G;S9tt&e|^-%kRlzCehgq`_#V{gj6_diRJrA3I*Jped+IEGaK4;#2H zV>=Y>5z%OcxQ5M|wY1ltyvQ9pv$AQtT*!jLmd$xuv-dt*S-EYSTNd+g2DChO$D&rm zG71%M)}hvoPkn>@JVl(W6rcGx*%qyN;J@O-2wo6G!+AGr56fWOjU_?CNNmSzWh+%*6A zm~2tg1!Csa`?WJI33oKz_f(}azxdtXh+h`2a18w+#hby}rBdaS%tB_73E+KJYR-w1 zq)BKM(oC}}*fg@7MX@RjXr*Pznv*G4$Xq)O*^Y(0ZeH~=e}DZY_j`BEIM=UkfO)Hl z7IXtN;$!c#jC)%;VKncasz@+>`R;E7=BS*zo*oN6OZCe4D#Tg}EmUGs;o9`VY;Rr6 z(lwj6qHV87yI!A>S?d0ghVe&^-$p#|%kp`zC|btCdi6akRdqhL=p}3Hu`NHOw*K=|u4#-G z|1h)Q#n9$PT}1JnubMVQT<66Lg))SOXD7s$FTm3s;K9cEIoClQ>-_iAF-Abe-&y^&7iTn2vP0FWtn@Z_(gS1fj+2k{t8BD*7nT{^H>p z7vG`&z9;wAMhGz9>v#Cgm~SZ>?}$%okV5>t{|v2k(zgl?tphTE7`_AkDzyQyxre2bgcs&z{4HxF(*z;iRCE53}UF?br~KD?ai|< zYN$bmb6#LZKCrjKd30o8+NJI}w6xnfl+P4lt zatt1QuI8u<$g(QknE*AMPY?Q#Xn0gUK6LEw`xGG| z3TQBb*?j(NXek51rNOX@U%f^kNY;kcA1s9E(FEOel*S*7t5ydmS>`BVx|f4_#5Bpb4}NP(9*nGvCZ~)(uH#i7?U52Mn7-mZt3riURH)$dHq*H z&Ma7@R!SsFi2D;CbFtcI$6Tcd@@iejTsdx2o3TixibDR|D5SA7()B5E`V1fl(DN2e zboCJ@`V_^AqCr)kb$HEYc*ucqc%-n~?8;JV0eAKKO* zN^ENqAWED)h*Jpgvmr`hMWs!PG6-%b>eS{g2;|jpc9DBivHZ` bMBF7PhRJZ?3JT!m(<4T=kpIu`{TKcX%+Z%c diff --git a/application/admin/view/image/win_bg.png b/application/admin/view/image/win_bg.png deleted file mode 100644 index e7714943b5de128419c31cd4c4e3b1e5cca18f17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmeAS@N?(olHy`uVBq!ia0y~yV2S{;ML3v&WZK@%7l4#xiEBhjaDG}zd16s2gJVj5 zQmTSyZen_BP-8}Q5fS%(Hh4#bShTi2ox8r| l>G}yxSO315+0VetkUCvTVM|cItjU-FLHT$PM78HJ-O$%c=(L(Yv1m_`}EG&%iP7g9#t}& XTyI;pK4!N)&^QK9S3j3^P6|6H_V+Po~-c6)AeUIEGZ*O4{@3k@;Z_iMR*$EPsA~=kNIc@9*d5{0`>YDhU7p diff --git a/application/admin/view/index_index.html b/application/admin/view/index_index.html deleted file mode 100644 index 04f1af8..0000000 --- a/application/admin/view/index_index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - 管理中心 - {$pt.PRONAME} - - - - - -
-
- - - -
-
-
- {section loop=menu} -
    - {section loop=loop.sons item=submenu} -
  • -

    {$submenu.name}

    -
    - {section loop=submenu.sons item=submenulist} - {$submenulist.name} - {/section} -
    -
  • - {/section} -
- {/section} -
-
- -
-
-
- - - -
- -
- - \ No newline at end of file diff --git a/application/admin/view/index_welcome.html b/application/admin/view/index_welcome.html deleted file mode 100644 index daa52e7..0000000 --- a/application/admin/view/index_welcome.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - 管理中心 - {$pt.PRONAME} - - - - - -
-
您好 {$username},您是{$groupname},欢迎进入{$pt.PRONAME} 控制台!
-
- {loop=$tips} -
-

{$loop.content}

-
- {/loop} - -
-
-
-
-
- -
程序介绍
-
-
-

{$pt.PRONAME},定位于中小型站长,基于“同源”技术,可以对同一本小说在不同站点进行匹配,也可以进行章节在不同站点的匹配,进行换源阅读,获取更好的阅读体验。

-

{$pt.PRONAME}继承PT产品一惯依赖的智能化、傻瓜化、草根化的技术特点,30秒安装,3分钟建站,在极短的时间内即可以完成建站,同时复制程序重新安装即可以进行批量快速建站,更内置签到程序,签到后当天即可以可以无广告阅读。

-

在程序开发的过程中,非常感谢开发组同学的提供协助,还有非常多的内测人员为我们提出个宝贵的意见,再次一并感谢。

-
-
-
-
-
-
- -
最新新闻
-
-
-
-
-
-
-
-
-
-

服务器信息

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
当前程序名称:当前程序更新时间:
当前程序版本:最新程序版本:Loading......
服务器操作系通服务器解译引擎
服务器PHP版本服务器GD库版本
服务器磁盘空间M服务器附件上传
当前程序路径:服务器日期时间
MySQL数据库程序未使用使用curl远程采集:√ 支持';}else{echo '× 不支持';}?> curl
使用URL远程采集:√ 支持';}else{echo '× 不支持';}?> allow_url_fopen使用GET远程采集:√ 支持';}else{echo '× 不支持';}?> file_get_contents
-

版权信息

-
-

一旦您使用本程序,即代表您同意了下面的条款:

-
-

一、{$pt.PRONAME}PTCMS工作室开发组独立开发,严禁使用任何非法手段破解本程序,进行修改发布等行为;

-

二、不得使用本程序进行违反我国现行法律法规的任何行为,如传播病毒木马、恶意软件、淫秽色情、等;

-

三、严禁使用本程序进行刷流量、刷联盟等行为,如经发现,我们有权在不告知用户的情况下追回程序使用权;

-

四、本程序仅仅是一个建站程序,如果使用者用于非法用途或者侵犯版权,与本程序无关;

-

五、如因用户违反程序使用条例,本站有权终止对该用户的技术支持、更新升级、数据采集等服务并保留追究其相应的法律责任;

-

六、特殊说明(针对本程序):

-

  1、{$pt.PRONAME}为小说搜索程序,严禁使用本程序做任何违反我国现行法律法规的任何行为;

-

  2、{$pt.PRONAME}提供基本的采集功能,可以将其他站点的内容进行采集,用户对此功能进行使用需付完全责任;

-

  3、{$pt.PRONAME}仅为一个程序,如何使用完全为用户的个人行为,本公司对此不承担任何责任;

-
-
-
-
-
-
-
-
-

程序已经发布新版本,请点击下面链接下载更新!

-

-
-
-
- - - - -
- -
- - \ No newline at end of file diff --git a/application/admin/view/node_add.html b/application/admin/view/node_add.html deleted file mode 100644 index f3d4abf..0000000 --- a/application/admin/view/node_add.html +++ /dev/null @@ -1,70 +0,0 @@ -
-

添加{$menuinfo.menu.name}

-
-
-
-
-
- 节点名称: - -
-
-
-
- 上级节点: - -
-
-
-
- 所属模块: - -
-
-
-
- 所属控制器: - -
-
-
-
- 所属方法: - -
-
-
-
- 排序序号: - -
-
-
-
是否显示: - - -
-
-
-
-
-
- -     -
-
-
-
-
-
- - \ No newline at end of file diff --git a/application/admin/view/node_edit.html b/application/admin/view/node_edit.html deleted file mode 100644 index 0bd75bd..0000000 --- a/application/admin/view/node_edit.html +++ /dev/null @@ -1,76 +0,0 @@ -
-

修改{$menuinfo.menu.name}

-
-
-
-
-
- 节点名称: - -
-
-
-
- 上级节点: - -
-
-
-
- 所属模块: - -
-
-
-
- 所属控制器: - -
-
-
-
- 所属方法: - -
-
-
-
- 排序序号: - -
-
-
-
是否显示: - - -
-
-
-
-
-
- - -     -
-
-
-
-
-
- - - \ No newline at end of file diff --git a/application/admin/view/node_index.html b/application/admin/view/node_index.html deleted file mode 100644 index 84ba4df..0000000 --- a/application/admin/view/node_index.html +++ /dev/null @@ -1,59 +0,0 @@ -
-

{$menuinfo.menu.name}管理

-
-
-
-
- 添加 - -
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - -
节点名称模块控制器方法排序状态操作
{{loop.showname}}{{loop.module}}{{loop.controller}}{{loop.action}} - - - 隐藏 - 显示 - - 子类 - 编辑 - 删除 -
- -
-
-
-{include file="public_angular"} \ No newline at end of file diff --git a/application/admin/view/public_angular.html b/application/admin/view/public_angular.html deleted file mode 100644 index 7abf049..0000000 --- a/application/admin/view/public_angular.html +++ /dev/null @@ -1,34 +0,0 @@ - - - \ No newline at end of file diff --git a/application/admin/view/public_layout.html b/application/admin/view/public_layout.html deleted file mode 100644 index acf2508..0000000 --- a/application/admin/view/public_layout.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - 管理中心 - {$pt.PRONAME} - - - - - - - - - - - - -
-
- 当前位置: - {$pt.PRONAME} - > {$menuinfo.menu.name} - {if isset($menuinfo.submenu.name)} - > {$menuinfo.submenu.name} - {/if} -
- __CONTENT__ -
-
-
__RUNINFO__
-
- -
- - - diff --git a/application/admin/view/public_login.html b/application/admin/view/public_login.html deleted file mode 100644 index 4d71890..0000000 --- a/application/admin/view/public_login.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - 管理登录 - {$pt.PRONAME} - - - - - - - -
- - -
- - - -
- -
- - diff --git a/application/admin/view/script/admin.js b/application/admin/view/script/admin.js deleted file mode 100644 index 1287ccf..0000000 --- a/application/admin/view/script/admin.js +++ /dev/null @@ -1,255 +0,0 @@ -$.admin = $.admin || {}; -$.extend($.admin, { - 'init': function () { - $.admin.iframe.init(); - $.admin.sidebarmenu.init() - }, 'iframe': { - 'init': function () { - $('#pt-mainframe').bind('load', $.admin.iframe.reheight()); - $(window).bind('resize', $.admin.iframe.reheight()) - }, 'reheight': function () { - var height = $(document).height(); - if (height > 94) { - setTimeout(function () { - $('#pt-mainframe').height(height - 110); - $('.pt-sidebar').height(height - 110); - $('.pt-main').height(height - 110) - }, 0) - } - } - }, 'sidebarmenu': { - 'init': function () { - var n = $.admin.sidebarmenu.getposition(); - $.admin.sidebarmenu.select(n[0], n[1]); - $.admin.sidebarmenu.titleclick(); - $.admin.sidebarmenu.menuclick(); - $.admin.sidebarmenu.linkclick() - }, 'getposition': function () { - var n = [], hash = window.location.hash; - if (hash.length > 1) { - n = hash.substr(1).split(',', 2); - return [parseInt(n[0]), parseInt(n[1])] - } else { - return [0, 0] - } - }, 'select': function (n, m) { - $('.pt-sidebar li').removeClass('open'); - $('.pt-sidebar li a').removeClass('current'); - $('.pt-sidebar .pt-sidebar-menu-info').hide(); - $('.pt-sidebar .pt-sidebar-menu').hide().eq(n).show().find('li a').eq(m).addClass('current').parents('li').addClass('open').find('.pt-sidebar-menu-info').show(); - window.location.hash = '#' + n + ',' + m; - $('#pt-mainframe').attr('src', $('.pt-sidebar-menu').eq(n).find('li a').eq(m).attr('href')) - }, 'titleclick': function () { - $('#pt-header .menu a').bind('click', function () { - m = $('#pt-header .menu a').index(this); - $.admin.sidebarmenu.select(m, 0); - $(this).addClass('current').siblings().removeClass('current'); - return false - }) - }, 'menuclick': function () { - $('.pt-sidebar h3').bind('click', function () { - $(this).siblings('div').show(200).parent().addClass('open').siblings().removeClass('open').find('.pt-sidebar-menu-info').hide(200) - }) - }, 'linkclick': function () { - $('.pt-sidebar a').bind('click', function () { - n = $.admin.sidebarmenu.getposition(); - m = $(this).parents('.pt-sidebar-menu').find('a').index(this); - $.admin.sidebarmenu.select(n[0], m); - return false - }) - } - }, 'tab': { - 'init': function () { - $('.pt-tab').each(function () { - var tab = this, id = $(tab).find('.pt-tab-nav a').index($(tab).find('.pt-tab-nav a.current')); - $(tab).find('.pt-tab-item').eq(id).show().siblings('.pt-tab-item').hide(); - $(tab).find('.pt-tab-nav a').bind('click', function () { - var aid = $(tab).find('.pt-tab-nav a').index($(this)); - $(this).addClass('current').siblings().removeClass('current'); - $(tab).find('.pt-tab-item').eq(aid).show().siblings('.pt-tab-item').hide(); - return false - }) - }) - } - }, 'tool': { - 'checkAll': function () { - $('.checkall').each(function () { - $(this).bind('change', function () { - var name = $(this).attr('data'); - if ($(this).is(':checked')) { - $('input[name="' + name + '"]').attr('checked', true) - } else { - $('input[name="' + name + '"]').attr('checked', false) - } - }) - }) - }, 'selectJump': function () { - $('select').each(function () { - var field = $(this).attr('data'); - if (field != undefined) { - $(this).change(function () { - var arr = SELF.split('/'), param = [], url = '/' + arr[1] + '/' + arr[2] + '/' + arr[3]; - for (i = 4; i < arr.length; i += 2) { - if (arr[i] != '') param[arr[i]] = arr[i + 1] - } - param[field] = $(this).find('option:selected').val(); - for (var key in param) { - if (param[key] != '') { - url += '/' + key + '/' + param[key] - } - } - window.location.href = url - }) - } - }) - }, 'tooltips': function () { - }, 'successtip': function (html, obj, url, t) { - t = t || 1; - layer.tips(html, obj, {style: ['background-color:#3c763d;color:#fff;font-size:14px;line-height:30px;font-weight:bold', '#3c763d'], maxWidth: 185, guide: 1, time: t, closeBtn: false}, function () { - if (url != undefined) { - window.location.href = url - } - }) - }, 'errortip': function (html, obj, t) { - t = t || 3; - layer.tips(html, obj, {style: ['background-color:darkred;color:#fff;font-size:14px;line-height:30px;font-weight:bold', 'darkred'], maxWidth: 185, guide: 1, time: t, closeBtn: false}) - }, 'tipbox': function (id, boxtitle, callback) { - $.layer({ - type: 1, title: boxtitle, closeBtn: [0, true], border: [5, 0.3, '#666', true], offset: ['50px', ''], shadeClose: true, area: ['500px', 'auto'], page: {dom: id}, success: function () { - if ($.isFunction(callback)) callback(); - layer.shift('top', 500) - } - }) - } - } -}); -$.fn.extend({ - 'alert': function (type, text, url) { - var h = ''; - $('body,html').animate({scrollTop: 0}, 500); - $('.alert').remove(); - h += '
'; - h += ' '; - h += ' ' + text; - h += '
'; - $(this).before(h); - $('.alert').fadeIn(300).delay(2000).fadeOut(500, function () { - if (url != undefined) { - window.location.href = url - } - }); - if (url != undefined) { - setTimeout(function () { - window.location.href = url - }, 5000) - } - } -}); -function del(id) { - layer.confirm('确认删除么', function () { - $.ajax({ - 'url': URL + '/multi/', 'type': 'POST', 'data': {'dooperate': 'del', 'id[]': id}, 'dataType': 'json', success: function (data) { - if (data.status) { - layer.msg('操作成功', 2, 1, function () { - window.location.href = SELF - }) - } else { - layer.msg(data.info, 2, 3) - } - } - }) - layer.closeAll() - }, '删除提示', function () { - layer.closeAll() - }) -} -$(function () { - if ($('.pt-tab').length > 0) { - $.admin.tab.init() - } - $('select').width($('select').width() + 8) - $.admin.tool.checkAll(); - $.admin.tool.selectJump(); - $('.alert .close').live('click', function () { - $(this).parent().fadeOut(500) - }); - $('input.date').live('click', function () { - WdatePicker({skin: 'ext', dateFmt: 'yyyy-MM-dd', el: this}) - }); - $('input.datetime').live('click', function () { - WdatePicker({skin: 'ext', dateFmt: 'yyyy-MM-dd HH:mm:ss', el: this}) - }); - $('.additem').click(function () { - $.layer({ - type: 1, title: '添加' + TYPENAME, closeBtn: [0, true], border: [5, 0.3, '#666', true], offset: ['50px', ''], shadeClose: true, area: ['500px', 'auto'], page: {dom: '#addbox'}, - success: function () { - if ($.isFunction(addfunc)) addfunc(); - layer.shift('top', 500) - } - }) - }); - $('.edititem').click(function () { - $.get(URL + '/getinfo/id/' + $(this).data('id'), function (d) { - if (d.status) { - $.layer({ - type: 1, title: '修改' + TYPENAME, closeBtn: [0, true], border: [5, 0.3, '#666', true], offset: ['50px', ''], shadeClose: true, area: ['500px', 'auto'], page: {dom: '#editbox'}, success: function () { - if ($.isFunction(editfunc)) editfunc(d); - layer.shift('top', 500) - } - }) - } else { - $.layer.msg(d.info, 2, 3) - } - }, 'json') - }); - if ($('.vform').length > 0) { - $('.vform').Validform({ - tiptype: 3 - }); - } -}); -function checkselt(name, form) { - si = 0; - var ss = $("input[name='" + name + "']"); - for (var i = 0; i < ss.length; i++) { - if (ss[i].checked) { - si++ - } - } - if (si == 0) { - layer.alert('请选择您要操作的记录!', 8); - return false - } - if ($("select[name='dooperate']").val() == 0) { - layer.alert('请选择您要进行的操作!', 8); - return false - } - layer.confirm('请注意提交后操作就不能再恢复,您确定提交吗?', function () { - $(form).submit() - }); - return false -} -/*before after的支持*/ -var patterns = {text: /^['"]?(.+?)["']?$/, url: /^url\(["']?(.+?)['"]?\)$/}; -function clean(content) { - if (content && content.length) { - var text = content.match(patterns.text)[1], url = text.match(patterns.url); - return url ? '' : text - } -} -function inject(prop, elem, content) { - if (prop != 'after') prop = 'before'; - if (content = clean(elem.currentStyle[prop])) { - $(elem)[prop == 'before' ? 'prepend' : 'append']($(document.createElement('span')).addClass(prop).html(content)) - } -} -$.pseudo = function (elem) { - inject('before', elem); - inject('after', elem); - elem.runtimeStyle.behavior = null -}; -if (document.createStyleSheet) { - var o = document.createStyleSheet(null, 0); - o.addRule('.dummy', 'display:static;'); - o.cssText = 'html, head, head *, body, *.before, *.after, *.before *, *.after *{behavior:none}*{behavior:expression($.pseudo(this))}' -} \ No newline at end of file diff --git a/application/admin/view/script/tongji.js b/application/admin/view/script/tongji.js deleted file mode 100644 index e69de29..0000000 diff --git a/application/admin/view/theme_config.html b/application/admin/view/theme_config.html deleted file mode 100644 index f10a0f3..0000000 --- a/application/admin/view/theme_config.html +++ /dev/null @@ -1,53 +0,0 @@ -
-

模版参数设置

-
-

- 设置的参数您可以在程序中通过 C('tplconfig.参数KEY') 调用,在模版中通过 {$pt.config.tplconfig.参数KEY} 调用;
-

-
-
-
-
-

- 当前共有 {$config|count} 个参数 -

-
-
-
- - - - - - - - - - - {loop="config"} - - - - - - - {/loop} - - - - - - - -
操作参数名称参数key参数值
删除
新参数
- -
-
-
-
-
\ No newline at end of file diff --git a/application/admin/view/theme_index.html b/application/admin/view/theme_index.html deleted file mode 100644 index 1db286b..0000000 --- a/application/admin/view/theme_index.html +++ /dev/null @@ -1,47 +0,0 @@ -
-

模版列表

-
-
-
-

- 当前共有 {$list|count} 个模版 -

-
-
- - - - - - - - - - - - {loop="list"} - - - - - - - - {/loop} - -
模版预览模版信息版本状态操作
- {$loop.name}
- 作者:{$loop.author}
- 邮箱:{$loop.email}
- 网址:{$loop.url}
- 版本:{$loop.version}
- 简介:{$loop.description}
-
{$loop.version}{if $defaulttpl==$key} 默认{/if} - 预览 - 使用 - 参数 -
-
-
-
-
\ No newline at end of file diff --git a/application/admin/view/user_add.html b/application/admin/view/user_add.html deleted file mode 100644 index 5542b3e..0000000 --- a/application/admin/view/user_add.html +++ /dev/null @@ -1,53 +0,0 @@ -
-

添加用户

-
-
-
-
-
- 用户帐号: - -
-
-
-
- 用户组: - -
-
-
-
- 用户备注: - -
-
-
-
帐号状态: - - -
-
-
-
-
-
- -     -
-
-
-
-
-
- - \ No newline at end of file diff --git a/application/admin/view/user_edit.html b/application/admin/view/user_edit.html deleted file mode 100644 index 53f4fc3..0000000 --- a/application/admin/view/user_edit.html +++ /dev/null @@ -1,58 +0,0 @@ -
-

修改用户

-
-
-
-
-
- 用户帐号: - -
-
-
-
- 用户组: - -
-
-
-
- 用户备注: - -
-
-
-
帐号状态: - - -
-
-
-
-
-
- -     -
-
-
-
-
-
- - - \ No newline at end of file diff --git a/application/admin/view/user_index.html b/application/admin/view/user_index.html deleted file mode 100644 index b3f920e..0000000 --- a/application/admin/view/user_index.html +++ /dev/null @@ -1,60 +0,0 @@ -
-

{$menuinfo.menu.name}

-
-
-
-
- 添加 -
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
用户名用户组创建人创建时间修改人修改时间登录数登录时间状态操作
{{loop.username}}{{loop.groupname}}{{loop.create_username}}{{loop.create_time}}{{loop.update_username}}{{loop.update_time}}{{loop.login_num}}{{loop.login_time}} - 禁用 - 正常 - - 编辑 - 删除 -
- -
-
-
-{include file="public_angular"} \ No newline at end of file diff --git a/application/common/block/friendlink.php b/application/common/block/friendlink.php deleted file mode 100644 index 667b685..0000000 --- a/application/common/block/friendlink.php +++ /dev/null @@ -1,9 +0,0 @@ -where(array('status'=>1))->field('name,url,description,logo,isbold,color')->order('ordernum asc')->limit($num)->getlist(); - return $list; - - } -} \ No newline at end of file diff --git a/application/common/block/pagelist.php b/application/common/block/pagelist.php deleted file mode 100644 index ad9d4ff..0000000 --- a/application/common/block/pagelist.php +++ /dev/null @@ -1,53 +0,0 @@ - 1, 'status' => 1); - $list['prev'] = array('num' => 1, 'status' => 1); - } else { - $list['first'] = array('num' => 1, 'status' => 0); - $list['prev'] = array('num' => $param['page'] - 1, 'status' => 0); - } - if ($param['page'] == $param['maxpage']) { - $list['last'] = array('num' => $param['maxpage'], 'status' => 1); - $list['next'] = array('num' => $param['maxpage'], 'status' => 1); - } else { - $list['last'] = array('num' => $param['maxpage'], 'status' => 0); - $list['next'] = array('num' => $param['page'] + 1, 'status' => 0); - } - $start = $param['page'] - $param['section']; - if ($start >= $param['minpage']) { - $end = $param['page'] + $param['section']; - if ($end > $param['maxpage']) { - $end = $param['maxpage']; - $start = $param['maxpage'] - 2 * $param['section']; - $start = ($start < $param['minpage']) ? $param['minpage'] : $start; - } - } else { - $start = $param['minpage']; - $end = $param['minpage'] + 2 * $param['section']; - $end = ($end > $param['maxpage']) ? $param['maxpage'] : $end; - } - for ($i = $start; $i <= $end; $i++) { - $list['num'][] = array( - 'num' => $i, - 'status' => ($i == $param['page']) ? 1 : 0, - ); - } - $list['totalnum'] = $param['totalnum']; - $list['page'] = $param['page']; - $list['pagenum'] = $param['pagenum']; - $list['pagesize'] = $param['pagesize']; - return $list; - } -} \ No newline at end of file diff --git a/application/common/config.php b/application/common/config.php deleted file mode 100644 index 691d8c8..0000000 --- a/application/common/config.php +++ /dev/null @@ -1,31 +0,0 @@ -'default', - 'runinfo'=>'Processed in {time}(s), Memory: {mem}MB, Sqls: {sql}, cacheread: {cacheread}, cachewrite: {cachewrite}, net:{net}.', - 'DB_MYSQL' => array( - 'DRIVER' => 'Pdo', - 'PREFIX' => 'ptcms_', - 'CHARSET' => 'utf8', - 'MASTER' => array( - array( - 'HOST' => '127.0.0.1', - 'PORT' => '3306', - 'NAME' => 'ptcms', - 'USER' => 'root', - 'PWD' => 'root' - ) - ), - 'SLAVE' => array( - ), - ), - - - 'URL_RULES' => array( - 'index.article.list' => '/{dir}[/{key}][/{page}]', - ), - - 'URL_ROUTER' => array( - '^(news|course)$' => 'index/article/list?module', - ), - -); \ No newline at end of file diff --git a/application/common/controller/admin.php b/application/common/controller/admin.php deleted file mode 100644 index fa42421..0000000 --- a/application/common/controller/admin.php +++ /dev/null @@ -1,56 +0,0 @@ -skipnode=array('admin.index.index'); - } - - public function init() { - session_start(); - // 登录状态判断 - if (empty($_SESSION['admin'])) { - //未登录 - $this->redirect(U('admin.public.login')); - } else { - $this->username = $_SESSION['admin']['username']; - $this->groupname=$_SESSION['admin']['groupname']; - session_write_close(); - } - // 设置了表名则自动初始化model - if ($this->tableName){ - $this->model=M($this->tableName); - } - // 当前页面信息 - $this->menuinfo=M('admin_node')->getMenuInfo(); - //判断是否有权限访问当前页面 创始人 访问权限 免验节点 ajax - if ($_SESSION['admin']['userid']!='1' - && !in_array($this->menuinfo['nodeid'],explode(',',dc::get('admin_group',$_SESSION['admin']['groupid'],'node'))) - && !in_array(MODULE_NAME.'.'.CONTROLLER_NAME.'.'.ACTION_NAME,$this->skipnode) - && ACTION_NAME!='ajax'){ - $this->error('您没有权限访问这个页面!',0,0); - } - // 其他初始化 - } - - // 防止进入空控制器 - public function addAction() {} - public function editAction() {} - public function delAction() { - $id=I('request.id','int',0); - $this->model->del(array('id'=>$id)); - $this->success('删除成功'); - } - public function multiAction() {} - public function ajaxAction() {} -} \ No newline at end of file diff --git a/application/common/controller/common.php b/application/common/controller/common.php deleted file mode 100644 index dfaf591..0000000 --- a/application/common/controller/common.php +++ /dev/null @@ -1,8 +0,0 @@ -/', '', $text); - //完全过滤动态代码 - $text = preg_replace('/<\?|\?' . '>/', '', $text); - //完全过滤js - $text = preg_replace('//', '', $text); - - $text = str_replace('[', '[', $text); - $text = str_replace(']', ']', $text); - $text = str_replace('|', '|', $text); - //br - $text = preg_replace('//i', '[br]', $text); - $text = preg_replace('//i', '[br]', $text); - $text = preg_replace('/(\[br\]\s*){10,}/i', '[br]', $text); - //过滤危险的属性,如:过滤on事件lang js - while (preg_match('/(<[^><]+)( lang|on|action|background|codebase|dynsrc|lowsrc)[^><]+/i', $text, $mat)) { - $text = str_replace($mat[0], $mat[1], $text); - } - while (preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i', $text, $mat)) { - $text = str_replace($mat[0], $mat[1] . $mat[3], $text); - } - if (empty($tags)) { - $tags = 'br'; - } - //允许的HTML标签 - $text = preg_replace('/<(' . $tags . ')( [^><\[\]]*)>/i', '[\1\2]', $text); - $text = preg_replace('/<\/(' . $tags . ')>/Ui', '[/\1]', $text); - //过滤多余html - $text = preg_replace('/<\/?(html|head|meta|link|base|basefont|body|bgsound|title|style|script|form|iframe|frame|frameset|applet|id|ilayer|layer|name|script|style|xml|table|td|th|tr|i|u|strong|img|p|br|div|strong|em|ul|ol|li|dl|dd|dt|a)[^><]*>/i', '', $text); - //过滤合法的html标签 - while (preg_match('/<([a-z]+)[^><\[\]]*>[^><]*<\/\1>/i', $text, $mat)) { - $text = str_replace($mat[0], str_replace('>', ']', str_replace('<', '[', $mat[0])), $text); - } - //转换引号 - while (preg_match('/(\[[^\[\]]*=\s*)(\"|\')([^\2=\[\]]+)\2([^\[\]]*\])/i', $text, $mat)) { - $text = str_replace($mat[0], $mat[1] . '|' . $mat[3] . '|' . $mat[4], $text); - } - //过滤错误的单个引号 - while (preg_match('/\[[^\[\]]*(\"|\')[^\[\]]*\]/i', $text, $mat)) { - $text = str_replace($mat[0], str_replace($mat[1], '', $mat[0]), $text); - } - //转换其它所有不合法的 < > - $text = str_replace('<', '<', $text); - $text = str_replace('>', '>', $text); - $text = str_replace('"', '"', $text); - //反转换 - $text = str_replace('[', '<', $text); - $text = str_replace(']', '>', $text); - $text = str_replace('|', '"', $text); - //过滤多余空格 - $text = str_replace(' ', ' ', $text); - return $text; -} - -function formattext($content) { - // 去除
- $content = str_ireplace(array('
', '
', '
', ' '), "\n", $content); - $content = str_replace("\r", "\n", $content); - do { - $content = str_replace("\n\n", "\n", $content); - } while (strpos($content, "\n\n") !== false); - // 去除空格 - $content = trim(str_replace(array(' ', ' '), ' ', $content)); - // 去除其他html - $content = strip_tags(safetext($content)); - // 加换行及空格 - $content = str_replace("\n", "\r\n", trim($content)); - return $content; -} \ No newline at end of file diff --git a/application/common/library/tree.php b/application/common/library/tree.php deleted file mode 100644 index 87af3f8..0000000 --- a/application/common/library/tree.php +++ /dev/null @@ -1,101 +0,0 @@ -model = $model; - $this->pidkey = $pidkey; - } - - public function getList($pid = 0, $field = '*', $where = array(), $order = 'ordernum asc', $level = 1) { - $where[$this->pidkey] = $pid; - $data = $this->model->field($field)->where($where)->order($order)->select(); - if ($data === null) return array(); - $list = array(); - foreach ($data as $v) { - $v['level'] = $level; - $list[] = $v; - $sons = $this->getlist($v[$this->model->getPk()], $field, $where, $order, $level + 1); - $list = array_merge($list, $sons); - } - return $list; - } - - public function getIconList($list, $startlevel = 1) { - if ($startlevel > 1) { - $preicon[] = array_fill(0, $startlevel - 1, $this->icon['3']); - } else { - $preicon = array(); - } - - foreach ($list as $k => &$v) { - $v['showname'] = $v['name']; - if ($v['level'] >= $startlevel) { - $icon = $this->icon['2']; - $preicon[$v['level'] - $startlevel] = $this->icon['3']; - foreach (array_slice($list, $k + 1) as $n) { - if ($n['level'] < $v['level']) { - //后面没有同级的 - $preicon[$v['level'] - $startlevel] = $this->icon['3']; - break; - } elseif ($n['level'] == $v['level']) { - //后面没有同级的 - $icon = $this->icon['1']; - $preicon[$v['level'] - $startlevel] = $this->icon['0']; - break; - } - } - $v['showname'] = implode('', array_slice($preicon, 0, $v['level'] - $startlevel)) . $icon . $v['name']; - } - } - return $list; - } - - public function getSonList($pid = 0, $field = '*', $where = array(), $limitlevel = 3, $order = 'ordernum asc', $level = 1) { - $where[$this->pidkey] = $pid; - $data = $this->model->field($field)->where($where)->order($order)->select(); - if ($data === null) return array(); - $list = array(); - foreach ($data as $v) { - $v['level'] = $level; - if (isset($v['module'])) { - $v['url'] = ($v['module'] == '') ? '' : U($v['module'] . '.' . $v['controller'] . '.' . $v['action']); - unset($v['module'], $v['controller'], $v['action']); - } - if ($level < $limitlevel) { - $v['sons'] = $this->getSonList($v[$this->model->getPk()], $field, $where, $limitlevel, $order, $level + 1); - } - $list[] = $v; - } - return $list; - } - - public function getAuthList($pid = 0, $field = '*', $where = array(), $order = 'ordernum asc', $level = 1) { - $where[$this->pidkey] = $pid; - $data = $this->model->field($field)->where($where)->order($order)->select(); - if ($data === null) return array(); - $list = array(); - foreach ($data as $v) { - $v['level'] = $level; - if ($level < 4) { - $son=$this->getAuthList($v[$this->model->getPk()], $field, $where, $order, $level + 1); - if ($level == 3) { - $list = array_merge($list, array($v), $son); - } else { - $v['sons'] = $son; - $list[] = $v; - } - }else{ - $list[] = $v; - } - } - return $list; - } -} \ No newline at end of file diff --git a/application/common/model/ad.php b/application/common/model/ad.php deleted file mode 100644 index 53fe149..0000000 --- a/application/common/model/ad.php +++ /dev/null @@ -1,46 +0,0 @@ -insert($param); - } - - /** - * 修改 - * @param $param - * @return mixed - */ - public function edit($param) { - //更新缓存 - return $this->update($param); - } - - /** - * 删除数据 - * @param $where - */ - public function del($where) { - $this->where($where)->delete(); - } - - //获取列表 - public function getlist() { - $list=(array)$this->select(); - foreach($list as &$v){ - if (isset($v['create_user_id'])){ - //后台 - $v['create_username']=dc::get('passport',$v['create_user_id'],'name'); - $v['update_username']=dc::get('passport',$v['update_user_id'],'name'); - $v['url_edit']=U('ad.manage.edit',array('id'=>$v['id'])); - $v['url_show']=U('ad.manage.show',array('id'=>$v['id'])); - $v['create_time']=$v['create_time']?date('Y-m-d H:i',$v['create_time']):''; - $v['update_time']=$v['update_time']?date('Y-m-d H:i',$v['update_time']):''; - } - } - return $list; - } -} \ No newline at end of file diff --git a/application/common/model/admin_group.php b/application/common/model/admin_group.php deleted file mode 100644 index cd381cb..0000000 --- a/application/common/model/admin_group.php +++ /dev/null @@ -1,43 +0,0 @@ -insert($param); - } - - /** - * 修改 - * @param $param - * @return mixed - */ - public function edit($param) { - //更新缓存 - dc::refresh('admin_group',$param['id']); - return $this->update($param); - } - - /** - * 删除数据 - * @param $where - */ - public function del($where) { - $this->where($where)->delete(); - } - - // 获取列表 - public function getlist() { - $list=(array)$this->select(); - foreach($list as &$v){ - $v['create_username']=dc::get('passport',$v['create_user_id'],'name'); - $v['update_username']=dc::get('passport',$v['update_user_id'],'name'); - $v['url_edit']=U('admin.group.edit',array('id'=>$v['id'])); - $v['create_time']=$v['create_time']?date('Y-m-d H:i',$v['create_time']):''; - $v['update_time']=$v['update_time']?date('Y-m-d H:i',$v['update_time']):''; - } - return $list; - } -} \ No newline at end of file diff --git a/application/common/model/admin_node.php b/application/common/model/admin_node.php deleted file mode 100644 index 61f442e..0000000 --- a/application/common/model/admin_node.php +++ /dev/null @@ -1,69 +0,0 @@ -insert($param); - } - - /** - * 修改 - * @param $param - * @return mixed - */ - public function edit($param) { - return $this->update($param); - } - - /** - * 删除数据 - * @param $where - */ - public function del($where) { - $this->where($where)->delete(); - } - - /** - * 获取当前节点及父节点的信息 - * @return mixed - */ - public function getMenuInfo() { - $info=$this->field('id,name,pid')->where(array('module'=>MODULE_NAME,'controller'=>CONTROLLER_NAME,'action'=>ACTION_NAME))->find(); - $parentinfo=$this->field('name,pid,module,controller,action')->where(array('id'=>$info['pid']))->find(); - if (empty($parentinfo['module'])){ - $res['menu']['name']=$info['name']; - $res['menu']['url']=U(MODULE_NAME.'.'.CONTROLLER_NAME.'.'.ACTION_NAME); - $res['submenu']['name']=''; - $res['submenu']['url']=''; - }else{ - $res['menu']['name']=$parentinfo['name']; - $res['menu']['url']=U($parentinfo['module'].'.'.$parentinfo['controller'].'.'.$parentinfo['action']); - $res['submenu']['name']=$info['name']; - $res['submenu']['url']=U(MODULE_NAME.'.'.CONTROLLER_NAME.'.'.ACTION_NAME); - } - $res['nodeid']=$info['id']; - return $res; - } - - public function getParentList($id) { - $info=$this->where(array('id'=>$id))->field('id,pid')->find(); - if ($info['pid']==0) return array(); - $res[]=$info['pid']; - $res=array_merge($res,$this->getParentList($info['pid'])); - return $res; - } - - public function toNodeAuth($arr) { - foreach($arr as $v){ - $plist=$this->getParentList($v); - foreach($plist as $id){ - if (!in_array($id,$arr)) $arr[]=$id; - } - } - return $arr; - } -} \ No newline at end of file diff --git a/application/common/model/admin_user.php b/application/common/model/admin_user.php deleted file mode 100644 index a8ff966..0000000 --- a/application/common/model/admin_user.php +++ /dev/null @@ -1,71 +0,0 @@ -where(array('passport_id'=>$userid))->getfield('status'); - } - - // 设置用户登录状态 - public function setLoginStatus($userid) { - //设置登录信息 - $_SESSION['admin']['userid']=$userid; - $_SESSION['admin']['username']=M('passport')->where(array('id'=>$userid))->getField('name'); - $_SESSION['admin']['groupid']=$this->where(array('passport_id'=>$userid))->getField('group_id'); - $_SESSION['admin']['groupname']=dc::get('admin_group',$_SESSION['admin']['groupid'],'name'); - // 更新通行证登录时间 - $data['login_ip']=get_ip(); - $data['login_time']=NOW_TIME; - M('passport')->where(array('id'=>$userid))->update($data); - // 更新后台表信息 - $data['login_num']=array('exp','`login_num`+1'); - $this->where(array('passport_id'=>$userid))->update($data); - } - - // 删除用户登录信息 - public function delLoginStatus() { - $_SESSION['admin']=null; - } - - // 获取列表 - public function getlist() { - $list=$this->select(); - foreach($list as &$v){ - $v['username']=dc::get('passport',$v['passport_id'],'name'); - $v['groupname']=dc::get('admin_group',$v['group_id'],'name'); - $v['create_username']=dc::get('passport',$v['create_user_id'],'name'); - $v['update_username']=dc::get('passport',$v['update_user_id'],'name'); - $v['url_edit']=U('admin.user.edit',array('id'=>$v['id'])); - $v['create_time']=$v['create_time']?date('Y-m-d H:i',$v['create_time']):''; - $v['update_time']=$v['update_time']?date('Y-m-d H:i',$v['update_time']):''; - $v['login_time']=$v['login_time']?date('Y-m-d H:i',$v['login_time']):''; - } - return $list; - } - - /** - * 插入数据 - * @param $param - * @return mixed - */ - public function add($param) { - return $this->insert($param); - } - - /** - * 修改 - * @param $param - * @return mixed - */ - public function edit($param) { - return $this->update($param); - } - - /** - * 删除数据 - * @param $where - */ - public function del($where) { - $this->where($where)->delete(); - } -} \ No newline at end of file diff --git a/application/common/model/friendlink.php b/application/common/model/friendlink.php deleted file mode 100644 index f718f19..0000000 --- a/application/common/model/friendlink.php +++ /dev/null @@ -1,58 +0,0 @@ -insert($param); - } - - /** - * 修改 - * @param $param - * @return mixed - */ - public function edit($param) { - //更新缓存 - return $this->update($param); - } - - /** - * 删除数据 - * @param $where - */ - public function del($where) { - $this->where($where)->delete(); - } - - //获取列表 - public function getlist() { - $list=(array)$this->select(); - foreach($list as &$v){ - $v['showname']=$this->getshowname($v); - if (isset($v['create_user_id'])){ - //后台 - $v['create_username']=dc::get('passport',$v['create_user_id'],'name'); - $v['update_username']=dc::get('passport',$v['update_user_id'],'name'); - $v['url_edit']=U('friendlink.manage.edit',array('id'=>$v['id'])); - $v['create_time']=$v['create_time']?date('Y-m-d H:i',$v['create_time']):''; - $v['update_time']=$v['update_time']?date('Y-m-d H:i',$v['update_time']):''; - } - } - return $list; - } - - //获取展示的链接名 - public function getshowname($v) { - $v['showname']=$v['name']; - if ($v['isbold']){ - $v['showname']=''.$v['showname'].''; - } - if ($v['color']!==''){ - $v['showname']="{$v['showname']}"; - } - return $v['showname']; - } -} \ No newline at end of file diff --git a/application/common/model/passport.php b/application/common/model/passport.php deleted file mode 100644 index f69ffc4..0000000 --- a/application/common/model/passport.php +++ /dev/null @@ -1,12 +0,0 @@ -where(array('name'=>$username))->field('id,password,salt')->find()){ - if ($info['password']==md5(md5($password).$info['salt'])){ - return $info['id']; - } - } - return false; - } -} \ No newline at end of file diff --git a/application/common/ptf.coding.io.config.php b/application/common/ptf.coding.io.config.php deleted file mode 100644 index a0e1dff..0000000 --- a/application/common/ptf.coding.io.config.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - 'DRIVER' => 'Pdo', - 'PREFIX' => 'ptcms_', - 'CHARSET' => 'utf8', - 'MASTER' => array( - array( - 'HOST' => '10.9.1.188', - 'PORT' => '3306', - 'NAME' => 'cf_92aa4934_9075_4c43_8bc6_8c4a304f58b9', - 'USER' => 'C5M1OJxpIKbQVNlY', - 'PWD' => 'k31GzgvccXk5GITk' - ) - ), - 'SLAVE' => array( - ), - ), -); \ No newline at end of file diff --git a/application/friendlink/controller/manage.php b/application/friendlink/controller/manage.php deleted file mode 100644 index faded5e..0000000 --- a/application/friendlink/controller/manage.php +++ /dev/null @@ -1,111 +0,0 @@ -tableName='friendlink'; - parent::init(); - } - - public function indexAction() { - $this->list=$this->model->getlist(); - $this->display(); - } - - public function addAction() { - if (IS_POST){ - $param['name']=I('name','str',''); - if (!$param['name']){ - $this->error('请输入链接名称'); - } - $param['url']=I('url','url',''); - if (!$param['url']){ - $this->error('请输入链接地址'); - } - $param['logo']=I('logo','str',''); - $param['description']=I('description','str',''); - $param['color']=I('color','str',''); - $param['ordernum']=I('ordernum','int',50); - $param['status']=I('status','int',1); - $param['isblod']=I('isblod','int',0); - $param['create_user_id']=$_SESSION['admin']['userid']; - $param['create_time']=NOW_TIME; - if($this->model->add($param)){ - $this->success('添加成功',U('index')); - }else{ - $this->error('添加失败'); - } - } - $this->display(); - } - - public function editAction() { - $id=I('request.id','int',0); - $info=$this->model->where(array('id'=>$id))->find(); - if (IS_POST){ - $param['name']=I('name','str',''); - if (!$param['name']){ - $this->error('请输入链接名称'); - } - $param['url']=I('url','url',''); - if (!$param['url']){ - $this->error('请输入链接地址'); - } - $param['logo']=I('logo','str',''); - $param['description']=I('description','str',''); - $param['color']=I('color','str',''); - $param['ordernum']=I('ordernum','int',50); - $param['status']=I('status','int',50); - $param['isblod']=I('isblod','int',50); - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - $param['id']=$id; - if ($this->model->edit($param)){ - $this->success('修改成功',U('index')); - }else{ - $this->error('修改失败'); - } - } - $this->info=$info; - $this->display(); - } - - public function ajaxAction() { - $id=I('request.id','int',0); - $value=I('param','username',''); - if ($value){ - if ($passport_id=M('passport')->where(array('name'=>$value))->getfield('id')){ - $oid=$this->model->where(array('passport_id'=>$passport_id))->getfield('id'); - if ($oid && $oid!=$id){ - $data=array('status'=>'n','info'=>'您输入的用户名已经使用了'); - }else{ - $data=array('status'=>'y','info'=>'帐号可以使用'); - } - }else{ - $data=array('status'=>'n','info'=>'您输入的用户名不存在'); - } - }else{ - $data=array('status'=>'n','info'=>'输入的用户名有误'); - } - $this->ajax($data); - } - - public function multiAction() { - $param['update_user_id']=$_SESSION['admin']['userid']; - $param['update_time']=NOW_TIME; - if (isset($_POST['changestatus'])){ - foreach($_POST['id'] as $k=>$v){ - $param['id']=$v; - $param['status']=$_POST['value'][$k]; - $this->model->edit($param); - } - $this->success('修改状态成功'); - }elseif(isset($_POST['reorder'])){ - foreach($_POST['ordernum'] as $k=>$v){ - $param['id']=$k; - $param['ordernum']=$v; - $this->model->edit($param); - } - $this->success('排序成功'); - }else{ - } - } -} \ No newline at end of file diff --git a/application/friendlink/view/manage_add.html b/application/friendlink/view/manage_add.html deleted file mode 100644 index 6ebe5d4..0000000 --- a/application/friendlink/view/manage_add.html +++ /dev/null @@ -1,76 +0,0 @@ -
-

添加链接

-
-
-
-
-
- 链接名称: - -
-
-
-
- 链接地址: - -
-
-
-
- 链接描述: - -
-
-
-
- 链接logo: - -
-
-
-
- 排序序号: - -
-
-
-
- 链接颜色: - -
-
-
-
链接字体: - - -
-
- -
-
链接状态: - - -
-
-
-
-
-
- -     -
-
-
-
-
-
- - diff --git a/application/friendlink/view/manage_edit.html b/application/friendlink/view/manage_edit.html deleted file mode 100644 index a4aa2dd..0000000 --- a/application/friendlink/view/manage_edit.html +++ /dev/null @@ -1,83 +0,0 @@ -
-

修改链接

-
-
-
-
-
- 链接名称: - -
-
-
-
- 链接地址: - -
-
-
-
- 链接描述: - -
-
-
-
- 链接logo: - -
-
-
-
- 排序序号: - -
-
-
-
- 链接颜色: - -
-
-
-
链接字体: - - -
-
- -
-
链接状态: - - -
-
-
-
-
-
- - -     -
-
-
-
-
-
- - - \ No newline at end of file diff --git a/application/friendlink/view/manage_index.html b/application/friendlink/view/manage_index.html deleted file mode 100644 index 9860a59..0000000 --- a/application/friendlink/view/manage_index.html +++ /dev/null @@ -1,62 +0,0 @@ -
-

{$menuinfo.menu.name}

-
-
-
-
- 添加 - -
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
链接名称链接地址排序创建人创建时间修改人修改时间状态操作
{{loop.url}} - - {{loop.create_username}}{{loop.create_time}}{{loop.update_username}}{{loop.update_time}} - 禁用 - 正常 - - 编辑 - 删除 -
- -
-
-
-{include file="/application/admin/view/public_angular.html"} \ No newline at end of file diff --git a/application/index/controller/index.php b/application/index/controller/index.php deleted file mode 100644 index 8e27701..0000000 --- a/application/index/controller/index.php +++ /dev/null @@ -1,13 +0,0 @@ -display(); - } -} \ No newline at end of file diff --git a/index.php b/index.php deleted file mode 100644 index fa75a77..0000000 --- a/index.php +++ /dev/null @@ -1,10 +0,0 @@ -array( - 'user'=>array( - 模块1=>地址1 - 模块2=>地址2 - ) - ) - 'block'=>array() - ) -根据这个map来做自动加载 - -2、 -模块必须设置了才允许访问 - - -##官网 -社区管理员标识 置顶 删除 屏蔽 \ No newline at end of file diff --git a/ptcms.sql b/ptcms.sql deleted file mode 100644 index 9fc45ca..0000000 --- a/ptcms.sql +++ /dev/null @@ -1,157 +0,0 @@ -# Host: localhost (Version: 5.5.38) -# Date: 2014-10-09 08:55:17 -# Generator: MySQL-Front 5.3 (Build 4.120) - -/*!40101 SET NAMES utf8 */; - -# -# Structure for table "ptcms_admin_group" -# - -DROP TABLE IF EXISTS `ptcms_admin_group`; -CREATE TABLE `ptcms_admin_group` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(10) NOT NULL DEFAULT '', - `intro` varchar(255) NOT NULL DEFAULT '', - `node` text NOT NULL, - `create_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人', - `update_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改人', - `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', - `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改时间', - PRIMARY KEY (`id`) -) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户组信息表'; - -# -# Data for table "ptcms_admin_group" -# - -/*!40000 ALTER TABLE `ptcms_admin_group` DISABLE KEYS */; -INSERT INTO `ptcms_admin_group` VALUES (1,'超级管理员','拥有所有权限','4,5,15,8,9,10,11,12,14,17,19,20,21,18,22,23,24,25,3,1,6,7,13,2,16',1,1,1412777739,1412778653); -/*!40000 ALTER TABLE `ptcms_admin_group` ENABLE KEYS */; - -# -# Structure for table "ptcms_admin_node" -# - -DROP TABLE IF EXISTS `ptcms_admin_node`; -CREATE TABLE `ptcms_admin_node` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '文档ID', - `name` varchar(50) NOT NULL DEFAULT '' COMMENT '标题', - `pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '上级分类ID', - `module` varchar(20) DEFAULT NULL, - `controller` varchar(50) DEFAULT NULL, - `action` varchar(50) DEFAULT NULL, - `ordernum` smallint(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序(同级有效)', - `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态', - `create_user_id` int(11) unsigned DEFAULT '0' COMMENT '创建人', - `update_user_id` int(11) unsigned DEFAULT '0' COMMENT '修改人', - `create_time` int(11) unsigned DEFAULT '0' COMMENT '创建时间', - `update_time` int(11) unsigned DEFAULT '0' COMMENT '修改时间', - PRIMARY KEY (`id`), - KEY `pid` (`pid`), - KEY `status` (`status`) -) ENGINE=MyISAM AUTO_INCREMENT=26 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; - -# -# Data for table "ptcms_admin_node" -# - -/*!40000 ALTER TABLE `ptcms_admin_node` DISABLE KEYS */; -INSERT INTO `ptcms_admin_node` VALUES (1,'常用',0,'','','',1,1,1,1,1412696793,1412757936),(2,'系统',0,'','','',1,1,1,1,1412696797,1412757936),(3,'系统概况',1,'','','',50,1,1,1,1412699544,1412757936),(4,'欢迎界面',3,'admin','index','welcome',10,1,1,1,1412699598,1412757936),(5,'系统探针',3,'admin','index','system',20,1,1,1,1412699662,1412757936),(6,'常用功能',1,'','','',50,1,1,1,1412699681,1412757936),(7,'开发功能',1,'','','',50,1,1,1,1412699705,1412757936),(8,'权限节点',7,'admin','node','index',50,1,1,1,1412699737,1412757936),(9,'添加节点',8,'admin','node','add',50,1,1,1,1412699752,1412757936),(10,'修改节点',8,'admin','node','edit',50,1,1,1,1412699787,1412757936),(11,'删除节点',8,'admin','node','del',50,1,1,1,1412699817,1412757936),(12,'批量操作',8,'admin','node','multi',50,1,1,1,1412700038,1412757936),(13,'系统设置',2,'','','',50,1,1,1,1412701712,1412757936),(14,'基本参数',13,'','','',50,1,1,1,1412701727,1412757936),(15,'添加菜单',6,'','','',50,1,1,1,1412701869,1412757936),(16,'管理员设置',2,'','','',50,1,1,1,1412749506,1412757936),(17,'用户管理',16,'admin','user','index',50,1,1,1,1412749542,1412757936),(18,'用户组管理',16,'admin','group','index',50,1,1,1,1412749571,1412757936),(19,'添加用户',17,'admin','user','add',50,1,1,1,1412749589,1412757936),(20,'修改用户',17,'admin','user','edit',50,1,1,1,1412749624,1412757936),(21,'删除用户',17,'admin','user','del',50,1,1,1,1412749640,1412757936),(22,'添加用户组',18,'admin','group','add',50,1,1,1,1412749659,1412757936),(23,'修改用户组',18,'admin','group','edit',50,1,1,1,1412749668,1412757936),(24,'删除用户组',18,'admin','group','del',50,1,1,1,1412749694,1412757936),(25,'批量操作',18,'admin','group','multi',50,1,1,1,1412749710,1412757936); -/*!40000 ALTER TABLE `ptcms_admin_node` ENABLE KEYS */; - -# -# Structure for table "ptcms_admin_user" -# - -DROP TABLE IF EXISTS `ptcms_admin_user`; -CREATE TABLE `ptcms_admin_user` ( - `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, - `passport_id` int(11) NOT NULL DEFAULT '0', - `group_id` smallint(5) DEFAULT '0' COMMENT '用户组', - `intro` varchar(255) NOT NULL DEFAULT '', - `create_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人', - `update_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改人', - `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', - `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改时间', - `login_num` int(11) unsigned DEFAULT '0' COMMENT '登录次数', - `login_ip` varchar(15) DEFAULT NULL, - `login_time` int(11) unsigned DEFAULT '0' COMMENT '最后登录时间', - `status` tinyint(3) unsigned DEFAULT '1' COMMENT '用户状态 1正常 0未审核', - PRIMARY KEY (`id`), - UNIQUE KEY `passport_id` (`passport_id`), - KEY `group_id` (`group_id`) -) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='用户信息表'; - -# -# Data for table "ptcms_admin_user" -# - -/*!40000 ALTER TABLE `ptcms_admin_user` DISABLE KEYS */; -INSERT INTO `ptcms_admin_user` VALUES (1,1,1,'默认管理员帐号',1,1,1411978787,1412813064,12,'127.0.0.1',1412778449,1),(3,2,1,'haha',1,0,1412815173,0,0,NULL,0,1); -/*!40000 ALTER TABLE `ptcms_admin_user` ENABLE KEYS */; - -# -# Structure for table "ptcms_caption" -# - -DROP TABLE IF EXISTS `ptcms_caption`; -CREATE TABLE `ptcms_caption` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `key` varchar(50) DEFAULT NULL, - `name` varchar(100) DEFAULT NULL COMMENT '名称', - `description` varchar(255) DEFAULT NULL COMMENT '描述信息', - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='key中文解释'; - -# -# Data for table "ptcms_caption" -# - -/*!40000 ALTER TABLE `ptcms_caption` DISABLE KEYS */; -/*!40000 ALTER TABLE `ptcms_caption` ENABLE KEYS */; - -# -# Structure for table "ptcms_passport" -# - -DROP TABLE IF EXISTS `ptcms_passport`; -CREATE TABLE `ptcms_passport` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) DEFAULT NULL, - `password` char(32) DEFAULT NULL, - `salt` char(6) DEFAULT NULL, - `reg_ip` varchar(15) DEFAULT NULL, - `reg_time` int(11) unsigned DEFAULT '0', - `login_ip` varchar(15) DEFAULT NULL, - `login_time` int(11) unsigned DEFAULT '0', - PRIMARY KEY (`id`), - KEY `name` (`name`(5)) -) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户信息主表'; - -# -# Data for table "ptcms_passport" -# - -/*!40000 ALTER TABLE `ptcms_passport` DISABLE KEYS */; -INSERT INTO `ptcms_passport` VALUES (1,'admin','db4dfadff18f7145ca4f6a2a15ff6303','565795','127.0.0.1',1411978787,'127.0.0.1',1412778449),(2,'test1',NULL,NULL,NULL,0,NULL,0),(3,'test2',NULL,NULL,NULL,0,NULL,0),(4,'test3',NULL,NULL,NULL,0,NULL,0); -/*!40000 ALTER TABLE `ptcms_passport` ENABLE KEYS */; - -# -# Structure for table "ptcms_user" -# - -DROP TABLE IF EXISTS `ptcms_user`; -CREATE TABLE `ptcms_user` ( - `user_id` int(11) NOT NULL DEFAULT '0', - `group_id` smallint(6) DEFAULT NULL, - `status` tinyint(3) unsigned DEFAULT '1' COMMENT '用户状态 1正常 0未审核', - PRIMARY KEY (`user_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='用户信息表'; - -# -# Data for table "ptcms_user" -# - -/*!40000 ALTER TABLE `ptcms_user` DISABLE KEYS */; -/*!40000 ALTER TABLE `ptcms_user` ENABLE KEYS */; diff --git a/ptcms/core/api.php b/ptcms/core/api.php new file mode 100644 index 0000000..1c30ad9 --- /dev/null +++ b/ptcms/core/api.php @@ -0,0 +1,70 @@ +apiurl = $this->config->get('apiserver'); + $driverclass = 'Driver_Api_' . $this->config->get('driver_api', 'ptcms'); + $this->handle = new $driverclass; + } + + public function __call($method, $param = array()) { + $param = ($param == array()) ? array() : $param['0']; + return $this->call($method, $param); + } + + public function method($var) { + $this->name = $var; + return $this; + } + + public function param($var) { + $this->param = $var; + return $this; + } + + public function header($var) { + $this->header = $var; + return $this; + } + + public function get() { + return $this->call($this->name, $this->param, 'GET', $this->header); + } + + public function post() { + return $this->call($this->name, $this->param, 'POST', $this->header); + } + + public function put() { + return $this->call($this->name, $this->param, 'PUT', $this->header); + } + + public function delete() { + return $this->call($this->name, $this->param, 'DELETE', $this->header); + } + + // 调用API + public function call($name, $param = array(), $method = 'GET', $header = array()) { + + if (strpos($name, 'http') === 0) { + $url = $name; + } else { + $url = $this->apiurl . '/' . $name; + } + //get方式则把参数加到url里面 + if ($method == 'GET' && $header != array()) { + $param = array_merge($param, $header); + } + return $this->handle->call($url, $param, $method, $header); + } +} \ No newline at end of file diff --git a/ptcms/core/block.php b/ptcms/core/block.php index c135847..f1f1748 100644 --- a/ptcms/core/block.php +++ b/ptcms/core/block.php @@ -5,19 +5,43 @@ * @Email : admin@ptcms.com * @File : block.php */ -abstract class block extends Controller { +class PT_Block{ + protected $pt; + public function __construct() { + $this->pt=PT_Base::getInstance(); + } + + public function getInstance($class) { + static $_class; + $class = $class . 'Block'; + if (empty($_class[$class])) { + if (class_exists($class)) { + $_class[$class] = new $class(); + }else{ + $_class[$class] = null; + } + } + return $_class[$class]; + } - public function run($param) { - $key = $this->getKey($param); - $cachetime = empty($param['cachetime']) ? C('CACHE_TIME', null, 600) : intval($param['cachetime']); - $data = $this->checkCache($key, $cachetime); - if (APP_DEBUG || $data === false) { - $data = $this->exec($param); + public function getData($name,$param) { + $key = $this->getKey($name,$param); + $cachetime = $this->pt->input->param('cachetime','int',$this->pt->config->get('cachetime', 600),$param); + $data = $this->pt->cache->get($key); + $hander=$this->getInstance($name); + if ($hander && (APP_DEBUG || $data === null)) { + $data = $hander->run($param); if (!empty($param['template'])) { - $this->assign('block', $data); - $data = $this->render($param['template'], 'common'); + $this->pt->view->set($param); + if ($layout=$this->pt->config->get('layout')){ + $this->pt->config->get('layout',false); + $data = $this->pt->view->fetch($param['template']); + $this->pt->config->get('layout',$layout); + }else{ + $data = $this->pt->view->fetch($param['template']); + } } - if (!APP_DEBUG) Cache::set($key, array('time' => NOW_TIME, 'data' => $data), $cachetime); + $this->pt->cache->set($key, $data, $cachetime); } return $data; } @@ -30,23 +54,15 @@ public function run($param) { * @return bool */ public function checkCache($key, $cachetime) { - $data = Cache::get($key); + $data = $this->pt->cache->get($key); if (!isset($data['time']) || ($cachetime <> 0 && $data['time'] + $cachetime < NOW_TIME)) { return false; } return $data['data']; } - public function getKey($param) { - return md5(get_class($this) . serialize($param)); + public function getKey($name,$param) { + return md5($name . serialize($param)); } - /** - * 需要实现的方法 - * - * @param $param - * @return mixed - */ - abstract public function exec($param); - } \ No newline at end of file diff --git a/ptcms/core/cache.php b/ptcms/core/cache.php index 5ec21f7..5e4559f 100644 --- a/ptcms/core/cache.php +++ b/ptcms/core/cache.php @@ -5,37 +5,43 @@ * @Email : admin@ptcms.com * @File : Cache.php */ -class Cache { +class PT_Cache{ protected static $handler = null; + protected $pt; + + public function __construct() { + $this->pt=PT_Base::getInstance(); + } /** + * @param string $type; * @return Driver_Cache_File */ - public static function getInstance() { - $key = C('cache_type', null, 'file'); - if (empty(self::$handler[$key])) { - $class = 'Driver_Cache_' . C('cache_type'); - self::$handler[$key] = new $class(C('cache_option', null, array())); + public function getInstance($type = '') { + $type = $type ? $type : $this->pt->config->get('cache_driver', 'file'); + if (empty(self::$handler[$type])) { + $class = 'Driver_Cache_' . $this->pt->config->get('cache_driver'); + self::$handler[$type] = new $class($this->pt->config->get('cache_option', array())); } - return self::$handler[$key]; + return self::$handler[$type]; } - public static function set($key, $value, $time = 0) { + public function set($key, $value, $time = 0) { $GLOBALS['_cacheWrite']++; - return self::getInstance()->set($key, $value, $time); + return $this->getInstance()->set($key, $value, $time); } - public static function get($key) { + public function get($key) { $GLOBALS['_cacheRead']++; - return self::getInstance()->get($key); + return $this->getInstance()->get($key); } - public static function rm($key) { - return self::getInstance()->rm($key); + public function rm($key) { + return $this->getInstance()->rm($key); } - public static function clear() { - self::getInstance()->clear(); + public function clear() { + $this->getInstance()->clear(); } } \ No newline at end of file diff --git a/ptcms/core/config.php b/ptcms/core/config.php new file mode 100644 index 0000000..6f0192d --- /dev/null +++ b/ptcms/core/config.php @@ -0,0 +1,82 @@ +register($key); + //多级模式 + $c = self::$_config; + $k = &$c; + $fields = explode('.', $key); + foreach ($fields as $field) { + $k = &$k[$field]; + } + $k = $var; + self::$_config=$c; + return true; + } + + /* + * 注册配置 + */ + public function register($config){ + if (!is_array($config)) return false; + self::$_config = array_merge(self::$_config, array_change_key_case($config)); + return true; + } + + // save 只可以写入公共配置文件的 支持数组 + public function save($key, $value='') { + $file=APP_PATH . '/common/config.php'; + $config = include $file; + if (is_array($key)){ + $config=array_merge($config, $key); + }elseif(isset($config[$key])){ + $config[$key]=$value; + }else{ + return; + } + if (!F($file, $config)){ + $this->response->error('修改失败,请检查'.$file . '文件权限',0,0); + }; + } +} diff --git a/ptcms/core/controller.php b/ptcms/core/controller.php index 6f36bcd..8b5e4a4 100644 --- a/ptcms/core/controller.php +++ b/ptcms/core/controller.php @@ -5,25 +5,20 @@ * @Email : admin@ptcms.com * @File : controller.php */ -class Controller { - protected function getView() { +class PT_Controller extends PT_Base { + public function getView() { static $view; if (!isset($view)) { - plugin::call('view_start'); + $this->plugin->call('view_start'); //实例化view - $view = new View(); + $view = new PT_View(); //初始化模版 $view->getTheme(); } return $view; } - public function assign($name, $value = null) { - $this->getView()->assign($name, $value); - return $this; //支持连贯操作 - } - /** * 显示当前页面的视图内容 * @@ -33,8 +28,8 @@ public function assign($name, $value = null) { * @param string $theme 所属模版 * @return void */ - protected function display($tpl = null, $module = null, $theme = null) { - $content = $this->render($tpl, $module, $theme); + public function display($tpl = null, $module = null, $theme = null) { + $content = $this->fetch($tpl, $module, $theme); $this->show($content); } @@ -47,123 +42,96 @@ protected function display($tpl = null, $module = null, $theme = null) { * @return void */ protected function show($content, $mimeType = 'text/html') { - pt::show($content, $mimeType); - } - - protected function render($tpl = null, $module = null, $theme = null) { - if (C('html', null, false)) { - $rules = C('URL_RULES'); - $key = $_GET['m'] . '.' . $_GET['c'] . '.' . $_GET['a']; - if (isset($rules[$key])) { - $param = $_GET; - unset($param['m'], $param['c'], $param['a'], $param['s'], $param['t']); - C('is_gen_html', true); - $content = $this->getView()->render($tpl, $module, $theme); - $url = empty($this->htmlurl) ? U($key, $param, C('link_ignore', null, array())) : $this->htmlurl; - html::create($url, $content); - return $content; - } - } - return $this->getView()->render($tpl, $module, $theme); + $this->response->setBody($content, $mimeType); } - // 实现 $this->name=value 的赋值方法 - public function __set($name, $value) { - $this->getView()->assign($name, $value); + protected function fetch($tpl = null, $module = null, $theme = null) { + return $this->view->fetch($tpl, $module, $theme); } - // 获取 $this->name 的值 - public function __get($name) { - return $this->getView()->getassign($name); + protected function render($var){ + if ($var===true){ + $this->response->enableRender(); + }elseif($var===false){ + $this->response->disableRender(); + }else{ + $this->view->setFile($var); + } } - protected function success($info, $jumpUrl = '', $second = 1) { + public function success($info, $jumpUrl = '', $second = 1) { $this->dispatchJump($info, 1, $jumpUrl, $second); } - protected function error($info, $jumpUrl = '', $second = 3) { + public function error($info, $jumpUrl = '', $second = 3) { $this->dispatchJump($info, 0, $jumpUrl, $second); } protected function dispatchJump($message, $status = 1, $jumpurl = '', $second = 1) { - C('LAYOUT', false); - if (IS_AJAX or $second === true) { + $this->config->set('layout', false); + if ($this->request->isAjax() or $second === true) { $data['status'] = $status; - $data['info'] = $message; - $data['url'] = $jumpurl; + $data['info'] = $message; + $data['url'] = $jumpurl; $this->ajax($data); } else { - defined('PT_SITENAME') ? $this->assign('msgname', PT_SITENAME) : $this->assign('msgname', C('SITENAME', null, 'PTFrameWork')); + defined('PT_SITENAME') ? $this->view->set('msgname', PT_SITENAME) : $this->view->set('msgname', $this->config->get('sitename', null, 'PTFrameWork')); //如果设置了关闭窗口,则提示完毕后自动关闭窗口 - $this->assign('status', $status); // 状态 - $this->assign('waitsecond', $second); - $this->assign('message', $message); // 提示信息 - $this->assign('msgtitle', $status ? '成功' : '失败'); + $this->view->set('status', $status); // 状态 + $this->view->set('waitsecond', $second); + $this->view->set('message', $message); // 提示信息 + $this->view->set('msgtitle', $status ? '成功' : '失败'); if ($status) { //发送成功信息 - $this->assign('msgtype', 'success'); // 提示类型 + $this->view->set('msgtype', 'success'); // 提示类型 // 默认操作成功自动返回操作前页面 if ($jumpurl) { - $this->assign("jumpurl", $jumpurl); + $this->view->set("jumpurl", $jumpurl); } elseif (!empty($_SERVER['HTTP_REFERER'])) { - $this->assign("jumpurl", $_SERVER["HTTP_REFERER"]); + $this->view->set("jumpurl", $_SERVER["HTTP_REFERER"]); } else { - $this->assign('jumpurl', $_SERVER['REQUEST_URI']); + $this->view->set('jumpurl', $_SERVER['REQUEST_URI']); } } else { - $this->assign('msgtype', 'error'); // 提示类型 + $this->view->set('msgtype', 'error'); // 提示类型 // 默认发生错误的话自动返回上页 if ($jumpurl) { - $this->assign("jumpurl", $jumpurl); + $this->view->set("jumpurl", $jumpurl); } elseif (!empty($_SERVER['HTTP_REFERER'])) { - $this->assign("jumpurl", '#back#'); + $this->view->set("jumpurl", '#back#'); } else { - $this->assign('jumpurl', $_SERVER['REQUEST_URI']); + $this->view->set('jumpurl', $_SERVER['REQUEST_URI']); } } - $this->display('message', 'common', C('tpl_theme') ? C('tpl_theme') : 'default'); + $this->display('message', 'common', $this->config->get('tpl_theme') ? $this->config->get('tpl_theme') : 'default'); exit; } } - protected function ajax($data, $type = 'json') { + public function ajax($data, $type = 'json') { + // 跨域 + header('Access-Control-Allow-Origin:*'); + header('Access-Control-Allow-Headers:accept, content-type'); + switch (strtoupper($type)) { case 'JSON' : // 返回JSON数据格式到客户端 包含状态信息 - pt::show(json_encode($data), 'application/json'); + $data=$this->response->jsonEncode($data); break; case 'JSONP': - // 返回JSON数据格式到客户端 包含状态信息 - $handler = isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : 'ptcms_jsonp'; - pt::show($handler . '(' . json_encode($data) . ');', 'application/json'); + // 返回JSONP数据格式到客户端 包含状态信息 + $data=$this->response->jsonpEncode($data); break; case 'EVAL' : // 返回可执行的js脚本 - pt::show($data); break; default : - // 用于扩展其他返回格式数据 } + $this->response->setBody($data, 'application/json'); exit; } public function redirect($url, $type = 302) { - if ($type == 302) { - header('HTTP/1.1 302 Moved Temporarily'); - header('Status:302 Moved Temporarily'); // 确保FastCGI模式下正常 - } else { - header('HTTP/1.1 301 Moved Permanently'); - header('Status:301 Moved Permanently'); - } - header('Location: ' . $url); - exit; - } - - public function _empty($msg) { - if (APP_DEBUG) { - $this->error($msg, '', 0); - } else { - halt($msg); - } + $this->response->redirect($url, $type); } } \ No newline at end of file diff --git a/ptcms/core/cookie.php b/ptcms/core/cookie.php new file mode 100644 index 0000000..cdeac18 --- /dev/null +++ b/ptcms/core/cookie.php @@ -0,0 +1,60 @@ +option = array( + 'prefix' => $this->config->get('cookie_prefix', 'PTCMS_'), + // cookie 保存时间 + 'expire' => intval($this->config->get('cookie_expire', 2592000)), + // cookie 保存路径 + 'path' => $this->config->get('cookie_path', '/'), + // cookie 有效域名 + 'domain' => $this->config->get('cookie_domain'), + ); + } + + public function get($name, $default=null) { + $name = $this->option['prefix'] . $name; + if (isset($_COOKIE[$name])) { + return $_COOKIE[$name]; + } else { + return $default; + } + } + + public function set($name, $value = '', $option = null) { + if (!is_null($option)) { + if (is_numeric($option)) + $option = array('expire' => $option); + elseif (is_string($option)) + parse_str($option, $option); + $config = array_merge($this->option, array_change_key_case($option)); + } else { + $config = $this->option; + } + $name = $this->option['prefix'] . $name; + $expire = !empty($config['expire']) ? time() + $config['expire'] : 0; + setcookie($name, $value, $expire, $config['path'], $config['domain']); + $_COOKIE[$name] = $value; + } + + public function del($name) { + $name = $this->option['prefix'] . $name; + setcookie($name, '', time() - 3600, $this->option['path'], $this->option['domain']); + // 删除指定cookie + unset($_COOKIE[$name]); + } + + public function clear() { + foreach ($_COOKIE as $key => $val) { + if (0 === stripos($key, $this->option['prefix'])) { + setcookie($key, '', time() - 3600, $this->option['prefix']['path'], $this->option['prefix']['domain']); + unset($_COOKIE[$key]); + } + } + return true; + } +} \ No newline at end of file diff --git a/ptcms/core/db.php b/ptcms/core/db.php new file mode 100644 index 0000000..8b31561 --- /dev/null +++ b/ptcms/core/db.php @@ -0,0 +1,77 @@ +pt=PT_Base::getInstance(); + } + + /** + * @param string $name + * @return Driver_Db_Dao + */ + public function getInstance($name='') { + if (self::$_config == array()) { + self::$_config = $this->parseConfig(); + } + $name=($name=='')?'__empty__':$name; + if (empty(self::$_class[$name])){ + $class='Driver_Db_'.self::$_config['type'].'_dao'; + self::$_class[$name]=new $class(self::$_config,$name); + } + return self::$_class[$name]; + } + + /** + * @param $name + * @return mixed + */ + public function table($name='') { + return $this->getInstance($name); + } + + public function parseConfig() { + $config_params['type']=$this->pt->config->get('db_type', 'mysql'); + switch($config_params['type']){ + case 'mysql': + $config_params['master'] = array( + array( + 'host' => $this->pt->config->get('db_mysql_master_host', 'localhost'), + 'port' => $this->pt->config->get('db_mysql_master_port', '3306'), + 'name' => $this->pt->config->get('db_mysql_master_name', 'ptcms'), + 'user' => $this->pt->config->get('db_mysql_master_user', 'root'), + 'pwd' => $this->pt->config->get('db_mysql_master_pwd', ''), + ) + ); + if ($this->pt->config->get('db_mysql_salve_host')){ + $config_params['singleton']=false; + $config_params['slave'] = array( + array( + 'host' => $this->pt->config->get('db_mysql_salve_host', 'localhost'), + 'port' => $this->pt->config->get('db_mysql_salve_port', '3306'), + 'name' => $this->pt->config->get('db_mysql_salve_name', 'ptcms'), + 'user' => $this->pt->config->get('db_mysql_salve_user', 'root'), + 'pwd' => $this->pt->config->get('db_mysql_salve_pwd', ''), + ) + ); + }else{ + $config_params['singleton']=true; + $config_params['slave'] = $config_params['master']; + } + $config_params['driver']=$this->pt->config->get('db_mysql_driver', 'pdo'); + $config_params['prefix']=$this->pt->config->get('db_mysql_prefix', 'ptcms_'); + $config_params['charset']=$this->pt->config->get('db_mysql_charset', 'utf8'); + break; + } + return $config_params; + } +} + diff --git a/ptcms/core/dispatcher.php b/ptcms/core/dispatcher.php index 4102677..6e2dffa 100644 --- a/ptcms/core/dispatcher.php +++ b/ptcms/core/dispatcher.php @@ -5,41 +5,53 @@ * @Email : admin@ptcms.com * @File : dispatcher.php */ -class dispatcher { +class PT_Dispatcher extends PT_Base { // 入口文件 - public static function run() { - if (!empty($_POST['s'])) $_GET['s'] = $_POST['s']; - if (!empty($_POST['m'])) $_GET['m'] = $_POST['m']; - if (!empty($_POST['c'])) $_GET['c'] = $_POST['c']; - if (!empty($_POST['a'])) $_GET['a'] = $_POST['a']; + public function run() { + // 暂时去掉post设置参数 + //if (!empty($_POST['s'])) $_GET['s'] = $_POST['s']; + //if (!empty($_POST['m'])) $_GET['m'] = $_POST['m']; + //if (!empty($_POST['c'])) $_GET['c'] = $_POST['c']; + //if (!empty($_POST['a'])) $_GET['a'] = $_POST['a']; if (empty($_GET['s'])) { //设置默认值 - $_GET['m']=empty($_GET['m'])?C('default_module', null, 'index'):$_GET['m']; - $_GET['c']=empty($_GET['c'])?C('default_controller', null, 'index'):$_GET['c']; - $_GET['a']=empty($_GET['a'])?C('default_action', null, 'index'):$_GET['a']; + $_GET['m'] = empty($_GET['m']) ? $this->config->get('default_module', 'index') : $_GET['m']; + $_GET['c'] = empty($_GET['c']) ? $this->config->get('default_controller', 'index') : $_GET['c']; + $_GET['a'] = empty($_GET['a']) ? $this->config->get('default_action', 'index') : $_GET['a']; } else { $_GET['s'] = trim($_GET['s'], '/');//去除左右的/防止干扰 - self::router();//路由校验 - self::parseSuperVar();//解析超级变量 + $this->router();//路由校验 + $this->parseSuperVar();//解析超级变量 } + $_GET['f'] = empty($_GET['f']) ? $this->config->get('default_format', 'html') : $_GET['f']; //module映射 - $mapModule = C('map_module', null, array()); + $mapModule = $this->config->get('map_module', array()); if (isset($mapModule[$_GET['m']])) { halt('当前模块已经改名', __FILE__, __LINE__ - 1); } elseif (in_array($_GET['m'], $mapModule)) { $_GET['_m'] = $_GET['m']; $_GET['m'] = array_search($_GET['m'], $mapModule); } + //过滤xss及参数前后空白 + foreach($_GET as &$v){ + $v=trim(strip_tags($v)); + } $_REQUEST = array_merge($_GET, $_POST); } // 解析超级变量 - public static function parseSuperVar() { - $param = explode('/', $_GET['s']); - $var['m'] = isset($param['0']) ? array_shift($param) : C('default_module', null, 'index'); - $var['c'] = isset($param['0']) ? array_shift($param) : C('default_controller', null, 'index'); - $var['a'] = isset($param['0']) ? array_shift($param) : C('default_action', null, 'index'); + public function parseSuperVar() { + if (strpos($_GET['s'], '.')) { + $param = explode('.', $_GET['s'], 2); + $_GET['f'] = $param['1']; + $param = explode('/', $param['0']); + } else { + $param = explode('/', $_GET['s']); + } + $var['m'] = isset($param['0']) ? array_shift($param) : $this->config->get('default_module', 'index'); + $var['c'] = isset($param['0']) ? array_shift($param) : $this->config->get('default_controller', 'index'); + $var['a'] = isset($param['0']) ? array_shift($param) : $this->config->get('default_action', 'index'); while ($k = each($param)) { $var[$k['value']] = current($param); next($param); @@ -48,8 +60,8 @@ public static function parseSuperVar() { } // 解析路由 - public static function router() { - if ($router = C('url_router')) { + public function router() { + if ($router = $this->config->get('url_router')) { foreach ($router as $rule => $url) { if (preg_match('{' . $rule . '}isU', $_GET['s'], $match)) { unset($match['0']); diff --git a/ptcms/core/filter.php b/ptcms/core/filter.php new file mode 100644 index 0000000..4a8e226 --- /dev/null +++ b/ptcms/core/filter.php @@ -0,0 +1,135 @@ +regex($value, $filter) ? $value : $default); + } + } + + public function regex($value, $rule) { + $validate = array( + //必填 + 'require' => '/.+/', + //邮箱 + 'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', + //链接 + 'url' => '/^http:\/\/[a-zA-Z0-9]+\.[a-zA-Z0-9]+[\/=\?%\-&_~`@\[\]\':+!]*([^<>\"\"])*$/', + //货币 + 'currency' => '/^\d+(\.\d+)?$/', + //数字 + 'number' => '/^\d+$/', + //邮编 + 'zip' => '/^[0-9]\d{5}$/', + //电话 + 'tel' => '/^1[\d]{10}$/', + //整型 + 'integer' => '/^[-\+]?\d+$/', + //带小数点 + 'double' => '/^[-\+]?\d+(\.\d+)?$/', + //英文字母 + 'english' => '/^[a-zA-Z]+$/', + //中文汉字 + 'chinese' => '/^[\x{4e00}-\x{9fa5}]+$/u', + //拼音 + 'pinyin' => '/^[a-zA-Z0-9\-\_]+$/', + //用户名 + 'username' => '/^(?!_)(?!.*?_$)[a-zA-Z0-9_\x{4e00}-\x{9fa5}]{3,15}$/u', + //英文字符 + 'en' => '/^[a-zA-Z0-9_\s\-\.]+$/', + //中文字符 + 'cn' => '/^[\w\s\-\x{4e00}-\x{9fa5}]+$/u', + //安全字符串 + 'safestring' => '/^[^\$\?]+$/' + ); + // 检查是否有内置的正则表达式 + if (isset($validate[ strtolower($rule) ])) $rule = $validate[ strtolower($rule) ]; + return preg_match($rule, strval($value)) === 1; + } + + //安全的剔除字符 单行等 用于搜索 链接等地方 + public function safeStrip($kw) { + if (strlen($kw) == 0) return ''; + $kw=strip_tags($kw); + $badString = '~!@#$%^&*()+|=\\{}[];\'"/<>?'; + $length = strlen($badString); + $pos = 0; + while ($pos < $length) { + $kw = str_replace($badString{$pos}, '', $kw); + $pos++; + } + return preg_replace('/([\r\n\t]+)/', '', $kw); + } + + /** + * 过滤掉html字符 + * @param string $text + * @param string $tags 允许的html标签 + * @return mixed|string + */ + public function safetext($text,$tags='br') { + $text = trim($text); + //完全过滤注释 + $text = preg_replace('//', '', $text); + //完全过滤动态代码 + $text = preg_replace('/<\?|\?' . '>/', '', $text); + //完全过滤js + $text = preg_replace('//', '', $text); + + $text = str_replace('[', '[', $text); + $text = str_replace(']', ']', $text); + $text = str_replace('|', '|', $text); + //br + $text = preg_replace('//i', '[br]', $text); + $text = preg_replace('//i', '[br]', $text); + $text = preg_replace('/(\[br\]\s*){10,}/i', '[br]', $text); + //过滤危险的属性,如:过滤on事件lang js + while (preg_match('/(<[^><]+)( lang|on|action|background|codebase|dynsrc|lowsrc)[^><]+/i', $text, $mat)) { + $text = str_replace($mat[0], $mat[1], $text); + } + while (preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i', $text, $mat)) { + $text = str_replace($mat[0], $mat[1] . $mat[3], $text); + } + //允许的HTML标签 + $text = preg_replace('/<(' . $tags . ')( [^><\[\]]*)>/i', '[\1\2]', $text); + $text = preg_replace('/<\/(' . $tags . ')>/Ui', '[/\1]', $text); + //过滤多余html + $text = preg_replace('/<\/?(html|head|meta|link|base|basefont|body|bgsound|title|style|script|form|iframe|frame|frameset|applet|id|ilayer|layer|name|script|style|xml|table|td|th|tr|i|u|strong|img|p|br|div|strong|em|ul|ol|li|dl|dd|dt|a)[^><]*>/i', '', $text); + //过滤合法的html标签 + while (preg_match('/<([a-z]+)[^><\[\]]*>[^><]*<\/\1>/i', $text, $mat)) { + $text = str_replace($mat[0], str_replace('>', ']', str_replace('<', '[', $mat[0])), $text); + } + //转换引号 + while (preg_match('/(\[[^\[\]]*=\s*)(\"|\')([^\2=\[\]]+)\2([^\[\]]*\])/i', $text, $mat)) { + $text = str_replace($mat[0], $mat[1] . '|' . $mat[3] . '|' . $mat[4], $text); + } + //过滤错误的单个引号 + while (preg_match('/\[[^\[\]]*(\"|\')[^\[\]]*\]/i', $text, $mat)) { + $text = str_replace($mat[0], str_replace($mat[1], '', $mat[0]), $text); + } + //转换其它所有不合法的 < > + $text = str_replace('<', '<', $text); + $text = str_replace('>', '>', $text); + $text = str_replace('"', '"', $text); + //反转换 + $text = str_replace('[', '<', $text); + $text = str_replace(']', '>', $text); + $text = str_replace('|', '"', $text); + //过滤多余空格 + $text = str_replace(' ', ' ', $text); + return $text; + } +} \ No newline at end of file diff --git a/ptcms/core/input.php b/ptcms/core/input.php new file mode 100644 index 0000000..8931a1a --- /dev/null +++ b/ptcms/core/input.php @@ -0,0 +1,53 @@ +param($name, $type, $default, $_GET); + } + + public function post($name, $type = 'int', $default = null) { + return $this->param($name, $type, $default, $_POST); + } + + public function request($name, $type = 'int', $default = null) { + return $this->param($name, $type, $default, $_REQUEST); + } + + public function put($name, $type = 'int', $default = null) { + static $input = null; + if ($input === null) parse_str(file_get_contents('php://input'), $input); + return $this->param($name, $type, $default, $input); + } + + public function server($name, $type = 'int', $default = null) { + return $this->param($name, $type, $default, $_SERVER); + } + + public function globals($name, $type = 'int', $default = null) { + return $this->param($name, $type, $default, $GLOBALS); + } + + public function cookie($name, $type = 'int', $default = null) { + return $this->param($this->config->get('cookie_prefix', '') . $name, $type, $default, $_COOKIE); + } + + public function session($name, $type = 'int', $default = null) { + return $this->param($name, $type, $default, $GLOBALS); + } + + public function files($name, $type = 'int', $default = null) { + return $this->param($name, $type, $default, $_FILES); + } + + public function has($name, $type = 'request') { + + } + + public function param($name, $filter = 'int', $default = null, $param = array()) { + $value = isset($param[ $name ]) ? $param[ $name ] : null; + return $this->filter->filter($value, $filter, $default); + } + + +} \ No newline at end of file diff --git a/ptcms/core/log.php b/ptcms/core/log.php index a32b017..7601702 100644 --- a/ptcms/core/log.php +++ b/ptcms/core/log.php @@ -1,7 +1,7 @@ $log) { - $file = CACHE_PATH . '/log/' . $type . '_' . date('Ymd') . '.log'; + $file = CACHE_PATH . '/log/' . $type . '_' . date('Ymd') . '.txt'; if (is_array($log)) { foreach ($log as $v) { F($file, $v, FILE_APPEND); diff --git a/ptcms/core/model.php b/ptcms/core/model.php index 2cedd17..50eb0fe 100644 --- a/ptcms/core/model.php +++ b/ptcms/core/model.php @@ -1,681 +1,133 @@ config->get('db_type')) $this->hasdb = true; + } /** - * 相关数据存储 + * __call魔法方法 用于调用db相关的方法 * - * @var array + * @param $method + * @param $args + * @return mixed */ - protected $data = array(); - - - public function __construct($tablename = '') { - //定义model字段缓存文件目录 - $this->cachePath = CACHE_PATH . '/fields'; - //获取数据库连接参数 - self::$config = $this->parseConfig(); - - if ($tablename) { - $this->setTable($tablename); - } - return true; - } - - public function __set($key, $value) { - $this->data[strtolower($key)] = $value; - } - - public function __get($key) { - return $this->data[strtolower($key)]; - } - - public function __isset($key) { - return isset($this->data[strtolower($key)]); - } - - public function __unset($key) { - unset($this->data[strtolower($key)]); - } - public function __call($method, $args) { - $method = strtolower($method); - //todo join union - if (in_array($method, array('field', 'order', 'limit', 'page', 'group', 'having', 'table', 'distinct'))) { - $this->parts[$method] = isset($args['0']) ? $args['0'] : ''; - } elseif ($method == 'where') { - foreach ($args as $v) { - if (is_string($v)) { - $this->parts['where'][] = array('_string' => $v); - } elseif (is_array($v)) { - foreach ($v as $field => $var) { - $this->parts['where'][] = array($field => $var); + if (!$this->dbhand) { + //设置table则用table实例化db 否则是按照类名来实例化db + $name = $this->table ? $this->table : substr(get_class($this), 0, -5); + $this->dbhand = $this->db($name); + } + if (method_exists($this->dbhand, $method)) { + $res=call_user_func_array(array($this->dbhand, $method), $args); + if (is_subclass_of($res,'Driver_Db_Dao')) return $this; + return $res; + } + $this->response->error('未定义的model操作', $method, 'f'); + return false; + } + + public function get($table, $id, $field = '') { + $db = $this->db($table); + if ($id == 0) return null; + if (!isset(self::$_data[$table][$id])) { + // 检索memCache,不存在则读取数据库 + self::$_data[$table][$id] = $this->cache->get($table . '.' . $id); + if (self::$_data[$table][$id] === null) { + self::$_data[$table][$id] = $db->find($id); + if (self::$_data[$table][$id]) { + //其他处理 如小说的链接 + $modelclass = strtr($table, '_', '') . 'model'; + if ($this->$modelclass && method_exists($this->$modelclass, 'dataAppend')) { + self::$_data[$table][$id] = $this->$modelclass->dataAppend(self::$_data[$table][$id]); } } - } - } elseif (in_array($method, array('count', 'max', 'min', 'avg', 'sum'))) { - $this->parts['field'] = empty($args['0']) ? '*' : $args['0']; - return $this->parseCount($method); - } elseif ($method == 'data') { - $this->data = $args['0']; - } else { - halt('不具备的Model操作' . $method); - } - return $this; - } - - public function setTable($tablename) { - $this->tableName = $this->prefix . $tablename; - $this->getTableField(); - } - - // 配置解析 - public function parseConfig() { - $params = C('DB_MYSQL', null, array()); - - //分析,检测配置文件内容 - if (!is_array($params)) { - halt('数据库配置文件必须为数组'); - } - $params = array_change_key_case($params); - - //获取数据表前缀,默认为空 - $this->prefix = (isset($params['prefix']) && $params['prefix']) ? trim($params['prefix']) : ''; - - - // 指定数据库链接引擎 - $this->driver = (isset($params['driver']) && $params['driver']) ? trim($params['driver']) : 'Pdo'; - - //分析主数据库连接参数 - $config_params = array(); - if (isset($params['master']) && is_array($params['master'])) { - $config_params['master'] = $params['master']; - } else { - halt('主库数据库配置不存在'); - } - - //分析从数据库连接参数 - if (isset($params['slave']) && $params['slave']) { - $config_params['slave'] = $params['slave']; - } else { - //当没有从库连接参数时,开启单例模式 - $this->singleton = true; - $config_params['slave'] = $config_params['master']; - } - //将数据库的用户名及密码及时从内存中注销,提高程序安全性 - unset($params); - - return $config_params; - } - - /** - * @param string $id - * @return mixed - */ - public function master($id = null) { - if (self::$master) { - return self::$master[array_rand(self::$master)]; - } - $driverclass = 'Driver_Model_' . $this->driver; - foreach (self::$config['master'] as $k => $v) { - $v = array_change_key_case($v); - self::$master[$k] = new $driverclass($v); - } - if ($this->singleton) - self::$slave = self::$master; - if ($id === null) - return self::$master[array_rand(self::$master)]; - else - return self::$master[$id]; - } - - /** - * @return mixed - */ - public function slave() { - if (self::$slave) { - return self::$slave[array_rand(self::$slave)]; - } - $driverclass = 'Driver_Model_' . $this->driver; - foreach (self::$config['slave'] as $k => $v) { - $v = array_change_key_case($v); - self::$slave[$k] = new $driverclass($v); - } - if ($this->singleton) - self::$master = self::$slave; - return self::$slave[array_rand(self::$slave)]; - } - - public function getTableField($tablename = '') { - $tablename = empty($tablename) ? $this->tableName : $tablename; - if (!$tablename) { - halt('您必须设置表名后才可以使用该方法'); - } - $cachefile = $this->cachePath . '/' . $tablename . '.php'; - if (!APP_DEBUG && is_file($cachefile)) - list($this->pk, $this->fields) = include $cachefile; - else { - $pks = $fields = array(); - if ($tableInfo = (array)$this->slave()->fetchAll("SHOW FIELDS FROM {$tablename}")) { - foreach ($tableInfo as $v) { - if ($v['Key'] == 'PRI') $pks[] = strtolower($v['Field']); - $fields[] = strtolower($v['Field']); - } - $this->pk = empty($pks) ? '' : $pks['0']; - $this->fields = $fields; - if (!APP_DEBUG) { - $cacheData = array($this->pk, $this->fields); - F($cachefile, $cacheData); - } - } else { - halt('获取表' . $tablename . '信息发送错误 ' . $this->slave()->error()); - } - } - return $this->fields; - } - - public function getPk() { - if ($this->pk === null) - $this->getTableField(); - return $this->pk; - } - - /** - * @param array $data - * @param bool $replace - * @return mixed - */ - public function insert($data = array(), $replace = false) { - if (!empty($data)) $this->data = array_merge($this->data, array_change_key_case($data)); - if ($this->tableName || $this->parts['table']) { - foreach ($this->data as $k => $v) { // 过滤参数 - if (in_array($k, $this->fields)) - $this->data[$k] = $this->parseValue($v); - else - unset($this->data[$k]); - } - $fields = array_map(array($this, 'parseKey'), array_keys($this->data)); - $this->sql = ($replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable() . '(' . implode(',', $fields) . ') VALUES (' . implode(',', $this->data) . ');'; - $this->data = $this->parts = array(); - $this->errorinfo = ''; //清空存储 - if ($this->master()->execute($this->sql)) { - return $this->master()->insertId(); - } else { - $this->errorinfo = $this->master()->errno() . ':' . $this->master()->error(); - return false; - } - } else { - halt('insert操作必须设置要操作的表'); - } - } - - /** - * @param array $data - * @return mixed - */ - public function update($data = array()) { - if (!empty($data)) $this->data = array_merge($this->data, array_change_key_case($data)); - if ($this->tableName || $this->parts['table']) { - $sets = array(); - if (!empty($this->data[$this->pk])) { //主键不允许更改 当作where条件 - $this->parts['where'][] = array($this->pk => $this->data[$this->pk]); - unset($this->data[$this->pk]); - } - if (empty($this->parts['field'])) { //通过field连贯操作限制更新的字段 - $fields = $this->fields; - } else { - $fields = is_string($this->parts['field']) ? explode(',', $this->parts['field']) : $this->parts['field']; - } - foreach ($this->data as $k => $v) { // 数据解析 - if (in_array($k, $fields)) { - $sets[] = $this->parseKey($k) . '=' . $this->parseValue($v); + $this->cache->set($table . '.' . $id, self::$_data[$table][$id], $this->config->get('cache_time', 900)); + } + } + if ($field !== '') { + if (strpos($field, '.')) { + $name = explode('.', $field); + $value = self::$_data[$table][$id]; + foreach ($name as $n) { + if (isset($value[$n])) { + $value = $value[$n]; + } else { + return null; + } } - } - $this->sql = 'UPDATE ' . $this->parseTable() . ' SET ' . implode(',', $sets) - . $this->parseWhere() - . $this->parseOrder() - . $this->parseLimit(); - $this->data = $this->parts = array(); - $this->errorinfo = ''; //清空存储 - $affectRow = $this->master()->execute($this->sql); - if ($this->master()->error()) { - $this->errorinfo = $this->master()->errno() . ':' . $this->master()->error(); - return false; - } else { - return $affectRow; - } - } else { - halt('update操作必须设置要操作的表'); - } - } - - public function delete() { - if (!empty($data)) $this->data = array_merge($this->data, array_change_key_case($data)); - if ($this->tableName || $this->parts['table']) { - $this->sql = 'DELETE FROM' . $this->parseTable() - . $this->parseWhere() - . $this->parseOrder() - . $this->parseLimit(); - $this->data = $this->parts = array(); - $this->errorinfo = ''; //清空存储 - if ($affectRow = $this->master()->execute($this->sql)) { - return $affectRow; - } else { - $this->errorinfo = $this->master()->errno() . ':' . $this->master()->error(); - return false; - } - } else { - halt('update操作必须设置要操作的表'); - } - } - - public function find($id = null) { - if (is_scalar($id)) $this->parts['where'][] = array($this->pk => $id); - $this->parts['limit'] = 1; - $this->sql = "SELECT " - . $this->parseField() . ' FROM ' - . $this->parseTable() - . $this->parseJoin() - . $this->parseWhere() - . $this->parseGroup() - . $this->parseHaving() - . $this->parseOrder() - . $this->parseLimit() - . $this->parseUnion(); - $this->data = $this->parts = array(); - $this->errorinfo = ''; //清空存储 - $row = $this->slave()->fetch($this->sql); - if (!$this->slave()->error()) { - if ($row) { - return $row; + return $value; + } elseif (strpos($field, ',')) { + //多字段获取 如"novelid,novelname" + return array_intersect_key(self::$_data[$table][$id], array_flip(explode(',', $field))); } else { - return null; - } - } else { - $this->errorinfo = $this->slave()->errno() . ':' . $this->slave()->error(); - return false; - } - } - - public function select() { - $this->sql = "SELECT " - . $this->parseField() . ' FROM ' - . $this->parseTable() - . $this->parseJoin() - . $this->parseWhere() - . $this->parseGroup() - . $this->parseHaving() - . $this->parseOrder() - . $this->parseLimit() - . $this->parseUnion(); - $this->data = $this->parts = array(); - $this->errorinfo = ''; //清空存储 - $row = $this->slave()->fetchAll($this->sql); - if (!$this->slave()->error()) { - if ($row) { - return $row; - } else { - return null; - } - } else { - $this->errorinfo = $this->slave()->errno() . ':' . $this->slave()->error(); - return false; - } - } - - public function getField($field, $isArr = false) { - if (empty($this->parts['field'])) $this->parts['field'] = $field; - if ($isArr) { - $row = $this->select(); - if ($row === false || $row === null) - return $row; - else { - $res = array(); - if ($field !== true && strpos($field, ',') === false) { - foreach ($row as $v) { - $res[] = $v[$field]; - } + //单字段 + if (isset(self::$_data[$table][$id][$field])) { + return self::$_data[$table][$id][$field]; } else { - foreach ($row as $v) { - $res[current($v)] = (count($v) == 1) ? current($v) : $v; - } + return null; } - return $res; } - } else { - $row = $this->find(); - if ($row === false || $row === null) - return $row; - elseif ($field === true) - return current($row); - elseif (isset($row[$field])) - return $row[$field]; - else - return ''; - } - } - - public function setField($field, $data) { - if (is_array($field)) { - $this->data = $field; - } elseif (is_string($field)) { - $this->data[$field] = $data; - } - $this->update(); - } - - public function setInc($field, $step = 1) { - $this->setField($field, array('exp', "{$field}+{$step}")); - } - - public function setDec($field, $step = 1) { - $this->setField($field, array('exp', "{$field}-{$step}")); - } - - /** - * 字段和表名处理添加` - * - * @access protected - * @param string $key - * @return string - */ - protected function parseKey(&$key) { - $key = trim($key); - if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { - $key = '`' . $key . '`'; } - return $key; + return self::$_data[$table][$id]; } - /** - * value分析 - * - * @access protected - * @param mixed $value - * @return string - */ - protected function parseValue($value) { - if (is_string($value)) { - $value = '\'' . $this->master()->escapeString($value) . '\''; - } elseif (isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp') { - $value = $this->master()->escapeString($value[1]); - } elseif (is_array($value)) { - $value = array_map(array($this, 'parseValue'), $value); - } elseif (is_bool($value)) { - $value = $value ? '1' : '0'; - } elseif (is_null($value)) { - $value = 'null'; - } - return $value; - } - - public function getLastSql() { - return $this->sql; - } - - public function getError() { - return $this->errorinfo; - } - - protected function parseWhere() { - if (empty($this->parts['where'])) return ' WHERE 1'; - return ' WHERE ' . $this->parseWhereCondition($this->parts['where']); - } - - protected function parseWhereCondition($condition) { - $logic = ' AND '; - $wheres = array(); - foreach ($condition as $var) { - $k = key($var); - $v = current($var); - if (in_array($k, $this->fields)) { - $wheres[] = '(' . $this->parseWhereItem($this->parseKey($k), $v) . ')'; - } elseif ($k == '_logic' && in_array(strtolower($v), array('or', 'and', 'xor'))) { - $logic = ' ' . strtoupper($v) . ' '; - } elseif ($k == '_string') { - $wheres[] = '(' . $v . ')'; - } else { - } - } - return implode($logic, $wheres); - } - - /** - * @param $field - * @param $var - * @return mixed - */ - protected function parseWhereItem($field, $var) { - if (is_array($var)) { - switch (strtolower($var['0'])) { - case '>': - case '<': - case '>=': - case '<=': - case '=': - case '<>': - case 'like': - case 'not like': - return $field . ' ' . $var['0'] . ' ' . $this->parseValue($var['1']); - case 'in': - case 'not in': - if (is_array($var['1'])) - $var['1'] = implode(',', $var['1']); - return "{$field} {$var['0']} ( {$var['1']} )"; - case 'between': - case 'not between': - if (is_string($var['1'])) - $var['1'] = explode(',', $var['1']); - return "{$field} {$var['0']} {$var['1']['0']} and {$var['1']['1']}"; - case 'exp': - return "{$field} {$var['1']}"; - default: - return ''; - } - } else { - return $field . ' = ' . $this->parseValue($var); - } - } - - protected function parseOrder() { - if (!empty($this->parts['order'])) { - if (is_string($this->parts['order'])) { - return ' ORDER BY ' . $this->parts['order']; - } - } - return ''; - } - - protected function parseGroup() { - if (!empty($this->parts['group'])) { - if (is_string($this->parts['group'])) { - return ' GROUP BY ' . $this->parseKey($this->parts['group']); - } elseif (is_array($this->parts['group'])) { - array_walk($this->parts['group'], array($this, 'parseKey')); - return ' GROUP BY ' . implode(',', $this->parts['group']); - } - } - return ''; - } - - protected function parseHaving() { - if (empty($this->parts['having'])) return ''; - return ' HAVING ' . $this->parseWhereCondition($this->parts['having']); - } - - protected function parseLimit() { - if (isset($this->parts['page'])) { - // 根据页数计算limit - if (strpos($this->parts['page'], ',')) { - list($page, $listRows) = explode(',', $this->parts['page']); - } else { - $page = $this->parts['page']; - } - $page = $page ? $page : 1; - $listRows = isset($listRows) ? $listRows : (is_numeric($this->parts['limit']) ? $this->parts['limit'] : 20); - $offset = $listRows * ((int)$page - 1); - return ' LIMIT ' . $offset . ',' . $listRows; - } elseif (!empty($this->parts['limit'])) { - return ' LIMIT ' . $this->parts['limit']; + public function set($table, $id, $data) { + $db = $this->db($table); + if ($db->where(array($db->getPk() => $id))->update($data)) { + return $this->rm($table, $id); } else { - return ''; - } - } - - protected function parseUnion() { - - } - - protected function parseJoin() { - - } - - protected function parseField() { - if (empty($this->parts['field'])) { - return '*'; - } else { - if (is_string($this->parts['field'])) { - $this->parts['field'] = explode(',', $this->parts['field']); - } - array_walk($this->parts['field'], array($this, 'parseKey')); - return implode(',', $this->parts['field']); - } - } - - protected function parseTable() { - if (empty($this->parts['table'])) { - if ($this->tableName) - return $this->parseKey($this->tableName); - else - halt('必须设置表才可以进行此操作'); - } else { - return str_replace('!@#_', self::$config['prefix'], $this->parts['table']); + return false; } } - protected function parseDistinct() { - return $this->parts['distinct'] ? ' DISTINCT ' : ''; - } - - public function parseCount($method) { - $this->parts['field'] = "{$method}({$this->parts['field']}) as pt_num"; - return $this->getField('pt_num'); - } - - public function start() { - $this->master(0)->startTrans(); - } - - public function commit() { - $this->master(0)->commit(); - } - - public function rollback() { - $this->master(0)->rollback(); - } - - public function fetch($sql) { - return $this->slave()->fetch($sql); - } - - public function fetchall($sql) { - return $this->slave()->fetchall($sql); + public function rm($table, $id) { + $this->cache->rm($table . '.' . $id); + unset(self::$_data[$table][$id]); + return true; } - -} - +} \ No newline at end of file diff --git a/ptcms/core/plugin.php b/ptcms/core/plugin.php index f91f88c..9b6c8c9 100644 --- a/ptcms/core/plugin.php +++ b/ptcms/core/plugin.php @@ -5,11 +5,15 @@ * @Email : admin@ptcms.com * @File : plugin.php */ -class plugin { +class PT_Plugin extends PT_Base { - public $tag = ''; + protected $pt; + //子类hook点 public static $_tags = array(); + public function __construct() { + $this->pt=PT_Base::getInstance(); + } /** * 调用插件 * @@ -83,6 +87,10 @@ public static function get($tag = '') { } } + /** + * 获取开启的所有的插件 + * @return array + */ public static function getlist() { $list = array(); foreach (self::$_tags as $v) { @@ -91,50 +99,19 @@ public static function getlist() { return array_unique($list); } - /** - * 安装插件 - */ - public function install() { - $name = substr(get_class($this), 0, -6); - if ($this->checkstatus($name)) { - return 0; - } elseif ($this->tag == '') { - return -1; - } - self::add($this->tag, $name); - $config = include APP_PATH . '/common/config.php'; - $config['plugin'] = self::$_tags; - F(APP_PATH . '/common/config.php', $config); - return 1; - } - - // 卸载插件 - public function uninstall() { - $name = substr(get_class($this), 0, -6); - if (!$this->checkstatus($name)) { - return 0; - } elseif ($this->tag == '') { - return -1; - } - self::del($this->tag, substr(get_class($this), 0, -6)); - $config = include APP_PATH . '/common/config.php'; - $config['plugin'] = self::$_tags; - F(APP_PATH . '/common/config.php', $config); - return 1; - } - - // 检查插件是否被安装 - public function checkstatus($plugin) { - if (substr($plugin, -4) == '.php') $plugin = substr($plugin, 0, -4); - foreach (self::$_tags as $tag) { - if (in_array($plugin, $tag)) return true; - } - return false; - } // 返回插件的配置项 - public function getconfig($key) { + public function loadconfig() { $name = substr(get_class($this), 0, -6); - return C('plugin_config.' . $name . '.' . $key); + $list=pt::import(APP_PATH.'/common/plugin/'.$name.'/config.php'); + if ($list){ + $config=array(); + foreach($list as $v){ + $config[$v['key']]=$v['value']; + } + $this->pt->config->set(array('pluginconfig'=>$config)); + return $config; + } + return array(); } } \ No newline at end of file diff --git a/ptcms/core/request.php b/ptcms/core/request.php new file mode 100644 index 0000000..ed00354 --- /dev/null +++ b/ptcms/core/request.php @@ -0,0 +1,109 @@ + 15 && $i[1] < 32) || ($i[0] == 192 && $i[1] == 168)) { + //如果是内网ip重新获取 + $keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP'); + foreach ($keys as $key) { + if (empty($_SERVER[ $key ])) continue; + $ips = explode(',', $_SERVER[ $key ], 1); + $ip = $ips[0]; + break; + } + } + $l = ip2long($ip); + if ((false !== $l) && ($ip === long2ip($l))) return $ip; + return $default; + } + + /** + * 获取host + * @param null $domain + * @return mixed|null|string + */ + public static function getSiteCode($domain = null) { + $domain = ($domain!==null) ? parse_url($domain,PHP_URL_HOST) : $_SERVER['HTTP_HOST']; + // 替换域名中的-为_ + $domain = str_replace('-', '_', $domain); + // 去掉端口 + if (strpos($domain, ':') !== false) $domain = substr($domain, 0, strpos($domain, ':')); + // 去掉开始的www. + if (stripos($domain, 'www.') === 0) $domain = substr($domain, 4); + return $domain; + } +} \ No newline at end of file diff --git a/ptcms/core/response.php b/ptcms/core/response.php new file mode 100644 index 0000000..9d9696f --- /dev/null +++ b/ptcms/core/response.php @@ -0,0 +1,215 @@ +config->get('gzip_encode', false)) { + $zlib = ini_get('zlib.output_compression'); + if (empty($zlib)) ob_start('ob_gzhandler'); + } + if (!headers_sent()) { + //设置系统的输出字符为utf-8 + header("Content-Type: $mimeType; charset=utf-8"); + //支持页面回跳 + header("Cache-control: private"); + //版权标识 + header("X-Powered-By: PTcms Studio (www.ptcms.com)"); + } + } + + public function setBody($content = '', $mimeType = 'text/html') { + if (!headers_sent()) { + $this->setHeader($mimeType); + } + echo $content; + } + + public function disableRender() { + $this->autoRender = false; + } + + public function enableRender() { + $this->autoRender = true; + } + + public function isAutoRender() { + return $this->autoRender; + } + + + public function jsonEncode($data, $format = 0) { + if (APP_DEBUG && $format == 0) { + $format = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE; + } + return json_encode($data, $format); + } + + public function jsonpEncode($data, $format = 0) { + if (APP_DEBUG && $format == 0) { + $format = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE; + } + $callback = $this->input->get($this->config->get('jsonp_callback'), 'en', 'ptcms_jsonp'); + return $callback . '(' . json_encode($data, $format) . ');'; + } + + /** + * XML编码 + * + * @param mixed $data 数据 + * @param string $root 根节点名 + * @param string $attr 根节点属性 + * @param string $encoding 数据编码 + * @return string + */ + public function xmlEncode($data, $root = 'ptcms', $attr = '', $encoding = 'utf-8') { + if (is_array($attr)) { + $_attr = array(); + foreach ($attr as $key => $value) { + $_attr[] = "{$key}=\"{$value}\""; + } + $attr = implode(' ', $_attr); + } + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = ""; + $xml .= "<{$root}{$attr}>"; + $xml .= $this->dataToXml($data); + $xml .= ""; + return preg_replace('/[\x00-\x1f]/', '', $xml); + } + + public function error($msg = '找不到指定的页面', $level = 'f') { + if (APP_DEBUG) { + halt($msg); + } else { + if ($level != 'f') { + $this->controller->error($msg, 0, 0); + } else { + $this->error($msg, '', 0); + $file = PT_ROOT . '/' . $this->config->get('404file', '404.html'); + $this->log->write($msg); + if (is_file($file)) { + $content = F($file); + $content = str_replace(array('{$sitename}', '{$siteurl}', '{$msg}'), array($this->config->get('sitename', 'PTCMS FrameWork'), $this->config->get('siteurl', PT_URL), $msg), $content); + exit($content); + } else { + exit($msg . ' 页面出现错误,如需自定义此错误,请创建文件:' . $file); + } + } + } + exit; + } + + public function _empty($msg) { + if (APP_DEBUG) { + $this->error($msg, '', 0); + } else { + halt($msg); + } + } + + public function redirect($url, $type = 302) { + if ($type == 302) { + header('HTTP/1.1 302 Moved Temporarily'); + header('Status:302 Moved Temporarily'); // 确保FastCGI模式下正常 + } else { + header('HTTP/1.1 301 Moved Permanently'); + header('Status:301 Moved Permanently'); + } + header('Location: ' . $url); + exit; + } + + public function runinfo() { + if ($this->config->get('is_gen_html')) return ''; + $tpl = $this->config->get('runinfo', 'Power by PTCMS, Processed in {time}(s), Memory usage: {mem}MB.'); + $from[] = '{time}'; + $to[] = number_format(microtime(true) - $GLOBALS['_startTime'], 3); + $from[] = '{mem}'; + $to[] = number_format((memory_get_usage() - $GLOBALS['_startUseMems']) / 1024 / 1024, 3); + if (strpos($tpl, '{net}')) { + $from[] = '{net}'; + $to[] = $GLOBALS['_apinum']; + } + if (strpos($tpl, '{file}')) { + $from[] = '{file}'; + $to[] = count(get_included_files()); + } + if (strpos($tpl, '{sql}')) { + $from[] = '{sql}'; + $to[] = $GLOBALS['_sqlnum']; + } + if (strpos($tpl, '{cacheread}')) { + $from[] = '{cacheread}'; + $to[] = $GLOBALS['_cacheRead']; + } + if (strpos($tpl, '{cachewrite}')) { + $from[] = '{cachewrite}'; + $to[] = $GLOBALS['_cacheWrite']; + } + $runtimeinfo = str_replace($from, $to, $tpl); + return $runtimeinfo; + } + + + /** + * 数据XML编码 + * + * @param mixed $data 数据 + * @param string $parentkey + * @return string + */ + protected function dataToXml($data, $parentkey = '') { + $xml = ''; + foreach ($data as $key => $val) { + if (is_numeric($key)) { + $key = $parentkey; + } + $xml .= "<{$key}>"; + if (is_array($val) || is_object($val)) { + $len = strlen("<{$key}>"); + $con = $this->dataToXml($val, $key); + if (strpos($con, "<{$key}>") === 0) { + $con = substr($con, $len, -($len + 1)); + } + $xml .= $con; + } elseif (strlen($val) > 150 || preg_match('{[<>&\'|"]+}', $val)) { + $xml .= ''; + } else { + $xml .= $val; + } + $xml .= ""; + } + return $xml; + } + + /** + * 下载文件 + * @param $con + * @param $name + * @param string $type + */ + public function download($con, $name, $type = 'file') { + $length = ($type == 'file') ? filesize($con) : strlen($con); + header("Content-type: application/octet-stream"); + header("Accept-Ranges: bytes"); + header("Content-Length: " . $length); + header('Pragma: cache'); + header('Cache-Control: public, must-revalidate, max-age=0'); + header('Content-Disposition: attachment; filename="' . urlencode($name) . '.txt"; charset=utf-8'); //下载显示的名字,注意格式 + header("Content-Transfer-Encoding: binary "); + if ($type == 'file') { + readfile($con); + } else { + echo $con; + } + } + + +} \ No newline at end of file diff --git a/ptcms/core/session.php b/ptcms/core/session.php new file mode 100644 index 0000000..153c593 --- /dev/null +++ b/ptcms/core/session.php @@ -0,0 +1,123 @@ +pt=PT_Base::getInstance(); + } + + public function start($name=array()) { + $name=array_merge($this->pt->config->get('session',array()),$name); + if ($this->pt->config->get('var_session_id') && isset($_REQUEST[$this->pt->config->get('var_session_id')])) { + session_id($_REQUEST[$this->pt->config->get('var_session_id')]); + } elseif (isset($name['id'])) { + session_id($name['id']); + } + if (empty($name['type']) && $this->pt->config->get('driver_session')){ + $name['type']=$this->pt->config->get('driver_session'); + } + if (isset($name['name'])) session_name($name['name']); + if (isset($name['path'])) session_save_path($name['path']); + if (isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']); + if (isset($name['expire'])) ini_set('session.gc_maxlifetime', $name['expire']); + if (isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid'] ? 1 : 0); + if (isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies'] ? 1 : 0); + if (isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']); + if (isset($name['cache_expire'])) session_cache_expire($name['cache_expire']); + if (isset($name['type'])){ + $type = $name['type']; + $class = 'Driver_Session_'.$type; + $hander = new $class(); + session_set_save_handler( + array(&$hander, "open"), + array(&$hander, "close"), + array(&$hander, "read"), + array(&$hander, "write"), + array(&$hander, "destroy"), + array(&$hander, "gc")); + } + session_start(); + } + + public function __set($name,$value) { + return $this->set($name,$value); + } + + public function __get($name) { + return $this->get($name); + } + + public function get($name='', $default = null) { + if ($name=='') return $_SESSION; + //数组模式 找到返回 + if (strpos($name,'.')){ + //数组模式 找到返回 + $c = $_SESSION; + $fields = explode('.', $name); + foreach($fields as $field){ + if(!isset($c[$field])) return $default; + $c = $c[$field]; + } + return $c; + }elseif (isset($_SESSION[$name])) { + return $_SESSION[$name]; + } else { + return $default; + } + } + + public function set($key, $value = '') { + $_SESSION[$key] = $value; + return true; + } + + public function rm($key) { + if (!isset($_SESSION[$key])) { + return false; + } + + unset($_SESSION[$key]); + + return true; + } + + /** + * 清空session值 + * + * @access public + * @return void + */ + public static function clear() { + + $_SESSION = array(); + } + + /** + * 注销session + * + * @access public + * @return void + */ + public static function destory() { + + if (session_id()) { + unset($_SESSION); + session_destroy(); + } + } + + /** + * 当浏览器关闭时,session将停止写入 + * + * @access public + * @return void + */ + public static function close() { + + if (session_id()) { + session_write_close(); + } + } +} \ No newline at end of file diff --git a/ptcms/core/storage.php b/ptcms/core/storage.php index 0cd5177..a9f43f2 100644 --- a/ptcms/core/storage.php +++ b/ptcms/core/storage.php @@ -5,20 +5,21 @@ * @Email : admin@ptcms.com * @File : Storage.php */ -class Storage { +class PT_Storage extends PT_Base { protected static $handler = null; /** + * @param string $type * @return Driver_Storage_File */ - static public function getInstance() { - $key = C('storage_type', null, 'file') . '_' . C('storage_path', null, 'storage'); - if (empty(self::$handler[$key])) { - $class = 'Driver_Storage_' . C('storage_type'); - self::$handler[$key] = new $class(C('storage_option', null, array())); + static public function getInstance($type = '') { + $type = $type ? $type : PT_Base::getInstance()->config->get('storage_type', 'file') . '_' . PT_Base::getInstance()->config->get('storage_path', 'storage'); + if (empty(self::$handler[$type])) { + $class = 'Driver_Storage_' . PT_Base::getInstance()->config->get('storage_type'); + self::$handler[$type] = new $class(PT_Base::getInstance()->config->get('storage_option', array())); } - return self::$handler[$key]; + return self::$handler[$type]; } public static function exist($file) { @@ -49,6 +50,10 @@ public static function getUrl($file) { return self::getInstance()->getUrl($file); } + public static function getPath($file) { + return self::getInstance()->getPath($file); + } + public static function error() { return self::getInstance()->error(); } diff --git a/ptcms/core/view.php b/ptcms/core/view.php index 2fffabb..6682998 100644 --- a/ptcms/core/view.php +++ b/ptcms/core/view.php @@ -5,44 +5,63 @@ * @Email : admin@ptcms.com * @File : view.php */ -class View { +class PT_View { // 模板存储变量 protected $_tpl_vars = array(); // 模版基地址 - protected $tplpath; - // 模版路径 - protected $tplFile; + protected $tplpath = TPL_PATH; + // 模版文件名 + protected $tplfile = ''; + // 模版全路径 + protected $tplfilepath = ''; // 模版 protected $theme = ''; + protected $pt; public function __construct() { - $this->tplpath = TPL_PATH; + $this->pt=PT_Base::getInstance(); + PT_Plugin::call('view_start'); + //初始化模版 + $this->getTheme(); } + public function setFile($file) { + $this->tplfile = $file; + } + + public function setPath($path) { + $this->tplpath = $path; + } + + /** + * 获取风格 + * + * @return mixed|string + */ public function getTheme() { //设置了默认模版名 - $this->theme = C('tpl_theme', null, 'default'); + $this->theme = $this->pt->config->get('tpl_theme', 'default'); if ($this->theme) { //值不为空 则为自动侦测目录 if (isset($_GET['t'])) { $auto = $_GET['t']; - cookie('THEME_' . MODULE_NAME, $auto, 25920000); - } elseif (cookie('THEME_' . MODULE_NAME)) { - $auto = cookie('THEME_' . MODULE_NAME); + $this->pt->cookie->set('THEME_' . MODULE_NAME, $auto, 25920000); + } elseif ($this->pt->cookie->get('THEME_' . MODULE_NAME)) { + $auto = $this->pt->cookie->get('THEME_' . MODULE_NAME); } if (isset($auto)) { if (is_dir($this->tplpath . '/' . $auto)) { $this->theme = $auto; - C('tpl_theme', $this->theme); + $this->pt->config->set('tpl_theme', $this->theme); } else { - cookie('THEME_' . MODULE_NAME, null); + $this->pt->cookie->del('THEME_' . MODULE_NAME); } } //读取模版配置文件 if ($tplconfig = pt::import($this->tplpath . '/' . $this->theme . '/config.php')) { foreach ($tplconfig as $k => $v) { - C("tplconfig.{$k}", $v['value']); + $this->pt->config->set("tplconfig.{$k}", $v['value']); } } } @@ -50,31 +69,33 @@ public function getTheme() { } /** - * 模板变量赋值 + * 模板变量赋值,支持连贯操作 * * @access public * @param mixed $var * @param mixed $value - * @return void + * @return PT_View */ - public function assign($var, $value = null) { + public function set($var, $value = null) { if (is_array($var)) { $this->_tpl_vars = array_merge($this->_tpl_vars, $var); } else { $this->_tpl_vars[$var] = $value; } + return $this; } /* * 获取模板变量值 */ - public function getassign($var) { + public function get($var = '') { + if ($var == '') return $this->_tpl_vars; if (isset($this->_tpl_vars[$var])) return $this->_tpl_vars[$var]; if (strpos($var, '.') !== false) { $arr = explode('.', $var); $tmp = $this->_tpl_vars; foreach ($arr as $v) { - if (substr($v, 0, 1) === '$') $v = $this->getassign($v); + if (substr($v, 0, 1) === '$') $v = $this->get($v); $tmp = $tmp[$v]; } if (!empty($tmp)) { @@ -84,6 +105,18 @@ public function getassign($var) { return null; } + public function __set($name, $var) { + if (!is_object($var)) return $this->set($name, $var); + return false; + } + + public function __get($name) { + if (isset($this->_tpl_vars[$name])){ + return $this->_tpl_vars[$name]; + } + return null; + } + /** * 加载并视图片段文件内容 * @@ -93,8 +126,8 @@ public function getassign($var) { * @param string $theme 所属模版 * @return string */ - public function render($tpl = null, $module = null, $theme = null) { - $this->tplFile = $this->getTplFile($tpl, $module, $theme); + public function fetch($tpl = null, $module = null, $theme = null) { + $this->tplfilepath = $this->getTplFile($tpl, $module, $theme); extract($this->_tpl_vars, EXTR_OVERWRITE); ob_start(); include $this->checkCompile(); @@ -112,358 +145,100 @@ public function render($tpl = null, $module = null, $theme = null) { * @return string */ protected function getTplFile($tpl, $module = null, $theme = null) { - $theme = ($theme === null) ? $this->theme : $theme; + $tpl = ($tpl === null) ? $this->tplfile : $tpl; + $theme = ($theme === null) ? $this->theme : $theme; $module = ($module === null) ? MODULE_NAME : $module; if (substr($tpl, 0, 1) === '/') { //绝对目录 可以设置模版 $tplfile = PT_ROOT . $tpl; - $tmpl = $this->tplpath . "/{$theme}/" . C("tpl_public", null, 'public'); + $tmpl = $this->tplpath . "/{$theme}/" . $this->pt->config->get("tpl_public", 'public'); } else { - if ($tpl == '') { + if (!$tpl) { $tpl = CONTROLLER_NAME . '_' . ACTION_NAME; } //判断模版目录 - $protect = C('tpl_protect', null, ''); - $suffix = C('tpl_suffix', null, 'html'); + $protect = $this->pt->config->get('tpl_protect', ''); + $suffix = $this->pt->config->get('tpl_suffix', 'html'); if ($theme) { // 设置了模版 模版目录为template下对应的设置的模版目录 - $tplfile = $this->tplpath . "/{$theme}/{$module}/{$protect}/{$tpl}.{$suffix}"; + $tplfile = rtrim($this->tplpath . "/{$theme}/{$module}/{$protect}", '/') . "/{$tpl}.{$suffix}"; if (!is_file($tplfile)) { //没有找到的模版默认使用default匹配一次 if (is_file($this->tplpath . "/{$theme}/{$module}/{$tpl}.{$suffix}")) { //去掉保护目录 $tplfile = $this->tplpath . "/{$theme}/{$module}/{$tpl}.{$suffix}"; - log::record('指定的模版(' . $tplfile . ')不存在,尝试使用' . $tplfile . '模版成功'); + $this->log->record('指定的模版(' . $tplfile . ')不存在,尝试使用' . $tplfile . '模版成功'); } elseif ($theme !== 'default' && is_file($this->tplpath . "/default/{$module}/{$tpl}.{$suffix}")) { //使用默认模版 - log::record('指定的模版(' . $tplfile . ')不存在,尝试使用默认模版成功'); + $this->log->record('指定的模版(' . $tplfile . ')不存在,尝试使用默认模版成功'); $tplfile = $this->tplpath . "/default/{$module}/{$tpl}.{$suffix}"; - $theme = 'default'; + $theme = 'default'; } } - $tmpl = $this->tplpath . "/{$theme}/" . C("tpl_public", null, 'public'); + $tmpl = $this->tplpath . "/{$theme}/" . $this->pt->config->get("tpl_public", 'public'); } else { //未设置模版 模版目录为对应模块的view目录 - if ($module == 'plugin') { - $tplfile = APP_PATH . "/common/plugin/" . CONTROLLER_NAME . "/view/" . ACTION_NAME . ".{$suffix}"; - } else { - $tplfile = APP_PATH . "/{$module}/view/{$tpl}.{$suffix}"; - } - $tmpl = APP_PATH . "/{$module}/view/"; + $tplfile = APP_PATH . "/{$module}/view/{$tpl}.{$suffix}"; + $tmpl = APP_PATH . "/{$module}/view/"; } } $realtpl = str_replace('\\', '/', realpath($tplfile)); if (!$realtpl) { - halt("模版{$tpl}不存在:" . $tplfile); + if (APP_DEBUG){ + halt("模版{$tpl}不存在:" . $tplfile); + }else{ + $this->pt->response->error("模版{$tpl}不存在"); + } } defined('__TMPL__') || define('__TMPL__', rtrim(PT_DIR . str_replace(PT_ROOT, '', $tmpl), '/')); return $realtpl; } - // 校验编译模板 + /** + * @return string + */ protected function checkCompile() { - $tplfile = ltrim(str_replace(array(PT_ROOT, '/application/', '/template/'), '/', $this->tplFile), '/'); + $tplfile = ltrim(str_replace(array(PT_ROOT, '/application/', '/template/'), '/', $this->tplfilepath), '/'); $compiledFile = CACHE_PATH . '/template/' . substr(str_replace('/', ',', $tplfile), 0, -5) . '.php'; - if (APP_DEBUG || !is_file($compiledFile) || filemtime($compiledFile) < filemtime($this->tplFile)) { + if (APP_DEBUG || !is_file($compiledFile) || filemtime($compiledFile) < filemtime($this->tplfilepath)) { // 获取模版内容 - $content = F($this->tplFile); - plugin::call('template_compile_start', $content); + $content = F($this->tplfilepath); + $this->pt->plugin->call('template_compile_start', $content); + $driverclass = 'Driver_View_' . $this->pt->config->get('view_driver', 'Mc'); + /* @var $driver Driver_view_MC */ + $driver = new $driverclass(); // 解析模版 - $content = $this->compile($content); + $content = $driver->compile($content); //判断是否开启layout - if (C('LAYOUT', null, false)) { - $includeFile = $this->getTplFile(C('LAYOUT_NAME', null, 'layout')); - $layout = $this->compile(F($includeFile)); - $content = str_replace('__CONTENT__', $content, $layout); + if ($this->pt->config->get('layout', false)) { + $includeFile = $this->getTplFile($this->pt->config->get('layout_name', 'layout')); + $layout = $driver->compile(F($includeFile)); + $content = str_replace('__CONTENT__', $content, $layout); } $content = '' . $this->replace($content); - plugin::call('template_compile_end', $content); + $this->pt->plugin->call('template_compile_end', $content); F($compiledFile, $content); } return $compiledFile; } - // css压缩 - public function compressCss($match) { - return ''; - } - - // js压缩 - public function compressJs($march) { - return str_replace($march['1'], compressJs($march['1']), $march['0']); - } - // 模版输出替换 protected function replace($content) { $replace = array( - '__TMPL__' => '', // 项目模板目录 - '__ROOT__' => '', // 当前网站地址 - '__APP__' => '', // 当前项目地址 - '__MODULE__' => '', - '__ACTION__' => '', // 当前操作地址 - '__SELF__' => '', // 当前页面地址 - '__URL__' => '', // 当前控制器地址 - '__PUBLIC__' => '' . '/public', // 站点公共目录 - '__RUNINFO__' => '', // 站点公共目录 + '__TMPL__' => '', // 项目模板目录 + '__ROOT__' => '', // 当前网站地址 + '__APP__' => '', // 当前项目地址 + '__MODULE__' => '', + '__ACTION__' => '', // 当前操作地址 + '__SELF__' => '', // 当前页面地址 + '__URL__' => '', // 当前控制器地址 + '__PUBLIC__' => '' . '/public', // 站点公共目录 + '__RUNINFO__' => 'pt->response->runinfo();?>', // 站点公共目录 ); - // 允许用户自定义模板的字符串替换 - $content = str_replace(array_keys($replace), array_values($replace), $content); - // 特定替换 + $content = strtr($content, $replace); // 判断是否显示runtime info 信息 return $content; } - // 编译解析 - public function compile($content) { - $left = preg_quote('{', '/'); - $right = preg_quote('}', '/'); - if (!preg_match('/' . $left . '.*?' . $right . '/s', $content)) return $content; - // 解析载入 - $content = preg_replace_callback('/' . $left . 'include\s+file\s*\=\s*(\'|\")([^\}]*?)\1\s*' . $right . '/i', array('self', 'parseInlcude'), $content); - // 解析代码 - $content = preg_replace_callback('/' . $left . '(code|php)' . $right . '(.*?)' . $left . '\/\1' . $right . '/is', array('self', 'parseEncode'), $content); - // 模板注释 - $content = preg_replace('/' . $left . '\/\*.*?\*\/' . $right . '/s', '', $content); - $content = preg_replace('/' . $left . '\/\/.*?' . $right . '/', '', $content); - // 解析变量 - $content = preg_replace_callback('/' . $left . '(\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.[\w\-]+)*))((?:\s*\|\s*[\w\:]+(?:\s*=\s*(?:@|"[^"]*"|\'[^\']*\'|#[\w\-]+|\$[\w\-]+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.[\w\-]+)*)|[^\|\:,"\'\s]*?)(?:\s*,\s*(?:@|"[^"]*"|\'[^\']*\'|#[\w\-]+|\$[\w\-]+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.[\w\-]+)*)|[^\|\:,"\'\s]*?))*)?)*)\s*' . $right . '/', array('self', 'parseVariable'), $content); - // 解析函数 - $content = preg_replace_callback('/' . $left . '(\=|~)\s*(.+?)\s*' . $right . '/', array('self', 'parseFunction'), $content); - // 解析判断 - $content = preg_replace_callback('/' . $left . '(if|else\s*if)\s+(.+?)\s*' . $right . '/', array('self', 'parseJudgment'), $content); - $content = preg_replace('/' . $left . 'else\s*' . $right . '/i', '', $content); - $content = preg_replace('/' . $left . 'sectionelse\s*' . $right . '/i', '', $content); - $content = preg_replace('/' . $left . '\/if\s*' . $right . '/i', '', $content); - // 解析链接 - $content = preg_replace_callback('/' . $left . 'link\=((?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?)(?:(?:\s+\w+\s*\=\s*(?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?))*?))\s*' . $right . '/i', array('self', 'parseLink'), $content); - // 解析微件 - $content = preg_replace_callback('/' . $left . 'block((?:\s+\w+\s*\=\s*(?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?))+)\s*' . $right . '/i', array('self', 'parseBlock'), $content); - // 解析循环 - $content = preg_replace_callback('/' . $left . 'loop\s*=([\'|"]?)(\$?\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*))\1\s*' . $right . '/i', array('self', 'parseLoop'), $content); - $content = preg_replace_callback('/' . $left . 'loop' . $right . '/i', array('self', 'parseLoop'), $content); - $content = preg_replace_callback('/' . $left . 'section((?:\s+\w+\s*\=\s*(?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?))+)\s*' . $right . '/i', array('self', 'parseSection'), $content); - $content = preg_replace('/' . $left . '\/(?:loop|section)\s*' . $right . '/i', '', $content); - // 解析标题 - $content = preg_replace('/(]*>.*?]*>.*?]*>.+?)(?=<\/title[^>]*>.*?<\/head[^>]*>)/is', '\1 - ' . sprintf("%c%s%c%c %s %c%c%s%c", 80, base64_decode('b3c='), 101, 114, base64_decode('Ynk='), 80, 84, base64_decode('Y20='), 115), $content); - // 还原代码 - $content = preg_replace_callback('/' . chr(2) . '(.*?)' . chr(3) . '/', array('self', 'parseDecode'), $content); - // 内容后续处理 - - if (!APP_DEBUG) { -// $content = preg_replace_callback('/]*>([^<]*)<\/style>/isU', array('self', 'compressCss'), $content); -// $content = preg_replace_callback('/]*>([^<]+?)<\/script>/isU', array('self', 'compressJs'), $content); -// $content = preg_replace(array("/>\s+ <'), $content); - $content = preg_replace('/\?>\s*<\?php/', '', $content); -// $content = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' '), ' ', $content); - $content = strip_whitespace($content); - } - // 返回内容 - return $content; - } - - // 解析变量名 - private function parseVar($var) { - $var = strtolower(is_array($var) ? reset($var) : trim($var)); - if (substr($var, 0, 1) !== '$') $var = '$' . $var; - if (preg_match('/^\$\w+(\.[\w\-]+)+$/', $var)) { - if (substr($var, 0, 4) === '$pt.') { - $vars = array_pad(explode('.', $var, 3), 3, ''); - switch ($vars[1]) { - case 'server': - $var = '$_SERVER[\'' . strtoupper($vars[2]) . '\']'; - break; - case 'const': - $var = strtoupper($vars[2]); - break; - case 'config': - $var = 'C("' . $vars[2] . '")'; - break; - case 'get': - $var = '$_GET[\'' . $vars[2] . '\']'; - break; - case 'post': - $var = '$_POST[\'' . $vars[2] . '\']'; - break; - case 'request': - $var = '$_REQUEST[\'' . $vars[2] . '\']'; - break; - case 'cookie': - $var = 'Cookie("' . $vars[2] . '")'; - break; - case 'getad': - // 当广告js存在时才会解析出来 否则不会解析 - if (is_file(PT_ROOT . "/public/" . C('addir') . "/" . $vars[2] . ".js")) { - $var = "''"; - } else { - $var = '""'; - } - break; - default: - $var = strtoupper($vars[1]); - break; - } - } else { - $var = preg_replace('/\.(\w+)/', '[\'\1\']', $var); - } - } - return $var; - } - - /** - * @param $string - * @param $format - * @return array - * $format中值true则按照变量解析 其他为默认值 - */ - private function parseAttribute($string, $format) { - $attribute = array('_etc' => array()); - preg_match_all('/(?:^|\s+)(\w+)\s*\=\s*(?|(")([^"]*)"|(\')([^\']*)\'|(#)(\w+)|(\$)(\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*))|()([^"\'\s]+?))(?=\s+\w+\s*\=|$)/', $string, $match); - foreach ($match[0] as $key => $value) { - $name = strtolower($match[1][$key]); - $value = trim($match[3][$key]); - if (isset($format[$name]) && is_bool($format[$name])) { - $attribute[$name] = $format[$name] ? self::parseVar($value) : $value; - } else { - switch ($match[2][$key]) { - case '#': - $value = strtoupper($value); - break; - case '$': - $value = self::parseVar($value); - break; - case '"': - case '\'': - $value = $match[2][$key] . $value . $match[2][$key]; - break; - default: - $value = is_numeric($value) ? $value : var_export($value, true); - } - if (isset($format[$name])) { - $attribute[$name] = $value; - } else { - $attribute['_etc'][$name] = $value; - } - } - } - return array_merge($format, $attribute); - } - - // 解析变量 - private function parseVariable($matches) { - $variable = self::parseVar($matches[1]); - if ($matches[2]) { - preg_match_all('/\s*\|\s*([\w\:]+)(\s*=\s*(?:@|"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^\|\:,"\'\s]*?)(?:\s*,\s*(?:@|"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^\|\:,"\'\s]*?))*)?(?=\||$)/', $matches[2], $match); - foreach ($match[0] as $key => $value) { - $function = $match[1][$key]; - if (strtolower($function) == 'parsetpl') { - return ""; - } elseif (in_array($function, array('date', 'default'))) { - $function .= 'var'; - } - $param = array($variable); - preg_match_all('/(?:=|,)\s*(?|(@)|(")([^"]*)"|(\')([^\']*)\'|(#)(\w+)|(\$)(\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*))|()([^\|\:,"\'\s]*?))(?=,|$)/', $match[2][$key], $mat); - if (array_search('@', $mat[1]) !== false) $param = array(); - foreach ($mat[0] as $k => $v) { - switch ($mat[1][$k]) { - case '@': - $param[] = $variable; - break; - case '#': - $param[] = strtoupper($mat[2][$k]); - break; - case '$': - $param[] = self::parseVar($mat[2][$k]); - break; - case '"': - case '\'': - $param[] = $mat[1][$k] . $mat[2][$k] . $mat[1][$k]; - break; - default: - $param[] = is_numeric($mat[2][$k]) ? $mat[2][$k] : var_export($mat[2][$k], true); - } - } - $variable = $function . '(' . implode(',', $param) . ')'; - } - } - return ""; - } - - - // 解析载入 - private function parseInlcude($matches) { - $includeFile = $this->getTplFile($matches['2']); - $truereturn = realpath($includeFile); - if ($truereturn) { - $content = file_get_contents($truereturn); - return $this->compile($content); - } else { - halt("include参数有误,得不到设置的模版,参数[{$matches['2']}],解析模版路径[{$includeFile}]"); - } - } - - // 解析函数 - private function parseFunction($matches) { - $operate = $matches[1] === '=' ? 'echo' : ''; - $expression = preg_replace_callback('/\$\w+(?:\.\w+)+/', array('self', 'parseVar'), $matches[2]); - return ""; - } - - // 解析判断 - private function parseJudgment($matches) { - $judge = strtolower($matches[1]) === 'if' ? 'if' : 'elseif'; - $condition = preg_replace_callback('/\$\w+(?:\.\w+)+/', array('self', 'parseVar'), $matches[2]); - return ""; - } - - // 解析链接 - private function parseLink($matches) { - $attribute = self::parseAttribute('_type_=' . $matches[1], array('_type_' => false)); - if (!is_string($attribute['_type_'])) return $matches[0]; - $var = array(); - foreach ($attribute['_etc'] as $key => $value) { - $var[] = "'$key'=>$value"; - } - return ""; - } - - // 解析微件 - private function parseBlock($matches) { - $attribute = self::parseAttribute($matches[1], array('method' => false, 'name' => false)); - if (!is_string($attribute['method'])) return $matches[0]; - $name = is_string($attribute['name']) ? '$' . $attribute['name'] : '$list'; - $var = array(); - foreach ($attribute['_etc'] as $key => $value) { - $var[] = "'$key'=>$value"; - } - if (empty($attribute['_etc']['template'])) { - return ""; - } else { - return ""; - } - } - - // 解析循环 - private function parseLoop($matches) { - $loop = empty($matches[2]) ? '$list' : (self::parseVar($matches[2])); - return "\$loop):?>"; - } - - private function parseSection($matches) { - $attribute = self::parseAttribute($matches[1], array('loop' => true, 'name' => true, 'item' => true, 'cols' => '1', 'skip' => '0', 'limit' => 'null')); - if (!is_string($attribute['loop'])) return $matches[0]; - $name = is_string($attribute['name']) ? $attribute['name'] : '$i'; - $list = is_string($attribute['item']) ? $attribute['item'] : '$loop'; - return "{$name}['list']): $list={$name}['list']; {$name}['order']++; {$name}['col']++; if({$name}['col']=={$attribute['cols']}): {$name}['col']=0; {$name}['row']++; endif; {$name}['first']={$name}['order']==1; {$name}['last']={$name}['order']=={$name}['count']; {$name}['extra']={$name}['order']>{$name}['count'];?>"; - } - - // 解析代码 - private function parseEncode($matches) { - return chr(2) . base64_encode(strtolower($matches[1]) === 'php' ? "" : trim($matches[2])) . chr(3); - } - - // 还原代码 - private function parseDecode($matches) { - return base64_decode($matches[1]); - } } /** @@ -472,7 +247,7 @@ private function parseDecode($matches) { * @return string */ function defaultvar() { - $args = func_get_args(); + $args = func_get_args(); $value = array_shift($args); if (isset($args[$value])) { return $args[$value]; @@ -490,60 +265,23 @@ function defaultvar() { * @return mixed */ function datevar($time, $format) { - if ($time=='0') return ''; + if ($time == '0') return ''; return date($format, $time); } -function compressJS($content) { - $lines = explode("\n", $content); - foreach ($lines as &$line) { - $line = trim($line) . "\n"; - } - return implode('', $lines); - /* $content = preg_replace('/{(\/\/[^\n]*)/', '{', $content); // {//注释情况特殊处理 - $content = preg_replace('/(^\/\/[^\n]*)|([\s]+\/\/[^\n]*)/', '', $content); //行注释 - $content = preg_replace('/\)\s*[\n\r]+/', ');', $content); //圆括号换行处理 - $content = preg_replace('/([\w\$\'""]+?)\s*[\n\r]+\s*([\w\$\'""]+?)/', '$1;$2', $content); //圆括号换行处理 - $content = preg_replace('/[\n\r\t]+/', ' ', $content); //换行空格等过滤 - $content = preg_replace('/>\\s<', $content); - $content = preg_replace('/\\/\\*.*?\\*\\//i', '', $content); - $content = preg_replace("/[\n\r\t]+}/", "}", $content); - $content = preg_replace("/}[\n\r\t]+/", "}", $content); - $content = preg_replace("/[\n\r\t]+{/", "{", $content); - $content = preg_replace("/{[\n\r\t]+/", "{", $content); - $content = preg_replace("/[\n\r\t]+;/", ";", $content); - $content = preg_replace("/;[\n\r\t]+/", ";", $content); - $content = preg_replace("/[\n\r\t]+:/", ":", $content); - $content = preg_replace("/:[\n\r\t]+/", ":", $content); - $content = preg_replace("/[\n\r\t]+=/", "=", $content); - $content = preg_replace("/=[\n\r\t]+/", "=", $content); - $content = preg_replace("/,[\n\r\t]{2,}/", ", ", $content); - $content = preg_replace("/[\n\r\t]{2,}/", " ", $content); - //js特殊处理补全 - $content = preg_replace("/;}/", "}", $content); - $content = preg_replace("/}var/", "};var", $content); - $content = preg_replace("/}return/", "};return", $content); - return $content;*/ -} - -function compressCss($content) { - - $content = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $content); //删除注释 - $content = preg_replace('![ ]{2,}!', ' ', $content); //删除注释 - $content = str_replace(array("\r\n", "\r", "\n", "\t"), '', $content); //删除空白 - return $content; -} - /** * @param string $content - * @param object $view View * @return string */ -function parseTpl($content, $view) { +function parseTpl($content) { $cachefile = CACHE_PATH . '/template/parsetpl/' . md5($content) . '.php'; if (!is_file($cachefile)) { - $content = $view->compile($content); + $driverclass = 'Driver_View_' . PT_Base::getInstance()->config->get('view_driver', 'Mc'); + /* @var $driver Driver_view_MC */ + $driver = new $driverclass(); + $content = $driver->compile($content); F($cachefile, $content); } return $cachefile; -} \ No newline at end of file +} + diff --git a/ptcms/driver/api/ptcms.php b/ptcms/driver/api/ptcms.php new file mode 100644 index 0000000..2b69417 --- /dev/null +++ b/ptcms/driver/api/ptcms.php @@ -0,0 +1,50 @@ +appid = $this->config->get('appid'); + $this->appkey = $this->config->get('appkey'); + } + + public function call($url, $params = array(), $method = 'GET', $header = array()) { + $params['rule'] = $this->config->get('apirule'); + $params['appid'] = $this->appid; + $params['format'] = 'json'; + $params['datetime'] = $_SERVER['REQUEST_TIME']; + $params['host'] = $_SERVER['HTTP_HOST']; + $params['sign'] = $this->sign($params); + $data = array(); + for ($i = 0; $i < 5; $i++) { + $con = ($method == 'GET') ? http::get($url, $params) : http::post($url, $params, $header); + if ($con) { + $data=json_decode($con,true); + break; + } + } + if (!empty($data) && is_array($data)) { + if ($data['status'] == 1) { + return $data['data']; + } else { + $this->log->write('调用接口出现错误!原因:' . $data['msg'] . ' 参数:' . var_export($params, true)); + } + } else { + $this->log->write('调用接口失败!方法' . $method . ' 参数:' . var_export($params, true)); + } + return array(); + } + + //对参数进行签名 + public function sign($params) { + asort($params); + $str = ''; + foreach ($params as $k => $v) { + $str .= $k . '=' . $v . '&'; + } + $str = substr($str, 0, -1); + return md5($str . $this->appkey); + } +} \ No newline at end of file diff --git a/ptcms/driver/cache/file.php b/ptcms/driver/cache/file.php index a9305ac..83e7ac6 100644 --- a/ptcms/driver/cache/file.php +++ b/ptcms/driver/cache/file.php @@ -16,13 +16,13 @@ public function set($key, $value, $time = 0) { $file = self::key2file($key); $data['data'] = $value; $data['time'] = ($time == 0) ? 0 : (NOW_TIME + $time); - return F($file, $data); + return F($file, serialize($data)); } public function get($key) { $file = self::key2file($key); if (is_file($file)) { - $data = pt::import($file); + $data = unserialize(F($file)); if ($data && ($data['time'] > 0 && $data['time'] < NOW_TIME)) { self::rm($key); return null; @@ -42,10 +42,30 @@ public function rm($key) { public function key2file($key) { $key = md5($key); - $file = CACHE_PATH . '/data/' . substr($key, 0, 1) . '/' . substr($key, 1, 2) . '/' . $key . '.php'; + $file = CACHE_PATH . '/data/cache/' . $key{0} . '/' . $key{1} . '/' . $key . '.php'; return $file; } + public function inc($key,$num=1){ + $data=$this->get($key); + if ($data){ + $data+=$num; + $this->set($key,$data); + return $data; + } + return false; + } + + public function dec($key,$num=1){ + $data=$this->get($key); + if ($data){ + $data-=$num; + $this->set($key,$data); + return $data; + } + return false; + } + public function clear() { F(CACHE_PATH . '/data'); } diff --git a/ptcms/driver/cache/memcache.php b/ptcms/driver/cache/memcache.php index 632024e..598bbf7 100644 --- a/ptcms/driver/cache/memcache.php +++ b/ptcms/driver/cache/memcache.php @@ -5,15 +5,30 @@ * @Email : admin@ptcms.com * @File : Memcache.php */ -class Driver_Cache_Memcache { +class Driver_Cache_Memcache extends PT_Base { protected static $handler = null; - protected static $prefix = null; + protected static $prefix = null; public function __construct($option = array()) { - self::$handler = new Memcache(); - self::$handler->connect(C('memcache_host', null, '127.0.0.1'), C('memcache_port', null, '11211')); - self::$prefix = C('cache_prefix', null, substr(md5(PT_URL), 0, 3) . '_'); + if ((function_exists('saeAutoLoader') or function_exists('sae_auto_load')) && function_exists('memcache_init')) { + self::$handler = memcache_init(); + } elseif (isset($_SERVER['HTTP_BAE_LOGID'])) { + include PT_PATH . '/library/bae/BaeMemcache.class.php'; + $cacheid = $this->config->get('bae_cache_id'); + $host = $this->config->get('bae_cache_host'); + $port = $this->config->get('bae_cache_port'); + $user = $this->config->get('bae_cache_user'); + $pwd = $this->config->get('bae_cache_pwd'); + self::$handler = new BaeMemcache($cacheid, $host . ': ' . $port, $user, $pwd); + } else { + self::$handler = new Memcache(); + self::$handler->connect($this->config->get('memcache_host', '127.0.0.1'), $this->config->get('memcache_port', null, '11211')); + } + if (!self::$handler) { + PT_Log::record('链接缓存驱动失败'); + } + self::$prefix = $this->config->get('cache_prefix', substr(md5(PT_URL), 3, 3) . '_'); } public function set($key, $value, $time = 0) { @@ -21,16 +36,23 @@ public function set($key, $value, $time = 0) { } public function get($key) { - if ($return=self::$handler->get(self::$prefix . $key)){ - return $return; - } - return null; + $return = self::$handler->get(self::$prefix . $key); + if ($return === false) return null; + return $return; } public function rm($key) { return self::$handler->delete(self::$prefix . $key); } + public function inc($key, $num = 1) { + return self::$handler->increment(self::$prefix . $key, $num); + } + + public function dec($key, $num = 1) { + return self::$handler->decrement(self::$prefix . $key, $num); + } + public function clear() { self::$handler->flush(); } diff --git a/ptcms/driver/db/dao.php b/ptcms/driver/db/dao.php new file mode 100644 index 0000000..ab7a741 --- /dev/null +++ b/ptcms/driver/db/dao.php @@ -0,0 +1,829 @@ +cachePath = CACHE_PATH . '/fields'; + // pt基础函数 + $this->pt = PT_Base::getInstance(); + //获取数据库连接参数 + self::$_config = $config; + if ($tablename) { + $this->setTable($tablename); + } + } + + public function __call($method, $args) { + $this->pt->response->error('不具备的Model操作' . $method); + } + + public function sum($value='') { + $value = empty($value) ? '*' : $value; + $this->parts['field'] = "sum({$value}) as pt_num"; + return $this->getField('pt_num'); + } + public function avg($value='') { + $value = empty($value) ? '*' : $value; + $this->parts['field'] = "avg({$value}) as pt_num"; + return $this->getField('pt_num'); + } + + public function min($value='') { + $value = empty($value) ? '*' : $value; + $this->parts['field'] = "min({$value}) as pt_num"; + return $this->getField('pt_num'); + } + public function max($value='') { + $value = empty($value) ? '*' : $value; + $this->parts['field'] = "max({$value}) as pt_num"; + return $this->getField('pt_num'); + } + public function count($value='') { + $value = empty($value) ? '*' : $value; + $this->parts['field'] = "count({$value}) as pt_num"; + return $this->getField('pt_num'); + } + public function where($v) { + if (is_string($v)) { + $this->parts['where'][] = array('_string' => $v); + } elseif (is_array($v)) { + foreach ($v as $field => $var) { + $this->parts['where'][] = array($field => $var); + } + } + return $this; + } + public function option($value) { + if (isset($value['where'])) $value['where']=array($value['where']); + $this->parts=$value; + return $this; + } + public function data($value) { + $this->data=$value; + return $this; + } + public function db($value) { + $this->parts['db']=$value; + return $this; + } + public function distinct($value) { + $this->parts['distinct']=$value; + return $this; + } + public function table($value) { + $this->parts['table']=$value; + return $this; + } + public function having($value) { + $this->parts['having']=$value; + return $this; + } + public function group($value) { + $this->parts['group']=$value; + return $this; + } + public function page($value) { + $this->parts['page']=$value; + return $this; + } + public function limit($value) { + $this->parts['limit']=$value; + return $this; + } + public function order($value) { + $this->parts['order']=$value; + return $this; + } + + public function field($value) { + $this->parts['field']=$value; + return $this; + } + + public function setTable($tablename) { + $this->tableName = self::$_config['prefix'] . $tablename; + $this->getTableField(); + } + + + /** + * @return mixed + */ + protected function master() { + if (self::$master) { + return self::$master; + } + $driverclass = 'Driver_Db_' . self::$_config['type'] . '_' . self::$_config['driver']; + $config = self::$_config['master'][array_rand(self::$_config['master'])]; + $config['charset'] = self::$_config['charset']; + self::$master = new $driverclass($config); + if (self::$_config['singleton']) self::$slave = self::$master; + return self::$master; + } + + /** + * @return mixed + */ + protected function slave() { + if (self::$slave) { + return self::$slave; + } + $driverclass = 'Driver_Db_' . self::$_config['type'] . '_' . self::$_config['driver']; + $config = self::$_config['slave'][array_rand(self::$_config['slave'])]; + $config['charset'] = self::$_config['charset']; + self::$slave = new $driverclass($config); + if (self::$_config['singleton']) self::$master = self::$slave; + return self::$slave; + } + + protected function getTableField($tablename = '') { + $tablename = empty($tablename) ? $this->tableName : $tablename; + if (!$tablename) { + halt('您必须设置表名后才可以使用该方法'); + } + $data = $this->pt->cache->get('tablefield_' . $tablename); + if (!APP_DEBUG && $data) { + list($this->pk, $this->fields) = $data; + } else { + $pks = $fields = array(); + $db = $this->slave(); + if ($tableInfo = (array)$db->fetchAll("SHOW FIELDS FROM {$tablename}")) { + foreach ($tableInfo as $v) { + if ($v['Key'] == 'PRI') $pks[] = strtolower($v['Field']); + $fields[] = strtolower($v['Field']); + } + $this->pk = empty($pks) ? '' : $pks['0']; + $this->fields = $fields; + if (!APP_DEBUG) { + $cacheData = array($this->pk, $this->fields); + $this->pt->cache->set('tablefield_' . $tablename, $cacheData); + } + } else { + halt('获取表' . $tablename . '信息发送错误 ' . $db->error()); + return false; + } + } + return $this->fields; + } + + public function getPk() { + if ($this->pk === null) + $this->getTableField(); + return $this->pk; + } + + /** + * @param array $data + * @param bool $replace + * @return mixed + */ + public function insert($data = array(), $replace = false) { + if (!empty($data)) $this->data = array_merge($this->data, array_change_key_case($data)); + if ($this->tableName || $this->parts['table']) { + foreach ($this->data as $k => $v) { // 过滤参数 + if (in_array($k, $this->fields)) + $this->data[$k] = $this->parseValue($v); + else + unset($this->data[$k]); + } + $fields = array_map(array($this, 'parseKey'), array_keys($this->data)); + $this->sql = ($replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable() . '(' . implode(',', $fields) . ') VALUES (' . implode(',', $this->data) . ');'; + $this->data = $this->parts = array(); + $this->errorinfo = ''; //清空存储 + $db = $this->master(); + if ($db->execute($this->sql)) { + return $db->insertId(); + } else { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } + } else { + halt('insert操作必须设置要操作的表'); + return false; + } + } + + /** + * 插入记录 + * + * @access public + * @param mixed $datas 数据 + * @param boolean $replace 是否replace + * @return false | integer + */ + public function insertAll($datas, $replace = false) { + if (!is_array($datas[0])) return false; + if ($this->tableName || $this->parts['table']) { + $values = array(); + foreach ($datas as $data) { + $value = array(); + foreach ($data as $key => $val) { + if (in_array($key, $this->fields)) + $value[$key] = $this->parseValue($val); + } + $values[] = '(' . implode(',', $value) . ')'; + } + $fields = array_map(array($this, 'parseKey'), array_keys($datas[0])); + + $this->sql = ($replace ? 'REPLACE' : 'INSERT') . ' INTO ' . $this->parseTable() . ' (' . implode(',', $fields) . ') VALUES ' . implode(',', $values); + $this->data = $this->parts = array(); + $this->errorinfo = ''; //清空存储 + $db = $this->master(); + if ($db->execute($this->sql)) { + return $db->insertId(); + } else { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } + } else { + halt('insert操作必须设置要操作的表'); + return false; + } + } + + /** + * @param array $data + * @return mixed + */ + public function update($data = array()) { + if (!empty($data)) $this->data = array_merge($this->data, array_change_key_case($data)); + if ($this->tableName || $this->parts['table']) { + $sets = array(); + if (!empty($this->data[$this->pk])) { //主键不允许更改 当作where条件 + $this->parts['where'][] = array($this->pk => $this->data[$this->pk]); + unset($this->data[$this->pk]); + } + if (empty($this->parts['field'])) { //通过field连贯操作限制更新的字段 + $fields = $this->fields; + } else { + $fields = is_string($this->parts['field']) ? explode(',', $this->parts['field']) : $this->parts['field']; + } + foreach ($this->data as $k => $v) { // 数据解析 + if (in_array($k, $fields)) { + $sets[] = $this->parseKey($k) . '=' . $this->parseValue($v); + } + } + $this->sql = 'UPDATE ' . $this->parseTable() . ' SET ' . implode(',', $sets) + . $this->parseWhere() + . $this->parseOrder() + . $this->parseLimit(); + $this->data = $this->parts = array(); + $this->errorinfo = ''; //清空存储 + $db = $this->master(); + $affectRow = $db->execute($this->sql); + if ($affectRow === false) { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } else { + return $affectRow; + } + } else { + halt('update操作必须设置要操作的表'); + return false; + } + } + + public function delete() { + if (!empty($data)) $this->data = array_merge($this->data, array_change_key_case($data)); + if ($this->tableName || $this->parts['table']) { + $this->sql = 'DELETE FROM' . $this->parseTable() + . $this->parseWhere() + . $this->parseOrder() + . $this->parseLimit(); + $this->data = $this->parts = array(); + $this->errorinfo = ''; //清空存储 + $db = $this->master(); + $affectRow = $db->execute($this->sql); + if ($affectRow === false) { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } else { + return $affectRow; + } + } else { + halt('update操作必须设置要操作的表'); + return false; + } + } + + public function find($id = null) { + if (is_scalar($id)) $this->parts['where'][] = array($this->pk => $id); + $this->parts['limit'] = 1; + $this->sql = "SELECT " . $this->parseField() . ' FROM ' + . $this->parseTable() + . $this->parseJoin() + . $this->parseWhere() + . $this->parseGroup() + . $this->parseHaving() + . $this->parseOrder() + . $this->parseLimit() + . $this->parseUnion(); + //清空存储 + $this->data = $this->parts = array(); + $this->errorinfo = ''; + //执行查询 + $db = $this->slave(); + $row = $db->fetch($this->sql); + if ($row === false) { + $this->errorinfo = $db->errno() . ':' . $db->error(); + } else { + if (!$row) { + $row = null; + } + } + return $row; + } + + public function select() { + $this->sql = "SELECT " . $this->parseField() . ' FROM ' + . $this->parseTable() + . $this->parseJoin() + . $this->parseWhere() + . $this->parseGroup() + . $this->parseHaving() + . $this->parseOrder() + . $this->parseLimit() + . $this->parseUnion(); + $this->data = $this->parts = array(); + $this->errorinfo = ''; //清空存储 + $db = $this->slave(); + $row = $db->fetchAll($this->sql); + if ($row === false) { + $this->errorinfo = $db->errno() . ':' . $db->error(); + } else { + if (!$row) { + $row = null; + } + } + return $row; + } + + /** + * 获取具体字段的值 + * + * @param $field + * @param bool $isArr 是否返回数组 + * @return mixed|null|string + */ + public function getField($field, $isArr = false) { + if (empty($this->parts['field'])) $this->parts['field'] = $field; + if ($isArr) { + $row = $this->select(); + if ($row === false || $row === null) + return $row; + else { + $res = array(); + if ($field !== true && strpos($field, ',') === false) { + foreach ($row as $v) { + $res[] = $v[$field]; + } + } else { + foreach ($row as $v) { + $res[current($v)] = (count($v) == 1) ? current($v) : $v; + } + } + return $res; + } + } else { + $row = $this->find(); + if ($row === false || $row === null) + return $row; + elseif ($field === true) + return current($row); + elseif (isset($row[$field])) + return $row[$field]; + else + return ''; + } + } + + /** + * 设置某个字段的值 + * + * @param $field + * @param $data + */ + public function setField($field, $data) { + if (is_array($field)) { + $this->data = $field; + } elseif (is_string($field)) { + $this->data[$field] = $data; + } + $this->update(); + } + + /** + * 增加数据库中某个字段值 + * + * @param $field + * @param int $step + */ + public function setInc($field, $step = 1) { + $this->setField($field, array('exp', "{$field}+{$step}")); + } + + /** + * 减少数据库中某个字段值 + * + * @param $field + * @param int $step + */ + public function setDec($field, $step = 1) { + $this->setField($field, array('exp', "{$field}-{$step}")); + } + + /** + * 字段和表名处理添加` + * + * @access protected + * @param string $key + * @return string + */ + protected function parseKey(&$key) { + $key = trim($key); + if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { + $key = '`' . $key . '`'; + } + return $key; + } + + /** + * value分析 + * + * @access protected + * @param mixed $value + * @return string + */ + protected function parseValue($value) { + if (is_string($value)) { + $value = '\'' . $this->master()->escapeString($value) . '\''; + } elseif (isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp') { + $value = $this->master()->escapeString($value[1]); + } elseif (is_array($value)) { + $value = array_map(array($this, 'parseValue'), $value); + } elseif (is_bool($value)) { + $value = $value ? '1' : '0'; + } elseif (is_null($value)) { + $value = 'null'; + } + return $value; + } + + public function getLastSql() { + return $this->sql; + } + + public function getError() { + return $this->errorinfo; + } + + protected function parseWhere() { + if (empty($this->parts['where'])) return ' WHERE 1'; + return ' WHERE ' . $this->parseWhereCondition($this->parts['where']); + } + + protected function parseWhereCondition($condition) { + $logic = ' AND '; + $wheres = array(); + foreach ($condition as $var) { + $k = key($var); + $v = current($var); + if (in_array($k, $this->fields, true)) { + $wheres[] = '(' . $this->parseWhereItem($this->parseKey($k), $v) . ')'; + } elseif ($k == '_logic' && in_array(strtolower($v), array('or', 'and', 'xor'))) { + $logic = ' ' . strtoupper($v) . ' '; + } elseif ($k == '_string') { + $wheres[] = '(' . $v . ')'; + } else { + } + } + return ($wheres === array()) ? 1 : implode($logic, $wheres); + } + + /** + * @param $field + * @param $var + * @return mixed + */ + protected function parseWhereItem($field, $var) { + if (is_array($var)) { + if (isset($_REQUEST[$field]) && is_array($_REQUEST[$field])) return $field . ' = ' . $this->parseValue(strval($var)); + switch (strtolower($var['0'])) { + case '>': + case '<': + case '>=': + case '<=': + case '=': + case '<>': + case 'like': + case 'not like': + return $field . ' ' . $var['0'] . ' ' . $this->parseValue($var['1']); + case 'in': + case 'not in': + if (empty($var['1'])) return '1'; + if (is_array($var['1'])) { + $var['1'] = implode(',', $this->parseValue($var['1'])); + } + return "{$field} {$var['0']} ( {$var['1']} )"; + case 'between': + case 'not between': + if (is_string($var['1'])) + $var['1'] = explode(',', $var['1']); + return "{$field} {$var['0']} {$var['1']['0']} and {$var['1']['1']}"; + case 'exp': + return "{$field} {$var['1']}"; + default: + return '1'; + } + } else { + return $field . ' = ' . $this->parseValue($var); + } + } + + protected function parseOrder() { + if (!empty($this->parts['order'])) { + if (is_string($this->parts['order'])) { + return ' ORDER BY ' . $this->parts['order']; + } + } + return ''; + } + + protected function parseGroup() { + if (!empty($this->parts['group'])) { + if (is_string($this->parts['group'])) { + return ' GROUP BY ' . $this->parseKey($this->parts['group']); + } elseif (is_array($this->parts['group'])) { + array_walk($this->parts['group'], array($this, 'parseKey')); + return ' GROUP BY ' . implode(',', $this->parts['group']); + } + } + return ''; + } + + protected function parseHaving() { + if (empty($this->parts['having'])) return ''; + return ' HAVING ' . $this->parseWhereCondition($this->parts['having']); + } + + protected function parseLimit() { + if (isset($this->parts['page'])) { + // 根据页数计算limit + if (strpos($this->parts['page'], ',')) { + list($page, $listRows) = explode(',', $this->parts['page']); + } else { + $page = $this->parts['page']; + } + $page = $page ? $page : 1; + $listRows = isset($listRows) ? $listRows : (is_numeric($this->parts['limit']) ? $this->parts['limit'] : 20); + $offset = $listRows * ((int)$page - 1); + return ' LIMIT ' . $offset . ',' . $listRows; + } elseif (!empty($this->parts['limit'])) { + return ' LIMIT ' . $this->parts['limit']; + } else { + return ''; + } + } + + protected function parseUnion() { + + } + + protected function parseJoin() { + + } + + protected function parseField() { + if (empty($this->parts['field'])) { + return '*'; + } else { + if (is_string($this->parts['field'])) { + $this->parts['field'] = explode(',', $this->parts['field']); + } + array_walk($this->parts['field'], array($this, 'parseKey')); + return implode(',', $this->parts['field']); + } + } + + protected function parseTable() { + if (empty($this->parts['table'])) { + if ($this->tableName) { + $table = $this->tableName; + } else { + trigger_error('必须设置表才可以进行此操作', E_USER_ERROR); + return false; + } + } else { + $table = (strpos($this->parts['table'], self::$_config['prefix']) === false) ? self::$_config['prefix'] . $this->parts['table'] : $this->parts['table']; + } + $table = $this->parseKey($table); + //判断是否带数据库 + return (empty($this->parts['db'])) ? $table : $this->parseKey($this->parts['db']) . '.' . $table; + } + + protected function parseDistinct() { + return $this->parts['distinct'] ? ' DISTINCT ' : ''; + } + + public function parseCount($method) { + $this->parts['field'] = "{$method}({$this->parts['field']}) as pt_num"; + return $this->getField('pt_num'); + } + + public function start() { + $this->master()->startTrans(); + } + + public function commit() { + $this->master()->commit(); + } + + public function rollback() { + $this->master()->rollback(); + } + + public function fetch($sql) { + $this->errorinfo = ''; //清空存储 + $db = $this->slave(); + $row = $db->fetch($sql);; + if (!$db->error()) { + if ($row) { + return $row; + } else { + return null; + } + } else { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } + } + + public function fetchall($sql) { + $this->errorinfo = ''; //清空存储 + $db = $this->slave(); + $row = $db->fetchall($sql);; + if (!$db->error()) { + if ($row) { + return $row; + } else { + return null; + } + } else { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } + } + + public function query($sql) { + $this->errorinfo = ''; //清空存储 + if (self::$_config['prefix'] != 'ptcms_' && strpos($sql, 'ptcms_')) { + $sql = str_replace('ptcms_', self::$_config['prefix'], $sql); + } + $db = $this->slave(); + if (APP_DEBUG || isset($_GET['debug'])) { + $t = microtime(true); + $row = $db->query($sql);; + $GLOBALS['_sql'][] = number_format(microtime(true) - $t, 5) . ' - ' . $sql; + } else { + $row = $db->query($sql);; + } + $GLOBALS['_sqlnum']++; + if (!$db->error()) { + if ($row || $row === 0) { + return $row; + } else { + return null; + } + } else { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } + } + + public function execute($sql) { + $this->errorinfo = ''; //清空存储 + if (self::$_config['prefix'] != 'ptcms_' && strpos($sql, 'ptcms_')) { + $sql = str_replace('ptcms_', self::$_config['prefix'], $sql); + } + $db = $this->master(); + if (APP_DEBUG || isset($_GET['debug'])) { + $t = microtime(true); + $row = $db->execute($sql);; + $GLOBALS['_sql'][] = number_format(microtime(true) - $t, 5) . ' - ' . $sql; + } else { + $row = $db->execute($sql);; + } + $GLOBALS['_sqlnum']++; + + if (!$db->error()) { + if ($row || $row === 0) { + return $row; + } else { + return null; + } + } else { + $this->errorinfo = $db->errno() . ':' . $db->error(); + return false; + } + } +} + diff --git a/ptcms/driver/db/mysql/dao.php b/ptcms/driver/db/mysql/dao.php new file mode 100644 index 0000000..6da09db --- /dev/null +++ b/ptcms/driver/db/mysql/dao.php @@ -0,0 +1,4 @@ + true - $this->db_link = @new PDO("mysql:host={$params['host']};port={$params['port']};dbname={$params['name']}", $params['user'], $params['pwd'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); + $params['charset']=empty($params['charset'])?'utf8':$params['charset']; + $this->db_link = @new PDO("mysql:host={$params['host']};port={$params['port']};dbname={$params['name']}", $params['user'], $params['pwd'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES {$params['charset']}")); if (!$this->db_link) { trigger_error($params['driver'] . ' Server connect fail!
Error Message:' . $this->error() . '
Error Code:' . $this->errno(), E_USER_ERROR); } - return true; } @@ -63,8 +61,6 @@ public function query($sql) { return false; } $result = $this->db_link->query($sql); - - $GLOBALS['_sql'][] = $sql; return $result; } @@ -74,7 +70,7 @@ public function execute($sql) { return false; } $result = $this->db_link->exec($sql); - $GLOBALS['_sql'][] = $sql; + $GLOBALS['_sqlnum']++; return $result; } @@ -85,9 +81,7 @@ public function execute($sql) { * @return string */ public function error() { - $info = $this->db_link->errorInfo(); - return $info[2]; } @@ -160,7 +154,6 @@ public function fetchAll($sql) { * @return int */ public function insertId() { - return $this->db_link->lastInsertId(); } diff --git a/ptcms/driver/model/mysqi.php b/ptcms/driver/model/mysqi.php deleted file mode 100644 index e69de29..0000000 diff --git a/ptcms/driver/model/mysql.php b/ptcms/driver/model/mysql.php deleted file mode 100644 index e69de29..0000000 diff --git a/ptcms/driver/storage/file.php b/ptcms/driver/storage/file.php index 90843f5..d624ffa 100644 --- a/ptcms/driver/storage/file.php +++ b/ptcms/driver/storage/file.php @@ -5,14 +5,14 @@ * @Email : admin@ptcms.com * @File : File.php */ -class Driver_Storage_File { +class Driver_Storage_File extends PT_Base { protected static $path = null; - protected static $url = null; + protected static $url = null; public function __construct($domain = '') { - self::$path = PT_ROOT . '/' . C('storage_path') . '/'; - self::$url = PT_DIR . '/' . C('storage_path') . '/'; + self::$path = PT_ROOT . '/' . $this->config->get('storage_path') . '/'; + self::$url = PT_DIR . '/' . $this->config->get('storage_path') . '/'; } public function exist($file) { @@ -39,6 +39,10 @@ public function getUrl($file) { return self::$url . $file; } + public function getPath($file) { + return self::$path . $file; + } + public function error() { return ''; } diff --git a/ptcms/driver/storage/ftp.php b/ptcms/driver/storage/ftp.php deleted file mode 100644 index f238ef5..0000000 --- a/ptcms/driver/storage/ftp.php +++ /dev/null @@ -1,37 +0,0 @@ -config->get('storage_path'); return self::$handler; } @@ -38,6 +38,10 @@ public function getUrl($file) { return self::$handler->getUrl(self::$domain, $file); } + public function getPath($file) { + return self::$handler->getUrl(self::$domain, $file); + } + public function error() { return self::$handler->errmsg(); } diff --git a/ptcms/driver/view/mc.php b/ptcms/driver/view/mc.php new file mode 100644 index 0000000..3b07d46 --- /dev/null +++ b/ptcms/driver/view/mc.php @@ -0,0 +1,313 @@ +', $content); + } + if (!preg_match('/' . $left . '.*?' . $right . '/s', $content)) return $content; + // 解析载入 + $content = preg_replace_callback('/' . $left . 'include\s+file\s*\=\s*(\'|\")([^\}]*?)\1\s*' . $right . '/i', array('self', 'parseInlcude'), $content); + // 解析代码 + $content = preg_replace_callback('/' . $left . '(code|php)' . $right . '(.*?)' . $left . '\/\1' . $right . '/is', array('self', 'parseEncode'), $content); + // 模板注释 + $content = preg_replace('/' . $left . '\/\*.*?\*\/' . $right . '/s', '', $content); + $content = preg_replace('/' . $left . '\/\/.*?' . $right . '/', '', $content); + // 解析变量 + $content = preg_replace_callback('/' . $left . '(\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.[\w\-]+)*))((?:\s*\|\s*[\w\:]+(?:\s*=\s*(?:@|"[^"]*"|\'[^\']*\'|#[\w\-]+|\$[\w\-]+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.[\w\-]+)*)|[^\|\:,"\'\s]*?)(?:\s*,\s*(?:@|"[^"]*"|\'[^\']*\'|#[\w\-]+|\$[\w\-]+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.[\w\-]+)*)|[^\|\:,"\'\s]*?))*)?)*)\s*' . $right . '/', array('self', 'parseVariable'), $content); + // 解析函数 + $content = preg_replace_callback('/' . $left . '(\=|~)\s*(.+?)\s*' . $right . '/', array('self', 'parseFunction'), $content); + // 解析判断 + $content = preg_replace_callback('/' . $left . '(if|else\s*if)\s+(.+?)\s*' . $right . '/', array('self', 'parseJudgment'), $content); + $content = preg_replace('/' . $left . 'else\s*' . $right . '/i', '', $content); + $content = preg_replace('/' . $left . 'sectionelse\s*' . $right . '/i', '', $content); + $content = preg_replace('/' . $left . '\/if\s*' . $right . '/i', '', $content); + // 解析链接 + $content = preg_replace_callback('/' . $left . 'link\=((?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?)(?:(?:\s+\w+\s*\=\s*(?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?))*?))\s*' . $right . '/i', array('self', 'parseLink'), $content); + // 解析微件 + $content = preg_replace_callback('/' . $left . 'block((?:\s+\w+\s*\=\s*(?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?))+)\s*' . $right . '/i', array('self', 'parseBlock'), $content); + // 解析循环 + $content = preg_replace_callback('/' . $left . 'loop\s*=([\'|"]?)(\$?\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*))\1\s*' . $right . '/i', array('self', 'parseLoop'), $content); + $content = preg_replace_callback('/' . $left . 'loop' . $right . '/i', array('self', 'parseLoop'), $content); + $content = preg_replace_callback('/' . $left . 'section((?:\s+\w+\s*\=\s*(?:"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^"\'\s]+?))+)\s*' . $right . '/i', array('self', 'parseSection'), $content); + $content = preg_replace('/' . $left . '\/(?:loop|section)\s*' . $right . '/i', '', $content); + // 解析标题 + $content = preg_replace('/(]*>.*?]*>.*?]*>.+?)(?=<\/title[^>]*>.*?<\/head[^>]*>)/is', '\1 - ' . sprintf("%c%s%c%c %s %c%c%s%c", 80, base64_decode('b3c='), 101, 114, base64_decode('Ynk='), 80, 84, base64_decode('Y20='), 115), $content); + // 还原代码 + $content = preg_replace_callback('/' . chr(2) . '(.*?)' . chr(3) . '/', array('self', 'parseDecode'), $content); + // 内容后续处理 + + /*if (!APP_DEBUG) { + $content = preg_replace_callback('/]*>([^<]*)<\/style>/isU', array('self', 'compressCss'), $content); + $content = preg_replace_callback('/]*>([^<]+?)<\/script>/isU', array('self', 'compressJs'), $content); + $content = preg_replace(array("/>\s+ <'), $content); + $content = preg_replace('/\?>\s*<\?php/', '', $content); + $content = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' '), ' ', $content); + $content = strip_whitespace($content); + }*/ + // 返回内容 + return $content; + } + + // css压缩 + public function compressCss($match) { + return ''; + } + + // js压缩 + public function compressJs($march) { + return str_replace($march['1'], compressJs($march['1']), $march['0']); + } + + // 解析变量名 + private function parseVar($var) { + $var = strtolower(is_array($var) ? reset($var) : trim($var)); + if (substr($var, 0, 1) !== '$') $var = '$' . $var; + if (preg_match('/^\$\w+(\.[\w\-]+)+$/', $var)) { + if (substr($var, 0, 4) === '$pt.') { + $vars = array_pad(explode('.', $var, 3), 3, ''); + switch ($vars[1]) { + case 'server': + $var = '$_SERVER[\'' . strtoupper($vars[2]) . '\']'; + break; + case 'const': + $var = strtoupper($vars[2]); + break; + case 'config': + $var = '$this->pt->config->get("' . $vars[2] . '")'; + break; + case 'get': + $var = '$_GET[\'' . $vars[2] . '\']'; + break; + case 'post': + $var = '$_POST[\'' . $vars[2] . '\']'; + break; + case 'request': + $var = '$_REQUEST[\'' . $vars[2] . '\']'; + break; + case 'cookie': + $var = 'Cookie("' . $vars[2] . '")'; + break; + case 'getad': + // 当广告js存在时才会解析出来 否则不会解析 + if (is_file(PT_ROOT . "/public/" . $this->pt->config->get('addir') . "/" . $vars[2] . ".js")) { + $var = "''"; + } else { + $var = '""'; + } + break; + default: + $var = strtoupper($vars[1]); + break; + } + } else { + $var = preg_replace('/\.(\w+)/', '[\'\1\']', $var); + } + } + return $var; + } + + /** + * @param $string + * @param $format + * @return array + * $format中值true则按照变量解析 其他为默认值 + */ + private function parseAttribute($string, $format) { + $attribute = array('_etc' => array()); + preg_match_all('/(?:^|\s+)(\w+)\s*\=\s*(?|(")([^"]*)"|(\')([^\']*)\'|(#)(\w+)|(\$)(\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*))|()([^"\'\s]+?))(?=\s+\w+\s*\=|$)/', $string, $match); + foreach ($match[0] as $key => $value) { + $name = strtolower($match[1][$key]); + $value = trim($match[3][$key]); + if (isset($format[$name]) && is_bool($format[$name])) { + $attribute[$name] = $format[$name] ? self::parseVar($value) : $value; + } else { + switch ($match[2][$key]) { + case '#': + $value = strtoupper($value); + break; + case '$': + $value = self::parseVar($value); + break; + case '"': + case '\'': + $value = $match[2][$key] . $value . $match[2][$key]; + break; + default: + $value = is_numeric($value) ? $value : var_export($value, true); + } + if (isset($format[$name])) { + $attribute[$name] = $value; + } else { + $attribute['_etc'][$name] = $value; + } + } + } + return array_merge($format, $attribute); + } + + // 解析变量 + private function parseVariable($matches) { + $variable = self::parseVar($matches[1]); + if ($matches[2]) { + preg_match_all('/\s*\|\s*([\w\:]+)(\s*=\s*(?:@|"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^\|\:,"\'\s]*?)(?:\s*,\s*(?:@|"[^"]*"|\'[^\']*\'|#\w+|\$\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*)|[^\|\:,"\'\s]*?))*)?(?=\||$)/', $matches[2], $match); + foreach ($match[0] as $key => $value) { + $function = $match[1][$key]; + if (strtolower($function) == 'parsetpl') { + return ""; + } elseif (in_array($function, array('date', 'default'))) { + $function .= 'var'; + } + $param = array($variable); + preg_match_all('/(?:=|,)\s*(?|(@)|(")([^"]*)"|(\')([^\']*)\'|(#)(\w+)|(\$)(\w+(?:(?:\[(?:[^\[\]]+|(?R))*\])*|(?:\.\w+)*))|()([^\|\:,"\'\s]*?))(?=,|$)/', $match[2][$key], $mat); + if (array_search('@', $mat[1]) !== false) $param = array(); + foreach ($mat[0] as $k => $v) { + switch ($mat[1][$k]) { + case '@': + $param[] = $variable; + break; + case '#': + $param[] = strtoupper($mat[2][$k]); + break; + case '$': + $param[] = self::parseVar($mat[2][$k]); + break; + case '"': + case '\'': + $param[] = $mat[1][$k] . $mat[2][$k] . $mat[1][$k]; + break; + default: + $param[] = is_numeric($mat[2][$k]) ? $mat[2][$k] : var_export($mat[2][$k], true); + } + } + $variable = $function . '(' . implode(',', $param) . ')'; + } + } + return ""; + } + + + // 解析载入 + private function parseInlcude($matches) { + //20141215 防止写空导致调用死循环 + if ($matches['2']) { + $includeFile = $this->getTplFile($matches['2']); + $truereturn = realpath($includeFile); + if ($truereturn) { + $content = file_get_contents($truereturn); + return $this->compile($content); + } + halt("include参数有误,得不到设置的模版,参数[{$matches['2']}],解析模版路径[{$includeFile}]"); + } + return ''; + } + + // 解析函数 + private function parseFunction($matches) { + $operate = $matches[1] === '=' ? 'echo' : ''; + $expression = preg_replace_callback('/\$\w+(?:\.\w+)+/', array('self', 'parseVar'), $matches[2]); + return ""; + } + + // 解析判断 + private function parseJudgment($matches) { + $judge = strtolower($matches[1]) === 'if' ? 'if' : 'elseif'; + $condition = preg_replace_callback('/\$\w+(?:\.\w+)+/', array('self', 'parseVar'), $matches[2]); + return ""; + } + + // 解析链接 + private function parseLink($matches) { + $attribute = self::parseAttribute('_type_=' . $matches[1], array('_type_' => false)); + if (!is_string($attribute['_type_'])) return $matches[0]; + $var = array(); + foreach ($attribute['_etc'] as $key => $value) { + $var[] = "'$key'=>$value"; + } + return ""; + } + + // 解析微件 + private function parseBlock($matches) { + $attribute = self::parseAttribute($matches[1], array('method' => false, 'name' => false)); + $var = array(); + foreach ($attribute['_etc'] as $key => $value) { + $var[] = "'$key'=>$value"; + } + if (empty($attribute['name']) || $attribute['name'] === false) { + return "pt->block->getdata('{$attribute['method']}',array(" . implode(',', $var) . "));?>"; + } else { + $name = '$' . $attribute['name']; + return "pt->block->getdata('{$attribute['method']}',array(" . implode(',', $var) . "));?>"; + } + } + + // 解析循环 + private function parseLoop($matches) { + $loop = empty($matches[2]) ? '$list' : (self::parseVar($matches[2])); + return "\$loop):?>"; + } + + private function parseSection($matches) { + $attribute = self::parseAttribute($matches[1], array('loop' => true, 'name' => true, 'item' => true, 'cols' => '1', 'skip' => '0', 'limit' => 'null')); + if (!is_string($attribute['loop'])) return $matches[0]; + $name = is_string($attribute['name']) ? $attribute['name'] : '$i'; + $list = is_string($attribute['item']) ? $attribute['item'] : '$loop'; + return "{$name}['list']): $list={$name}['list']; {$name}['order']++; {$name}['col']++; if({$name}['col']=={$attribute['cols']}): {$name}['col']=0; {$name}['row']++; endif; {$name}['first']={$name}['order']==1; {$name}['last']={$name}['order']=={$name}['count']; {$name}['extra']={$name}['order']>{$name}['count'];?>"; + } + + // 解析代码 + private function parseEncode($matches) { + return chr(2) . base64_encode(strtolower($matches[1]) === 'php' ? "" : trim($matches[2])) . chr(3); + } + + // 还原代码 + private function parseDecode($matches) { + return base64_decode($matches[1]); + } +} + + +function compressJS($content) { + $lines = explode("\n", $content); + foreach ($lines as &$line) { + $line = trim($line) . "\n"; + } + return implode('', $lines); + /* $content = preg_replace('/{(\/\/[^\n]*)/', '{', $content); // {//注释情况特殊处理 + $content = preg_replace('/(^\/\/[^\n]*)|([\s]+\/\/[^\n]*)/', '', $content); //行注释 + $content = preg_replace('/\)\s*[\n\r]+/', ');', $content); //圆括号换行处理 + $content = preg_replace('/([\w\$\'""]+?)\s*[\n\r]+\s*([\w\$\'""]+?)/', '$1;$2', $content); //圆括号换行处理 + $content = preg_replace('/[\n\r\t]+/', ' ', $content); //换行空格等过滤 + $content = preg_replace('/>\\s<', $content); + $content = preg_replace('/\\/\\*.*?\\*\\//i', '', $content); + $content = preg_replace("/[\n\r\t]+}/", "}", $content); + $content = preg_replace("/}[\n\r\t]+/", "}", $content); + $content = preg_replace("/[\n\r\t]+{/", "{", $content); + $content = preg_replace("/{[\n\r\t]+/", "{", $content); + $content = preg_replace("/[\n\r\t]+;/", ";", $content); + $content = preg_replace("/;[\n\r\t]+/", ";", $content); + $content = preg_replace("/[\n\r\t]+:/", ":", $content); + $content = preg_replace("/:[\n\r\t]+/", ":", $content); + $content = preg_replace("/[\n\r\t]+=/", "=", $content); + $content = preg_replace("/=[\n\r\t]+/", "=", $content); + $content = preg_replace("/,[\n\r\t]{2,}/", ", ", $content); + $content = preg_replace("/[\n\r\t]{2,}/", " ", $content); + //js特殊处理补全 + $content = preg_replace("/;}/", "}", $content); + $content = preg_replace("/}var/", "};var", $content); + $content = preg_replace("/}return/", "};return", $content); + return $content;*/ +} + +function compressCss($content) { + + $content = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $content); //删除注释 + $content = preg_replace('![ ]{2,}!', ' ', $content); //删除注释 + $content = str_replace(array("\r\n", "\r", "\n", "\t"), '', $content); //删除空白 + return $content; +} diff --git a/ptcms/library/apiclient.php b/ptcms/library/apiclient.php index 4f68d7d..94ac449 100644 --- a/ptcms/library/apiclient.php +++ b/ptcms/library/apiclient.php @@ -15,18 +15,30 @@ public function __construct($apiuri, $apiid, $apikey) { $this->apiurl = $apiuri; } - // 调用API public function __call($method, $params = array()) { - $params = ($params == array()) ? array() : $params['0']; + $params=($params == array()) ? array() : $params['0']; + return $this->call($method,$params); + } + + // 调用API + public function call($method, $params = array()) { + $url=$this->apiurl; + if (strpos($method,'/')){ + $tmp=explode('/',$method,2); + $url.='/'.$tmp['0']; + $method=$tmp['1']; + } $params['action'] = $method; $params['appid'] = $this->appid; $params['format'] = 'json'; $params['datetime'] = $_SERVER['REQUEST_TIME']; $params['sign'] = $this->sign($params); //自动重试5次 防止失败! + $data = array(); for ($i = 0; $i < 5; $i++) { - $data = json_decode(http::get($this->apiurl, $params), true); - if (is_array($data)) { + $con = http::get($url, $params); + if ($con) { + $data = json_decode($con, true); break; } } @@ -34,10 +46,10 @@ public function __call($method, $params = array()) { if ($data['status'] == 1) { return $data['data']; } else { - log::write('调用接口失败!原因:' . $data['msg'] . ' 参数:' . var_export($params, true)); + PT_Log::write('调用接口出现错误!原因:' . $data['msg'] . ' 参数:' . var_export($params, true)); } } else { - log::write('调用接口失败!方法' . $method . ' 参数:' . var_export($params, true)); + PT_Log::write('调用接口失败!方法' . $method . ' 参数:' . var_export($params, true)); } return array(); } diff --git a/ptcms/library/bae/BaeImageService.class.php b/ptcms/library/bae/BaeImageService.class.php new file mode 100644 index 0000000..0ee1139 --- /dev/null +++ b/ptcms/library/bae/BaeImageService.class.php @@ -0,0 +1,1399 @@ + 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_SYS => 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL => 'php sdk init error', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM => 'param invalid', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR + => 'http status is error, and the body returned is not a json string', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR + => 'http status is ok, but the body returned is not a json string', + ); + + + public function getRequestId() + { + return $this->_requestId; + } + + public function __construct($accessKey, $secretKey, $host) + { + $this->paramArr = array(); + + if (is_null($accessKey) || $this->_checkString($accessKey, 1, 64)) { + $this->_clientId = $accessKey; + } else { + throw new BaeException("invalid param - access key[${accessKey}], which must be a 1 - 64 length string", + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL); + } + + if (is_null($secretKey) || $this->_checkString($secretKey, 1, 64)) { + $this->_clientSecret = $secretKey; + } else { + throw new BaeException("invalid param - secret key[${secretKey}], which must be a 1 - 64 length string", + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL); + } + + if (is_null($host) || $this->_checkString($host, 1, 1024)) { + if (!is_null($host)) { + $this->_host = $host; + } + } else { + throw new BaeException("invalid param - host[${host}], which must be a 1 - 1024 length string", + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL); + } + $this->_resetErrorStatus(); + + } + + private function _get_ak_sk_host(&$opt, $opt_key, $member, $g_key, $env_key, $min, $max) + { + $dis = array( + 'client_id' => 'access_key', + 'client_secret' => 'secret_key', + 'host' => 'host' + ); + + global $$g_key; + + if (isset($opt[$opt_key])) { + if (!$this->_checkString($opt[$opt_key], $min, $max)) { + throw new BaeException('invalid ' . $dis[$opt_key] . ' in $optinal(' + . $opt[$opt_key] . '), which must be a ' . $min . ' - ' . $max . ' length string', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + return; + } + if ($this->_checkString($member, $min, $max)) { + $opt[$opt_key]= $member; + return; + } + if (isset($$g_key)) { + if (!$this->_checkString($$g_key, $min, $max)) { + throw new BaeException('invalid ' . $g_key . ' in global area(' + . $$g_key . '), which must be a ' . $min . ' - ' . $max . ' length string', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $opt[$opt_key]= $$g_key; + return; + } + if (false !== getenv($env_key)) { + if (! $this->_checkString(getenv($env_key), $min, $max)) { + throw new BaeException('invalid ' . $env_key . ' in environment variable(' + . getenv($env_key). '), which must be a ' . $min . ' - ' . $max . ' length string', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $opt[$opt_key]= getenv($env_key); + return; + } + if ($opt_key === self::HOST) { + $opt[$opt_key]= self::DEFAULT_HOST; + return; + } + + throw new BaeException('no param(' . $dis[$opt_key] . ')was found', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + + private function _adjustOpt(&$opt) + { + if (! isset($opt) || empty($opt) || !is_array($opt)) { + throw new BaeException('no params are set', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if (!isset($opt[self::TIMESTAMP])) { + $opt[self::TIMESTAMP]= time(); + } + + $this->_get_ak_sk_host($opt, self::ACCESS_KEY, $this->_clientId, + 'g_accessKey', 'HTTP_BAE_ENV_AK', 1, 64); + $this->_get_ak_sk_host($opt, self::SECRET_KEY, $this->_clientSecret, + 'g_secretKey', 'HTTP_BAE_ENV_SK', 1, 64); + $this->_get_ak_sk_host($opt, self::HOST, $this->_host, + 'g_host', 'HTTP_BAE_ENV_ADDR_BUS', 1, 1024); + } + + private function _getSign(&$opt, &$arrContent, $arrNeed = array()) + { + $arrData = array(); + $arrContent = array(); + $arrNeed[] = self::TIMESTAMP; + $arrNeed[] = self::METHOD; + $arrNeed[] = self::ACCESS_KEY; + if (isset($opt[self::EXPIRES])) { + $arrNeed[] = self::EXPIRES; + } + if (isset($opt[self::VERSION])) { + $arrNeed[] = self::VERSION; + } + + $arrExclude = array(self::HOST, self::SECRET_KEY); + foreach ($arrNeed as $key) { + if (!isset($opt[$key]) || (!is_integer($opt[$key]) && empty($opt[$key]))) { + throw new BaeException("lack param(${key})", BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if (in_array($key, $arrExclude)) { + continue; + } + $arrData[$key] = $opt[$key]; + $arrContent[$key] = $opt[$key]; + } + foreach ($opt as $key => $value) { + if (!in_array($key, $arrNeed) && !in_array($key, $arrExclude)) { + $arrData[$key]= $value; + $arrContent[$key]= $value; + } + } + ksort($arrData); + $url = 'http://' . $opt[self::HOST] . '/rest/2.0/' . self::PRODUCT . '/'; + if (isset($opt[self::RESOURCE]) && !is_null($opt[self::RESOURCE])){ + $url .= $opt[self::RESOURCE]; + $arrContent[self::RESOURCE]= $opt[self::RESOURCE]; + }else { + $url .= self::RESOURCE; + } + $basicString = 'POST' . $url; + foreach ($arrData as $key => $value) { + $basicString .= $key . '=' . $value; + } + $basicString .= $opt[self::SECRET_KEY]; + + $sign = md5(urlencode($basicString)); + $arrContent[self::SIGN] = $sign; + $arrContent[self::HOST] = $opt[self::HOST]; + } + + private function _baseControl($opt) + { + $content = ''; + $resource = self::RESOURCE; + if (isset($opt[self::RESOURCE]) && !is_null($opt[self::RESOURCE])) { + $resource = $opt[self::RESOURCE]; + } + + $host = $opt[self::HOST]; + unset($opt[self::HOST]); + + foreach ($opt as $k => $v) { + if (is_string($v)) { + $v = urlencode($v); + } + $content .= $k . '=' . $v . '&'; + } + $content = substr($content, 0, strlen($content)- 1); + $url = 'http://' . $host . '/rest/2.0/' . self::PRODUCT . '/'; + $url .= $resource; + + $request = new RequestCore($url); + $headers['Content-Type'] = 'application/x-www-form-urlencoded'; + $headers['User-Agent'] = 'Baidu ImageUi Phpsdk Client'; + foreach ($headers as $headerKey => $headerValue) { + $headerValue = str_replace(array("\r", "\n"), '', $headerValue); + if ($headerValue !== '') { + $request->add_header($headerKey, $headerValue); + } + } + $request->set_method('POST'); + $request->set_body($content); + $request->send_request(); + return new ResponseCore($request->get_response_header(), + $request->get_response_body(), + $request->get_response_code()); + } + + + private function _commonProcess($paramOpt = NULL, $arrNeed = array()) + { + $this->_adjustOpt($paramOpt); + $arrContent = array(); + $this->_getSign($paramOpt, $arrContent, $arrNeed); + /****************************debug**********************/ + //var_dump($arrContent); + $ret = $this->_baseControl($arrContent); + if (empty($ret)) { + throw new BaeException('base control returned empty object', BaeImageConstant::BAE_IMAGEUI_SDK_SYS); + } + if ($ret->isOK()) { + $result = json_decode($ret->body, true); + if (is_null($result)) { + throw new BaeException($ret->body, + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR); + } + $this->_requestId = $result['request_id']; + + return $result; + } + $result = json_decode($ret->body, true); + if (is_null($result)) { + throw new BaeException('ret body: ' . $ret->body, + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR); + } + $this->_requestId = $result['request_id']; + + trigger_error("request_id : " . $this->_requestId . ", fail . error_msg: " + . $result['error_msg'].", error_code: " . $result['error_code'], + E_USER_WARNING); + throw new BaeException($result['error_msg'], $result['error_code']); + } + + /** + * Apply transforms into an image + * @param baeImageSource array

image source, + * contains image source or image url

+ * @param baeImageTransform BaeImageTransform,

contains variety transforms

+ * @param isURL bool

true for image source is URL, false for image + * byte string

+ * @return Image-relevant data,if success, otherwise return false + */ + public function applyTransformByObject($baeImageSource, $baeImageTransform) + { + $isURL=true; + $URL = ''; + $this->_resetErrorStatus(); + try { + if(empty($baeImageTransform) || !($baeImageTransform instanceof BaeImageTransform)){ + throw new BaeException('input source is not an instance of BaeImageTransform', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($baeImageTransform->errcode !== 0){ + $this->errcode = $baeImageTransform->errcode; + $this->errmsg = $baeImageTransform->errmsg; + return false; + + } + if(empty($baeImageSource)){ + throw new BaeException('no bae image source', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + + /********************examming url pattern*******************************/ + if($isURL === true){ + $this->_examURL($baeImageSource); + $URL = $baeImageSource; + }else{ + //restrict image into 2M + if(!$this->_checkString($baeImageSource, 0, 2*1024*1024)){ + throw new BaeException('image must be less than 2M', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + $paramArr = $baeImageTransform->getOperations();// obtain the operations setting on the image + $paramArr['src'] = $URL; + $arrArgs = array( + self::METHOD => 'process',/*'appid'=>"appid7avderfd05",'dev_uid'=>'12345','secret_key'=>'pNceSAlS4HB8fToDilmXQvwSc6nHInHW',*/ + ); + $arrArgs = array_merge($arrArgs, $paramArr); + return $this->_commonProcess($arrArgs,array('src',)); + + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + + } + + /** + * Apply transforms into an image + * @param image string

image source, + * contains image source or image url

+ * @param params array

options operating into an image

+ * @param isURL bool

true for image source is URL, false for image + * byte string

+ * @return Image-relevant data,if success, otherwise return false + * + */ + public function applyTransform($baeImageSource, $params=array()) + { + $isURL=true; + $URL = ''; + $baeImageTransform = new BaeImageTransform(); + $this->_resetErrorStatus(); + try{ + if(!is_array($params)){ + throw new BaeException(sprintf('invalid parameters, [%s] should be array', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + + if (!empty($params)){ + foreach ($params as $key => $value){ + if(!is_string($key)){ + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch($key){ + case BaeImageConstant::TRANSFORM_ZOOMING: + if(!is_array($value) || count($value) < 2 || count($value) > 3){ + throw new BaeException('invalid zooming param', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(count($value) == 3){ + $baeImageTransform->setZooming($value[0], $value[1],$value[2]); + }else{ + $baeImageTransform->setZooming($value[0], $value[1]); + } + break; + case BaeImageConstant::TRANSFORM_CROPPING: + if(!is_array($value) || count($value) != 4){ + throw new BaeException('invalid cropping param', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $baeImageTransform->setCropping($value[0], $value[1], $value[2], $value[3]); + break; + case BaeImageConstant::TRANSFORM_ROTATE: + $baeImageTransform->setRotation($value); + break; + case BaeImageConstant::TRANSFORM_HUE: + $baeImageTransform->setHue($value); + break; + case BaeImageConstant::TRANSFORM_LIGHTNESS: + $baeImageTransform->setLightness($value); + break; + case BaeImageConstant::TRANSFORM_CONTRAST: + $baeImageTransform->setContrast($value); + break; + case BaeImageConstant::TRANSFORM_SHARPNESS: + $baeImageTransform->setSharpness($value); + break; + case BaeImageConstant::TRANSFORM_SATURATION: + $baeImageTransform->setSaturation($value); + break; + case BaeImageConstant::TRANSFORM_TRANSCODE: + if(!is_array($value) || count($value) > 2 || count($value) == 0){ + throw new BaeException('invalid transcode param', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(count($value) == 2){ + $baeImageTransform->setTranscoding($value[0], $value[1]); + }else{ + $baeImageTransform->setTranscoding($value[0]); + } + break; + case BaeImageConstant::TRANSFORM_QUALITY: + $baeImageTransform->setQuality($value); + break; + case BaeImageConstant::TRANSFORM_GETGIFFIRSTFRAME: + $baeImageTransform->setGetGifFirstFrame(); + break; + case BaeImageConstant::TRANSFORM_HORIZONTALFLIP: + $baeImageTransform->horizontalFlip(); + break; + case BaeImageConstant::TRANSFORM_VERTICALFLIP: + $baeImageTransform->verticalFlip(); + break; + case BaeImageConstant::TRANSFORM_AUTOROTATE: + $baeImageTransform->setAutorotate(); + break; + case BaeImageConstant::TRANSFORM_CLEAROPERATIONS: + $baeImageTransform->clearOperations(); + break; + default: + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + } + if($baeImageTransform->errcode !== 0){ + $this->errcode = $baeImageTransform->errcode; + $this->errmsg = $baeImageTransform->errmsg; + return false; + } + if(empty($baeImageSource)){ + throw new BaeException('no bae image source', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + // handle the baeImageSource + if($isURL === true){ + $this->_examURL($baeImageSource); + $URL = $baeImageSource; + }else{ + //restrict image into 2M + if(!$this->_checkString($baeImageSource, 0, 2*1024*1024)){ + throw new BaeException('image must be less than 2M', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + unset($params); + $params = $baeImageTransform->getOperations(); + $params['src'] = $URL; + $arrArgs = array( + self::METHOD => 'process',); + $arrArgs = array_merge($arrArgs, $params); + return $this->_commonProcess($arrArgs,array('src',)); + + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + } + + + /** + * Apply an annotation into an image + * @param baeImageSource string,

image source or image url

+ * @param isURL bool,

true for $image field + * is URL, false for image byte string

+ * @param baeImageAnnotate BaeImageAnnotate, contains variety of + * operations about annotation. + * @return Image-relevant data,if success, otherwise return false + */ + public function applyAnnotateByObject($baeImageSource, $baeImageAnnotate) + { + $isURL=true; + $URL = ''; + $this->_resetErrorStatus(); + try { + if(empty($baeImageAnnotate) || !($baeImageAnnotate instanceof BaeImageAnnotate)){ + throw new BaeException('input source is not an instance of BaeImageAnnotate', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($baeImageAnnotate->errcode !== 0){ + $this->errcode = $baeImageAnnotate->errcode; + $this->errmsg = $baeImageAnnotate->errmsg; + return false; + } + if(empty($baeImageSource)){ + throw new BaeException('no bae image source', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + /********************examming url pattern*******************************/ + if($isURL === true){ + $this->_examURL($baeImageSource); + $URL = $baeImageSource; + }else{ + if(!$this->_checkString($baeImageSource, 0, 2*1024*1024)){ + throw new BaeException('image must be less than 2M', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + $operations = $baeImageAnnotate->getOperations(); + + // $operations must contain text + if (empty($operations['text'])) { + throw new BaeException('no text script', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $jsonParams = $this->_formJsonParams($URL, $operations, $this->ProcType_Annotate, true); + $paramArr = array('strudata'=>$jsonParams); + $arrArgs = array( + self::METHOD => 'processExt',/*'appid'=>"appid7avderfd05",'dev_uid'=>'12345','secret_key'=>'pNceSAlS4HB8fToDilmXQvwSc6nHInHW',*/ + ); + $arrArgs = array_merge($arrArgs, $paramArr); + return $this->_commonProcess($arrArgs); + + }catch (Exception $ex) { + //echo "exception:". $ex->getMessage(); + $this->_exceptionHandler($ex); + return false; + } + } + + /** + * Apply an annotation into an image + * @param image string,

image source or image url

+ * @param isURL bool,

true for $image field + * is URL, false for image data source

+ * @param params array,

contains variety of + * operations about annotation

+ * @return Image-relevant data,if success, otherwise return false + */ + public function applyAnnotate($baeImageSource, $text, $params=array()) + { + $isURL=true; + $URL = ''; + $baeImageAnnotate = new BaeImageAnnotate(); + $this->_resetErrorStatus(); + try{ + if(!is_array($params)){ + throw new BaeException(sprintf('invalid parameters, [%s] should be array', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if (!empty($params)) { + foreach ($params as $key => $value){ + if(!is_string($key)){ + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch($key){ + case BaeImageConstant::ANNOTATE_OPACITY: + $baeImageAnnotate->setOpacity($value); + break; + case BaeImageConstant::ANNOTATE_OUTPUTCODE: + $baeImageAnnotate->setOutputCode($value); + break; + case BaeImageConstant::ANNOTATE_QUALITY: + $baeImageAnnotate->setQuality($value); + break; + case BaeImageConstant::ANNOTATE_FONT: + if(!is_array($value) || count($value) != 3){ + throw new BaeException('invalid font param', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $baeImageAnnotate->setFont($value[0],$value[1],$value[2]); + break; + case BaeImageConstant::ANNOTATE_POS: + if(!is_array($value) || count($value) != 2){ + throw new BaeException('invalid pos param', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $baeImageAnnotate->setPos($value[0],$value[1]); + break; + case BaeImageConstant::ANNOTATE_CLEAROPERATIONS: + $baeImageAnnotate->clearOperations(); + break; + default: + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + } + if(empty($baeImageSource)){ + throw new BaeException('no bae image source', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(empty($text)){ + throw new BaeException('no text script', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $baeImageAnnotate->setText($text); // check $text + if($baeImageAnnotate->errcode !== 0){ + $this->errcode = $baeImageAnnotate->errcode; + $this->errmsg = $baeImageAnnotate->errmsg; + return false; + } + /********************examming url pattern*******************************/ + if($isURL == true){ + $this->_examURL($baeImageSource); + $URL = $baeImageSource; + }else{ + //restrict image into 2M + if(!$this->_checkString($baeImageSource, 0, 2*1024*1024)){ + throw new BaeException('image must be less than 2M', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + unset($params); + + $operations = $baeImageAnnotate->getOperations(); + $jsonParams = $this->_formJsonParams($URL, $operations, $this->ProcType_Annotate, true); + $paramArr = array('strudata'=>$jsonParams); + $arrArgs = array( + self::METHOD => 'processExt',); + $arrArgs = array_merge($arrArgs, $paramArr); + return $this->_commonProcess($arrArgs); + + } catch (Exception $ex) { + //echo "exception:". $ex->getMessage(); + $this->_exceptionHandler($ex); + return false; + } + } + + /** + * Generate a QR Code image about a text script. + * @param baeImageQRCode BaeImageQRCode,

contains variety of + * operations about QR Code

+ * @return Image-relevant data,if success, otherwise return false + */ + public function applyQRCodeByObject($baeImageQRCode) + { + $this->_resetErrorStatus(); + try { + if(empty($baeImageQRCode) || !($baeImageQRCode instanceof BaeImageQRCode)){ + throw new BaeException('input source is not an instance of BaeImageQRCode', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($baeImageQRCode->errcode !== 0){ + $this->errcode = $baeImageQRCode->errcode; + $this->errmsg = $baeImageQRCode->errmsg; + return false; + } + $operations = $baeImageQRCode->getOperations(); + // $operations must contain text + if (empty($operations['text'])) { + throw new BaeException('no text script', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $jsonParams = $this->_formJsonParams(null, $operations, $this->ProcType_QRCode, false); + $paramArr = array('strudata'=>$jsonParams); + $arrArgs = array( + self::METHOD => 'processExt', + ); + $arrArgs = array_merge($arrArgs, $paramArr); + return $this->_commonProcess($arrArgs); + + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + } + + /** + * Generate a QR Code image about a text script. + * @param text string,

text script for processing

+ * @param params array,

contains variety of + * operations about QR Code

+ * @return Image-relevant data,if success, otherwise return false + */ + public function applyQRCode($text, $params=array()) + { + $baeImageQRCode = new BaeImageQRCode(); + $this->_resetErrorStatus(); + try{ + if(empty($text)){ + throw new BaeException('no text script', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(!is_array($params)){ + throw new BaeException(sprintf('invalid parameters, [%s] should be array', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if (!empty($params)){ + foreach ($params as $key => $value){ + if(!is_string($key)){ + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch($key){ + case BaeImageConstant::QRCODE_SIZE: + $baeImageQRCode->setSize($value); + break; + case BaeImageConstant::QRCODE_LEVEL: + $baeImageQRCode->setLevel($value); + break; + case BaeImageConstant::QRCODE_VERSION: + $baeImageQRCode->setVersion($value);; + break; + case BaeImageConstant::QRCODE_MARGIN: + $baeImageQRCode->setMargin($value); + break; + case BaeImageConstant::QRCODE_FOREGROUND: + $baeImageQRCode->setForeground($value); + break; + case BaeImageConstant::QRCODE_BACKGROUND: + $baeImageQRCode->setBackground($value); + break; + case BaeImageConstant::QRCODE_CLEAROPERATIONS: + $baeImageQRCode->clearOperations(); + break; + default: + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + } + unset($params); + if($baeImageQRCode->errcode !== 0){ + $this->errcode = $baeImageQRCode->errcode; + $this->errmsg = $baeImageQRCode->errmsg; + return false; + } + $operations = $baeImageQRCode->getOperations(); + // GBK ENCODE + $this->_checkString2($text,'text', 1,500); + $text = mb_convert_encoding($text, 'GBK', 'UTF-8'); + $operations['text'] = $text; + $jsonParams = $this->_formJsonParams(null, $operations, $this->ProcType_QRCode, false); + $paramArr = array('strudata'=>$jsonParams); + $arrArgs = array( + self::METHOD => 'processExt',); + $arrArgs = array_merge($arrArgs, $paramArr); + return $this->_commonProcess($arrArgs); + + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + } + + /** + * Apply composition + * @param composites array,

a set of BaeImageComposite object

+ * @param canvas_width[optional] int,

canvas width

+ * @param canvas_height[optional] int,

canvas height

+ * @param outputcode[optional] BaeImageConstant,

output image type

+ * @param quality[optional] int,

output image quality

+ * @return Image-relevant data,if success, otherwise return false + */ + public function applyCompositeByObject($composites, $canvas_width = 1000, $canvas_height = 1000, + $outputcode = BaeImageConstant::JPG, $quality = 80) + { + + $this->_resetErrorStatus(); + try { + if(empty($composites) || ! is_array($composites)){ + throw new BaeException('input source is not a BaeImageComposite array', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + //common params + $this->_checkInt($canvas_width, 'canvas width', 0, 10000); + $this->_checkInt($canvas_height, 'canvas height', 0, 10000); + $this->_checkInt($outputcode, 'outputcode', 0, 3); + $this->_checkInt($quality, 'quality', 0, 100); + $commParams = array('desttype'=> $outputcode, 'canvas_width'=> $canvas_width, + 'canvas_height'=>$canvas_height, 'quality'=>$quality); + $len = count($composites); + if($len < 2){ + throw new BaeException('short of images, at least two elements', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($len > 2){ + throw new BaeException('too many images, at most two elements', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + /*construct parameter array of _formJsonParmas()*/ + $operations = array(); + $isURL = array(); + $imageSource = array(); + if(!($composites[0] instanceof BaeImageComposite)){ + throw new BaeException('input source is not an instance of BaeImageComposite', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($composites[0]->errcode !== 0){ + $this->errcode = $composites[0]->errcode; + $this->errmsg = $composites[0]->errmsg; + return false; + } + $operations[0] = $composites[0]->getOperations(); + // merge common params + $operations = array_merge($operations, $commParams); + $baeImageSource = $composites[0]->getBaeImageSource(); + if (empty($baeImageSource['data'])) { + throw new BaeException('no commosite image parameters', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $imageSource[0] = $baeImageSource['data']; + $isURL[0] = $baeImageSource['isURL']; + + for($i=1;$i<$len;$i++){ + if(!($composites[$i] instanceof BaeImageComposite)){ + throw new BaeException('input source is not an instance of BaeImageComposite', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($composites[$i]->errcode !== 0){ + $this->errcode = $composites[$i]->errcode; + $this->errmsg = $composites[$i]->errmsg; + return false; + } + $operations[1] = $composites[$i]->getOperations(); + $baeImageSource = $composites[$i]->getBaeImageSource(); + if (empty($baeImageSource['data'])) { + throw new BaeException('no commosite image parameters', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $imageSource[1] = $baeImageSource['data']; + $isURL[1] = $baeImageSource['isURL']; + $jsonParams = $this->_formJsonParams($imageSource, $operations,$this->ProcType_Composite, $isURL); + $paramArr = array('strudata'=>$jsonParams); + $arrArgs = array( + self::METHOD => 'processExt',); + $arrArgs = array_merge($arrArgs, $paramArr); + $retImage = $this->_commonProcess($arrArgs); + } + return $retImage; + + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + } + + /** + * Apply composition + * @param params array,

contains variety of operaitons about composite

+ * @param canvas_width[optional] int,

canvas width

+ * @param canvas_height[optional] int,

canvas height

+ * @param outputcode[optional] BaeImageConstant,

output image type

+ * @param quality[optional] int,

output image quality

+ * @return Image-relevant data,if success, otherwise return false + */ + public function applyComposite($params,$canvas_width = 1000, $canvas_height = 1000, + $outputcode = BaeImageConstant::JPG, $quality = 80) + { + $baeImageComposite = new BaeImageComposite(); + $this->_resetErrorStatus(); + try{/*check common paramters*/ + $this->_checkInt($canvas_width, 'canvas width', 0, 10000); + $this->_checkInt($canvas_height, 'canvas height', 0, 10000); + $this->_checkInt($outputcode, 'outputcode', 0, 3); + $this->_checkInt($quality, 'quality', 0, 100); + $commParams = array('desttype'=> $outputcode, 'canvas_width'=> $canvas_width, + 'canvas_height'=>$canvas_height, 'quality'=>$quality); + + if (empty($params) || !is_array($params)) {//// + throw new BaeException(sprintf('invalid parameters, [%s] should be array', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(count($params) < 2){ + throw new BaeException('short of images, at least two elements', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(count($params) > 2){ + throw new BaeException('too many images, at most two elements', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + + $operations = array(); + $isURL = array(); + $imageSource = array(); + $paramElement = $params[0]; + foreach ($paramElement as $key => $value){ + if(!is_string($key)){ + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch($key){ + case BaeImageConstant::COMPOSITE_BAEIMAGESOURCE: + //if(!is_array($value) || count($value) != 2){ + if(!is_array($value)){ + throw new BaeException('invalid bae image source parameter', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if (empty($value[0])) { + throw new BaeException('no image source parameters', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(count($value) === 2){ + $baeImageComposite->setBaeImageSource($value[0], $value[1]); + }else{ + $baeImageComposite->setBaeImageSource($value[0]); + } + break; + case BaeImageConstant::COMPOSITE_OPACITY: + $baeImageComposite->setOpacity($value); + break; + case BaeImageConstant::COMPOSITE_ANCHOR: + $baeImageComposite->setAnchor($value); + break; + case BaeImageConstant::COMPOSITE_POS: + if(!is_array($value) || count($value) != 2){ + throw new BaeException('invalid position parameter', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $baeImageComposite->setPos($value[0],$value[1]); + break; + case BaeImageConstant::COMPOSITE_CLEAROPERATIONS: + $baeImageComposite->clearOperations(); + break; + default: + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + if($baeImageComposite->errcode !== 0){ + $this->errcode = $baeImageComposite->errcode; + $this->errmsg = $baeImageComposite->errmsg; + return false; + } + $operations[0] = $baeImageComposite->getOperations(); + $operations = array_merge($operations, $commParams); + $baeImageSource = $baeImageComposite->getBaeImageSource(); + $imageSource[0] = $baeImageSource['data']; + $isURL[0] = $baeImageSource['isURL']; + + for($i=1,$len=count($params);$i<$len;$i++){ + $baeImageComposite->clearOperations(); + $paramElement = $params[$i]; + foreach ($paramElement as $key => $value){ + if(!is_string($key)){ + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch($key){ + case BaeImageConstant::COMPOSITE_BAEIMAGESOURCE: + if(!is_array($value)){ + throw new BaeException('invalid bae image source parameter', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if (empty($value[0])) { + throw new BaeException('no image source parameters', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(count($value) === 2){ + $baeImageComposite->setBaeImageSource($value[0], $value[1]); + }else{ + $baeImageComposite->setBaeImageSource($value[0]); + } + break; + case BaeImageConstant::COMPOSITE_OPACITY: + $baeImageComposite->setOpacity($value); + break; + case BaeImageConstant::COMPOSITE_ANCHOR: + $baeImageComposite->setAnchor($value); + break; + case BaeImageConstant::COMPOSITE_POS: + if(!is_array($value) || count($value) != 2){ + throw new BaeException('invalid position parameter', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + $baeImageComposite->setPos($value[0],$value[1]); + break; + case BaeImageConstant::COMPOSITE_CLEAROPERATIONS: + $baeImageComposite->clearOperations(); + break; + default: + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + if($baeImageComposite->errcode !== 0){ + $this->errcode = $baeImageComposite->errcode; + $this->errmsg = $baeImageComposite->errmsg; + return false; + + } + $operations[1] = $baeImageComposite->getOperations(); + $baeImageSource = $baeImageComposite->getBaeImageSource(); + $imageSource[1] = $baeImageSource['data']; + $isURL[1] = $baeImageSource['isURL']; + + $jsonParams = $this->_formJsonParams($imageSource, $operations, + $this->ProcType_Composite, $isURL); + $paramArr = array('strudata'=>$jsonParams); + $arrArgs = array( + self::METHOD => 'processExt',); + $arrArgs = array_merge($arrArgs, $paramArr); + $retImage = $this->_commonProcess($arrArgs); + } + return $retImage; + } catch (Exception $ex) { + //echo "exception:" . $ex->getMessage(); + $this->_exceptionHandler($ex); + return false; + } + } + + /** + * Generate verificaion code + * @param baeImageVCode BaeImageVCode,

contains variety of setting about vcdoe

+ * @return image url of vcode,if success, otherwise return false + */ + public function generateVCode($params=array()) + { + $this->_resetErrorStatus(); + $baeImageVCode = new BaeImageVCode(); + try { + if(!is_array($params)){ + throw new BaeException(sprintf('invalid parameters, [%s] should be array', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + + if (!empty($params)) { + foreach ($params as $key => $value){ + if(!is_string($key)){ + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch ($key){ + case BaeImageConstant::VCODE_LEN: + $baeImageVCode->setLen($value); + break; + case BaeImageConstant::VCODE_PATTERN: + $baeImageVCode->setPattern($value); + break; + case BaeImageConstant::VCODE_CLEAROPERATIONS: + $baeImageVCode->clearOperations(); + break; + default: + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + } + unset($params); + if($baeImageVCode->errcode !== 0){ + $this->errcode = $baeImageVCode->errcode; + $this->errmsg = $baeImageVCode->errmsg; + return false; + } + + $paramArr = $baeImageVCode->getOperations();// obtain the operations setting on the vcode + $paramArr['vcservice'] = 0;//generate vcode + $arrArgs = array( + self::METHOD => 'process', + ); + $arrArgs = array_merge($arrArgs, $paramArr); + $retArr = $this->_commonProcess($arrArgs); + $retStatus = $retArr['response_params']['status']; + if($retStatus !== 0){ + throw new BaeException('failed to get verification code', BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR); + } + return $retArr; + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + + } + + /** + * Verify vcode + * @param baeImageVCode BaeImageVCode,

contains variety of setting about vcdoe

+ * @return result of vcode,if success, otherwise return false + */ + public function verifyVCode($params) + { + $this->_resetErrorStatus(); + $baeImageVCode = new BaeImageVCode(); + try { + if(empty($params)){ + throw new BaeException(sprintf('invalid parameters, [%s] is empty', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(!is_array($params)){ + throw new BaeException(sprintf('invalid parameters, [%s] should be array', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(empty($params['input'])){ + throw new BaeException(sprintf('invalid parameters, [%s] input field is empty ', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if(empty($params['secret'])){ + throw new BaeException(sprintf('invalid parameters, [%s] secret field is empty ', $params), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + foreach ($params as $key => $value){ + if(!is_string($key)){ + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch ($key){ + case BaeImageConstant::VCODE_INPUT: + $baeImageVCode->setInput($value); + break; + case BaeImageConstant::VCODE_SECRET: + $baeImageVCode->setSecret($value); + break; + case BaeImageConstant::VCODE_CLEAROPERATIONS: + $baeImageVCode->clearOperations(); + break; + default: + throw new BaeException(sprintf('invalid key [%s]', $key), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + unset($params); + if($baeImageVCode->errcode !== 0){ + $this->errcode = $baeImageVCode->errcode; + $this->errmsg = $baeImageVCode->errmsg; + return false; + } + $paramArr = $baeImageVCode->getOperations();// obtain the operations setting on the vcode + $paramArr['vcservice'] = 1;//verify vcode + $arrArgs = array( + self::METHOD => 'process', + ); + $arrArgs = array_merge($arrArgs, $paramArr); + return $this->_commonProcess($arrArgs); + + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + } + + /* + * + * formed json type params using the given input + * @param type mixed $imageSource, image source data or url + * @param type array $operations + * @param int $procType + * @param bool $isURL + * + * @return the json-formed params + */ + private function _formJsonParams($imageSource, $operations, $procType, $isURL) + { + $jsonParamArr = array(); + switch ($procType) { + /****************************QR Code*******************************/ + case 0: + $jsonParamArr['process_type'] = $procType . '';// value = '0' + $jsonParamArr['req_data_num'] = '1'; // fixed value; + $jsonParamArr['req_data_source'] = array(); + $jsonParamArr['source_data'] = array(); + $text = $this->_getOperation($operations, 'text'); //get text in qr code + $jsonParamArr['source_data']['data1'] = base64_encode($text); + $jsonParamArr['req_data_source'][0] = array('sourcemethod' => 'BODY'); + $jsonParamArr['req_data_source'][0]['source_data_type'] = 0; //0-text script, 1-image + $jsonParamArr['req_data_source'][0]['operations'] = array(); + $jsonParamArr['req_data_source'][0]['http_reqpack'] = array(); //reserve + + if(!is_null($this->_getOperation($operations, 'size'))){ + $jsonParamArr['req_data_source'][0]['operations']['size'] = $this->_getOperation($operations, 'size'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['size'] = 3; + } + + if(!is_null($this->_getOperation($operations, 'version'))){ + $jsonParamArr['req_data_source'][0]['operations']['version'] = $this->_getOperation($operations, 'version'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['version'] = 0; + } + + if(!is_null($this->_getOperation($operations,'margin'))){ + $jsonParamArr['req_data_source'][0]['operations']['margin'] = $this->_getOperation($operations,'margin'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['margin'] = 4; + } + if(!is_null($this->_getOperation($operations,'level'))){ + $jsonParamArr['req_data_source'][0]['operations']['level'] = $this->_getOperation($operations,'level'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['level'] = 2; + } + + if(!is_null($this->_getOperation($operations,'foreground'))){ + $jsonParamArr['req_data_source'][0]['operations']['foreground'] = $this->_getOperation($operations,'foreground'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['foreground'] = '000000'; + } + if(!is_null($this->_getOperation($operations,'background'))){ + $jsonParamArr['req_data_source'][0]['operations']['background'] = $this->_getOperation($operations,'background'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['background'] = 'FFFFFF'; + } + break; + /****************Annotate*********************/ + case 1: + $jsonParamArr['process_type'] = $procType . '';// value = '1' + $jsonParamArr['req_data_num'] = '2'; // fixed value; + $jsonParamArr['req_data_source'] = array(); + $jsonParamArr['source_data'] = array(); + $text = $this->_getOperation($operations, 'text'); //get text in annotate + if($isURL === true){ + $jsonParamArr['req_data_source'][0] = array('sourcemethod' => 'GET'); + $jsonParamArr['req_data_source'][0]['source_url'] = $imageSource; + $jsonParamArr['source_data']['data1'] = base64_encode($text); + }else{ + $jsonParamArr['req_data_source'][0] = array('sourcemethod' => 'BODY'); + // image source must be filled in 'data1',if exist. followed by text in data2 + $jsonParamArr['source_data']['data1'] = base64_encode($imageSource); + $jsonParamArr['source_data']['data2'] = base64_encode($text); + + } + $jsonParamArr['req_data_source'][0]['source_data_type'] = 1; + $jsonParamArr['req_data_source'][0]['operations'] = array(); + $jsonParamArr['req_data_source'][0]['http_reqpack'] = array(); + + $jsonParamArr['req_data_source'][1] = array('sourcemethod' => 'BODY'); + $jsonParamArr['req_data_source'][1]['source_data_type'] = 0; + $jsonParamArr['req_data_source'][1]['operations'] = array(); + $jsonParamArr['req_data_source'][1]['http_reqpack'] = array(); + // operations cant be empty in req_data_source[0][operations] + if(!is_null($this->_getOperation($operations, 'x_offset'))){ + $jsonParamArr['req_data_source'][0]['operations']['x_offset'] = $this->_getOperation($operations, 'x_offset'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['x_offset'] = 0; + } + + if(!is_null($this->_getOperation($operations, 'y_offset'))){ + $jsonParamArr['req_data_source'][0]['operations']['y_offset'] = $this->_getOperation($operations, 'y_offset'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['y_offset'] = 0; + } + + if(!is_null($this->_getOperation($operations, 'opacity'))){ + $opacity = $this->_getOperation($operations, 'opacity'); + $strOpacity = strtoupper(dechex(ceil(255-$opacity*255)). ''); + if(strlen($strOpacity) === 1){ + $strOpacity = '0'. $strOpacity; + } + }else{ + $strOpacity = "FF"; + } + + if(!is_null($this->_getOperation($operations,'font_name'))){ + $jsonParamArr['req_data_source'][0]['operations']['font_name'] = $this->_getOperation($operations,'font_name'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['font_name'] = BaeImageConstant::SUN; + } + if(!is_null($this->_getOperation($operations,'font_color'))){ + $jsonParamArr['req_data_source'][0]['operations']['font_color'] = '#'. $this->_getOperation($operations,'font_color'). $strOpacity; + //echo "color" . $jsonParamArr['req_data_source'][0]['operations']['font_color']; + }else{ + $jsonParamArr['req_data_source'][0]['operations']['font_color'] = '#000000'. $strOpacity; + } + + if(!is_null($this->_getOperation($operations,'font_size'))){ + $jsonParamArr['req_data_source'][0]['operations']['font_size'] = $this->_getOperation($operations,'font_size'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['font_size'] = 25; + } + if(!is_null($this->_getOperation($operations,'desttype'))){ + $jsonParamArr['req_data_source'][0]['operations']['desttype'] = $this->_getOperation($operations,'desttype'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['desttype'] = 0; + } + if(!is_null($this->_getOperation($operations,'quality'))){ + $jsonParamArr['req_data_source'][0]['operations']['quality'] = $this->_getOperation($operations,'quality'); + }else{ + $jsonParamArr['req_data_source'][0]['operations']['quality'] = 80; + } + + break; + /********************Composite**********************/ + case 2: + $jsonParamArr['process_type'] = $procType . '';// value = '2' + $jsonParamArr['req_data_source'] = array(); + $jsonParamArr['source_data'] = array(); + + $num = count($imageSource); + $jsonParamArr['req_data_num'] = 2 .''; // fixed value; + $count = 0; + $isEmpty = true; + while($count < $num){ + if($isURL[$count] === true){ + $jsonParamArr['req_data_source'][$count] = array('sourcemethod' => 'GET'); + $jsonParamArr['req_data_source'][$count]['source_url'] = $imageSource[$count]; + }else{ + $jsonParamArr['req_data_source'][$count] = array('sourcemethod' => 'BODY'); + if($isEmpty === true){ + $jsonParamArr['source_data']['data1'] = base64_encode($imageSource[$count]); + $isEmpty = false; + }else{ + $jsonParamArr['source_data']['data2'] = base64_encode($imageSource[$count]); + } + + } + $jsonParamArr['req_data_source'][$count]['source_data_type'] = 1; + $jsonParamArr['req_data_source'][$count]['operations'] = array(); + $jsonParamArr['req_data_source'][$count]['http_reqpack'] = array(); + if(!is_null($this->_getOperation($operations[$count], 'x_offset'))){ + $jsonParamArr['req_data_source'][$count]['operations']['x_offset'] = $this->_getOperation($operations[$count], 'x_offset'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['x_offset'] = 0; + } + + if(!is_null($this->_getOperation($operations[$count], 'y_offset'))){ + $jsonParamArr['req_data_source'][$count]['operations']['y_offset'] = $this->_getOperation($operations[$count], 'y_offset'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['y_offset'] = 0; + } + + if(!is_null($this->_getOperation($operations[$count], 'opacity'))){ + $jsonParamArr['req_data_source'][$count]['operations']['opacity'] = $this->_getOperation($operations[$count], 'opacity'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['opacity'] = 0.0; + } + + if(!is_null($this->_getOperation($operations[$count],'anchor_point'))){ + $jsonParamArr['req_data_source'][$count]['operations']['anchor_point'] = $this->_getOperation($operations[$count],'anchor_point'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['anchor_point'] = BaeImageConstant::TOP_LEFT; + } + /*********************Common params********************************/ + if(!is_null($this->_getOperation($operations,'canvas_width'))){ + $jsonParamArr['req_data_source'][$count]['operations']['canvas_width'] = $this->_getOperation($operations,'canvas_width'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['canvas_width'] = 0; + } + if(!is_null($this->_getOperation($operations,'canvas_height'))){ + $jsonParamArr['req_data_source'][$count]['operations']['canvas_height'] = $this->_getOperation($operations,'canvas_height'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['canvas_height'] = 0; + } + if(!is_null($this->_getOperation($operations,'desttype'))){ + $jsonParamArr['req_data_source'][$count]['operations']['desttype'] = $this->_getOperation($operations,'desttype'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['desttype'] = 0; + } + if(!is_null($this->_getOperation($operations,'quality'))){ + $jsonParamArr['req_data_source'][$count]['operations']['quality'] = $this->_getOperation($operations,'quality'); + }else{ + $jsonParamArr['req_data_source'][$count]['operations']['quality'] = 80; + } + $count++; + + } + break; + + } + return json_encode($jsonParamArr); + } + + private function _getOperation($arrParams, $strOperation){ + if(!empty($arrParams[$strOperation])){ + return $arrParams[$strOperation]; + } + return null; + + } + /* + * Examming url pattern + * */ + private function _examURL($url) + { + $this->_checkString2($url, 'url', 0, 2048); + $pattern = "/^(http[s]?:\/\/){1}[.]*/"; + // regular match + if(!preg_match($pattern, $url)){ + throw new BaeException(sprintf('invalid image source url[%s]', $url), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM);// + } + return true; + } + + private function _resetErrorStatus() + { + $this->errcode = 0; + $this->errmsg = $this->_arrayErrorMap[$this->errcode]; + $this->_requestId = 0; + } + + private function _exceptionHandler($ex) + { + $tmpCode = $ex->getCode(); + if (0 === $tmpCode) { + $tmpCode = BaeImageConstant::BAE_IMAGEUI_SDK_SYS; + } + + $this->errcode = $tmpCode; + if ($this->errcode >= 30000) { + $this->errmsg = $ex->getMessage(); + } else { + $this->errmsg = $this->_arrayErrorMap[$this->errcode] + . ', detail info[' . $ex->getMessage() + . ', break point: ' . $ex->getFile(). ':' . $ex->getLine() . '].' + . "\n" + . $ex->getTraceAsString(); + } + } + + private function _checkInt($num, $prompt, $intMin = -1, $intMax = -1) + { + if (!is_integer($num)) { + throw new BaeException(sprintf('[%s] parameter not an integer', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMin !== -1 && $num < $intMin) { + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMax !== -1 && $intMax < $num) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkString($str, $min, $max) + { + if (is_string($str) && strlen($str) >= $min && strlen($str) <= $max) { + return true; + } + return false; + } + private function _checkString2($str, $prompt, $min=null, $max=null) + { + if (!is_string($str)){ + throw new BaeException(sprintf('[%s] parameter not a string', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($min !== null && strlen($str) < $min){ + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($max !== null && strlen($str) > $max) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } +} diff --git a/ptcms/library/bae/BaeMemcache.class.php b/ptcms/library/bae/BaeMemcache.class.php new file mode 100644 index 0000000..c69c824 --- /dev/null +++ b/ptcms/library/bae/BaeMemcache.class.php @@ -0,0 +1,256 @@ +_handle= $memcache; + } + return; + } + + /** + * Retrieve previously stored data if an item with such key exists on the server + * at this moment. You can pass array of keys to get array of values. The result + * array will contain only found key-value pairs. + * + * @param string|array $mixedKey The key or array of keys to fetch + * @param int|array $flag If present, flags fetched along with + * the values will be written to this parameter + * @return string|array + * @see http://cn.php.net/manual/zh/memcache.get.php + */ + public function get($key, $flag= null) + { + if(empty($key)) + { + return null; + } + $res= $this->_handle->getExt($key); + if(false === $res) + { + $this->errcode = $this->_handle->_last_errno; + $this->errmsg= $this->_handle->_convertErrmsg($this->errcode); + } + else + { + $this->errcode = 0; + $this->errmsg= "RES_SUCCESS"; + } + return $res; + } + + /** + * Store data at the memcache cluster + * + * @param string $key The key that will be associated with the item + * @param mixed $var The variable to store + * @param int $flag Use MEMCACHE_COMPRESSED to store the item compressed (uses zlib) + * @param int $expire Expiration time of the item. If it's equal to zero, the item will never expire + * @return bool + * @see http://cn.php.net/manual/zh/memcache.set.php + */ + public function set($key, $var, $flag=0, $expire=0) + { + $res= $this->_handle->set($key, $var, $expire); + if(!$res) + { + $this->errcode = $this->_handle->_last_errno; + $this->errmsg= $this->_handle->_convertErrmsg($this->errcode); + } + else + { + $this->errcode = 0; + $this->errmsg= "RES_SUCCESS"; + } + return $res; + } + + /** + * Add an item to the memcache cluster + * + * @param string $key The key that will be associated with the item + * @param mix $var The variable to store + * @param int $flag Use MEMCACHE_COMPRESSED to store the item compressed (uses zlib) + * @param int $expire Expiration time of the item. If it's equal to zero, the item will never expire + * @return bool + * @see http://cn.php.net/manual/zh/memcache.add.php + */ + public function add($key, $var, $flag= 0, $expire= 0) + { + $res= $this->_handle->add($key, $var, $expire); + if(!$res) + { + $this->errcode = $this->_handle->_last_errno; + $this->errmsg= $this->_handle->_convertErrmsg($this->errcode); + } + else + { + $this->errcode = 0; + $this->errmsg= "RES_SUCCESS"; + } + return $res; + } + + /** + * Replace value of the existing item in memcache cluster + * + * @param string $key The key that will be associated with the item + * @param mixed $var The variable to store + * @param int $flag Use MEMCACHE_COMPRESSED to store the item compressed (uses zlib) + * @param int $expire Expiration time of the item. If it's equal to zero, the item will never expire + * @return bool + * @see http://cn.php.net/manual/zh/memcache.replace.php + */ + public function replace($key, $var, $flag= 0, $expire= 0) + { + $res= $this->_handle->replace($key, $var, $expire); + if(!$res) + { + $this->errcode = $this->_handle->_last_errno; + $this->errmsg= $this->_handle->_convertErrmsg($this->errcode); + } + else + { + $this->errcode = 0; + $this->errmsg= "RES_SUCCESS"; + } + return $res; + } + + /** + * Increment cache item's value at the memcache cluster + * + * @param string $key Key of the item to increment + * @param int $value Increment the item by value + * @return int + * @see http://cn.php.net/manual/zh/memcache.increment.php + */ + public function increment($key, $value= 1) + { + $res= $this->_handle->increment($key, $value); + if(!$res) + { + $this->errcode = $this->_handle->_last_errno; + $this->errmsg= $this->_handle->_convertErrmsg($this->errcode); + } + else + { + $this->errcode = 0; + $this->errmsg= "RES_SUCCESS"; + } + return $res; + } + + /** + * Decrement cache item's value at the memcache cluster + * + * @param string $key Key of the item to decrement + * @param int $value Dncrement the item by value + * @return int + * @see http://cn.php.net/manual/zh/memcache.decrement.php + */ + public function decrement($key, $value= 1) + { + $res= $this->_handle->decrement($key, $value); + if(!$res) + { + $this->errcode = $this->_handle->_last_errno; + $this->errmsg= $this->_handle->_convertErrmsg($this->errcode); + } + else + { + $this->errcode = 0; + $this->errmsg= "RES_SUCCESS"; + } + return $res; + } + + /** + * Delete item from the memcache cluster + * + * @param string $key The key associated with the item to delete + * @param int $time The value will be deleted whithin $time seconds. + * @return bool + * @see http://cn.php.net/manual/zh/function.memcache-delete.php + */ + public function delete($key, $time = 0) + { + $res= $this->_handle->delete($key, $time); + if(!$res) + { + $this->errcode = $this->_handle->_last_errno; + $this->errmsg= $this->_handle->_convertErrmsg($this->errcode); + } + else + { + $this->errcode = 0; + $this->errmsg= "RES_SUCCESS"; + } + return $res; + } + + /** + * Close memcached connection + * + */ + public function close() + { + if($this->_handle) + { + //return $this->_handle->close(); + return true; + } + else + { + return false; + } + } + + public function set_shareAppid($appid) + { + if(!is_string($appid)) return false; + + $ret = $this->_handle->set_shareAppid($appid); + if($ret === false) return false; + + $this->appid = $appid; + return true; + } + + public function __destruct() + { + $this->close(); + } + +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 noet: */ diff --git a/ptcms/library/bae/images/BaeImageAnnotate.class.php b/ptcms/library/bae/images/BaeImageAnnotate.class.php new file mode 100644 index 0000000..3950740 --- /dev/null +++ b/ptcms/library/bae/images/BaeImageAnnotate.class.php @@ -0,0 +1,254 @@ + 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_SYS => 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL => 'php sdk init error', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM => 'param invalid', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR + => 'http status is error, and the body returned is not a json string', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR + => 'http status is ok, but the body returned is not a json string', + ); + + public function __construct($text = NULL) + { + $this->_resetErrorStatus(); + $this->paramArr = array(); + if(!is_null($text)){ + $this->setText($text); + } + + } + /** + * The text script of annotation + * @param text string,

range:1-500 characters

+ */ + public function setText($text) + { + try { + $this->_checkString($text, 1, 500); + $this->text = $text; + $this->paramArr['text'] = $text; + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + public function getText() + { + return $this->text; + + } + + public function getOperations() + { + return $this->paramArr; + } + + private function setParam($key, $value) + { + $this->paramArr[$key] = $value; + } + /** + * The opacity of an image + * @param floatOpacity float,

range:0-1

+ */ + public function setOpacity($floatOpacity) + { + //$this->_resetErrorStatus(); + try { + $this->_checkFloat($floatOpacity, 'opacity', 0.0, 1.0); + $this->setParam('opacity', $floatOpacity); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + /** + * Font options + * @param name BaeImageConstant + * @param size int,

range:0-1000,default 5

+ * @param color string,

range:6 bits RGB,default '000000'

+ */ + public function setFont($name, $size, $color) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($name,'font name', 0, 4); + $this->_checkInt($size, 'font size' ,0, 1000); + $this->_checkRGB($color); + $this->setParam('font_name', $name); + $this->setParam('font_color', $color); + $this->setParam('font_size', $size); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + /** + * Position of the text script + * @param x_offset int,

range:0-width of the image

+ * @param y_offset int,

range:0-height of the image

+ */ + public function setPos($x_offset, $y_offset) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($x_offset, 'x_offset', 0);//without restriction + $this->_checkInt($y_offset, 'y_offset', 0);//without restriction + $this->setParam('x_offset', $x_offset); + $this->setParam('y_offset', $y_offset); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + /** + * The output image type + * @param outputcode BaeImageConstant,

support by JPG,GIF,BMP,PNG,WEBP + */ + public function setOutputCode($outputcode) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($outputcode, 'outputcode', 0, 4); + $this->setParam('desttype', $outputcode); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + /** + * The quality of output image + * @param intQuality int,

range:0-100,default 80

+ */ + public function setQuality($intQuality) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intQuality, 'quality', 0, 100); + $this->setParam('quality', $intQuality); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + + public function clearOperations() + { + $this->paramArr = array(); + return true; + } + + private function _checkRGB($strRGB){ + $this->_checkString($strRGB, 6, 6); + $pattern = "/[AaBbCcDdEeFf0123456789]{6}/"; + // regular match + if(!preg_match($pattern, $strRGB)){ + throw new BaeException(sprintf('invalid RGB color[%s]', $strRGB), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM);// + } + } + + private function _checkFloat($num, $prompt, $floatMin = null, $floatMax = null) + { + if(is_integer($num)){ + $num = floatval($num); + } + if(!is_float($num)){ + throw new BaeException(sprintf('[%s] parameter not a float', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($floatMin !== null && $num < $floatMin){ + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($floatMax !== null && $num > $floatMax){ + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkEnum($value, $arrEnum = array(0,1,2),$name) + { + if(!in_array($value, $arrEnum)) { + throw new Exception(sprintf('Param % is incorrect',$name)); + } + } + + private function _checkInt($num, $prompt, $intMin = -1, $intMax = -1) + { + if (!is_integer($num)) { + throw new BaeException(sprintf('[%s] parameter not an integer', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMin !== -1 && $num < $intMin) { + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMax !== -1 && $intMax < $num) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkString($str, $min=null, $max=null) + { + if (!is_string($str)){ + throw new BaeException(sprintf('[%s] parameter not a string', $str), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($min !== null && strlen($str) < $min){ + throw new BaeException(sprintf('[%s] parameter less than minimum', $str), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($max !== null && strlen($str) > $max) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $str), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _resetErrorStatus() + { + $this->errcode = 0; + $this->errmsg = $this->_arrayErrorMap[$this->errcode]; + $this->_requestId = 0; + } + + private function _exceptionHandler($ex) + { + $tmpCode = $ex->getCode(); + if (0 === $tmpCode) { + $tmpCode = BaeImageConstant::BAE_IMAGEUI_SDK_SYS; + } + + $this->errcode = $tmpCode; + if ($this->errcode >= 30000) { + $this->errmsg = $ex->getMessage(); + } else { + $this->errmsg = $this->_arrayErrorMap[$this->errcode] + . ', detail info[' . $ex->getMessage() + . ', break point: ' . $ex->getFile(). ':' . $ex->getLine() . '].' + . "\n" + . $ex->getTraceAsString(); + } + } +} \ No newline at end of file diff --git a/ptcms/library/bae/images/BaeImageComposite.class.php b/ptcms/library/bae/images/BaeImageComposite.class.php new file mode 100644 index 0000000..a3e6f09 --- /dev/null +++ b/ptcms/library/bae/images/BaeImageComposite.class.php @@ -0,0 +1,246 @@ + 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_SYS => 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL => 'php sdk init error', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM => 'param invalid', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR + => 'http status is error, and the body returned is not a json string', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR + => 'http status is ok, but the body returned is not a json string', + ); + + public function __construct($baeImageSource = NULL) + { + $isURL = true; + $this->_resetErrorStatus(); + try{ + if(!is_null($baeImageSource)){ + if($isURL === true){ + $this->_examURL($baeImageSource); + $this->baeImageSource = $baeImageSource; + } + else{ + if(!$this->_checkString($baeImageSource, 0, 2*1024*1024)){ + throw new BaeException('image must be less than 2M', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + $this->isURL = true; + } + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + } + /** + * Setting the image source + * @param baeImageSource string,

image source url or byte string

+ * @param isURL bool,

true for $baeImageSource is url pattern, false for byte string

+ */ + public function setBaeImageSource($baeImageSource) + { + $isURL=true; + try{ + if(empty($baeImageSource)){ + throw new BaeException('no bae image source', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($isURL === true){ + $this->_examURL($baeImageSource); + $this->baeImageSource = $baeImageSource; + } + else{ + if(!$this->_checkString($baeImageSource, 0, 2*1024*1024)){ + throw new BaeException('image must be less than 2M', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + $this->isURL = true; + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + public function getBaeImageSource() + { + return array('data'=>$this->baeImageSource, 'isURL'=>$this->isURL); + } + + public function getOperations() + { + return $this->paramArr; + } + + private function setParam($key, $value) + { + $this->paramArr[$key] = $value; + } + /** + * Position of the image apart from anchor point + * @param x_offset int + * @param y_offset int + */ + public function setPos($x_offset, $y_offset) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($x_offset, 'x_offset');//without restriction + $this->_checkInt($y_offset, 'y_offset');//without restriction + $this->setParam('x_offset', $x_offset); + $this->setParam('y_offset', $y_offset); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + /** + * Opacity of the image + * @param floatOpacity float,

range:0-1

+ */ + public function setOpacity($floatOpacity) + { + //$this->_resetErrorStatus(); + try { + $this->_checkFloat($floatOpacity, 'opacity', 0.0, 1.0); + $this->setParam('opacity', $floatOpacity); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + /** + * Anchor point of the image + * @param anchor BaeImageConstant,

range:0-8,default 0

+ */ + public function setAnchor($anchor) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($anchor, 'anchor', 0, 8); + $this->setParam('anchor_point', $anchor); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + + } + + public function clearOperations() + { + $this->paramArr = array(); + return true; + } + + + + private function _checkFloat($num, $prompt, $floatMin = null, $floatMax = null) + { + if(is_integer($num)){ + $num = floatval($num); + } + if(!is_float($num)){ + throw new BaeException(sprintf('[%s] parameter not a float', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($floatMin !== null && $num < $floatMin){ + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($floatMax !== null && $num > $floatMax){ + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkInt($num, $prompt, $intMin = -1, $intMax = -1) + { + if (!is_integer($num)) { + throw new BaeException(sprintf('[%s] parameter not an integer', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMin !== -1 && $num < $intMin) { + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMax !== -1 && $intMax < $num) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkString($str, $min, $max) + { + if (is_string($str) && strlen($str) >= $min && strlen($str) <= $max) { + return true; + } + return false; + } + private function _checkString2($str, $prompt, $min=null, $max=null) + { + if (!is_string($str)){ + throw new BaeException(sprintf('[%s] parameter not a string', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($min !== null && strlen($str) < $min){ + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($max !== null && strlen($str) > $max) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + /* + * Examming url pattern + * */ + private function _examURL($url) + { + $this->_checkString2($url, 'url', 0, 2048); + $pattern = "/^(http[s]?:\/\/){1}[.]*/"; + // regular match + if(!preg_match($pattern, $url)){ + throw new BaeException(sprintf('invalid image source url[%s]', $url), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM);// + } + return true; + } + + private function _resetErrorStatus() + { + $this->errcode = 0; + $this->errmsg = $this->_arrayErrorMap[$this->errcode]; + $this->_requestId = 0; + } + + private function _exceptionHandler($ex) + { + $tmpCode = $ex->getCode(); + if (0 === $tmpCode) { + $tmpCode = BaeImageConstant::BAE_IMAGEUI_SDK_SYS; + } + + $this->errcode = $tmpCode; + if ($this->errcode >= 30000) { + $this->errmsg = $ex->getMessage(); + } else { + $this->errmsg = $this->_arrayErrorMap[$this->errcode] + . ', detail info[' . $ex->getMessage() + . ', break point: ' . $ex->getFile(). ':' . $ex->getLine() . '].' + . "\n" + . $ex->getTraceAsString(); + } + } + +} diff --git a/ptcms/library/bae/images/BaeImageConstant.class.php b/ptcms/library/bae/images/BaeImageConstant.class.php new file mode 100644 index 0000000..700e587 --- /dev/null +++ b/ptcms/library/bae/images/BaeImageConstant.class.php @@ -0,0 +1,99 @@ + \ No newline at end of file diff --git a/ptcms/library/bae/images/BaeImageQRCode.class.php b/ptcms/library/bae/images/BaeImageQRCode.class.php new file mode 100644 index 0000000..23a5e4e --- /dev/null +++ b/ptcms/library/bae/images/BaeImageQRCode.class.php @@ -0,0 +1,235 @@ + 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_SYS => 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL => 'php sdk init error', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM => 'param invalid', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR + => 'http status is error, and the body returned is not a json string', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR + => 'http status is ok, but the body returned is not a json string', + ); + + public function __construct($text = NULL) + { + $this->_resetErrorStatus(); + $this->paramArr = array(); + if(!is_null($text)){ + $this->setText($text); + } + + } + /** + * Setting the text script + * @param text string,

the text script to generate QR coderange:1-500 characters

+ */ + public function setText($text) + { + try { + $this->_checkString($text);//check if it is not a string + $text = mb_convert_encoding($text, 'GBK', 'UTF-8'); + //echo "---------:". $text." len:". strlen($text); + $this->_checkString($text, 1, 500); + $this->text = $text; + $this->paramArr['text'] = $text; + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + public function getText() + { + return $this->text; + } + + public function getOperations() + { + return $this->paramArr; + } + + private function setParam($key, $value) + { + $this->paramArr[$key] = $value; + } + /** + * The version of the QR code + * @param intVersion int,

range:0-30

+ */ + public function setVersion($intVersion) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intVersion, 'version', 0, 30); + $this->setParam('version', $intVersion); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * The size of the QR code + * @param intSize int,

range:1-100

+ */ + public function setSize($intSize) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intSize, 'size', 1, 100); + $this->setParam('size', $intSize); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * The error correction level of an QR code + * @param intLevel int,

range:1-4

+ */ + public function setLevel($intLevel) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intLevel, 'level', 1, 4); + $this->setParam('level', $intLevel); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * The margin of a QR code + * @param intMargin int,

range:1-100

+ */ + public function setMargin($intMargin) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intMargin, 'margin', 1, 100); + $this->setParam('margin', $intMargin); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Foreground color of QR code + * @param strForeground string,

range:6 bits RGB,default '000000'

+ */ + public function setForeground($strForeground) + { + //$this->_resetErrorStatus(); + try { + $this->_checkRGB($strForeground); + $this->setParam('foreground', $strForeground); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Background color of QR code + * @param strBackground string,

range:6 bits RGB,default 'FFFFFF'

+ */ + public function setBackground($strBackground) + { + //$this->_resetErrorStatus(); + try { + $this->_checkRGB($strBackground); + $this->setParam('background', $strBackground); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + public function clearOperations(){ + $this->paramArr = array(); + return true; + } + + + private function _checkInt($num, $prompt, $intMin = -1, $intMax = -1) + { + if (!is_integer($num)) { + throw new BaeException(sprintf('[%s] parameter not an integer', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMin !== -1 && $num < $intMin) { + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMax !== -1 && $intMax < $num) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkString($str, $min=null, $max=null) + { + if (!is_string($str)){ + throw new BaeException(sprintf('[%s] parameter not a string', $str), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($min !== null && strlen($str) < $min){ + throw new BaeException(sprintf('[%s] parameter less than minimum', $str), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($max !== null && strlen($str) > $max) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $str), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkRGB($strRGB){ + $this->_checkString($strRGB, 6, 6); + $pattern = "/[AaBbCcDdEeFf0123456789]{6}/"; + // regular match + if(!preg_match($pattern, $strRGB)){ + throw new BaeException(sprintf('invalid RGB color[%s]', $strRGB), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM);// + } + } + + private function _resetErrorStatus() + { + $this->errcode = 0; + $this->errmsg = $this->_arrayErrorMap[$this->errcode]; + $this->_requestId = 0; + } + + private function _exceptionHandler($ex) + { + $tmpCode = $ex->getCode(); + if (0 === $tmpCode) { + $tmpCode = BaeImageConstant::BAE_IMAGEUI_SDK_SYS; + } + + $this->errcode = $tmpCode; + if ($this->errcode >= 30000) { + $this->errmsg = $ex->getMessage(); + } else { + $this->errmsg = $this->_arrayErrorMap[$this->errcode] + . ', detail info[' . $ex->getMessage() + . ', break point: ' . $ex->getFile(). ':' . $ex->getLine() . '].' + . "\n" + . $ex->getTraceAsString(); + } + } + +} +?> \ No newline at end of file diff --git a/ptcms/library/bae/images/BaeImageTransform.class.php b/ptcms/library/bae/images/BaeImageTransform.class.php new file mode 100644 index 0000000..69a3190 --- /dev/null +++ b/ptcms/library/bae/images/BaeImageTransform.class.php @@ -0,0 +1,355 @@ + + * such as cropping,rotation,transcode and adjusting lightness an image.
+ * You can consider each operation or simultaneously combine some operations
+ * at one request. + * + */ +class BaeImageTransform extends BaeBase{ + + + private $_arrayErrorMap = array( + '0' => 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_SYS => 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL => 'php sdk init error', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM => 'param invalid', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR + => 'http status is error, and the body returned is not a json string', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR + => 'http status is ok, but the body returned is not a json string', + ); + + private $paramArr; + + private $_requestId; + + public function __construct(){ + $this->paramArr = array(); + $this->_resetErrorStatus(); + } + + public function getRequestId() + { + return $this->_requestId; + } + + private function setParam($key, $value) + { + $this->paramArr[$key] = $value; + } + + public function getOperations() + { + + return $this->paramArr; + } + + /** + * + * @param intZoomingType int,

the zooming type,including height,width and pixel

+ * @param intValue int,

the zooming value,width:0-1000 height:0-1000 + * pixel:0-1000000

+ * @param heightIntValue[optional],

+ * @throws BaeException + */ + public function setZooming($intZoomingType, $intValue, $heightIntValue = 0) + { + //$this->_resetErrorStatus(); + try { + switch ($intZoomingType) { + case BaeImageConstant::TRANSFORM_ZOOMING_TYPE_HEIGHT: + $this->_checkInt($intValue, 'zooming height' , 0, 10000); + $this->setParam('size', 'b0_' . $intValue); + break; + case BaeImageConstant::TRANSFORM_ZOOMING_TYPE_WIDTH: + $this->_checkInt($intValue, 'zooming width' ,0, 10000); + $this->setParam('size', 'b' . $intValue . '_0'); + break; + case BaeImageConstant::TRANSFORM_ZOOMING_TYPE_PIXELS: + $this->_checkInt($intValue, 'zooming pixels' ,0, 100000000); + $this->setParam('size','p' . $intValue); + break; + case BaeImageConstant::TRANSFORM_ZOOMING_TYPE_UNRATIO: + $this->_checkInt($intValue, 'zooming unratio' , 0, 10000); + $this->_checkInt($heightIntValue, 'zooming height(unratio)' , 0, 10000); + $this->setParam('size','u' . $intValue . '_' .$heightIntValue); + break; + default: + throw new BaeException('invalid zooming type parameters', BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Cropping an image + * @param intX int,

start with x coordinates,range:0-10000

+ * @param intY int,

start with y coordinates,range:0-10000

+ * @param intWidth,

end with x+width,range:0-10000

+ * @param intHeight,

end with y+height,range:0-10000

+ */ + public function setCropping($intX, $intY, $intWidth, $intHeight) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intX, 'cut_x' , 0, 10000); + $this->_checkInt($intY, 'cut_y' , 0, 10000); + $this->_checkInt($intHeight, 'cut_h' , 0, 10000); + $this->_checkInt($intWidth, 'cut_w' , 0, 10000); + + $this->setParam('cut_x', $intX); + $this->setParam('cut_y', $intY); + $this->setParam('cut_h', $intHeight); + $this->setParam('cut_w', $intWidth); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Rotating an image with any degree + * @param intDegree int,

the rotating value,range:0-360

+ */ + public function setRotation($intDegree) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intDegree, 'rotate' , 0, 360); + $this->setParam('rotate', $intDegree); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Setting the hue of an image + * @param intHue int,

the hue value,range:1-100

+ */ + public function setHue($intHue) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intHue, 'hue' ,1, 100); + $this->setParam('hue', $intHue); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Setting the lightness of an image + * @param intLightness int,

the lightness value range: bigger than 1

+ */ + public function setLightness($intLightness) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intLightness, 'lightness' , 1); + $this->setParam('lightness', $intLightness); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Setting the contrast of an image + * @param intContrast int,

0 for degenerate,1 for enhance.

+ */ + public function setContrast($intContrast) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intContrast, 'contrast' , 0, 1); + $this->setParam('contrast', $intContrast); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Setting the sharpness of an image + * @param intSharpness int,

the sharpness value,1-100 for sharpen, 101-200 for vague.

+ */ + public function setSharpness($intSharpness) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intSharpness, 'sharpness' , 1, 200); + $this->setParam('sharpen', $intSharpness); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Setting the saturation of an image + * @param intSaturation int,

the saturation value,range:1-100

+ */ + public function setSaturation($intSaturation) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intSaturation, 'saturation', 1, 100); + $this->setParam('saturation',$intSaturation); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Transcoding the output image with a given type + * @param imageType BaeImageConstant,

support by GIF,JPG,WEBP,BMP,PNG

intQuality + * @param intQuality[optional] int,

the quality of an image.range:0-100

+ * @throws BaeException + */ + public function setTranscoding($imageType, $intQuality = 60) + { + //$this->_resetErrorStatus(); + try { + if(!is_integer($imageType)){ + throw new BaeException(sprintf('invalid image type[%s]', $imageType), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + switch ($imageType) { + case BaeImageConstant::GIF: + $this->_checkInt($intQuality, 'quality' , 0, 100); + $this->setParam('quality', $intQuality); + $this->setParam('imgtype', 2); + break; + case BaeImageConstant::JPG: + $this->_checkInt($intQuality, 'quality' , 0, 100); + $this->setParam('quality', $intQuality); + $this->setParam('imgtype', 1); + break; + case BaeImageConstant::PNG: + $this->setParam('imgtype', 3); + break; + case BaeImageConstant::WEBP: + $this->setParam('imgtype', 4); + break; + default: + throw new BaeException(sprintf('invalid image type[%s]', $imageType), + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + /** + * Setting the quality of an image + * @param intQuality int,

the quality value, range:0-100

+ */ + public function setQuality($intQuality = 60) + { + //$this->_resetErrorStatus(); + try { + $this->_checkInt($intQuality, 'quality', 0, 100); + $this->setParam('quality', $intQuality); + } catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + public function setGetGifFirstFrame() + { + $this->setParam('tieba', 1); + return true; + } + + public function setAutorotate() + { + $this->setParam('autorotate', 1); + return true; + } + /** + * Flipping the image horizontally + */ + public function horizontalFlip() + { + $this->setParam('flop', 1); + return true; + } + /** + * Flipping the image vertically + */ + public function verticalFlip() + { + $this->setParam('flip', 1); + return true; + } + /** + * Clear operations + */ + public function clearOperations(){ + $this->paramArr = array(); + return true; + } + + private function _resetErrorStatus() + { + $this->errcode = 0; + $this->errmsg = $this->_arrayErrorMap[$this->errcode]; + $this->_requestId = 0; + } + + private function _exceptionHandler($ex) + { + $tmpCode = $ex->getCode(); + if (0 === $tmpCode) { + $tmpCode = BaeImageConstant::BAE_IMAGEUI_SDK_SYS; + } + + $this->errcode = $tmpCode; + if ($this->errcode >= 30000) { + $this->errmsg = $ex->getMessage(); + } else { + $this->errmsg = $this->_arrayErrorMap[$this->errcode] + . ', detail info[' . $ex->getMessage() + . ', break point: ' . $ex->getFile(). ':' . $ex->getLine() . '].' + . "\n" + . $ex->getTraceAsString(); + } + } + + private function _checkInt($num, $prompt, $intMin = -1, $intMax = -1) + { + if (!is_integer($num)) { + throw new BaeException(sprintf('[%s] parameter not an integer', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMin !== -1 && $num < $intMin) { + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMax !== -1 && $intMax < $num) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkString($str, $min, $max) + { + if (is_string($str) && strlen($str) >= $min && strlen($str) <= $max) { + return true; + } + return false; + } +} diff --git a/ptcms/library/bae/images/BaeImageVCode.class.php b/ptcms/library/bae/images/BaeImageVCode.class.php new file mode 100644 index 0000000..6f5ccf7 --- /dev/null +++ b/ptcms/library/bae/images/BaeImageVCode.class.php @@ -0,0 +1,173 @@ + 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_SYS => 'php sdk error', + BaeImageConstant::BAE_IMAGEUI_SDK_INIT_FAIL => 'php sdk init error', + BaeImageConstant::BAE_IMAGEUI_SDK_PARAM => 'param invalid', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_ERROR_AND_RESULT_ERROR + => 'http status is error, and the body returned is not a json string', + BaeImageConstant::BAE_IMAGEUI_SDK_HTTP_STATUS_OK_BUT_RESULT_ERROR + => 'http status is ok, but the body returned is not a json string', + ); + + public function __construct() + { + $this->_resetErrorStatus(); + $this->paramArr = array('len'=>4,'setno'=>0); + } + public function getOperations() + { + return $this->paramArr; + } + + private function setParam($key, $value) + { + $this->paramArr[$key] = $value; + } + /** + * The bits of the verification code + * @param intLen integer,

range:4-5

+ */ + public function setLen($intLen) + { + try { + $this->_checkInt($intLen, 'verification code len', 4, 5); + $this->setParam('len', $intLen); + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + /** + * The pattern of the verification code + * @param pattern integer,

range:0-3

+ */ + public function setPattern($pattern) + { + try { + $this->_checkInt($pattern, 'verification code pattern', 0, 3); + $this->setParam('setno', $pattern); + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + /** + * The input to verify + * @param strInput string,

range:4-5

+ */ + public function setInput($strInput) + { + try { + $this->_checkString($strInput, 'vcode.input' ,4, 5); + $this->setParam('input', $strInput); + $this->input = $strInput; + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + + public function getInput(){ + return $this->input; + } + + /** + * The secret text of the verification code + * @param strSecret string,

range:without restriction

+ */ + public function setSecret($strSecret) + { + try { + $this->_checkString($strSecret,'vcode.secret', 368, 368);//without restriction + $this->setParam('vcode', $strSecret); + $this->strSecret = $strSecret; + }catch (Exception $ex) { + $this->_exceptionHandler($ex); + return false; + } + return true; + } + public function getSecret(){ + return $this->strSecret; + } + + public function clearOperations() + { + $this->paramArr = array(); + return true; + } + + private function _checkInt($num, $prompt, $intMin = -1, $intMax = -1) + { + if (!is_integer($num)) { + throw new BaeException(sprintf('[%s] parameter not an integer', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMin !== -1 && $num < $intMin) { + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if ($intMax !== -1 && $intMax < $num) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _checkString($str, $prompt, $min=null, $max=null) + { + if (!is_string($str)){ + throw new BaeException(sprintf('[%s] parameter not a string', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($min !== null && strlen($str) < $min){ + throw new BaeException(sprintf('[%s] parameter less than minimum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + if($max !== null && strlen($str) > $max) { + throw new BaeException(sprintf('[%s] parameter greater than maximum', $prompt), BaeImageConstant::BAE_IMAGEUI_SDK_PARAM); + } + } + + private function _resetErrorStatus() + { + $this->errcode = 0; + $this->errmsg = $this->_arrayErrorMap[$this->errcode]; + $this->_requestId = 0; + } + + private function _exceptionHandler($ex) + { + $tmpCode = $ex->getCode(); + if (0 === $tmpCode) { + $tmpCode = BaeImageConstant::BAE_IMAGEUI_SDK_SYS; + } + + $this->errcode = $tmpCode; + if ($this->errcode >= 30000) { + $this->errmsg = $ex->getMessage(); + } else { + $this->errmsg = $this->_arrayErrorMap[$this->errcode] + . ', detail info[' . $ex->getMessage() + . ', break point: ' . $ex->getFile(). ':' . $ex->getLine() . '].' + . "\n" + . $ex->getTraceAsString(); + } + } +} \ No newline at end of file diff --git a/ptcms/library/bae/lib/BaeBase.class.php b/ptcms/library/bae/lib/BaeBase.class.php new file mode 100644 index 0000000..7fd1a22 --- /dev/null +++ b/ptcms/library/bae/lib/BaeBase.class.php @@ -0,0 +1,78 @@ +'; + debug_print_backtrace(); + echo ''; + trigger_error($error_msg, $error_type); + } + + /** + * @brief return the handle + * + */ + public function getHandle() + { + return $this->_handle; + } + + /** + * @brief return the error message + * + */ + public function errmsg() + { + return $this->errmsg; + } + + /** + * @brief return the error code + * + */ + public function errno() + { + return $this->errcode; + } + +} + +/* vim: set ts=4 sw=4 sts=4 tw=100 noet: */ +?> \ No newline at end of file diff --git a/ptcms/library/bae/lib/BaeException.class.php b/ptcms/library/bae/lib/BaeException.class.php new file mode 100644 index 0000000..39686ad --- /dev/null +++ b/ptcms/library/bae/lib/BaeException.class.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/ptcms/library/bae/lib/BaeTaskQueueException.class.php b/ptcms/library/bae/lib/BaeTaskQueueException.class.php new file mode 100644 index 0000000..2ffb584 --- /dev/null +++ b/ptcms/library/bae/lib/BaeTaskQueueException.class.php @@ -0,0 +1,6 @@ + diff --git a/ptcms/library/bae/lib/BccsServerException.class.php b/ptcms/library/bae/lib/BccsServerException.class.php new file mode 100644 index 0000000..4987923 --- /dev/null +++ b/ptcms/library/bae/lib/BccsServerException.class.php @@ -0,0 +1,6 @@ + diff --git a/ptcms/library/bae/lib/BcmsException.class.php b/ptcms/library/bae/lib/BcmsException.class.php new file mode 100644 index 0000000..cacd6c3 --- /dev/null +++ b/ptcms/library/bae/lib/BcmsException.class.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/ptcms/library/bae/lib/ChannelException.class.php b/ptcms/library/bae/lib/ChannelException.class.php new file mode 100644 index 0000000..ef7d02e --- /dev/null +++ b/ptcms/library/bae/lib/ChannelException.class.php @@ -0,0 +1,6 @@ + diff --git a/ptcms/library/bae/lib/CronException.class.php b/ptcms/library/bae/lib/CronException.class.php new file mode 100644 index 0000000..175f223 --- /dev/null +++ b/ptcms/library/bae/lib/CronException.class.php @@ -0,0 +1,6 @@ + diff --git a/ptcms/library/bae/lib/RequestCore.class.php b/ptcms/library/bae/lib/RequestCore.class.php new file mode 100644 index 0000000..8b6c85e --- /dev/null +++ b/ptcms/library/bae/lib/RequestCore.class.php @@ -0,0 +1,773 @@ +). + */ + public $request_class = 'RequestCore'; + /** + * The default class to use for HTTP Responses (defaults to ). + */ + public $response_class = 'ResponseCore'; + /** + * Default useragent string to use. + */ + public $useragent = 'RequestCore/1.4.2'; + /** + * File to read from while streaming up. + */ + public $read_file = null; + /** + * The resource to read from while streaming up. + */ + public $read_stream = null; + /** + * The size of the stream to read from. + */ + public $read_stream_size = null; + /** + * The length already read from the stream. + */ + public $read_stream_read = 0; + /** + * File to write to while streaming down. + */ + public $write_file = null; + /** + * The resource to write to while streaming down. + */ + public $write_stream = null; + /** + * Stores the intended starting seek position. + */ + public $seek_position = null; + /** + * The user-defined callback function to call when a stream is read from. + */ + public $registered_streaming_read_callback = null; + /** + * The user-defined callback function to call when a stream is written to. + */ + public $registered_streaming_write_callback = null; + /*%******************************************************************************************%*/ + // CONSTANTS + /** + * GET HTTP Method + */ + const HTTP_GET = 'GET'; + /** + * POST HTTP Method + */ + const HTTP_POST = 'POST'; + /** + * PUT HTTP Method + */ + const HTTP_PUT = 'PUT'; + /** + * DELETE HTTP Method + */ + const HTTP_DELETE = 'DELETE'; + /** + * HEAD HTTP Method + */ + const HTTP_HEAD = 'HEAD'; + /*%******************************************************************************************%*/ + // CONSTRUCTOR/DESTRUCTOR + /** + * Constructs a new instance of this class. + * + * @param string $url (Optional) The URL to request or service endpoint to query. + * @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class. + * @return $this A reference to the current instance. + */ + public function __construct($url = null, $proxy = null, $helpers = null) { + // Set some default values. + $this->request_url = $url; + $this->method = self::HTTP_GET; + $this->request_headers = array (); + $this->request_body = ''; + // Set a new Request class if one was set. + if (isset ( $helpers ['request'] ) && ! empty ( $helpers ['request'] )) { + $this->request_class = $helpers ['request']; + } + // Set a new Request class if one was set. + if (isset ( $helpers ['response'] ) && ! empty ( $helpers ['response'] )) { + $this->response_class = $helpers ['response']; + } + if ($proxy) { + $this->set_proxy ( $proxy ); + } + return $this; + } + /** + * Destructs the instance. Closes opened file handles. + * + * @return $this A reference to the current instance. + */ + public function __destruct() { + if (isset ( $this->read_file ) && isset ( $this->read_stream )) { + fclose ( $this->read_stream ); + } + if (isset ( $this->write_file ) && isset ( $this->write_stream )) { + fclose ( $this->write_stream ); + } + return $this; + } + /*%******************************************************************************************%*/ + // REQUEST METHODS + /** + * Sets the credentials to use for authentication. + * + * @param string $user (Required) The username to authenticate with. + * @param string $pass (Required) The password to authenticate with. + * @return $this A reference to the current instance. + */ + public function set_credentials($user, $pass) { + $this->username = $user; + $this->password = $pass; + return $this; + } + /** + * Adds a custom HTTP header to the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @param mixed $value (Required) The value to assign to the custom HTTP header. + * @return $this A reference to the current instance. + */ + public function add_header($key, $value) { + $this->request_headers [$key] = $value; + return $this; + } + /** + * Removes an HTTP header from the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @return $this A reference to the current instance. + */ + public function remove_header($key) { + if (isset ( $this->request_headers [$key] )) { + unset ( $this->request_headers [$key] ); + } + return $this; + } + /** + * Set the method type for the request. + * + * @param string $method (Required) One of the following constants: , , , , . + * @return $this A reference to the current instance. + */ + public function set_method($method) { + $this->method = strtoupper ( $method ); + return $this; + } + /** + * Sets a custom useragent string for the class. + * + * @param string $ua (Required) The useragent string to use. + * @return $this A reference to the current instance. + */ + public function set_useragent($ua) { + $this->useragent = $ua; + return $this; + } + /** + * Set the body to send in the request. + * + * @param string $body (Required) The textual content to send along in the body of the request. + * @return $this A reference to the current instance. + */ + public function set_body($body) { + $this->request_body = $body; + return $this; + } + /** + * Set the URL to make the request to. + * + * @param string $url (Required) The URL to make the request to. + * @return $this A reference to the current instance. + */ + public function set_request_url($url) { + $this->request_url = $url; + return $this; + } + /** + * Set additional CURLOPT settings. These will merge with the default settings, and override if + * there is a duplicate. + * + * @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings. + * @return $this A reference to the current instance. + */ + public function set_curlopts($curlopts) { + $this->curlopts = $curlopts; + return $this; + } + /** + * Sets the length in bytes to read from the stream while streaming up. + * + * @param integer $size (Required) The length in bytes to read from the stream. + * @return $this A reference to the current instance. + */ + public function set_read_stream_size($size) { + $this->read_stream_size = $size; + return $this; + } + /** + * Sets the resource to read from while streaming up. Reads the stream from its current position until + * EOF or `$size` bytes have been read. If `$size` is not given it will be determined by and + * . + * + * @param resource $resource (Required) The readable resource to read from. + * @param integer $size (Optional) The size of the stream to read. + * @return $this A reference to the current instance. + */ + public function set_read_stream($resource, $size = null) { + if (! isset ( $size ) || $size < 0) { + $stats = fstat ( $resource ); + if ($stats && $stats ['size'] >= 0) { + $position = ftell ( $resource ); + if ($position !== false && $position >= 0) { + $size = $stats ['size'] - $position; + } + } + } + $this->read_stream = $resource; + return $this->set_read_stream_size ( $size ); + } + /** + * Sets the file to read from while streaming up. + * + * @param string $location (Required) The readable location to read from. + * @return $this A reference to the current instance. + */ + public function set_read_file($location) { + $this->read_file = $location; + $read_file_handle = fopen ( $location, 'r' ); + return $this->set_read_stream ( $read_file_handle ); + } + /** + * Sets the resource to write to while streaming down. + * + * @param resource $resource (Required) The writeable resource to write to. + * @return $this A reference to the current instance. + */ + public function set_write_stream($resource) { + $this->write_stream = $resource; + return $this; + } + /** + * Sets the file to write to while streaming down. + * + * @param string $location (Required) The writeable location to write to. + * @return $this A reference to the current instance. + */ + public function set_write_file($location) { + $this->write_file = $location; + $write_file_handle = fopen ( $location, 'w' ); + return $this->set_write_stream ( $write_file_handle ); + } + /** + * Set the proxy to use for making requests. + * + * @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @return $this A reference to the current instance. + */ + public function set_proxy($proxy) { + $proxy = parse_url ( $proxy ); + $proxy ['user'] = isset ( $proxy ['user'] ) ? $proxy ['user'] : null; + $proxy ['pass'] = isset ( $proxy ['pass'] ) ? $proxy ['pass'] : null; + $proxy ['port'] = isset ( $proxy ['port'] ) ? $proxy ['port'] : null; + $this->proxy = $proxy; + return $this; + } + /** + * Set the intended starting seek position. + * + * @param integer $position (Required) The byte-position of the stream to begin reading from. + * @return $this A reference to the current instance. + */ + public function set_seek_position($position) { + $this->seek_position = isset ( $position ) ? ( integer ) $position : null; + return $this; + } + /** + * Register a callback function to execute whenever a data stream is read from using + * . + * + * The user-defined callback function should accept three arguments: + * + *
    + *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • + *
  • $file_handle - resource - Required - The file handle resource that represents the file on the local file system.
  • + *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • + *
+ * + * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    + *
  • The name of a global function to execute, passed as a string.
  • + *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • + *
  • An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance. + */ + public function register_streaming_read_callback($callback) { + $this->registered_streaming_read_callback = $callback; + return $this; + } + /** + * Register a callback function to execute whenever a data stream is written to using + * . + * + * The user-defined callback function should accept two arguments: + * + *
    + *
  • $curl_handle - resource - Required - The cURL handle resource that represents the in-progress transfer.
  • + *
  • $length - integer - Required - The length in kilobytes of the data chunk that was transferred.
  • + *
+ * + * @param string|array|function $callback (Required) The callback function is called by , so you can pass the following values:
    + *
  • The name of a global function to execute, passed as a string.
  • + *
  • A method to execute, passed as array('ClassName', 'MethodName').
  • + *
  • An anonymous function (PHP 5.3+).
+ * @return $this A reference to the current instance. + */ + public function register_streaming_write_callback($callback) { + $this->registered_streaming_write_callback = $callback; + return $this; + } + /*%******************************************************************************************%*/ + // PREPARE, SEND, AND PROCESS REQUEST + /** + * A callback function that is invoked by cURL for streaming up. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param resource $file_handle (Required) The open file handle resource. + * @param integer $length (Required) The maximum number of bytes to read. + * @return binary Binary data from a stream. + */ + public function streaming_read_callback($curl_handle, $file_handle, $length) { + // Once we've sent as much as we're supposed to send... + if ($this->read_stream_read >= $this->read_stream_size) { + // Send EOF + return ''; + } + // If we're at the beginning of an upload and need to seek... + if ($this->read_stream_read == 0 && isset ( $this->seek_position ) && $this->seek_position !== ftell ( $this->read_stream )) { + if (fseek ( $this->read_stream, $this->seek_position ) !== 0) { + throw new RequestCore_Exception ( 'The stream does not support seeking and is either not at the requested position or the position is unknown.' ); + } + } + $read = fread ( $this->read_stream, min ( $this->read_stream_size - $this->read_stream_read, $length ) ); // Remaining upload data or cURL's requested chunk size + $this->read_stream_read += strlen ( $read ); + $out = $read === false ? '' : $read; + // Execute callback function + if ($this->registered_streaming_read_callback) { + call_user_func ( $this->registered_streaming_read_callback, $curl_handle, $file_handle, $out ); + } + return $out; + } + /** + * A callback function that is invoked by cURL for streaming down. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param binary $data (Required) The data to write. + * @return integer The number of bytes written. + */ + public function streaming_write_callback($curl_handle, $data) { + $length = strlen ( $data ); + $written_total = 0; + $written_last = 0; + while ( $written_total < $length ) { + $written_last = fwrite ( $this->write_stream, substr ( $data, $written_total ) ); + if ($written_last === false) { + return $written_total; + } + $written_total += $written_last; + } + // Execute callback function + if ($this->registered_streaming_write_callback) { + call_user_func ( $this->registered_streaming_write_callback, $curl_handle, $written_total ); + } + return $written_total; + } + /** + * Prepares and adds the details of the cURL request. This can be passed along to a + * function. + * + * @return resource The handle for the cURL object. + */ + public function prep_request() { + $curl_handle = curl_init (); + // Set default options. + curl_setopt ( $curl_handle, CURLOPT_URL, $this->request_url ); + curl_setopt ( $curl_handle, CURLOPT_FILETIME, true ); + curl_setopt ( $curl_handle, CURLOPT_FRESH_CONNECT, false ); + curl_setopt ( $curl_handle, CURLOPT_SSL_VERIFYPEER, false ); + @ curl_setopt ( $curl_handle, CURLOPT_SSL_VERIFYHOST, true ); + curl_setopt ( $curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED ); + curl_setopt ( $curl_handle, CURLOPT_MAXREDIRS, 5 ); + curl_setopt ( $curl_handle, CURLOPT_HEADER, true ); + curl_setopt ( $curl_handle, CURLOPT_RETURNTRANSFER, true ); + curl_setopt ( $curl_handle, CURLOPT_TIMEOUT, 5184000 ); + curl_setopt ( $curl_handle, CURLOPT_CONNECTTIMEOUT, 120 ); + curl_setopt ( $curl_handle, CURLOPT_NOSIGNAL, true ); + curl_setopt ( $curl_handle, CURLOPT_REFERER, $this->request_url ); + curl_setopt ( $curl_handle, CURLOPT_USERAGENT, $this->useragent ); + curl_setopt ( $curl_handle, CURLOPT_READFUNCTION, array ( + $this, 'streaming_read_callback' ) ); + if ($this->debug_mode) { + curl_setopt ( $curl_handle, CURLOPT_VERBOSE, true ); + } + if (! ini_get ( 'safe_mode' )) { + //modify by zhengkan + //curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true); + } + // Enable a proxy connection if requested. + if ($this->proxy) { + curl_setopt ( $curl_handle, CURLOPT_HTTPPROXYTUNNEL, true ); + $host = $this->proxy ['host']; + $host .= ($this->proxy ['port']) ? ':' . $this->proxy ['port'] : ''; + curl_setopt ( $curl_handle, CURLOPT_PROXY, $host ); + if (isset ( $this->proxy ['user'] ) && isset ( $this->proxy ['pass'] )) { + curl_setopt ( $curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy ['user'] . ':' . $this->proxy ['pass'] ); + } + } + // Set credentials for HTTP Basic/Digest Authentication. + if ($this->username && $this->password) { + curl_setopt ( $curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY ); + curl_setopt ( $curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password ); + } + // Handle the encoding if we can. + if (extension_loaded ( 'zlib' )) { + curl_setopt ( $curl_handle, CURLOPT_ENCODING, '' ); + } + // Process custom headers + if (isset ( $this->request_headers ) && count ( $this->request_headers )) { + $temp_headers = array (); + foreach ( $this->request_headers as $k => $v ) { + $temp_headers [] = $k . ': ' . $v; + } + curl_setopt ( $curl_handle, CURLOPT_HTTPHEADER, $temp_headers ); + } + switch ($this->method) { + case self::HTTP_PUT : + curl_setopt ( $curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT' ); + if (isset ( $this->read_stream )) { + if (! isset ( $this->read_stream_size ) || $this->read_stream_size < 0) { + throw new RequestCore_Exception ( 'The stream size for the streaming upload cannot be determined.' ); + } + curl_setopt ( $curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size ); + curl_setopt ( $curl_handle, CURLOPT_UPLOAD, true ); + } else { + curl_setopt ( $curl_handle, CURLOPT_POSTFIELDS, $this->request_body ); + } + break; + case self::HTTP_POST : + curl_setopt ( $curl_handle, CURLOPT_POST, true ); + curl_setopt ( $curl_handle, CURLOPT_POSTFIELDS, $this->request_body ); + break; + case self::HTTP_HEAD : + curl_setopt ( $curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD ); + curl_setopt ( $curl_handle, CURLOPT_NOBODY, 1 ); + break; + default : // Assumed GET + curl_setopt ( $curl_handle, CURLOPT_CUSTOMREQUEST, $this->method ); + if (isset ( $this->write_stream )) { + curl_setopt ( $curl_handle, CURLOPT_WRITEFUNCTION, array ( + $this, 'streaming_write_callback' ) ); + curl_setopt ( $curl_handle, CURLOPT_HEADER, false ); + } else { + curl_setopt ( $curl_handle, CURLOPT_POSTFIELDS, $this->request_body ); + } + break; + } + // Merge in the CURLOPTs + if (isset ( $this->curlopts ) && sizeof ( $this->curlopts ) > 0) { + foreach ( $this->curlopts as $k => $v ) { + curl_setopt ( $curl_handle, $k, $v ); + } + } + return $curl_handle; + } + /** + * Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the + * data stored in the `curl_handle` and `response` properties unless replacement data is passed in via + * parameters. + * + * @param resource $curl_handle (Optional) The reference to the already executed cURL request. + * @param string $response (Optional) The actual response content itself that needs to be parsed. + * @return ResponseCore A object containing a parsed HTTP response. + */ + public function process_response($curl_handle = null, $response = null) { + // Accept a custom one if it's passed. + if ($curl_handle && $response) { + $this->curl_handle = $curl_handle; + $this->response = $response; + } + // As long as this came back as a valid resource... + if (is_resource ( $this->curl_handle )) { + // Determine what's what. + $header_size = curl_getinfo ( $this->curl_handle, CURLINFO_HEADER_SIZE ); + $this->response_headers = substr ( $this->response, 0, $header_size ); + $this->response_body = substr ( $this->response, $header_size ); + $this->response_code = curl_getinfo ( $this->curl_handle, CURLINFO_HTTP_CODE ); + $this->response_info = curl_getinfo ( $this->curl_handle ); + // Parse out the headers + $this->response_headers = explode ( "\r\n\r\n", trim ( $this->response_headers ) ); + $this->response_headers = array_pop ( $this->response_headers ); + $this->response_headers = explode ( "\r\n", $this->response_headers ); + array_shift ( $this->response_headers ); + // Loop through and split up the headers. + $header_assoc = array (); + foreach ( $this->response_headers as $header ) { + $kv = explode ( ': ', $header ); + //$header_assoc [strtolower ( $kv [0] )] = $kv [1]; + $header_assoc [$kv [0]] = $kv [1]; + } + // Reset the headers to the appropriate property. + $this->response_headers = $header_assoc; + $this->response_headers ['_info'] = $this->response_info; + $this->response_headers ['_info'] ['method'] = $this->method; + if ($curl_handle && $response) { + return new $this->response_class ( $this->response_headers, $this->response_body, $this->response_code, $this->curl_handle ); + } + } + // Return false + return false; + } + /** + * Sends the request, calling necessary utility functions to update built-in properties. + * + * @param boolean $parse (Optional) Whether to parse the response with ResponseCore or not. + * @return string The resulting unparsed data from the request. + */ + public function send_request($parse = false) { + $curl_handle = $this->prep_request (); + $this->response = curl_exec ( $curl_handle ); + if ($this->response === false) { + throw new RequestCore_Exception ( 'cURL resource: ' . ( string ) $curl_handle . '; cURL error: ' . curl_error ( $curl_handle ) . ' (' . curl_errno ( $curl_handle ) . ')' ); + } + $parsed_response = $this->process_response ( $curl_handle, $this->response ); + curl_close ( $curl_handle ); + if ($parse) { + return $parsed_response; + } + return $this->response; + } + /** + * Sends the request using , enabling parallel requests. Uses the "rolling" method. + * + * @param array $handles (Required) An indexed array of cURL handles to process simultaneously. + * @param array $opt (Optional) An associative array of parameters that can have the following keys:
    + *
  • callback - string|array - Optional - The string name of a function to pass the response data to. If this is a method, pass an array where the [0] index is the class and the [1] index is the method name.
  • + *
  • limit - integer - Optional - The number of simultaneous requests to make. This can be useful for scaling around slow server responses. Defaults to trusting cURLs judgement as to how many to use.
+ * @return array Post-processed cURL responses. + */ + public function send_multi_request($handles, $opt = null) { + // Skip everything if there are no handles to process. + if (count ( $handles ) === 0) + return array (); + if (! $opt) + $opt = array (); + + // Initialize any missing options + $limit = isset ( $opt ['limit'] ) ? $opt ['limit'] : - 1; + // Initialize + $handle_list = $handles; + $http = new $this->request_class (); + $multi_handle = curl_multi_init (); + $handles_post = array (); + $added = count ( $handles ); + $last_handle = null; + $count = 0; + $i = 0; + // Loop through the cURL handles and add as many as it set by the limit parameter. + while ( $i < $added ) { + if ($limit > 0 && $i >= $limit) + break; + curl_multi_add_handle ( $multi_handle, array_shift ( $handles ) ); + $i ++; + } + do { + $active = false; + // Start executing and wait for a response. + while ( ($status = curl_multi_exec ( $multi_handle, $active )) === CURLM_CALL_MULTI_PERFORM ) { + // Start looking for possible responses immediately when we have to add more handles + if (count ( $handles ) > 0) + break; + } + // Figure out which requests finished. + $to_process = array (); + while ( $done = curl_multi_info_read ( $multi_handle ) ) { + // Since curl_errno() isn't reliable for handles that were in multirequests, we check the 'result' of the info read, which contains the curl error number, (listed here http://curl.haxx.se/libcurl/c/libcurl-errors.html ) + if ($done ['result'] > 0) { + throw new RequestCore_Exception ( 'cURL resource: ' . ( string ) $done ['handle'] . '; cURL error: ' . curl_error ( $done ['handle'] ) . ' (' . $done ['result'] . ')' ); + } // Because curl_multi_info_read() might return more than one message about a request, we check to see if this request is already in our array of completed requests +elseif (! isset ( $to_process [( int ) $done ['handle']] )) { + $to_process [( int ) $done ['handle']] = $done; + } + } + // Actually deal with the request + foreach ( $to_process as $pkey => $done ) { + $response = $http->process_response ( $done ['handle'], curl_multi_getcontent ( $done ['handle'] ) ); + $key = array_search ( $done ['handle'], $handle_list, true ); + $handles_post [$key] = $response; + if (count ( $handles ) > 0) { + curl_multi_add_handle ( $multi_handle, array_shift ( $handles ) ); + } + curl_multi_remove_handle ( $multi_handle, $done ['handle'] ); + curl_close ( $done ['handle'] ); + } + } while ( $active || count ( $handles_post ) < $added ); + curl_multi_close ( $multi_handle ); + ksort ( $handles_post, SORT_NUMERIC ); + return $handles_post; + } + /*%******************************************************************************************%*/ + // RESPONSE METHODS + /** + * Get the HTTP response headers from the request. + * + * @param string $header (Optional) A specific header value to return. Defaults to all headers. + * @return string|array All or selected header values. + */ + public function get_response_header($header = null) { + if ($header) { + // return $this->response_headers [strtolower ( $header )]; + return $this->response_headers [$header]; + } + return $this->response_headers; + } + /** + * Get the HTTP response body from the request. + * + * @return string The response body. + */ + public function get_response_body() { + return $this->response_body; + } + /** + * Get the HTTP response code from the request. + * + * @return string The HTTP response code. + */ + public function get_response_code() { + return $this->response_code; + } +} +/** + * Container for all response-related methods. + */ +class ResponseCore { + /** + * Stores the HTTP header information. + */ + public $header; + /** + * Stores the SimpleXML response. + */ + public $body; + /** + * Stores the HTTP response code. + */ + public $status; + /** + * Constructs a new instance of this class. + * + * @param array $header (Required) Associative array of HTTP headers (typically returned by ). + * @param string $body (Required) XML-formatted response from AWS. + * @param integer $status (Optional) HTTP response status code from the request. + * @return object Contains an `header` property (HTTP headers as an associative array), a or `body` property, and an `status` code. + */ + public function __construct($header, $body, $status = null) { + $this->header = $header; + $this->body = $body; + $this->status = $status; + return $this; + } + /** + * Did we receive the status code we expected? + * + * @param integer|array $codes (Optional) The status code(s) to expect. Pass an for a single acceptable value, or an of integers for multiple acceptable values. + * @return boolean Whether we received the expected status code or not. + */ + public function isOK($codes = array(200, 201, 204, 206)) { + if (is_array ( $codes )) { + return in_array ( $this->status, $codes ); + } + return $this->status === $codes; + } +} +/** + * Default RequestCore Exception. + */ +class RequestCore_Exception extends Exception { +} diff --git a/ptcms/library/bae/zcache/memcache_errno.php b/ptcms/library/bae/zcache/memcache_errno.php new file mode 100644 index 0000000..96eede5 --- /dev/null +++ b/ptcms/library/bae/zcache/memcache_errno.php @@ -0,0 +1,26 @@ + "RES_PAYLOAD_FAILURE", + "0" => "RES_SUCCESS", + "1" => "RES_FAILURE", + "2" => "RES_USER_AUTH_FAILURE", + "7" => "RES_UNKNOWN_READ_FAILURE", + "8" => "RES_PROTOCOL_ERROR", + "9" => "RES_CLIENT_ERROR", + "10" => "RES_SERVER_ERROR", + "5" => "RES_WRITE_FAILURE", + "12" => "RES_DATA_EXISTS", + "14" => "RES_NOTSTORED", + "16" => "RES_NOTFOUND", + "18" => "RES_PARTIAL_READ", + "19" => "RES_SOME_ERRORS", + "20" => "RES_NO_SERVERS", + "21" => "RES_SERVER_BUSY", + "26" => "RES_ERRNO", + "32" => "RES_BUFFERED", + "31" => "RES_TIMEOUT", + "33" => "RES_BAD_KEY_PROVIDED", + "11" => "RES_CONNECTION_SOCKET_CREATE_FAILURE", + + ); + + private $errnomap = array ( + + ZCACHE_AGENT_ERR_PARAM => RES_CLIENT_ERROR, + ZCACHE_AGENT_ERR_MCPACK => RES_PROTOCOL_ERROR, + ZCACHE_AGENT_ERR_MEM => RES_SERVER_ERROR, + ZCACHE_AGENT_ERR_MCPACK_OP => RES_PROTOCOL_ERROR, + + ZCACHE_OK => RES_SUCCESS, + ZCACHE_ERR_PARAM => RES_CLIENT_ERROR, + ZCACHE_ERR_NOT_AUTH => RES_HOST_LOOKUP_FAILURE, + ZCACHE_ERR_BUF_NOT_ENOUGH => RES_BUFFERED, + ZCACHE_ERR_EXIST => RES_DATA_EXISTS, + ZCACHE_ERR_NOT_EXIST => RES_NOTFOUND, + ZCACHE_ERR_BLOCK_NOT_EXIST => RES_SERVER_ERROR, + ZCACHE_ERR_PRODUCT_NOT_EXIST => RES_SERVER_ERROR, + ZCACHE_ERR_BUSY => RES_END, + ZCACHE_ERR_FROZEN_DELETE => RES_SERVER_ERROR, + ZCACHE_ERR_BLOCK_UPDATED => RES_SERVER_ERROR, + ZCACHE_ERR_TIMEOUT => RES_TIMEOUT, + ZCACHE_ERR_NET => RES_SERVER_ERROR, + ZCACHE_ERR_MEM => RES_SERVER_ERROR, + ZCACHE_ERR_DISK => RES_SERVER_ERROR, + ZCACHE_ERR_METASERVER => RES_SERVER_ERROR, + ZCACHE_ERR_CACHESERVER => RES_SERVER_ERROR, + ZCACHE_ERR_LIB => RES_SERVER_ERROR, + ZCACHE_ERR_PART_SUC => RES_SERVER_ERROR, + ZCACHE_ERR_BLOCK_WRONG_STATE => RES_SERVER_ERROR, + ZCACHE_APIPLUS_INIT_FAIL => RES_SERVER_ERROR, + ZCACHE_ERR_CREATE_PRDT_FILE => RES_SERVER_ERROR, + ZCACHE_ERR_PRODUCT_ALREADY_EXIST => RES_SERVER_ERROR, + + ZCACHE_CLIENT_ERR_PARAM => RES_CLIENT_ERROR, + ZCACHE_CLIENT_ERR_CONNECT => RES_CONNECTION_SOCKET_CREATE_FAILURE, + ZCACHE_CLIENT_ERR_READ => RES_UNKNOWN_READ_FAILURE, + ZCACHE_CLIENT_ERR_WRITE => RES_WRITE_FAILURE, + ZCACHE_CLIENT_ERR_NSHEAD => RES_PROTOCOL_ERROR, + ZCACHE_CLIENT_ERR_MCPACK => RES_PROTOCOL_ERROR, + + ); + + private $_adapter; + private $_pname_str; + private $_token_str; + private $_logid_int; + private $_appid; + public $_last_errno; + + private function _convertErrno($errcode) { + if (array_key_exists($errcode, $this->errnomap)) { + return $this->errnomap[$errcode]; + } + return RES_SOME_ERRORS; + } + + private function _log($output) { + if(ENABLE_DEBUG !== 0) { + echo "--memcached: $output"; + } + } + + public function _convertErrmsg($errcode) { + if (array_key_exists(strval($errcode), $this->errmsgmap)) { + return $this->errmsgmap[strval($errcode)]; + } + return "RES_SOME_ERRORS"; + } + + public function __construct($cache_id, $memcache_addr, $user, $password) { + $cnfobj = new ZCacheConf(); + //$cnfobj->PERSISTENT = 0; + $cnfobj->CONNTIMEOUT = 1; + $cnfobj->MCPACK_VERSION = PHP_MC_PACK_V2; + + //retry time + $cnfobj->RETRYTIME = 3; + + $zcache_addrs = $memcache_addr; + + if($zcache_addrs === false) { + throw new MemcachedMeException("Missing cache server address"); + } + + $addr_arr = explode(",", $zcache_addrs); + if($addr_arr === false) { + throw new MemcachedMeException("invalid cache server address"); + } + + foreach($addr_arr as $addr) { + $ipport = explode(":", $addr); + if($ipport === false) { + throw new MemcachedMeException("invalid cache server address"); + } + $cnfobj->agent_servers[] = array( + "socket_address" => $ipport[0], + "socket_port" => intval($ipport[1]), + "socket_timeout" => 500 + ); + } + if(!$this->_getInitEnv($cache_id, $user, $password)) { + throw new MemcachedMeException("invalid cache evn"); + } + $this->_adapter = new ZCache($cnfobj); + $this->_adapter->set_shareAppid($this->_appid); + $this->_last_errno = RES_SUCCESS; + } + private function _getInitEnv($cache_id, $user, $password) { + $pname_str = $user; + $token_str = $password; + $logid_int = 1; + + $appid = $cache_id; + + if($pname_str === false || $token_str === false || $logid_int === false || $appid === false) { + $this->_log("Please setup HTTP_BAE_ENV_AK, HTTP_BAE_ENV_SK, HTTP_BAE_ENV_APPID\n"); + return false; + } + $logid_int = intval($logid_int); + $this->_pname_str = $pname_str; + $this->_token_str = $token_str; + $this->_logid_int = $logid_int; + $this->_appid = $appid; + + return true; + } + + private function _getEnv(&$pname_str, &$token_str, &$logid_int) { + $pname_str = $this->_pname_str; + $token_str = $this->_token_str; + $logid_int = $this->_logid_int; + + return true; + } + + private function _checkParamValue($value) { + if(!is_string($value)) + return true; + + $len = strlen($value); + if($len == 0 || $len > ZCACHE_MAX_VALUE_LEN) { + return false; + } + return true; + } + + private function _convertKey($key) { + if(is_numeric($key)) + return strval($key); + return $key; + } + + private function _convertValue($value) { + if(is_int($value)) { + $res = strval($value); + } else if(is_float($value)) { + $res = serialize(strval($value)); + } else if(is_string($value)) { + if(is_numeric($value)) { + if(strstr($value, ".") !== false) { ### float + $res = serialize(strval($value)); + } else + $res = $value; + } + $res = serialize($value); + } else { + $res = serialize($value); + } + + if($this->_checkParamValue($res) === false) return false; + else return $res; + } + + private function _convertOffset($offset) { + if(is_numeric($offset)) + return intval($offset); + return 0; + } + + private function _unconvertResult($result) { + if(!is_numeric($result)) { + return unserialize($result); + } + return $result; + } + + public function addEx($pname_str, $token_str, $logid_int, $key, $value, $expiration = 0) { + if(!is_int($expiration) || $expiration < 0) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + + $key = $this->_convertKey($key); + $value_str = $this->_convertValue($value); + if($value_str === false) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + $ret = $this->_adapter->addOne($pname_str, $token_str, $logid_int, $key, $value_str, $expiration*1000); + $this->_last_errno = $this->_convertErrno($this->_adapter->getLastErrCode()); + return $ret; + } + + public function add($key, $value, $expiration = 0) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->addEx($pname_str, $token_str, $logid_int, $key, $value, $expiration); + } + + public function setEx($pname_str, $token_str, $logid_int, $key, $value, $expiration = 0) { + if(!is_int($expiration) || $expiration < 0) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + + $key = $this->_convertKey($key); + $value_str = $this->_convertValue($value); + if($value_str === false) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + $ret = $this->_adapter->setOne($pname_str, $token_str, $logid_int, $key, $value_str, $expiration*1000); + $this->_last_errno = $this->_convertErrno($this->_adapter->getLastErrCode()); + return $ret; + } + + public function set($key, $value, $expiration = 0) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->setEx($pname_str, $token_str, $logid_int, $key, $value, $expiration); + } + + public function replaceEx($pname_str, $token_str, $logid_int, $key, $value, $expiration = 0) { + if(!is_int($expiration) || $expiration < 0) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + + $key = $this->_convertKey($key); + $value_str = $this->_convertValue($value); + if($value_str === false) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + + $ret = $this->_adapter->replaceOne($pname_str, $token_str, $logid_int, $key, $value_str, $expiration*1000); + $this->_last_errno = $this->_convertErrno($this->_adapter->getLastErrCode()); + return $ret; + } + + public function replace($key, $value, $expiration = 0) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->replaceEx($pname_str, $token_str, $logid_int, $key, $value, $expiration); + } + + public function deleteEx($pname_str, $token_str, $logid_int, $key, $time=0) { + $key = $this->_convertKey($key); + $ret = $this->_adapter->deleteOne($pname_str, $token_str, $logid_int, $key, $time*1000); + $this->_last_errno = $this->_convertErrno($this->_adapter->getLastErrCode()); + + return $ret; + } + + public function delete($key, $time = 0) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->deleteEx($pname_str, $token_str, $logid_int, $key, $time); + } + + public function incrementEx($pname_str, $token_str, $logid_int, $key, $offset = 1) { + $key = $this->_convertKey($key); + $offset = $this->_convertOffset($offset); + $ret = $this->_adapter->increment($pname_str, $token_str, $logid_int, $key, strval($offset), 0); + $this->_last_errno = $this->_convertErrno($this->_adapter->getLastErrCode()); + if($ret === false) return false; + return intval($ret); + } + + public function increment($key, $offset = 1) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->incrementEx($pname_str, $token_str, $logid_int, $key, $offset); + } + + public function decrementEx($pname_str, $token_str, $logid_int, $key, $offset = 1) { + $key = $this->_convertKey($key); + $offset = $this->_convertOffset($offset); + $ret = $this->_adapter->decrement($pname_str, $token_str, $logid_int, $key, strval($offset), 0); + $this->_last_errno = $this->_convertErrno($this->_adapter->getLastErrCode()); + if($ret === false) return false; + return intval($ret); + } + + public function decrement($key, $offset = 1) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->decrementEx($pname_str, $token_str, $logid_int, $key, $offset); + } + + public function getEx($pname_str, $token_str, $logid_int, $key) { + $key = $this->_convertKey($key); + $ret = $this->_adapter->getOne($pname_str, $token_str, $logid_int, $key); + $this->_last_errno = $this->_convertErrno($this->_adapter->getLastErrCode()); + $ret = $this->_unconvertResult($ret); + return $ret; + } + + public function get($key, $cache_cb = null, & $cas_token = null) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->getEx($pname_str, $token_str, $logid_int, $key); + } + + public function setMultiEx($pname_str, $token_str, $logid_int, array $items, $expiration = 0) { + if(!is_int($expiration) || $expiration < 0) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + $new_items = array(); + foreach($items as $key => $val) { + $key = $this->_convertKey($key); + $value_str = $this->_convertValue($val); + if($value_str === false) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + $new_items[$key] = $value_str; + } + + $ret_arr = $this->_adapter->setMulti($pname_str, $token_str, $logid_int, $new_items, $expiration*1000); + if(!$ret_arr) { + $this->_last_errno = RES_PAYLOAD_FAILURE; + return false; + } + + if(!isset($ret_arr['content']) || !is_array($ret_arr['content']) ) { + $this->_last_errno = RES_PAYLOAD_FAILURE; + return false; + } + + $count = count($ret_arr['content']); + if(count($items) != $count) { + $this->_last_errno = RES_PAYLOAD_FAILURE; + return false; + } + + for($i = 0; $i < $count; $i++) { + $result = $ret_arr['content']['result' . $i]; + if(isset($result['err_no']) && is_int($result['err_no']) && $result['err_no'] == ZCACHE_OK) { + continue; + } else { + $this->_last_errno = RES_PAYLOAD_FAILURE; + return false; + } + } + $this->_last_errno = RES_SUCCESS; + return true; + } + + public function setMulti(array $items, $expiration = 0) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->setMultiEx($pname_str, $token_str, $logid_int, $items, $expiration); + } + + public function getMultiEx($pname_str, $token_str, $logid_int, array $keys) { + if(!is_array($keys)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + + $strkey_arr = array(); + foreach($keys as $k => $v) { + $strkey_arr[] = $this->_convertKey($v); + } + + $ret_arr = $this->_adapter->getMulti($pname_str, $token_str, $logid_int, $strkey_arr); + if(!$ret_arr) { + + $this->_last_errno = RES_PAYLOAD_FAILURE; + return false; + } + + if(!isset($ret_arr['content']) || !is_array($ret_arr['content']) ) { + + $this->_last_errno = RES_PAYLOAD_FAILURE; + return false; + } + + $count = count($ret_arr['content']); + if(count($keys) != $count) { + + $this->_last_errno = RES_PAYLOAD_FAILURE; + return false; + } + + + $ret_values = array(); + for($i = 0; $i < $count; $i++) { + $result = $ret_arr['content']['result' . $i]; + if(isset($result['err_no']) && is_int($result['err_no']) && $result['err_no'] == ZCACHE_OK && + isset($result['value']) && is_string($result['value']) ) { + + $ret_values[$keys[$i]] = $this->_unconvertResult($result['value']); + } + } + $this->_last_errno = RES_SUCCESS; + return $ret_values; + } + + public function getMulti(array $keys, & $cas_tokens = null, $flags = 0) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->getMultiEx($pname_str, $token_str, $logid_int, $keys); + } +/* + public function getByKey($server_key, $key, $cache_cb = null, & $cas_token = null) { + throw new Exception("NotImplemented"); + } + + public function getMultiByKey($server_key, array $keys, & $cas_tokens = null, $flags = 0) { + throw new Exception("NotImplemented"); + } + + public function getDelayed(array $keys, $with_cas = null, $value_cb = null) { + throw new Exception("NotImplemented"); + } + + public function getDelayedByKey($server_key, array $keys, $with_cas = null, $value_cb = null) { + throw new Exception("NotImplemented"); + } + + public function fetch() { + throw new Exception("NotImplemented"); + } + + public function fetchAll() { + throw new Exception("NotImplemented"); + } + + public function setByKey($server_key, $key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function setMultiByKey($server_key, array $items, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function cas($token, $key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function casByKey($token, $server_key, $key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function addByKey($server_key, $key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function append($key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function appendByKey($server_ke, $key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function prepend($key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function prependByKey($server_key, $key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function replaceByKey($serve_key, $key, $value, $expiration = 0) { + throw new Exception("NotImplemented"); + } + + public function deleteByKey($key, $time = 0) { + throw new Exception("NotImplemented"); + } + + public function getOption($option) { + throw new Exception("NotImplemented"); + } + + public function setOption($option, $value) { + throw new Exception("NotImplemented"); + } + + public function addServer($host, $port, $weight = 0) { + throw new Exception("NotImplemented"); + } + + public function addServers(array $servers) { + throw new Exception("NotImplemented"); + } + + public function getServerList() { + throw new Exception("NotImplemented"); + } + + public function getServerByKey($server_key) { + throw new Exception("NotImplemented"); + } + + public function flush($delay = 0) { + throw new Exception("NotImplemented"); + } + + public function getStats() { + throw new Exception("NotImplemented"); + } + + public function getResultMessage() { + throw new Exception("NotImplemented"); + } +*/ + + public function getResultCode() { + return $this->_last_errno; + } + + public function getExtEx($pname_str, $token_str, $logid_int, $key) { + + $key = $this->_convertKey($key); + + if(is_string($key)) { + return $this->getEx($pname_str, $token_str, $logid_int, $key); + } elseif(is_array($key)) { + return $this->getMultiEx($pname_str, $token_str, $logid_int, $key); + } else { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + } + + public function getExt($key, $cache_cb = null, & $cas_token = null) { + $pname_str = ""; + $token_str = ""; + $logid_int = 0; + + if(!$this->_getEnv($pname_str, $token_str, $logid_int)) { + $this->_last_errno = RES_CLIENT_ERROR; + return false; + } + return $this->getExtEx($pname_str, $token_str, $logid_int, $key); + } + + public function set_shareAppid($appid) + { + if(!is_string($appid)) return false; + + $ret = $this->_adapter->set_shareAppid($appid); + if($ret === false) return false; + + $this->_appid = $appid; + return true; + } +} + +class MemcachedMeException extends Exception { + function __construct($errmsg = "", $errcode = 0) { + } + +} diff --git a/ptcms/library/bae/zcache/zcache_api.php b/ptcms/library/bae/zcache/zcache_api.php new file mode 100644 index 0000000..11db7e7 --- /dev/null +++ b/ptcms/library/bae/zcache/zcache_api.php @@ -0,0 +1,486 @@ +handlers = array (); + $this->zcfObj = $pZcfObj; + } + + public function __destruct() { + foreach($this->handlers as $k => $handler) { + $handler->close(); + unset ($this->handlers[$k]); + } + } + + private function _log($output) { + #echo "--zcached: $output"; + } + + protected function _getHandler() { + if (isset($this->_cur_handler)) + { + return $this->_cur_handler; + } + $servers = $this->zcfObj->agent_servers; + $num = count($servers); + $retry = $this->zcfObj->RETRYTIME; + + while ($retry-- > 0) { + $idx = rand() % $num; + $server = $servers[$idx]; + $key = $server['socket_address'] . ":" . $server['socket_port']; + $socket = new ZCacheSocket(); + $socket->set_vars_from_array($server); + if ($socket->connect($this->zcfObj->CONNTIMEOUT)) + { + $this->_cur_handler = $socket; + return $socket; + } + /* if (!isset ($this->handlers[$key])) { */ + /* $socket = new ZCacheSocket(); */ + /* $socket->set_vars_from_array($server); */ + + /* if ($socket->connect($this->zcfObj->CONNTIMEOUT)) { */ + /* $this->handlers[$key] = $socket; */ + /* return $socket; */ + /* } */ + /* } else */ + /* return $this->handlers[$key]; */ + } + return null; + } + + protected function _putHandler($handler, $force = 0) { + if (!$this->zcfObj->PERSISTENT || $force != 0) { + /* foreach ($this->handlers as $key => $value) { */ + /* if ($value === $handler) { */ + /* $handler->close(); */ + /* unset ($this->handlers[$key]); */ + /* break; */ + /* } */ + /* } */ + $handler->close(); + unset($this->_cur_handler); + } + } + + protected function _readResponse($handler) { + //ȡnshead + + $headbuf = $handler->read(36); + if (!$headbuf) { + $this->_log("read nshead failed\n"); + $this->_last_errno = ZCACHE_CLIENT_ERR_READ; + $this->_last_errmsg = "net read err"; + return NULL; + } + + //nshead + $head = zcache_split_nshead($headbuf); + if (!isset ($head['body_len'])) { + $this->_log("no body_len in nshead\n"); + $this->_last_errno = ZCACHE_CLIENT_ERR_NSHEAD; + $this->_last_errmsg = "nshead err"; + return NULL; + } + + //ȡݰ + $retbuffer = $handler->read($head['body_len']); + if (!$retbuffer) { + $this->_log("read nsbody " . $head['body_len'] . " failed\n"); + $this->_last_errno = ZCACHE_CLIENT_ERR_READ; + $this->_last_errmsg = "net read err"; + return NULL; + } + if($head['reserverd']) { + $decrypt_data = fcrypt_decode_hmac('key', $retbuffer); + //$this->_log("fcrypt_decode_hmac: " . strlen($retbuffer) . " " . strlen($decrypt_data) ); + return $decrypt_data; + } else { + return $retbuffer; + } + } + + public function getLastErrCode() { + return $this->_last_errno; + } + public function getLastErrMsg() { + return $this->_last_errmsg; + } + + private function _makeNshead($logid_int, $query_pack) { + $nshead = new ZCacheNsHead(); + $nshead_arr['provider'] = "zcacheadapter"; + $nshead_arr['log_id'] = $logid_int; + + $nshead_arr['reserved'] = $this->zcfObj->crypt_flag; + if($this->zcfObj->crypt_flag) { + $crypt_data = fcrypt_encode_hmac('key', $query_pack); + //$this->_log("fcrypt_encode_hmac: " . strlen($query_pack) . " " . strlen($crypt_data) ); + $nshead_arr['body_len'] = strlen($crypt_data); + $buffer = $nshead->build_nshead($nshead_arr) . $crypt_data; + } else { + $nshead_arr['body_len'] = strlen($query_pack); + $buffer = $nshead->build_nshead($nshead_arr) . $query_pack; + } + return $buffer; + } + + private function _makePack($pname_str, $token_str, $logid_int, $cmd_str, $expire_int, $item_arr) { + //fill query pack + $query_arr['cmd'] = $cmd_str; + $query_arr['pname'] = $pname_str; + $query_arr['token'] = $token_str; + $query_arr['logid'] = $logid_int; + $query_arr['appid'] = $this->_appid; + + $query_num = count($item_arr); + $query_arr['content']['query_num'] = $query_num; + + $i = 0; + foreach($item_arr as $value) { + $query_arr['content']['query' . $i]['key'] = $value['key']; + + if (isset($value['value'])) + $query_arr['content']['query' . $i]['value'] = $value['value']; + + if($expire_int >= 0) { + $query_arr['content']['query' . $i]['delay_time'] = $expire_int; + } + $i++; + } + + $query_pack = mc_pack_array2pack($query_arr, $this->zcfObj->MCPACK_VERSION); + return $this->_makeNshead($logid_int, $query_pack); + } + + public function parseResult($ret_arr) { + if(!isset($ret_arr['content']) || !is_array($ret_arr['content']) || + !isset($ret_arr['content']['result0']) || !is_array($ret_arr['content']['result0']) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_MCPACK; + return false; + } + + $val = $ret_arr['content']['result0']; + if (isset($val['err_no']) && is_int($val['err_no']) ) { + $this->_last_errno = $val['err_no']; + if($this->_last_errno == ZCACHE_OK) + return true; + return false; + } else { + $this->_last_errno = ZCACHE_CLIENT_ERR_MCPACK; + return false; + } + } + + public function parseResult2($ret_arr) { + if(!isset($ret_arr['content']) || !is_array($ret_arr['content']) || + !isset($ret_arr['content']['result0']) || !is_array($ret_arr['content']['result0']) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_MCPACK; + return false; + } + + $val = $ret_arr['content']['result0']; + if (isset($val['err_no']) && is_int($val['err_no']) && + isset($val['value']) && is_string($val['value']) ) { + $this->_last_errno = $val['err_no']; + return $val['value']; + } + else if(isset($val['err_no']) && is_int($val['err_no'])) { + $this->_last_errno = $val['err_no']; + return false; + } + else { + $this->_last_errno = ZCACHE_CLIENT_ERR_MCPACK; + return false; + } + } + + private function _talkWithServer($handler, $buffer) { + + if (!$handler->write($buffer)) { + $this->_last_errno = ZCACHE_CLIENT_ERR_WRITE; + $this->_last_errmsg = "net write err"; + $this->_putHandler($handler, 1); + return false; + } + + $retbuffer = $this->_readResponse($handler); + if (!$retbuffer) { + $this->_putHandler($handler, 1); + + //print("retry connect\n"); + $handler = $this->_getHandler(); // read error: retry connect , write , read once + if (!$handler) { + $this->_last_errno = ZCACHE_CLIENT_ERR_CONNECT; + $this->_last_errmsg = "retry net connect err"; + return false; + } + + //print("retry write\n"); + if (!$handler->write($buffer)) { + $this->_last_errno = ZCACHE_CLIENT_ERR_WRITE; + $this->_last_errmsg = "retry net write err"; + $this->_putHandler($handler, 1); + return false; + } + + //print("retry read\n"); + $retbuffer = $this->_readResponse($handler); + if (!$retbuffer) { + $this->_last_errno = ZCACHE_CLIENT_ERR_READ; + $this->_last_errmsg = "retry net read err"; + $this->_putHandler($handler, 1); + return false; + } + + } + + //print("query ok\n"); + $this->_putHandler($handler); + $ret_arr = mc_pack_pack2array($retbuffer); + + + + if (isset ($ret_arr['err_no']) && ZCACHE_OK == $ret_arr['err_no'] ) { + $this->_last_errno = ZCACHE_OK; + if(isset($ret_arr['error'])) { + $this->_last_errmsg = $ret_arr['error']; + } + return $ret_arr; + } else { + if (isset ($ret_arr['err_no'])) { + $this->_last_errno = $ret_arr['err_no']; + if(isset($ret_arr['error'])) { + $this->_last_errmsg = $ret_arr['error']; + } + } else { + $this->_last_errno = ZCACHE_CLIENT_ERR_MCPACK; + $this->_last_errmsg = "mcpack err"; + } + return false; + } + } + + private function talkWithServer($pname_str, $token_str, $logid_int, $cmd_str, $expire_int, $item_arr) { + $handler = $this->_getHandler(); + if (!$handler) { + $this->_last_errno = ZCACHE_CLIENT_ERR_CONNECT; + $this->_last_errmsg = "net connect err"; + return false; + } + + $buffer = $this->_makePack($pname_str, $token_str, $logid_int, $cmd_str, $expire_int, $item_arr); + return $this->_talkWithServer($handler, $buffer); + } + + private function talkWithServer2($logid_int, $query_arr) { + $handler = $this->_getHandler(); + if (!$handler) { + $this->_last_errno = ZCACHE_CLIENT_ERR_CONNECT; + $this->_last_errmsg = "net connect err"; + return false; + } + + $query_pack = mc_pack_array2pack($query_arr, $this->zcfObj->MCPACK_VERSION); + $buffer = $this->_makeNshead($logid_int, $query_pack); + return $this->_talkWithServer($handler, $buffer); + } + + private function _addSetReplace($pname_str, $token_str, $logid_int, $cmd_str, $key_str, $value_str, $expire_int) { + //param judge + if (!is_string($pname_str) || !is_string($token_str) || !is_int($logid_int) || + !is_string($key_str) || strlen($key_str) > ZCACHE_MAX_KEY_LEN || strlen($key_str) == 0 || + !is_string($value_str) || + !is_int($expire_int) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + + $query_arr = array( + array( + 'key' => $key_str, + 'value' => $value_str + ) + ); + $ret_arr = $this->talkWithServer($pname_str, $token_str, $logid_int, $cmd_str, $expire_int, $query_arr); + if($ret_arr === false) return false; + return $this->parseResult($ret_arr); + } + + public function addOne($pname_str, $token_str, $logid_int, $key_str, $value_str, $expire_int = 0) { + return $this->_addSetReplace($pname_str, $token_str, $logid_int, "add", $key_str, $value_str, $expire_int); + } + + public function setOne($pname_str, $token_str, $logid_int, $key_str, $value_str, $expire_int = 0) { + return $this->_addSetReplace($pname_str, $token_str, $logid_int, "set", $key_str, $value_str, $expire_int); + } + + public function replaceOne($pname_str, $token_str, $logid_int, $key_str, $value_str, $expire_int = 0) { + return $this->_addSetReplace($pname_str, $token_str, $logid_int, "replace", $key_str, $value_str, $expire_int); + } + + public function deleteOne($pname_str, $token_str, $logid_int, $key_str, $delay_int = 0) { + //param judge + if (!is_string($pname_str) || !is_string($token_str) || !is_int($logid_int) || + !is_string($key_str) || strlen($key_str) > ZCACHE_MAX_KEY_LEN || strlen($key_str) == 0 || + !is_int($delay_int) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + + $query_arr = array( + array( + 'key' => $key_str, + ) + ); + $ret_arr = $this->talkWithServer($pname_str, $token_str, $logid_int, "delete", $delay_int, $query_arr); + if($ret_arr === false) return false; + return $this->parseResult($ret_arr); + } + + public function increment($pname_str, $token_str, $logid_int, $key_str, $value_str, $expire_int = 0) { + //param judge + if (!is_string($pname_str) || !is_string($token_str) || !is_int($logid_int) || + !is_string($key_str) || strlen($key_str) > ZCACHE_MAX_KEY_LEN || strlen($key_str) == 0 || + !is_string($value_str) || + !is_int($expire_int) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + $query_arr = array( + array( + 'key' => $key_str, + 'value' => $value_str + ) + ); + $ret_arr = $this->talkWithServer($pname_str, $token_str, $logid_int, "increment", $expire_int, $query_arr); + if($ret_arr === false) return false; + return $this->parseResult2($ret_arr); + } + + public function decrement($pname_str, $token_str, $logid_int, $key_str, $value_str, $expire_int = 0) { + //param judge + if (!is_string($pname_str) || !is_string($token_str) || !is_int($logid_int) || + !is_string($key_str) || strlen($key_str) > ZCACHE_MAX_KEY_LEN || strlen($key_str) == 0 || + !is_string($value_str) || + !is_int($expire_int) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + + $query_arr = array( + array( + 'key' => $key_str, + 'value' => $value_str + ) + ); + $ret_arr = $this->talkWithServer($pname_str, $token_str, $logid_int, "decrement", $expire_int, $query_arr); + if($ret_arr === false) return false; + return $this->parseResult2($ret_arr); + } + + /* + ** return: value(string) or FALSE + */ + public function getOne($pname_str, $token_str, $logid_int, $key_str) { + //param judge + if (!is_string($pname_str) || !is_string($token_str) || !is_int($logid_int) || + !is_string($key_str) || strlen($key_str) > ZCACHE_MAX_KEY_LEN || strlen($key_str) == 0) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + + $query_arr = array( + array( + 'key' => $key_str, + ) + ); + $ret_arr = $this->talkWithServer($pname_str, $token_str, $logid_int, "get", -1, $query_arr); + if($ret_arr === false) return false; + return $this->parseResult2($ret_arr); + } + + public function getMulti($pname_str, $token_str, $logid_int, $key_arr) { + //param judge + if (!is_string($pname_str) || !is_string($token_str) || !is_int($logid_int) || + !is_array($key_arr) || count($key_arr) > ZCACHE_MAX_QUERY_NUM) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + + $query_arr = array(); + foreach ($key_arr as $key) { + if (!is_string($key) || strlen($key) > ZCACHE_MAX_KEY_LEN || strlen($key) == 0) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + $query_arr[] = array( + 'key' => $key, + ); + } + return $this->talkWithServer($pname_str, $token_str, $logid_int, "get", -1, $query_arr); + } + + public function setMulti($pname_str, $token_str, $logid_int, $item_arr, $expire_int = 0) { + //param judge + if (!is_string($pname_str) || !is_string($token_str) || !is_int($logid_int) || + !is_array($item_arr) || count($item_arr) > ZCACHE_MAX_QUERY_NUM || + !is_int($expire_int) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + + $query_arr = array(); + foreach($item_arr as $key => $val) { + if (!is_string($key) || strlen($key) > ZCACHE_MAX_KEY_LEN || strlen($key) == 0 || + !is_string($val) ) { + $this->_last_errno = ZCACHE_CLIENT_ERR_PARAM; + $this->_last_errmsg = "param err"; + return false; + } + + $query_arr[] = array( + 'key' => $key, + 'value' => $val + ); + } + return $this->talkWithServer($pname_str, $token_str, $logid_int, "set", $expire_int, $query_arr); + } + + public function set_shareAppid($appid) + { + if(!is_string($appid)) return false; + + $this->_appid = $appid; + return true; + } +} diff --git a/ptcms/library/bae/zcache/zcache_conf.php b/ptcms/library/bae/zcache/zcache_conf.php new file mode 100644 index 0000000..0461fc6 --- /dev/null +++ b/ptcms/library/bae/zcache/zcache_conf.php @@ -0,0 +1,20 @@ + 0, + * 'version' => 0, + * 'log_id' => 0, + * 'provider' => "" + * 'magic_num' => 0xfb709394, #ħ, ⲿҪдԶ + * 'reserved' => 0, + * 'body_len' => 0 + * ); + * + * + * + * װһԷ͵nsheadͷݰ,ݣⲿƴװ + * + * @param $vars_arr Ҫnsheadͷݰ, + * @return һԷ͵nsheadͷݰ,ݣⲿƴװ + */ + public function build_nshead($vars_arr) + { + $nshead_arr = array( + 'id' => 0, + 'version' => 0, + 'log_id' => 0, + 'provider' => str_pad("", 16, "\0", STR_PAD_BOTH), + 'magic_num' => 0xfb709394, #ħ + 'reserved' => 0, + 'body_len' => 0 + ); + foreach ($vars_arr as $key => $value) + { + if (isset($nshead_arr[$key])) + { + $nshead_arr[$key] = $value; + } + } + $nshead = ""; + $nshead = pack("L*", (($nshead_arr['version'] << 16) + ($nshead_arr['id'])), $nshead_arr['log_id']); + //ȡ15ֽڵprovider + $nshead .= str_pad(substr($nshead_arr['provider'], 0, 15), 16, "\0"); + $nshead .= pack("L*", $nshead_arr['magic_num'], $nshead_arr['reserved']); + $nshead .= pack("L", $nshead_arr['body_len']); + return $nshead; + } + + /** + * nsheadbuf뷵bufֶ + * һnsheadݰ nshead + buf + * + * һnsheadarray, + * + * array( + * 'id' => + * 'version' => + * 'log_id' => + * 'provider' => + * 'magic_num' => + * 'reserved' => + * 'body_len' => + * 'buf' => + * ); + + * + * 'buf' DZʾʵʵ + * + * @param $head յnshead ݰ + * @param $get_buf Ҫݣget_buf == false, 'buf' + * @param һnsheadarray + */ + public function split_nshead($head, $get_buf = true) + { + $ret_arr = array( + 'id' => 0, + 'version' => 0, + 'log_id' => 0, + 'provider' => "", + 'magic_num' => 0, + 'reserved' => 0, + 'body_len' => 0, + 'buf' => "" + ); + + $ret = unpack("v1id/v1version/I1log_id", substr($head, 0, 8)); + foreach ($ret as $key => $value) + { + $ret_arr[$key] = $value; + } + $ret_arr['provider'] = substr($head, 8, 16); + $ret = unpack("I1magic_num/I1reserverd/I1body_len", substr($head, 24, 12)); + foreach ($ret as $key => $value) + { + $ret_arr[$key] = $value; + } + //36nshead_tṹС + if ($get_buf) { + $ret_arr['buf'] = substr($head, 36, $ret_arr['body_len']); + } + return $ret_arr; + } + + /** + * nshead ͨsocket $msgsocket ͳȥ + * + * @param $msgsocket Ҫдsocket + * @param $vars_arr Ҫ͵nsheadͷ + * @param $buf Ҫ͵ʵ + * @return ͵ʵݳ + */ + public function nshead_write($msgsocket, $vars_arr, $buf) + { + $nshead = $this->build_nshead($vars_arr); + $nshead .= $buf; + return fwrite($msgsocket, $nshead, strlen($nshead)); + } + + /** + * socket $msgsocket ȡnsheadݰ + * + * @param $msgsocket Ҫյsocket + * @param $nshead_check_magicnum ǷMAGICNUM, Ĭϼ + */ + public function nshead_read($msgsocket, $nshead_check_magicnum = true) + { + $temp_out = ""; + $this->socket_read_buf = ""; + //ȶnsheadͷ + $temp_out = fread($msgsocket, 36); + if ($temp_out === false) + { + return false; + } + $nshead = $this->split_nshead($temp_out, false); + // msgic num + if ($nshead_check_magicnum == true + && $nshead['magic_num'] != 0xfb709394 + && $nshead['magic_num'] != -76508268) + //php汾unpackʱbugжһ¸ + { + error_log("magic num mismatch: ret ".$nshead['magic_num']." want 0xfb709394"); + return false; + } + #nshead + $left_bytes = $nshead['body_len']; + while ($left_bytes > 0) { + $recv_data = fread($msgsocket, $left_bytes); + $recv_size = strlen($recv_data); + if ($recv_size > 0 && $recv_size <= $left_bytes) { + $nshead['buf'] .= $recv_data; + $left_bytes -= $recv_size; + } else { + return false; + } + } + return $nshead; + } +} + diff --git a/ptcms/library/bae/zcache/zcache_socket.php b/ptcms/library/bae/zcache/zcache_socket.php new file mode 100644 index 0000000..2832e5a --- /dev/null +++ b/ptcms/library/bae/zcache/zcache_socket.php @@ -0,0 +1,277 @@ +socket_domain = 1; //AF_INET; + $this->socket_type = 1; //SOCK_STREAM; + $this->socket_protocol = 6; //SOL_TCP; + $this->socket_address = "127.0.0.1"; + $this->socket_port = 9120; + $this->socket_read_len = 8192; + $this->socket_read_type = 2; //PHP_BINARY_READ; + $this->socket_timeout = 200; + $this->socket_error = ""; + $this->socket_errno = 0; + } + + function __destruct() + { + if (!empty($this->socket)) + { + if(is_resource($this->socket)) + { + fclose($this->socket); + //socket_close($this->socket); + } + $this->socket = NULL; + } + $this->socket_domain = NULL; + $this->socket_type = NULL; + $this->socket_protocol = NULL; + $this->socket_address = NULL; + $this->socket_port = NULL; + $this->socket_read_len = NULL; + $this->socket_read_type = NULL; + $this->socket_timeout = NULL; + $this->socket_error = NULL; + $this->socket_errno = NULL; + } + + function __set($name, $value) + { + switch ($name) + { + case "socket_domain": + if ($value == 2 /*AF_INET*/ || $value == 10 /*AF_INET6*/ || $value == 1 /*AF_UNIX*/) + { + $this->$name = $value; + } + break; + case "socket_type": + if ($value == 1 /*SOCK_STREAM*/ || $value = 2 /*SOCK_DGRAM*/ || $value == 3 /*SOCK_RAW*/ || + $value == 5 /*SOCK_SEQPACKET*/ || $value == 4 /*SOCK_RDM*/) + { + $this->$name = $value; + } + break; + case "socket_protocol": + if ($value == 6 /*SOL_TCP*/ || $value == 17 /*SOL_UDP*/ || $value == 1 /*SOL_SOCKET*/) + { + $this->$name = $value; + } + break; + case "socket_address": + //preg_match_all("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/", $value, $match); + //if ($match[0][0] == $value) + //{ + $this->$name = $value; + //} + break; + case "socket_port": + if ($value > 0 && $value <= 65535) + { + $this->$name = $value; + } + break; + case "socket_read_len": + if ($value > 0 && $value <= 8192) + { + $this->$name = $value; + } + break; + case "socket_read_type": + if ($value == 2 /*PHP_BINARY_READ*/ || $value == 1 /*PHP_NORMAL_READ*/) + { + $this->$name = $value; + } + break; + case "socket_timeout": + if ($value >= 0) + { + $this->$name = $value; + } + break; + } + } + + function __get($name) + { + switch ($name) + { + case "socket_domain": + case "socket_type": + case "socket_protocol": + case "socket_address": + case "socket_port": + case "socket_read_len": + case "socket_read_type": + case "socket_timeout": + case "socket_error": + case "socket_errno": + return $this->$name; + break; + default: + return NULL; + break; + } + } + + function set_vars_from_array($vars_arr) + { + foreach ($vars_arr as $key => $value) + { + $this->__set($key, $value); + } + } + + function get_vars_to_array() + { + $vars_arr = array( + 'socket_domain' => $this->socket_domain, + 'socket_type' => $this->socket_type, + 'socket_protocol' => $this->socket_protocol, + 'socket_address' => $this->socket_address, + 'socket_port' => $this->socket_port, + 'socket_read_len' => $this->socket_read_len, + 'socket_read_type' => $this->socket_read_type, + 'socket_timeout' => $this->socket_timeout, + 'socket_error' => $this->socket_error, + 'socket_errno' => $this->socket_errno, + ); + return $vars_arr; + } + + // NOTE: this function may report PHP WARNING + function tcp_connect($address, $port, $ctimeout = NULL) + { + $fp = fsockopen($address, $port, $error, $errstr, $ctimeout); + if(!$fp) { + return false; + } + + /*if(!stream_set_blocking($fp, 0)) { + fclose($fp); + return false; + }*/ + return $fp; + } + + public function connect($timeout) + { + $this->connect_timeout = $timeout; + $this->socket=$this->tcp_connect($this->socket_address, $this->socket_port, $timeout); + if(is_resource($this->socket)) + { + return true; + } + return false; + } + + function close() + { + if ($this->socket !== false || $this->socket !== NULL) + { + if(is_resource($this->socket)) + { + fclose($this->socket); + } + $this->socket = NULL; + } + } + + function write($buffer) + { + $orignbuf = $buffer; + $ret = false; + while (true) + { + $ret = @fwrite($this->socket, $buffer, strlen($buffer)); + if ($ret == false) + { + fclose($this->socket); + $this->socket = NULL; + break; + //return false; + + } + + if ($ret == strlen($buffer)) + break; + + $buffer = substr($buffer, $ret); + } + if ($ret == false)//ʧ + { + $ret = $this->connect($this->connect_timeout); + if ($ret ===false)//ʧ + { + return $ret; + } + $this->socket = $ret; + } + else//ͳɹ + { + return $ret; + } + + $ret = false; + $buffer = $orignbuf; + while (true) + { + $ret = @fwrite($this->socket, $buffer, strlen($buffer)); + if ($ret == false) + { + fclose($this->socket); + $this->socket = NULL; + return false; + + } + + if ($ret == strlen($buffer)) + break; + + $buffer = substr($buffer, $ret); + } + + return true; + } + + function read($len) + { + $buffer = ""; + while ((@ $temp = fread($this->socket, $len)) !== false) + { + if( strlen($temp) == 0 ) + { + //print("read error\n"); + return false; + } + $buffer .= $temp; + $len -= strlen($temp); + if ($len === 0) + break; + } + if ($temp === false) + { + fclose($this->socket); + $this->socket = NULL; + return false; + } + return $buffer; + } + } diff --git a/ptcms/library/bae/zcache/zcache_util.php b/ptcms/library/bae/zcache/zcache_util.php new file mode 100644 index 0000000..8e7ad65 --- /dev/null +++ b/ptcms/library/bae/zcache/zcache_util.php @@ -0,0 +1,95 @@ + 0, + 'version' => 0, + 'log_id' => zcache_build_logid(), + 'provider' => str_pad("", 16, "\0", STR_PAD_BOTH), + 'magic_num' => 0xfb709394, + 'reserved' => 0, + 'body_len' => 0 + ); + foreach ($vars_arr as $key => $value) + { + if (isset($nshead_arr[$key])) + { + $nshead_arr[$key] = $value; + } + } + $nshead = ""; + $nshead = pack("L*", (($nshead_arr['version'] << 16) + ($nshead_arr['id'])), $nshead_arr['log_id']); + $nshead .= $nshead_arr['provider']; + $nshead .= pack("L*", $nshead_arr['magic_num'], $nshead_arr['reserved']); + $nshead .= pack("L", $nshead_arr['body_len']); + return $nshead; + } + + /** + * nsheadbuf뷵bufֶ + * typedef struct _nshead_t + * { + * unsigned short id; + * unsigned short version; + * unsigned int log_id; + * char provider[16]; + * unsigned int magic_num; + * unsigned int reserved; + * unsigned int body_len; + * } nshead_t; + */ + function zcache_split_nshead($buf) + { + #echo "split nshead"; + $ret_arr = array( + 'id' => 0, + 'version' => 0, + 'log_id' => 0, + 'provider' => "", + 'magic_num' => 0, + 'reserved' => 0, + 'body_len' => 0, + 'buf' => "" + ); + $ret = unpack("v1id/v1version/I1log_id", substr($buf, 0, 8)); + foreach ($ret as $key => $value) + { + $ret_arr[$key] = $value; + } + $ret_arr['provider'] = substr($buf, 8, 16); + $ret = unpack("I1magic_num/I1reserverd/I1body_len", substr($buf, 24, 12)); + foreach ($ret as $key => $value) + { + $ret_arr[$key] = $value; + } + $ret_arr['buf'] = substr($buf, 36, $ret_arr['body_len']); + return $ret_arr; + } + + + diff --git a/ptcms/library/collect.php b/ptcms/library/collect.php index d0308d7..95823b6 100644 --- a/ptcms/library/collect.php +++ b/ptcms/library/collect.php @@ -2,6 +2,33 @@ class collect { + public static function getcontent($data) { + if(is_string($data)) $data=array('rule'=>$data,'charset'=>'auto'); + $content=http::get($data['rule']); + if ($content){ + // 处理编码 + if (!in_array($data['charset'], array('auto', 'utf-8', 'gbk'))) { + $data['charset'] = 'auto'; + } + if ($data['charset'] == 'auto') { + if (!mb_check_encoding($content,'UTF-8')) { + $content = mb_convert_encoding ($content,'UTF-8','GBK' ); + } + } elseif ($data['charset'] == 'gbk') { + $content = mb_convert_encoding ($content,'UTF-8','GBK' ); + } + //错误标识 + if (!empty($data['error']) && strpos($content,$data['error'])!==false){ + return ''; + } + if (!empty($data['replace'])) { + $content=collect::replace($content, $data['replace']); + } + return $content; + } + return ''; + } + /** * 根据正则批量获取 * @@ -12,7 +39,7 @@ class collect { */ public static function getMatchAll($pregArr, $code, $needposition = 0) { if (is_string($pregArr)) { - $pregArr = array('rule' => $pregArr); + $pregArr = array('rule' => self::parseMatchRule($pregArr)); } elseif (empty($pregArr['rule'])) { return array(); } @@ -51,7 +78,11 @@ public static function getMatchAll($pregArr, $code, $needposition = 0) { } } } - $matchvar = $match['1']; + if (isset($match['1'])){ + $matchvar = $match['1']; + }else{ + return false; + } } if (!empty($pregArr['replace'])) { foreach ($matchvar as $k => $v) { @@ -72,7 +103,7 @@ public static function getMatchAll($pregArr, $code, $needposition = 0) { */ public static function getMatch($pregArr, $code) { if (is_string($pregArr)) { - $pregArr = array('rule' => $pregArr); + $pregArr = array('rule' => self::parseMatchRule($pregArr)); } elseif (empty($pregArr['rule'])) { return ''; } @@ -111,7 +142,7 @@ public static function replace($con, array $arr) { $replace = isset($tmp['1']) ? $tmp['1'] : ''; $v['option'] = isset($v['option']) ? $v['option'] : ''; if ($v['method'] == 1) { //正则 - $con = preg_replace("{{$rule}}{$v['option']}", $replace, $con); + $con = preg_replace("{".$rule."}{$v['option']}", $replace, $con); } else { if (strpos($v['option'], 'i') === false) { $con = str_replace($rule, $replace, $con); @@ -132,17 +163,21 @@ public static function replace($con, array $arr) { * @return string */ public static function parseUrl($url, $path) { - if (strpos($url, '://') === false) { - if (substr($url, 0, 1) == '/') { - $tmp = parse_url($path); - $url = $tmp['scheme'] . '://' . $tmp['host'] . $url; - } elseif (substr($path, -1) == '/') { - $url = $path . $url; - } else { - $url = dirname($path) . '/' . $url; + if ($url){ + if (strpos($url, '://') === false) { + if (substr($url, 0, 1) == '/') { + $tmp = parse_url($path); + $url = $tmp['scheme'] . '://' . $tmp['host'] . $url; + } elseif (substr($path, -1) == '/') { + $url = $path . $url; + } else { + $url = dirname($path) . '/' . $url; + } } + return $url; + }else{ + return ''; } - return $url; } /** @@ -176,4 +211,20 @@ public static function cut($strings, $argl, $argr, $lt = false, $gt = false) { } return ($args); } + + public static function parseMatchRule($rules) { + $replace_pairs=array( + '{'=>'\{', + '}'=>'\}', + '[内容]'=>'(.*?)', + '[数字]'=>'\d*', + '[空白]'=>'\s*', + '[任意]'=>'.*?', + '[参数]'=>'[^\>\<]*?', + '[属性]'=>'[^\>\<\'"]*?', + ); + return strtr($rules,$replace_pairs); + } + + } \ No newline at end of file diff --git a/ptcms/library/dc.php b/ptcms/library/dc.php deleted file mode 100644 index 6e1d130..0000000 --- a/ptcms/library/dc.php +++ /dev/null @@ -1,103 +0,0 @@ -data($data)->where(array($model->getPk() => $id))->save()) { - return self::refresh($type, $id); - } else { - return false; - } - } - - //删除信息 - static public function delete($type, $id) { - Cache::rm($type . '.' . $id); - unset(self::$_data[$type][$id]); - return true; - } - - //更新信息 - static public function refresh($type, $id) { - $model = M($type); - self::$_data[$type][$id] = $model->find($id); - if (self::$_data[$type][$id]) { - //其他处理 如小说的链接 - if (method_exists($model, 'dataAppend')) { - self::$_data[$type][$id] = $model->dataAppend(self::$_data[$type][$id]); - } - } - // 写入缓存 - Cache::set($type . '.' . $id, self::$_data[$type][$id],C('cache_time',null,900)); - return self::$_data[$type][$id]; - } - - // 获取数据 - static public function get($type, $id, $field = '') { - if ($id == 0) return null; - if (!isset(self::$_data[$type][$id])) { - // 检索memCache,不存在则读取数据库 - self::$_data[$type][$id] = Cache::get($type . '.' . $id); - if (self::$_data[$type][$id] === null) { - $model = M($type); - self::$_data[$type][$id] = $model->find($id); - if (self::$_data[$type][$id]) { - //其他处理 如小说的链接 - if (method_exists($model, 'dataAppend')) { - self::$_data[$type][$id] = $model->dataAppend(self::$_data[$type][$id]); - } - } - Cache::set($type . '.' . $id, self::$_data[$type][$id],C('cache_time',null,900)); - } - } - if ($field !== '') { - if(strpos($field,',')){ - //多字段获取 如"novelid,novelname" - return array_intersect_key(self::$_data[$type][$id],array_flip(explode(',',$field))); - }else{ - //单字段 - if (isset(self::$_data[$type][$id][$field])) { - return self::$_data[$type][$id][$field]; - } else { - return null; - } - } - } - return self::$_data[$type][$id]; - } -} \ No newline at end of file diff --git a/ptcms/library/html.php b/ptcms/library/html.php index 38d2f80..4fdace4 100644 --- a/ptcms/library/html.php +++ b/ptcms/library/html.php @@ -6,7 +6,7 @@ class html { public static function create($url, $content) { $file = self::parseUrl($url); if ($file) { - return F($file, str_replace(C('gen_html_replace'), '', $content)); + return F($file, str_replace(PT_Base::getInstance()->config->get('gen_html_replace'), '', $content)); } else { return false; } @@ -29,16 +29,21 @@ public static function read($url) { // 地址解析 public static function parseUrl($url) { - if (!C('html') || strpos($url, '?') || strpos($url, '#') || strpos($url, '&') || strpos($url, '=')) return false; + if (!PT_Base::getInstance()->config->get('html') || strpos($url, '?') || strpos($url, '#') || strpos($url, '&') || strpos($url, '=')) return false; $path = parse_url($url, PHP_URL_PATH); if (strpos(basename($path), '.') === false) { - $path = trim($path, '/') . '/' . C('HTML_DEFAULTFILE', null, 'index.html'); + $path = trim($path, '/') . '/' . PT_Base::getInstance()->config->get('HTML_DEFAULTFILE', 'index.html'); } else { $path = trim($path, '/'); } - if (PT_DIR && substr($path, 0, strlen(PT_DIR)) == PT_DIR) { - $path = trim(substr($path, strlen(PT_DIR)), '/'); + $dir = trim(PT_DIR, '/'); + if ($dir && substr($path, 0, strlen($dir)) == $dir) { + $path = trim(substr($path, strlen($dir)), '/'); } return PT_ROOT . '/' . $path; } + + public static function trigger($url) { + http::trigger($url); + } } \ No newline at end of file diff --git a/ptcms/library/http.php b/ptcms/library/http.php index fa07715..299e336 100644 --- a/ptcms/library/http.php +++ b/ptcms/library/http.php @@ -2,22 +2,26 @@ class http { - public static function curl($url, $params = array(), $method = 'GET', $header = array()) { + public static function curl($url, $params = array(), $method = 'GET', $header = array(), $option = array()) { $opts = array( - CURLOPT_TIMEOUT => C('timeout', null, 10), - CURLOPT_CONNECTTIMEOUT => C('timeout', null, 10), + CURLOPT_TIMEOUT => PT_Base::getInstance()->config->get('timeout', 10), + CURLOPT_CONNECTTIMEOUT => PT_Base::getInstance()->config->get('timeout', 10), CURLOPT_RETURNTRANSFER => 1, CURLOPT_FOLLOWLOCATION => 1, - CURLOPT_HEADER => false, - CURLOPT_USERAGENT => C('user_agent', null, 'PTSingleNovel'), - CURLOPT_REFERER => $url, - CURLOPT_NOSIGNAL => 1, - CURLOPT_ENCODING => 'gzip, deflate', - CURLOPT_HTTPHEADER => $header, + CURLOPT_HEADER => false, + CURLOPT_USERAGENT => PT_Base::getInstance()->config->get('user_agent', 'PTCMS Spider'), + CURLOPT_REFERER => $url, + CURLOPT_NOSIGNAL => 1, + CURLOPT_ENCODING => 'gzip, deflate', + CURLOPT_HTTPHEADER => $header, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, ); - + //补充配置 + foreach ($option as $k => $v) { + $opts[$k] = $v; + } + //安全模式 if (ini_get("safe_mode") || ini_get('open_basedir')) { unset($opts[CURLOPT_FOLLOWLOCATION]); } @@ -28,8 +32,8 @@ public static function curl($url, $params = array(), $method = 'GET', $header = break; case 'POST': //判断是否传输文件 - $opts[CURLOPT_URL] = $url; - $opts[CURLOPT_POST] = 1; + $opts[CURLOPT_URL] = $url; + $opts[CURLOPT_POST] = 1; $opts[CURLOPT_POSTFIELDS] = $params; break; default: @@ -42,52 +46,58 @@ public static function curl($url, $params = array(), $method = 'GET', $header = $data = curl_exec($ch); //todo safe_mode模式下需要处理的location $error = curl_error($ch); + $errno = curl_errno($ch); curl_close($ch); - if ($error) return false; + if ($error && $errno !== 28) { + PT_Log::record('Curl获取远程内容错误!原因:' . $error . ' 地址:' . $url); + return false; + } return $data; } - public static function filegc($url, $params = array(), $method = 'GET') { - $header = array("Referer: $url", "User-Agent: " . C('user_agent', null, 'PTSingleNovel')); + public static function filegc($url, $params = array(), $method = 'GET', $header = array(), $option = array()) { + $header = array_merge(array("Referer: $url", "User-Agent: " . PT_Base::getInstance()->config->get('user_agent', 'PTCMS Spider', "Accept-Encoding: gzip,deflate")), $header); $context = array( 'http' => array( - 'method' => $method, - 'header' => implode("\r\n", $header), - 'timeout' => C('timeout', null, 10), + 'method' => $method, + 'header' => implode("\r\n", $header), + 'timeout' => PT_Base::getInstance()->config->get('timeout', 10), ) ); + if ($option) $context['http'] = array_merge($context['http'], $option); if ($method == 'POST') { if (is_array($params)) $params = http_build_query($params); - $content_length = strlen($params); - $header[] = "Content-type: application/x-www-form-urlencoded"; - $header[] = "Content-length: $content_length"; - $context['http']['header'] = implode("\r\n", $header); + $content_length = strlen($params); + $header[] = "Content-type: application/x-www-form-urlencoded"; + $header[] = "Content-length: $content_length"; + $context['http']['header'] = implode("\r\n", $header); $context['http']['content'] = $params; } $stream_context = stream_context_create($context); - $data = file_get_contents($url, false, $stream_context); - return $data; + $data = @file_get_contents($url, false, $stream_context); + return self::gzdecode($data); } - public static function fsock($url, $params, $method = 'GET') { + public static function fsock($url, $params = array(), $method = 'GET') { $urlinfo = parse_url($url); - $port = isset($urlinfo["port"]) ? $urlinfo["port"] : 80; - $path = $urlinfo['path'] . (!empty($urlinfo['query']) ? '?' . $urlinfo['query'] : '') . (!empty($urlinfo['fragment']) ? '#' . $urlinfo['fragment'] : ''); + $port = isset($urlinfo["port"]) ? $urlinfo["port"] : 80; + $path = $urlinfo['path'] . (!empty($urlinfo['query']) ? '?' . $urlinfo['query'] : '') . (!empty($urlinfo['fragment']) ? '#' . $urlinfo['fragment'] : ''); $in = "{$method} {$path} HTTP/1.1\r\n"; $in .= "Host: {$urlinfo['host']}\r\n"; $in .= "Content-Type: application/octet-stream\r\n"; $in .= "Connection: Close\r\n"; $in .= "Hostname: {$urlinfo['host']}\r\n"; - $in .= "User-Agent: " . C('user_agent', null, 'PTSingleNovel') . "\r\n"; + $in .= "User-Agent: " . PT_Base::getInstance()->config->get('user_agent', 'PTCMS Spider') . "\r\n"; $in .= "Referer: {$url}\r\n"; + $in .= "Accept-Encoding: gzip,deflate\r\n"; if ($method == 'POST') { $params = is_array($params) ? http_build_query($params) : $params; $in .= "Content-Length: " . strlen($params) . "\r\n\r\n"; } $address = gethostbyname($urlinfo['host']); - $fp = fsockopen($address, $port, $err, $errstr, C('timeout', null, 10)); + $fp = fsockopen($address, $port, $err, $errstr, PT_Base::getInstance()->config->get('timeout', 10)); if (!$fp) { exit ("cannot conncect to {$address} at port {$port} '{$errstr}'"); } @@ -103,7 +113,7 @@ public static function fsock($url, $params, $method = 'GET') { } public static function get($url, $data = array()) { - $func = C('httpmethod', null, 'curl'); + $func = PT_Base::getInstance()->config->get('httpmethod', 'curl'); if (is_array($data)) { $data = http_build_query($data); } @@ -115,17 +125,27 @@ public static function get($url, $data = array()) { } $data = array(); } - $t = microtime(true); - $res = self::$func($url, $data, 'GET'); - $GLOBALS['_api'][] = $func . ' GET ' . number_format(microtime(true) - $t, 5) . ' ' . $url; + if (APP_DEBUG || isset($_GET['debug'])) { + $t = microtime(true); + $res = self::$func($url, $data, 'GET'); + $GLOBALS['_api'][] = $func . ' GET ' . number_format(microtime(true) - $t, 5) . ' ' . strlen($res) . ' ' . $url; + } else { + $res = self::$func($url, $data, 'GET'); + } + $GLOBALS['_apinum']++; return $res; } - public static function post($url, $data = array()) { - $func = C('httpmethod', null, 'curl'); - $t = microtime(true); - $res = self::$func($url, $data, 'POST'); - $GLOBALS['_api'][] = $func . ' POST ' . number_format(microtime(true) - $t, 5) . ' ' . $url . json_encode($data, 256); + public static function post($url, $data = array(), $header = array()) { + $func = PT_Base::getInstance()->config->get('httpmethod', 'curl'); + if (APP_DEBUG || isset($_GET['debug'])) { + $t = microtime(true); + $res = self::$func($url, $data, 'POST'); + $GLOBALS['_api'][] = $func . ' POST ' . number_format(microtime(true) - $t, 5) . ' ' . strlen($res) . ' ' . $url . json_encode($data, 256); + } else { + $res = self::$func($url, $data, 'POST', $header); + } + $GLOBALS['_apinum']++; return $res; } @@ -142,4 +162,43 @@ public static function getMethod() { } return $method; } + + //触发G + public static function trigger($url) { + if (stripos($url, 'http') === 0) { + $func = PT_Base::getInstance()->config->get('httpmethod', 'curl'); + if ($func == 'curl') { + http::curl($url, array(), 'GET', array(), array( + CURLOPT_TIMEOUT_MS => 20, + CURLOPT_CONNECTTIMEOUT_MS => 20, + )); + } else { + http::filegc($url, array(), 'GET', array(), array( + 'timeout' => 0, + )); + } + } + return; + } + + // Gzip解压函数 + public static function gzdecode($data) { + if (strlen($data) < 18) return $data; + $res = unpack('vfile_type', substr($data, 0, 2)); + if ($res['file_type'] <> 35615) return $data; + if (function_exists('gzdecode') && $unpacked = gzdecode($data)) return $unpacked; + $flags = ord(substr($data, 3, 1)); + $headerlen = 10; + if ($flags & 4) { + $extralen = unpack('v', substr($data, 10, 2)); + $extralen = $extralen[1]; + $headerlen += $extralen + 2; + } + if ($flags & 8) $headerlen = strpos($data, chr(0), $headerlen) + 1; + if ($flags & 16) $headerlen = strpos($data, chr(0), $headerlen) + 1; + if ($flags & 2) $headerlen += 2; + $unpacked = gzinflate(substr($data, $headerlen)); + if ($unpacked === false) return $data; + return $unpacked; + } } \ No newline at end of file diff --git a/ptcms/library/image.php b/ptcms/library/image.php index 2203281..c06d81a 100644 --- a/ptcms/library/image.php +++ b/ptcms/library/image.php @@ -286,9 +286,10 @@ public function water($source, $posotion = image::IMAGE_WATER_SOUTHEAST, $alpha */ public function text($text, $font, $size = 20, $color = '#ff0000', $locate = Image::IMAGE_WATER_SOUTHEAST, $margin = '', $offset = 0, $angle = 0) { //资源检测 - if (!is_file($font)) return false; + //if (!is_file($font)) return false; if ($margin === '') $margin = ceil($size / 2); //获取文字信息 + $info = imagettfbbox($size, $angle, $font, $text); $minx = min($info[0], $info[2], $info[4], $info[6]); $maxx = max($info[0], $info[2], $info[4], $info[6]); diff --git a/ptcms/library/oauth.php b/ptcms/library/oauth.php index 8e2d9d7..9e95a77 100644 --- a/ptcms/library/oauth.php +++ b/ptcms/library/oauth.php @@ -108,8 +108,8 @@ public function __construct(array $config, $token = null) { */ public static function getInstance($type, $token = null) { if (empty(self::$_instance[$type])) { - $config['appid'] = C("oauth_{$type}_appid"); - $config['appsecret'] = C("oauth_{$type}_appsecret"); + $config['appid'] = PT_Base::getInstance()->config->get("oauth_{$type}_appid"); + $config['appsecret'] = PT_Base::getInstance()->config->get("oauth_{$type}_appsecret"); $classname = 'Driver_Oauth_' . $type; self::$_instance[$type] = new $classname($config, $token); } diff --git a/ptcms/library/pinyin.php b/ptcms/library/pinyin.php index b77d908..038aeab 100644 --- a/ptcms/library/pinyin.php +++ b/ptcms/library/pinyin.php @@ -7,9 +7,9 @@ */ class pinyin { - static $data = null; + protected static $data = null; - public static function getdata() { + protected static function getdata() { if (self::$data === null) { $fp = fopen(dirname(__FILE__) . '/data/pinyin.dat', 'r') or exit('读取字典失败'); while (!feof($fp)) { @@ -29,7 +29,7 @@ public static function getdata() { * @param string $default 匹配不到默认显示字符 * @return string */ - public static function change($str, $isfirst = false, $default = '-') { + public static function change($str, $isfirst = false, $default = '0') { $str = iconv('UTF-8', 'GBK//ignore', $str); $data = self::getdata(); $restr = ''; diff --git a/ptcms/library/steal.php b/ptcms/library/steal.php deleted file mode 100644 index 55ed5c0..0000000 --- a/ptcms/library/steal.php +++ /dev/null @@ -1,182 +0,0 @@ - $v) { - if ($v == '') { - for ($i = 2; $i < $count; $i++) { - if (!empty($match[$i][$k])) { - $match['1'][$k] = $match[$i][$k]; - break; - } - } - } - } - } - $matchvar = $match['1']; - } - if (!empty($pregArr['replace'])) { - foreach ($matchvar as $k => $v) { - $matchvar[$k] = self::replace($v, $pregArr['replace']); - } - } - return $matchvar; - } - return false; - } - - /** - * 根据正则获取指定数据 单个 - * - * @param string $pregArr 正则 - * @param string $code 源内容 - * @return bool|string - */ - public static function getMatch($pregArr, $code) - { - try { - if (empty($pregArr['rule'])) { - return ''; - } - $pregstr = '{' . $pregArr['rule'] . '}'; - if (!empty($pregArr['option'])) { - $pregstr .= $pregArr['option']; - } - preg_match($pregstr, $code, $match); - if (isset($match['1'])) { - if (empty($pregArr['replace'])) { - return $match['1']; - } else { - return self::replace($match[1], $pregArr['replace']); - } - } - return false; - } catch (Exception $e) { - halt($e->getMessage()); - return ''; - } - } - - /** - * 内容替换 支持正则批量替换 - * - * @param string $con 代替换的内容 - * @param array $arr 替换规则数组 单个元素如下 - * array( - * 'rule'=>'规则1',//♂后面表示要替换的 内容 - * 'option'=>'参数', - * 'method'=>1,//1 正则 0普通 - * ), - * @return mixed - */ - public static function replace($con, array $arr) - { - foreach ($arr as $v) { - if (!empty($v['rule'])) { - $tmp = explode('♂', $v['rule']); - $rule = $tmp['0']; - $replace = isset($tmp['1']) ? $tmp['1'] : ''; - $v['option'] = isset($v['option']) ? $v['option'] : ''; - if ($v['method'] == 1) { //正则 - $con = preg_replace("{{$rule}}{$v['option']}", $replace, $con); - } else { - if (strpos($v['option'], 'i') === false) { - $con = str_replace($rule, $replace, $con); - } else { - $con = str_ireplace($rule, $replace, $con); - } - } - } - } - return $con; - } - - /** - * 处理链接,根据当前页面地址得到完整的链接地址 - * - * @param string $url 当前链接 - * @param string $path 当前页面地址 - * @return string - */ - public static function parseUrl($url, $path) - { - if (strpos($url, '://') === false) { - if (substr($url, 0, 1) == '/') { - $tmp = parse_url($path); - $url = $tmp['scheme'] . '://' . $tmp['host'] . $url; - } elseif (substr($path, -1) == '/') { - $url = $path . $url; - } else { - $url = dirname($path) . '/' . $url; - } - } - return $url; - } - - //内容切割 - public static function cut($argl, $argr, $lt, $gt, $strings) - { - if (!$strings) return (""); - if (strpos($argl, ".+?")) { - $argl = strtr($argl, array("/" => "\/")); - if (@preg_match("/" . $argl . "/", $strings, $match)) $argl = $match[0]; - } - if (strpos($argr, ".+?")) { - $argr = strtr($argr, array("/" => "\/")); - if (@preg_match("/" . $argr . "/", $strings, $match)) $argr = $match[0]; - } - $args = @explode($argl, $strings); - $args = @explode($argr, $args[1]); - $args = $args[0]; - if ($args) { - if ($lt) $args = $argl . $args; - if ($gt) $args .= $argr; - } else { - $args = ""; - } - return ($args); - } -} \ No newline at end of file diff --git a/ptcms/library/upload.php b/ptcms/library/upload.php index 5dc68d3..b45638d 100644 --- a/ptcms/library/upload.php +++ b/ptcms/library/upload.php @@ -16,7 +16,7 @@ class upload { //自定义文件存放完整路径 public $filePath; //自定义允许文件后缀 - public $allowType = "jpg|png|gif|txt|bmp|doc|xls|jpeg|zip|rar"; + public $allowType = "jpg|png|gif|txt|bmp|ico|doc|xls|jpeg|zip|rar"; //自定义允许文件mime public $allowMime = array(); //自定义文件大小 Kb @@ -131,7 +131,7 @@ public function uploadone() { // 上传操作 if ($this->save(F($this->fileinfo['tmp_name']))) { $info['ext'] = $this->get_type(); - $info['fileurl'] = Storage::geturl($this->filePath); + $info['fileurl'] = PT_Base::getInstance()->storage->geturl($this->filePath); $info['filepath'] = $this->filePath; $info['filename'] = $this->fileinfo['name']; $info['hash'] = md5_file($this->fileinfo['tmp_name']); @@ -151,7 +151,7 @@ protected function save($content) { $content = $img->save(); } } - return storage::write($this->filePath, $content); + return PT_Base::getInstance()->storage->write($this->filePath, $content); } protected function geterrorinfo($num) { @@ -184,7 +184,7 @@ public function uploadurl($url, $content = '') { $this->getpath(); if ($this->save($content)) { $info['ext'] = $this->get_type(); - $info['fileurl'] = Storage::geturl($this->filePath); + $info['fileurl'] = PT_Base::getInstance()->storage->geturl($this->filePath); $info['filepath'] = $this->filePath; $info['filename'] = $this->fileinfo['name']; $info['hash'] = md5($content); diff --git a/ptcms/library/verify.php b/ptcms/library/verify.php index c21b425..2bd33b8 100644 --- a/ptcms/library/verify.php +++ b/ptcms/library/verify.php @@ -70,7 +70,7 @@ static public function randString($len = 6, $type = '', $addChars = '') { */ static function buildImageVerify($length = 4, $mode = 1, $type = 'png', $width = 48, $height = 22, $verifyName = 'verify') { $randval = self::randString($length, $mode); - $_SESSION[$verifyName] = strtolower($randval); + PT_Base::getInstance()->session->set($verifyName, strtolower($randval)); $width = ($length * 10 + 10) > $width ? $length * 10 + 10 : $width; if ($type != 'gif' && function_exists('imagecreatetruecolor')) { $im = imagecreatetruecolor($width, $height); diff --git a/ptcms/library/yarclient.php b/ptcms/library/yarclient.php index 68ffd8b..b6c4a72 100644 --- a/ptcms/library/yarclient.php +++ b/ptcms/library/yarclient.php @@ -1,10 +1,6 @@ $name = self::$_class[$name]; } - F($runtimefile, $str); + if ($name == 'pt') { + return $this->pt = self::getInstance(); + } + if (is_file(PT_PATH . "/core/{$name}.php")) { + $classname = 'PT_' . $name; + if (!class_exists($classname, true)) pt::import(PT_PATH . "/core/{$name}.php"); + return $this->$name = self::$_class[$name] = new $classname(); + } + return null; + } + + public function __get($name) { + return $this->$name=$this->getInstanceof($name); + } + + /** + * @param $name + * @return object + */ + public function model($name) { + $class=null; + if (isset(self::$_model[$name])) return self::$_model[$name]; + $classname=$name.'Model'; + if (class_exists($classname)){ + return self::$_model[$name]=new $classname($name); + } + return $class; + } + + /** + * @param $name + * @return Driver_Db_Dao + */ + public function db($name='') { + return $this->getInstanceof('db')->getInstance($name); + } + + /** + * @param $name + * @return PT_model + */ + public function block($name) { + return $this->getInstanceof('block')->getInstance($name); } - include $runtimefile; } -pt::start(); -class pt { +class pt extends PT_Base { + + protected static $base; /** * 框架开始调用 */ - public static function start() { + public function start() { + self::$base = PT_Base::getInstance(); //初始化加载 - self::init(); - plugin::call('app_init_start'); + $this->init(); + $this->plugin->call('app_init_start'); //加载站点配置文件 - C(self::import(APP_PATH . '/common/' . pt::getSiteCode() . '.config.php')); + $this->config->register(self::import(APP_PATH . '/common/' . $this->request->getSiteCode() . '.config.php')); // 路由解析 - plugin::call('dispatcher_start'); + $this->plugin->call('dispatcher_start'); self::dispatcher(); - plugin::call('dispatcher_end'); + $this->plugin->call('dispatcher_end'); if (MODULE_NAME != 'common') { // 加载模块文件 - C(self::import(APP_PATH . '/' . MODULE_NAME . '/config.php')); + $this->config->register(self::import(APP_PATH . '/' . MODULE_NAME . '/config.php')); // 加载函数 self::import(APP_PATH . '/' . MODULE_NAME . '/function.php'); } // 控制器调用 - self::app(); + $this->app(); } /** * 注册autoload等操作 */ - protected static function init() { + protected function init() { // 设定错误和异常处理 register_shutdown_function(array(__CLASS__, 'shutdown')); //set_error_handler(array(__CLASS__, 'error')); @@ -177,32 +203,34 @@ function stripslashes_deep($value) { return $value; } - $_POST = stripslashes_deep($_POST); - $_GET = stripslashes_deep($_GET); + $_POST = stripslashes_deep($_POST); + $_GET = stripslashes_deep($_GET); $_COOKIE = stripslashes_deep($_COOKIE); } } // 注册插件 - Plugin::register(C('plugin', null, array())); + $this->plugin->register($this->config->get('plugin', array())); } - protected static function app() { + protected function app() { //加载控制器启动的插件 - plugin::call('controller_start'); + $this->plugin->call('controller_start'); + //正常模式 + $controllerFile = APP_PATH . '/' . MODULE_NAME . '/controller/' . CONTROLLER_NAME . '.php'; + $classname = CONTROLLER_NAME . 'Controller'; + $actionname = ACTION_NAME . 'Action'; if (MODULE_NAME == 'plugin') { //插件控制器 $controllerFile = APP_PATH . '/common/plugin/' . CONTROLLER_NAME . '/manage.php'; - $classname = 'manageController'; - $actionname = ACTION_NAME . 'Action'; - } else { - //正常模式 - $controllerFile = APP_PATH . '/' . MODULE_NAME . '/controller/' . CONTROLLER_NAME . '.php'; - $classname = CONTROLLER_NAME . 'Controller'; - $actionname = ACTION_NAME . 'Action'; + $classname = 'manageController'; + $actionname = ACTION_NAME . 'Action'; + } elseif (!in_array(MODULE_NAME, explode(',', $this->config->get('allow_module', '')))) { + $this->response->error(MODULE_NAME . '模块不允许访问'); } if (is_file($controllerFile)) { include $controllerFile; if (class_exists($classname, false)) { + /* @var $app PT_Controller */ $app = new $classname(); //加载init方法 if (method_exists($app, 'init')) { @@ -211,17 +239,33 @@ protected static function app() { // 加载action if (method_exists($app, $actionname)) { $app->$actionname(); + if ($this->response->isAutoRender()) { + switch ($_GET['f']) { + case 'json': + $data = $app->view->get(); + $this->response->jsonEncode($data); + break; + case 'jsonp': + $data = $app->view->get(); + $this->response->jsonpEncode($data); + break; + case 'xml': + $data = $app->view->get(); + $this->response->xmlEncode($data); + break; + default: + $app->display(); + } + } } else { - $app->_empty("当前控制器下" . get_class($app) . "找不到指定的方法 {$_GET['a']}Action"); + $this->response->error("当前控制器下" . get_class($app) . "找不到指定的方法 {$_GET['a']}Action"); } - plugin::call('controller_end'); + $this->plugin->call('controller_end'); } else { - $app = new Controller(); - $app->_empty('控制器' . CONTROLLER_NAME . '对应的文件中未找到类' . $classname); + $this->response->error('控制器' . CONTROLLER_NAME . '对应的文件中未找到类' . $classname); } } else { - $app = new Controller(); - $app->_empty(MODULE_NAME . '模块下控制器' . CONTROLLER_NAME . 'Controller对应的文件不存在'); + $this->response->error(MODULE_NAME . '模块下控制器' . CONTROLLER_NAME . 'Controller对应的文件不存在'); } } @@ -239,7 +283,7 @@ public static function import($filename) { protected static function dispatcher() { - dispatcher::run(); + self::$base->dispatcher->run(); // 获取分组 模块和操作名称 define('MODULE_NAME', strtolower($_GET['m'])); define('CONTROLLER_NAME', strtolower($_GET['c'])); @@ -257,9 +301,9 @@ protected static function dispatcher() { // 自动加载 public static function autoload($class) { $classfile = strtolower(str_replace('_', '/', $class)); - if (in_array($classfile, array('controller', 'view', 'dispatcher', 'cache', 'model', 'plugin', 'storage', 'block', 'log'))) { - pt::import(PT_PATH . '/core/' . $classfile . '.php'); - } elseif (substr($classfile, 0, 6) == 'driver') { + //pt_开头的类指定目录到core + if (strpos($classfile, 'pt/') === 0) $classfile = str_replace('pt/', 'core/', $classfile); + if (is_file(PT_PATH . '/' . $classfile . '.php')) { pt::import(PT_PATH . '/' . $classfile . '.php'); } elseif (substr($classfile, -10) == 'controller') { if (!pt::import(APP_PATH . '/' . MODULE_NAME . '/controller/' . substr($classfile, 0, -10) . '.php')) { @@ -268,26 +312,44 @@ public static function autoload($class) { } elseif (substr($classfile, -5) == 'model') { //适配ptcms_a_b这样的表 $classfile = substr(str_replace('/', '_', $classfile), 0, -5); - if (MODULE_NAME == 'plugin') { - $file = APP_PATH . '/common/plugin/' . MODULE_NAME . '/model/' . $classfile . '.php'; - } else { - $file = APP_PATH . '/' . MODULE_NAME . '/model/' . $classfile . '.php'; - } - if (!pt::import($file)) { - pt::import(APP_PATH . '/common/model/' . $classfile . '.php'); + if (isset($GLOBALS['_automap']['model'][$classfile])) { + //存在这个model + if (isset($GLOBALS['_automap']['model'][$classfile][MODULE_NAME])) { + $file = $GLOBALS['_automap']['model'][$classfile][MODULE_NAME]; + } elseif (isset($GLOBALS['_automap']['model'][$classfile]['common'])) { + $file = $GLOBALS['_automap']['model'][$classfile]['common']; + } else { + $file = current(array_slice($GLOBALS['_automap']['model'][$classfile], 0, 1)); + } + pt::import($file); } } elseif (substr($classfile, -5) == 'block') { - if (!pt::import(APP_PATH . '/' . MODULE_NAME . '/block/' . substr($classfile, 0, -5) . '.php')) { - pt::import(APP_PATH . '/common/block/' . substr($classfile, 0, -5) . '.php'); + $classfile = substr($classfile, 0, -5); + if (isset($GLOBALS['_automap']['block'][$classfile])) { + //存在这个block + if (isset($GLOBALS['_automap']['block'][$classfile][MODULE_NAME])) { + $file = $GLOBALS['_automap']['block'][$classfile][MODULE_NAME]; + } elseif (isset($GLOBALS['_automap']['block'][$classfile]['common'])) { + $file = $GLOBALS['_automap']['block'][$classfile]['common']; + } else { + $file = current(array_slice($GLOBALS['_automap']['block'][$classfile], 0, 1)); + } + pt::import($file); } } elseif (substr($classfile, -6) == 'plugin') { $classname = substr($classfile, 0, -6); pt::import(APP_PATH . '/common/plugin/' . $classname . '/' . $classname . '.php'); } else { - (pt::import(PT_PATH . '/library/' . $classfile . '.php')) or - (pt::import(APP_PATH . '/common/library/' . $classfile . '.php')) or - (pt::import(APP_PATH . '/' . MODULE_NAME . '/library/' . $classfile . '.php')) or - (pt::import(APP_PATH . '/common/plugin/' . MODULE_NAME . '/library/' . $classfile . '.php')); + if (!pt::import(PT_PATH . '/library/' . $classfile . '.php') && isset($GLOBALS['_automap']['library'][$classfile])) { + if (isset($GLOBALS['_automap']['library'][$classfile][MODULE_NAME])) { + $file = $GLOBALS['_automap']['library'][$classfile][MODULE_NAME]; + } elseif (isset($GLOBALS['_automap']['library'][$classfile]['common'])) { + $file = $GLOBALS['_automap']['library'][$classfile]['common']; + } else { + $file = current(array_slice($GLOBALS['_automap']['library'][$classfile], 0, 1)); + } + pt::import($file); + } } } @@ -300,7 +362,7 @@ public static function shutdown() { } } //如果开启日志 则记录日志 - if (C('log', null, false)) log::build(); + if (self::$base->config->get('log', false)) self::$base->log->build(); // 如果自定义了close函数 则进行调用 if (function_exists('pt_close')) { pt_close(); @@ -329,180 +391,8 @@ public static function error($errno, $errstr, $errfile, $errline) { break; } } - - public static function err404($msg = '找不到指定的页面') { - $file = PT_ROOT . C('404file', null, '/404.html'); - log::write($msg); - if (is_file($file)) { - $content = F($file); - $content = str_replace(array('{$sitename}', '{$siteurl}', '{$msg}'), array(C('sitename'), C('siteurl'), $msg), $content); - exit($content); - } else { - exit($msg . ' 页面出现错误,如需自定义此错误,请创建文件:' . $file); - } - } - - /** - * 获取host - **/ - public static function getSiteCode() { - // 替换域名中的-为_ - $domain = str_replace('-', '_', $_SERVER['HTTP_HOST']); - // 去掉端口 - if (strpos($domain, ':') !== false) $domain = substr($domain, 0, strpos($domain, ':')); - // 去掉开始的www. - if (stripos($domain, 'www.') === 0) $domain = substr($domain, 4); - return $domain; - } - - /** - * 输出视图内容 - * - * @access public - * @param string $content 输出内容 - * @param string $mimeType MIME类型 - * @return void - */ - public static function show($content = '', $mimeType = 'text/html') { - if (C('gzip_encode', null, false)) { - $zlib = ini_get('zlib.output_compression'); - if (empty($zlib)) ob_start('ob_gzhandler'); - } - if (!headers_sent()) { - //设置系统的输出字符为utf-8 - header("Content-Type: $mimeType; charset=utf-8"); - //支持页面回跳 - header("Cache-control: private"); - //长连接 - header("Connection:Keep-Alive"); - //版权标识 - header("X-Powered-By: PTcms Studio (www.ptcms.com)"); - } - echo $content; - } -} - - -/** - * 获取和设置配置参数 支持批量定义 - * - * @param string|array $name 配置变量 - * @param mixed $value 配置值 - * @param mixed $default 默认值 - * @return mixed - */ -function C($name = null, $value = null, $default = null) { - static $_config = array(); - // 无参数时获取所有 - if (empty($name)) { - return $_config; - } - // 优先执行设置获取或赋值 - if (is_string($name)) { - $name = strtolower($name); - if (!strpos($name, '.')) { - if (is_null($value)) - return $_config[$name] = isset($_config[$name]) ? $_config[$name] : $default; - $_config[$name] = $value; - return true; - } - // 二维数组设置和获取支持 - $name = explode('.', $name); - if (is_null($value)) { - $value = $_config; - foreach ($name as $n) { - if (isset($value[$n])) { - $value = $value[$n]; - } else { - $value = $default; - break; - } - } - return $value; - } - $_config[$name[0]][$name[1]] = $value; - return true; - } - // 批量设置 - if (is_array($name)) { - $_config = array_merge($_config, array_change_key_case($name)); - return true; - } - // 避免非法参数 - return null; } -/** - * Cookie 设置、获取、删除 - * - * @param string $name cookies名称 - * @param string $value cookie值 - * @param string $option cookie参数 - * @return mixed - */ -function cookie($name, $value = '', $option = null) { - static $_config = null; - if (!$_config) { - // 默认设置 - $_config = array( - // cookie 名称前缀 - 'prefix' => C('cookie_prefix', null, 'PTCMS_'), - // cookie 保存时间 - 'expire' => intval(C('cookie_expire', null, 2592000)), - // cookie 保存路径 - 'path' => C('cookie_path', null, '/'), - // cookie 有效域名 - 'domain' => C('cookie_domain'), - ); - } - // 参数设置(会覆盖黙认设置) - if (!is_null($option)) { - if (is_numeric($option)) - $option = array('expire' => $option); - elseif (is_string($option)) - parse_str($option, $option); - $config = array_merge($_config, array_change_key_case($option)); - } else { - $config = $_config; - } - // 清除指定前缀的所有cookie - if (is_null($name)) { - if (empty($_COOKIE)) - return true; - // 要删除的cookie前缀,不指定则删除config设置的指定前缀 - $prefix = empty($value) ? $config['prefix'] : $value; - if (!empty($prefix)) { - // 如果前缀为空字符串将不作处理直接返回 - foreach ($_COOKIE as $key => $val) { - if (0 === stripos($key, $prefix)) { - setcookie($key, '', time() - 3600, $config['path'], $config['domain']); - unset($_COOKIE[$key]); - } - } - } - return true; - } - $name = $config['prefix'] . $name; - if ('' === $value) { - if (isset($_COOKIE[$name])) { - return $_COOKIE[$name]; - } else { - return null; - } - } else { - if (is_null($value)) { - setcookie($name, '', time() - 3600, $config['path'], $config['domain']); - // 删除指定cookie - unset($_COOKIE[$name]); - } else { - // 设置cookie - $expire = !empty($config['expire']) ? time() + $config['expire'] : 0; - setcookie($name, $value, $expire, $config['path'], $config['domain']); - $_COOKIE[$name] = $value; - } - } - return null; -} /** * 文件函数 @@ -533,11 +423,7 @@ function F($file, $content = false, $mod = '') { mkdir(dirname($file), 0755, true); } if (is_array($content)) { - if (APP_DEBUG) { - $content = str_replace('\\\\', '\\', 'response->setHeader(); $e['message'] = $msg; - $e['file'] = $file; - $e['line'] = $line; + $e['file'] = $file; + $e['line'] = $line; include PT_PATH . '/error.tpl'; exit; } else { - PT::err404($msg); - } -} - -/** - * 获取输入参数 支持过滤和默认值 - * - * @param string $name 变量的名称 支持指定类型 - * @param mixed $default 不存在的时候默认值 - * @param mixed $filter 参数过滤方法 - * @param array $input - * @return mixed - */ -function I($name, $filter = 'int', $default = null, $input = array()) { - // 可以从指定的数组中取值 - if ($input == array()) { - if (strpos($name, '.')) { - // 指定参数来源 - list($method, $name) = explode('.', $name, 2); - } else { - // 默认为post - $method = 'post'; - } - switch (strtolower($method)) { - case 'get' : - $input = $_GET; - break; - case 'post' : - $input = $_POST; - break; - case 'put' : - parse_str(file_get_contents('php://input'), $input); - break; - case 'request' : - $input = $_REQUEST; - break; - case 'session' : - $input = $_SESSION; - break; - case 'cookie' : - $input = $_COOKIE; - break; - case 'server' : - $input = $_SERVER; - break; - case 'globals' : - $input = $GLOBALS; - break; - default: - return NULL; - } + PT_Base::getInstance()->response->error($msg . ' [' . $file . '(' . $line . ')]'); } - $value = isset($input[$name]) ? $input[$name] : null; - if (is_array($filter)) return in_array($value, $filter) ? $value : $default; - if (!is_string($filter)) return $value; - switch ($filter) { - case 'int': - return is_null($value) ? (is_null($default) ? 0 : $default) : intval($value); - case 'str': - return is_null($value) ? (is_null($default) ? '' : $default) : strval($value); - case 'arr': - return is_array($value) ? $value : (is_array($default) ? $default : array()); - default: - return empty($value) ? $default : (regex($value, $filter) ? $value : $default); - } -} - - -/** - * regex - * 使用正则验证数据 - * - * @param string $value 要验证的数据 - * @param string $rule 验证规则 - * @return mixed - */ -function regex($value, $rule) { - $validate = array( - //必填 - 'require' => '/.+/', - //邮箱 - 'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', - //链接 - 'url' => '/^http:\/\/[a-zA-Z0-9]+\.[a-zA-Z0-9]+[\/=\?%\-&_~`@\[\]\':+!]*([^<>\"\"])*$/', - //货币 - 'currency' => '/^\d+(\.\d+)?$/', - //数字 - 'number' => '/^\d+$/', - //邮编 - 'zip' => '/^[0-9]\d{5}$/', - //电话 - 'tel' => '/^1[\d]{10}$/', - //整型 - 'integer' => '/^[-\+]?\d+$/', - //带小数点 - 'double' => '/^[-\+]?\d+(\.\d+)?$/', - //英文字母 - 'english' => '/^[a-zA-Z]+$/', - //中文汉字 - 'chinese' => '/^[\x{4e00}-\x{9fa5}]+$/u', - //拼音 - 'pinyin' => '/^[a-zA-Z0-9\-\_]+$/', - //用户名 - 'username' => '/^(?!_)(?!.*?_$)[a-zA-Z0-9_\x{4e00}-\x{9fa5}]{3,15}$/u', - //英文字符 - 'en' => '/^[a-zA-Z0-9_\s\-\.]+$/', - //中文字符 - 'cn' => '/^[\w\s\-\x{4e00}-\x{9fa5}]+$/u', - //安全字符串 - 'safestring' => '/^[^\$\?]+$/' - ); - // 检查是否有内置的正则表达式 - if (isset($validate[strtolower($rule)])) $rule = $validate[strtolower($rule)]; - return preg_match($rule, strval($value)) === 1; } /** @@ -716,10 +456,11 @@ function regex($value, $rule) { * @return string */ function U($method = '', $args = array(), $ignores = array()) { - static $rules = null, $_method = array(), $_map = array(); + static $rules = null, $_method = array(), $_map = array(),$power=false; if ($rules === null) { - $rules = C('URL_RULES'); - $_map = C('map_module'); + $rules = PT_Base::getInstance()->config->get('URL_RULES'); + $_map = PT_Base::getInstance()->config->get('map_module'); + $power = PT_Base::getInstance()->config->get('rewritepower',false); } //忽视args中的部分参数 if (!empty($ignores)) { @@ -740,24 +481,39 @@ function U($method = '', $args = array(), $ignores = array()) { $_method[$method] = strtolower($_method[$method]); } $method = $_method[$method]; - if (!empty($rules[$method])) { - $keys = array(); - $rule = $rules[$method]; + if (!empty($rules[$method]) && empty($args['_force']) && count($args) >= substr_count($rules[$method], '{')) { + $keys = array(); + $rule = $rules[$method]; + $oargs = $args; foreach ($args as $key => $arg) { $keys[] = '{' . $key . '}'; + if (strpos($rule, '{' . $key . '}')) unset($oargs[$key]); } $url = clearUrl(str_replace($keys, $args, $rule)); if (strpos($url, ']')) { $url = strtr($url, array('[' => '', ']' => '')); } - return PT_DIR . $url; + if ($oargs) { + return PT_DIR . $url . (strpos($url, '?') ? '&' : '?') . http_build_query($oargs); + } else { + return PT_DIR . $url; + } } else { list($param['m'], $param['c'], $param['a']) = explode('.', $method); + if (isset($_map[$param['m']])) $param['m'] = $_map[$param['m']]; //调整顺序为m c a krsort($param); $param = array_merge($param, $args); - if (isset($_map[$param['m']])) $param['m'] = $_map[$param['m']]; - return __APP__ . '?' . http_build_query($param); + if ($power){ + $url = PT_DIR . '/' . $param['m'] . '/' . $param['c'] . '/' . $param['a'] . '.' . $_GET['f']; + unset($param['m'], $param['c'], $param['a']); + if ($param) { + $url .= '?' . http_build_query($param); + } + }else{ + $url=__APP__.'?'.http_build_query($param); + } + return $url; } } @@ -784,7 +540,7 @@ function clearUrl($url) { function strip_whitespace($content) { $stripStr = ''; //分析php源码 - $tokens = token_get_all($content); + $tokens = token_get_all($content); $last_space = false; for ($i = 0, $j = count($tokens); $i < $j; $i++) { if (is_string($tokens[$i])) { @@ -826,110 +582,101 @@ function strip_whitespace($content) { return $stripStr; } - /** - * block调用函数 + * 获取自动加载的目录文件 * - * @param string $class block名称 - * @param array $param block参数 - * @return mixed + * @return array */ -function B($class, $param) { - static $_class; - $classname = ucfirst(strtolower($class)); - $class = $classname . 'Block'; - if (empty($_class[$class])) { - if (class_exists($class)) { - $_class[$class] = new $class(); - } else { - halt('不存在的block:' . $classname, __FILE__, __LINE__ - 4); +function get_auto_map() { + $map = array(); + $dirs = array_unique(explode(',', trim((PT_Base::getInstance()->config->get('allow_module', null, '') . ',common'), ','))); + foreach ($dirs as $dir) { + $path = APP_PATH . '/' . $dir; + if (!is_dir($path)) continue; + $handle = opendir($path); + while (($dirname = readdir($handle)) !== false) { + if (in_array($dirname, array('model', 'block', 'library'))) { + $handle1 = opendir($path . '/' . $dirname); + while (($filename = readdir($handle1)) !== false) { + if (substr($filename, -4) == '.php') { + $map[$dirname][substr($filename, 0, -4)][$dir] = $path . '/' . $dirname . '/' . $filename; + } + } + closedir($handle1); + } } + closedir($handle); } - return $_class[$class]->run($param); + return $map; } -function runinfo() { - if (C('is_gen_html')) return ''; - $tpl = C('runinfo', null, 'Power by PTCMS, Processed in {time}(s), Memory usage: {mem}MB.'); - $from[] = '{time}'; - $to[] = number_format(microtime(true) - $GLOBALS['_startTime'], 3); - $from[] = '{mem}'; - $to[] = number_format((memory_get_usage() - $GLOBALS['_startUseMems']) / 1024 / 1024, 3); - if (strpos($tpl, '{net}')) { - $from[] = '{net}'; - $to[] = count($GLOBALS['_api']); - } - if (strpos($tpl, '{file}')) { - $from[] = '{file}'; - $to[] = count(get_included_files()); - } - if (strpos($tpl, '{sql}')) { - $from[] = '{sql}'; - $to[] = count($GLOBALS['_sql']); - } - if (strpos($tpl, '{cacheread}')) { - $from[] = '{cacheread}'; - $to[] = $GLOBALS['_cacheRead']; - } - if (strpos($tpl, '{cachewrite}')) { - $from[] = '{cachewrite}'; - $to[] = $GLOBALS['_cacheWrite']; - } - $runtimeinfo = str_replace($from, $to, $tpl); - return $runtimeinfo; +// 判断是否有html缓存 +if ($_SERVER['REQUEST_METHOD'] === 'GET' && strpos($_SERVER['REQUEST_URI'], '.php') === false && is_file(PT_ROOT . $_SERVER['REQUEST_URI'])) { + readfile(PT_ROOT . $_SERVER['REQUEST_URI']); + exit; } - -function is_mobile() { - // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 - if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) { - return true; - } - // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息 - if (isset ($_SERVER['HTTP_VIA'])) { - // 找不到为flase,否则为true - return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false; - } - // 脑残法,判断手机发送的客户端标志,兼容性有待提高 - if (isset ($_SERVER['HTTP_USER_AGENT'])) { - $clientkeywords = array('nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile', 'UCBrowser'); - // 从HTTP_USER_AGENT中查找手机浏览器的关键字 - if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) { - return true; - } - } - // 协议法,因为有可能不准确,放到最后判断 - if (isset ($_SERVER['HTTP_ACCEPT'])) { - // 如果只支持wml并且不支持html那一定是移动设备 - // 如果支持wml和html但是wml在html之前则是移动设备 - if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) { - return true; - } - } - return false; +// 自动识别SAE环境 +if (function_exists('saeAutoLoader') or function_exists('sae_auto_load')) { + // sae + defined('APP_MODE') or define('APP_MODE', 'sae'); +} else { + // 普通模式 + defined('APP_MODE') or define('APP_MODE', 'common'); } -// 判断是否是蜘蛛 -function is_spider($ua = '') { - empty($ua) && $ua = $_SERVER['HTTP_USER_AGENT']; - $ua = strtolower($ua); - $spiders = array('bot', 'crawl', 'spider', 'slurp', 'sohu-search', 'lycos', 'robozilla'); - foreach ($spiders as $spider) { - if (false !== strpos($ua, $spider)) return true; +//后台运行程序 +if (!empty($_GET['backRun'])) { + //生成html + if (function_exists('fastcgi_finish_request')) { + fastcgi_finish_request(); + } else { + ignore_user_abort(true); } - return false; } -//获取客户端ip -function get_ip($default = '0.0.0.0') { - $keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'); +// 加载公共配置文件 +PT_Base::getInstance()->config->register(pt::import(APP_PATH . '/common/config.php')); +pt::import(APP_PATH . '/common/function.php'); - foreach ($keys as $key) { - if (empty($_SERVER[$key])) continue; - $ips = explode(',', $_SERVER[$key], 1); - $ip = $ips[0]; - $l = ip2long($ip); - if ((false !== $l) && ($ip === long2ip($l))) return $ip; +// 编译模式 +if (APP_DEBUG) { + // 开启错误输出 + ini_set('display_errors', 'on'); + // 设置错误输出级别 + error_reporting(E_ALL); + $GLOBALS['_automap'] = get_auto_map(); +} else { + // 开启错误输出 + ini_set('display_errors', 'off'); + // 设置错误输出级别 + error_reporting(0); + // 合并核心文件 + $runtimefile = CACHE_PATH . '/pt_runtime.php'; + if (!is_file($runtimefile)) { + $files = array( + PT_PATH . '/core/cache.php', + PT_PATH . '/driver/cache/' . strtolower(PT_Base::getInstance()->config->get('cache_driver', 'file')) . '.php', + PT_PATH . '/core/controller.php', + PT_PATH . '/core/dispatcher.php', + PT_PATH . '/core/log.php', + PT_PATH . '/core/plugin.php', + PT_PATH . '/core/view.php', + PT_PATH . '/core/block.php', + ); + if (PT_Base::getInstance()->config->get('mysql_driver')) { + $files[] = PT_PATH . '/core/model.php'; + $files[] = PT_PATH . '/driver/model/' . strtolower(PT_Base::getInstance()->config->get('mysql_driver', null, 'pdo')) . '.php'; + } + $str = "start(); diff --git a/ptcms_ad.sql b/ptcms_ad.sql deleted file mode 100644 index 8ac8afa..0000000 --- a/ptcms_ad.sql +++ /dev/null @@ -1,35 +0,0 @@ -# Host: localhost (Version: 5.5.38) -# Date: 2014-10-10 08:45:08 -# Generator: MySQL-Front 5.3 (Build 4.120) - -/*!40101 SET NAMES utf8 */; - -# -# Structure for table "ptcms_ad" -# - -DROP TABLE IF EXISTS `ptcms_ad`; -CREATE TABLE `ptcms_ad` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL DEFAULT '', - `key` varchar(50) NOT NULL DEFAULT '', - `width` smallint(6) DEFAULT '0', - `height` smallint(6) DEFAULT '0', - `code` text, - `intro` varchar(255) NOT NULL DEFAULT '', - `create_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人', - `update_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改人', - `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', - `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改时间', - `type` tinyint(3) DEFAULT '1' COMMENT '广告类型 1 html 2 js', - `status` tinyint(3) DEFAULT '1', - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -# -# Data for table "ptcms_ad" -# - -/*!40000 ALTER TABLE `ptcms_ad` DISABLE KEYS */; -INSERT INTO `ptcms_ad` VALUES (1,'ddd333','sss22',12,32,'123123','123',1,1,1412899971,1412900277,1,1),(2,'网站统计','tongji',0,0,'','',1,0,1412900092,0,1,1); -/*!40000 ALTER TABLE `ptcms_ad` ENABLE KEYS */; diff --git a/ptcms_friendlink.sql b/ptcms_friendlink.sql deleted file mode 100644 index 557a85d..0000000 --- a/ptcms_friendlink.sql +++ /dev/null @@ -1,35 +0,0 @@ -# Host: localhost (Version: 5.5.38) -# Date: 2014-10-10 08:45:16 -# Generator: MySQL-Front 5.3 (Build 4.120) - -/*!40101 SET NAMES utf8 */; - -# -# Structure for table "ptcms_friendlink" -# - -DROP TABLE IF EXISTS `ptcms_friendlink`; -CREATE TABLE `ptcms_friendlink` ( - `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(20) NOT NULL DEFAULT '', - `url` varchar(100) NOT NULL DEFAULT '', - `logo` varchar(100) NOT NULL, - `description` varchar(255) NOT NULL COMMENT '描述信息', - `ordernum` smallint(5) unsigned NOT NULL DEFAULT '50', - `color` varchar(20) NOT NULL COMMENT '颜色代码', - `isbold` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否加粗', - `create_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人', - `update_user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改人', - `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', - `update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '修改时间', - `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 1可用 0禁用', - PRIMARY KEY (`id`) -) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; - -# -# Data for table "ptcms_friendlink" -# - -/*!40000 ALTER TABLE `ptcms_friendlink` DISABLE KEYS */; -INSERT INTO `ptcms_friendlink` VALUES (6,'PTCMS工作室','http://www.ptcms.com','','PTCMS官方网站',10,'red',1,1,1,1412859114,1412862704,1); -/*!40000 ALTER TABLE `ptcms_friendlink` ENABLE KEYS */; diff --git a/public/image/114.png b/public/image/114.png deleted file mode 100644 index 3d082279d5940567ee19db51529f185575f0fc73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4616 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%0Db3^tZ#mVUg#{6NHDw! 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 BZCU^T diff --git a/public/image/57.png b/public/image/57.png deleted file mode 100644 index 07835dfa1d1b5f5ee7814c10da2772775a762511..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1631 zcmV-l2B7(gP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1@uWoK~!i%)tbw1 z97Pbu+dL!$LL4~2g@1qp2yR43%B8yw)m4LBf#P!16S4u}gloRJbyK(yeh5x3w37U758RvcB*Jgz8E`u%zzj+b#9cWef-X-BT z7KL9rgvLReIkAeRb{?=xd1b2ld1$QmC1_Uo^?5L}06GUc4`#mxeFH|nMZ@2N;Wf}Y z=(6z3lcC{4PRwHY?M3ZC=?FA;6!fw1D^sB3pp#(ulxBD?!SD(({6lCM&DL?btwou0 z#=_lmJ^-U1f)4YBtDj}uVK~y#Fs^qEm+vpdQE`tl7|}>}!*y+kU20f8!_qK3$8xR7 zNpUl_(|h2#`!i;a(=Zqv1swn#B!)i%vlF4=vNZfD2#<7i8Vr8{IujbMe`VNVIMR;% z2hE9bY^!&$W^AMk%N>@6;U!-=TgD+v}cK<5@)w%OkA}t0N7D zgB{illS@nAVOba3%ucM)UP&G~YM43F#vRrS%X-*udSZ?BOR&Rmp|zi3=18}m;S*q1 zUR?A@pABAS(jVQVOQyE)l5fJjzQpEOE2Clg6O8W1_B&&GnMey)BbD@9+F)4zS>?dF z9Y7n&L>2sX3xYAk=ZJ22lMfC!`X0KE^{S>ayrZgTL+ZnXO zLyPnhTDM#IUK6WEsV(jG9l660gLdLX3iSb6KdmaKpT;U?f>=D#g+Y-=TTxWOeo;R5 zXryr)r9sa{TW!?mL0jq<-ij41j@*i~W@0&v>Z|W!bUO4p@NDiwdm(C~6Xj!%#fs@l zf{Rz`hU)zDY)!O>Us=FFC-ed)RTp2uj5x8_g%@$AJM_BpRLP%cG1x_?zVZ%+^F#_* z$OIRwR66>gUp@b-@8;(*+8$NIcWXEjj&0<`v&tk6^Hk41*D7Kw6I`rGwzyYM#&R0J zw#NdKrSbc4ibn;fkqIu=BwM(6S|>1x<194TR(_+5*>SjdPR`gJn9&)PL!q^-O-dYm zn3LojygP_B!R2tWr8IGW5U-y`S}XWw8^>8xpxiTioBK*&JF+D)DBmExa5F?uPpE8mNtn)#gUN4m5InY zy2|f~U4cnSdGaAl>kNG-WKwzR5%?G1#EkAJ4h^*G>d-Ygp}i0}uoIyT>(Duq&|XMk zSj@`7orJtWRkJ#^<<}!-IBg7y$I)IJHMtX@&2rFrlh9Tan5cyT16XQ%ppA0Sd7}o! zGTMqm1GgHl_(!Bs4mzJCw8H~0C)a6k^Tv-@zQ52lov}M{GzyJL(!YaZ585%qCH4z_ z9j|%=XQJqFNkSXRs4ts2d6mC$+3dLRHd3!!p4x@8QQTin#A1_#7VLmyJI)oMs+`&b zT~x6hGhXQ$n=fTDC*k6gE2a>_zuZG^3rM%ZTez%$ynqnlNmIdKWw>m6WpKeyO+DAOfli|>m8 zZqcn2w$guKv1xtrehYT*30!__QUBMV&oaN+-b&zk-N!W7l^pK#;7&pQ3Y%-%Mw`Rr dJDHv!#D7!Sq`fD2g^>UN002ovPDHLkV1iI&3FQC) diff --git a/public/image/72.png b/public/image/72.png deleted file mode 100644 index 6107000bb2721c14d43a5494791368c5a02f9b6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2352 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 diff --git a/public/image/loading.gif b/public/image/loading.gif deleted file mode 100644 index ca8d7a288dfc529ff28b28ad2970a4870a19593a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1821 zcmV+&2jcigNk%w1VFm#l0I~uA%*@R1@9+Qr|K{fA_xJbS-rfKJ00000A^!_bMO0Hm zK~P09E-(WD0000X`2+4byHFmODjqw( zW`WX-EwkIWHxoUkgY8|sR)6JNPitvzZ+=^YY=vZTas!E8hk}c8D1mp7b(fZsgqeAr zd!K!wf1`$g0A>WLtE`Lztgr;Gv8{}>tFyPVwz|2uzO=vul~=mEa>l~2%C*S7yuZ-F z(y_|KQ_0lJ+Rbm-&e7o0;?>-^+}BUv-p}OQ?%izb^6l*5_T%`h=}q&g_4Muq%r~$c zymJRtF+-?tA1W*U#zX`&u}eiQ7mES>Cy@UmL65Qcz1k>|Bt?@JQDRi7v13V>Ct;@i zrJ#V#n>LN%+{tsN&YnPV{tOy)DAArqkNVW56ll_>IhjITddp@_o=>4>ZMs!y*P~yF zhAk>}>dmoE%U;DP!z|kvZf~}YTVQTnyKeEC)jO3hRJ?0#`fWN`Y2l-Xi6#!Z7--|3 zk9q119C>Huw=C$^g-iFcT+Vkv=M}w|bb+;=1)Ki6ns95wuMx*qJezTC$E&ZV-kiDf zZOFeR2e&*N^9s$o2iHtq{B!Tn&qqfuJ-u&p)zw*Nw+evycG%x#ho?Q>c6r?Afu|Q9 zUcq(V$9=CSKHqo=b)zM(|K9wf;0(EILg-o2hN$`x)=eyLTufz0HUHV}NB@S9N-8T824-H3W{1e2h)xg=*%cs7{+TGmG;pF4d<>=?r*y4Olxya4w?C{0(*Y?}( z=KSjKN#a=pw=Q46dj$#lt9NjpK6mg6NSsKq;zU;#GiJo7vHzn)jvh6F3~6yBNs1;< ze*C1eB+Hg43BW9nQf1APH%aCUxzl6Mjz2}doJrFW%nn2)B2BuKXw#Wbk8(&_AZkmi zDj{5*%9N{9uTa5C#XuG7NwXx;hK!I^>{hZ};eM4HmhRXKW!<*5`}VX}wN>BNo!j+p-@Rc!mc5znZ{e4bXC@xo_-E&#q0gp0-EU{<6meVBUXgot-rK=< z7yli2c=O{ed!M*oDS7tq-J>tBymkH8%!gx#KcD~o<0$zh7vOUH=|^302R4_Wfz|~# zpnVVGSD=6s61X6R7h2e0bQwY@T>=0h`2+cjx=w=w5W5Z&7K8Zz7)!mXiB3sbB>$}0l1!f0TMVMd<7zSpnT6E LH=TnDBme+AG~>JL diff --git a/public/image/loading2.gif b/public/image/loading2.gif deleted file mode 100644 index 5bb90fd6a49107a321c35b9cee4a7b810314b51f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1787 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 Cd?~pA diff --git a/public/image/success.gif b/public/image/success.gif deleted file mode 100644 index eb5905b98e1dbba242402d4b1aa17f85ac9ae1a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 678 zcmV;X0$Ke>Nk%w1VIlw`0K^{v_xtRy&qR!~BD&iQ(cr1Z%niQZ z6~We$w%9Gi<2q4=4W`FIsm~C(*+j3?6@#n_n!Po!)E-BD3a`@*zTOMK;325ZAEm-+ zccUtz$qla2GXMYoA^8LW0018VEC2ui03rY)000I5;3tk`xtvR>t}MbimLpp+hp_m# z$pTaSK#xGS$*Bl3&##eDI2D=3?;#@?MH`Ezz{Ge5n1NVqkP0ltTsBZ>df#L5W$p{0 zaapC}%@4=r5(Rc?B?K01dwqO=a~FXR7FHz=6a|Tji*XVXjs-&{J8hVXVhRSQ2Ae*2 zBMu%7qohy)0uvMw6%Yj!4kHK-qOp8X4*~=S#S9V^1r|3S90CPlUVBc8#1sbr00#mO zxdj{?BCfDuP8sUg)fvUx@B|aN5mX`;ZKW9zwE_)K*|u@pCNCF*2o^pp0H$C7u?YkK zED#W(i8}!YGG+uo;9IUO7ES;IV}PGPiT*DCZj3hp9E1cNnu)aJFu(?GI2Sy4Kp`T$ z0}Cbus374b$e9KP7zpqHXU+{LGa?X5^ks*mAMjjSwhpgm-9d>1Lgl1!f-r|R(+5Ly z<<)yt-0KmB9uy$H+R-wiMVBjXP9f5YH3cLj*iAmI=It8lvHEU7Is^0Y&u>@K9XNYw zxH_2Mjy{68^*JCx$qx}Qpg{r}Xy5@O8@p6-1qnM?z`+Cl0TCAmG}!lGV;IulVGW&a Mhyw~KY#0InJ7v8K1poj5 diff --git a/public/plugin/datepicker/WdatePicker.js b/public/plugin/datepicker/WdatePicker.js deleted file mode 100644 index 1d95ab3..0000000 --- a/public/plugin/datepicker/WdatePicker.js +++ /dev/null @@ -1,360 +0,0 @@ -/* - * My97 DatePicker 4.8 Beta2 - * License: http://www.my97.net/dp/license.asp - */ -var $dp, WdatePicker; -(function () { - var $ = { - $langList: [{name: "en", charset: "UTF-8"}, {name: "zh-cn", charset: "UTF-8"}, {name: "zh-tw", charset: "UTF-8"}], - $skinList: [ - {name: "default", charset: "gb2312"}, - {name: "whyGreen", charset: "gb2312"}, - {name: "blue", charset: "gb2312"}, - {name: "green", charset: "gb2312"}, - {name: "ext", charset: "gb2312"}, - {name: "blueFresh", charset: "gb2312"} - ], - $wdate: true, - $crossFrame: true, - $preLoad: false, - doubleCalendar: false, - enableKeyboard: true, - enableInputMask: true, - autoUpdateOnChanged: null, - weekMethod: "ISO8601", - position: {}, - lang: "auto", - skin: "ext", - dateFmt: "yyyy-MM-dd HH:mm:ss", -//dateFmt:"yyyy-MM-dd", - realDateFmt: "yyyy-MM-dd", - realTimeFmt: "HH:mm:ss", - realFullFmt: "%Date %Time", - minDate: "1900-01-01 00:00:00", - maxDate: "2099-12-31 23:59:59", - startDate: "", - alwaysUseStartDate: false, - yearOffset: 1911, - firstDayOfWeek: 0, - isShowWeek: false, - highLineWeekDay: true, - isShowClear: true, - isShowToday: true, - isShowOK: true, - isShowOthers: true, - readOnly: false, - errDealMode: 0, - autoPickDate: null, - qsEnabled: true, - autoShowQS: false, - specialDates: null, specialDays: null, disabledDates: null, disabledDays: null, opposite: false, onpicking: null, onpicked: null, onclearing: null, oncleared: null, ychanging: null, ychanged: null, Mchanging: null, Mchanged: null, dchanging: null, dchanged: null, Hchanging: null, Hchanged: null, mchanging: null, mchanged: null, schanging: null, schanged: null, eCont: null, vel: null, elProp: "", errMsg: "", quickSel: [], has: {}, getRealLang: function () { - var _ = $.$langList; - for (var A = 0; A < _.length; A++)if (_[A].name == this.lang)return _[A]; - return _[0] - } - }; - WdatePicker = T; - var X = window, S = {innerHTML: ""}, M = "document", H = "documentElement", C = "getElementsByTagName", U, A, R, G, a, W = navigator.appName; - if (W == "Microsoft Internet Explorer")R = true; else if (W == "Opera")a = true; else G = true; - A = J(); - if ($.$wdate)K(A + "skin/WdatePicker.css"); - U = X; - if ($.$crossFrame) { - try { - while (U.parent && U.parent[M] != U[M] && U.parent[M][C]("frameset").length == 0)U = U.parent - } catch (N) { - } - } - if (!U.$dp)U.$dp = {ff: G, ie: R, opera: a, status: 0, defMinDate: $.minDate, defMaxDate: $.maxDate}; - B(); - if ($.$preLoad && $dp.status == 0)E(X, "onload", function () { - T(null, true) - }); - if (!X[M].docMD) { - E(X[M], "onmousedown", D); - X[M].docMD = true - } - if (!U[M].docMD) { - E(U[M], "onmousedown", D); - U[M].docMD = true - } - E(X, "onunload", function () { - if ($dp.dd)O($dp.dd, "none") - }); - function B() { - U.$dp = U.$dp || {}; - obj = { - $: function ($) { - return (typeof $ == "string") ? X[M].getElementById($) : $ - }, $D: function ($, _) { - return this.$DV(this.$($).value, _) - }, $DV: function (_, $) { - if (_ != "") { - this.dt = $dp.cal.splitDate(_, $dp.cal.dateFmt); - if ($)for (var B in $)if (this.dt[B] === undefined)this.errMsg = "invalid property:" + B; else { - this.dt[B] += $[B]; - if (B == "M") { - var C = $["M"] > 0 ? 1 : 0, A = new Date(this.dt["y"], this.dt["M"], 0).getDate(); - this.dt["d"] = Math.min(A + C, this.dt["d"]) - } - } - if (this.dt.refresh())return this.dt - } - return "" - }, show: function () { - var A = U[M].getElementsByTagName("div"), $ = 100000; - for (var B = 0; B < A.length; B++) { - var _ = parseInt(A[B].style.zIndex); - if (_ > $)$ = _ - } - this.dd.style.zIndex = $ + 2; - O(this.dd, "block") - }, hide: function () { - O(this.dd, "none") - }, attachEvent: E - }; - for (var $ in obj)U.$dp[$] = obj[$]; - $dp = U.$dp - } - - function E(A, $, _) { - if (R)A.attachEvent($, _); else if (_) { - var B = $.replace(/on/, ""); - _._ieEmuEventHandler = function ($) { - return _($) - }; - A.addEventListener(B, _._ieEmuEventHandler, false) - } - } - - function J() { - var _, A, $ = X[M][C]("script"); - for (var B = 0; B < $.length; B++) { - _ = $[B].getAttribute("src") || ""; - _ = _.substr(0, _.toLowerCase().indexOf("wdatepicker.js")); - A = _.lastIndexOf("/"); - if (A > 0)_ = _.substring(0, A + 1); - if (_)break - } - return _ - } - - function K(A, $, B) { - var D = X[M][C]("HEAD").item(0), _ = X[M].createElement("link"); - if (D) { - _.href = A; - _.rel = "stylesheet"; - _.type = "text/css"; - if ($)_.title = $; - if (B)_.charset = B; - D.appendChild(_) - } - } - - function F($) { - $ = $ || U; - var A = 0, _ = 0; - while ($ != U) { - var D = $.parent[M][C]("iframe"); - for (var F = 0; F < D.length; F++) { - try { - if (D[F].contentWindow == $) { - var E = V(D[F]); - A += E.left; - _ += E.top; - break - } - } catch (B) { - } - } - $ = $.parent - } - return {"leftM": A, "topM": _} - } - - function V(G, F) { - if (G.getBoundingClientRect)return G.getBoundingClientRect(); else { - var A = {ROOT_TAG: /^body|html$/i, OP_SCROLL: /^(?:inline|table-row)$/i}, E = false, I = null, _ = G.offsetTop, H = G.offsetLeft, D = G.offsetWidth, B = G.offsetHeight, C = G.offsetParent; - if (C != G)while (C) { - H += C.offsetLeft; - _ += C.offsetTop; - if (Q(C, "position").toLowerCase() == "fixed")E = true; else if (C.tagName.toLowerCase() == "body")I = C.ownerDocument.defaultView; - C = C.offsetParent - } - C = G.parentNode; - while (C.tagName && !A.ROOT_TAG.test(C.tagName)) { - if (C.scrollTop || C.scrollLeft)if (!A.OP_SCROLL.test(O(C)))if (!a || C.style.overflow !== "visible") { - H -= C.scrollLeft; - _ -= C.scrollTop - } - C = C.parentNode - } - if (!E) { - var $ = Z(I); - H -= $.left; - _ -= $.top - } - D += H; - B += _; - return {"left": H, "top": _, "right": D, "bottom": B} - } - } - - function L($) { - $ = $ || U; - var B = $[M], A = ($.innerWidth) ? $.innerWidth : (B[H] && B[H].clientWidth) ? B[H].clientWidth : B.body.offsetWidth, _ = ($.innerHeight) ? $.innerHeight : (B[H] && B[H].clientHeight) ? B[H].clientHeight : B.body.offsetHeight; - return {"width": A, "height": _} - } - - function Z($) { - $ = $ || U; - var B = $[M], A = B[H], _ = B.body; - B = (A && A.scrollTop != null && (A.scrollTop > _.scrollTop || A.scrollLeft > _.scrollLeft)) ? A : _; - return {"top": B.scrollTop, "left": B.scrollLeft} - } - - function D($) { - var _ = $ ? ($.srcElement || $.target) : null; - try { - if ($dp.cal && !$dp.eCont && $dp.dd && _ != $dp.el && $dp.dd.style.display == "block")$dp.cal.close() - } catch ($) { - } - } - - function Y() { - $dp.status = 2 - } - - var P, _; - - function T(N, F) { - $dp.win = X; - B(); - N = N || {}; - for (var K in $)if (K.substring(0, 1) != "$" && N[K] === undefined)N[K] = $[K]; - if (F) { - if (!L()) { - _ = _ || setInterval(function () { - if (U[M].readyState == "complete")clearInterval(_); - T(null, true) - }, 50); - return - } - if ($dp.status == 0) { - $dp.status = 1; - N.el = S; - I(N, true) - } else return - } else if (N.eCont) { - N.eCont = $dp.$(N.eCont); - N.el = S; - N.autoPickDate = true; - N.qsEnabled = false; - I(N) - } else { - if ($.$preLoad && $dp.status != 2)return; - var J = H(); - if (J) { - N.srcEl = J.srcElement || J.target; - J.cancelBubble = true - } - N.el = N.el = $dp.$(N.el || N.srcEl); - if (!N.el || N.el["My97Mark"] === true || N.el.disabled || ($dp.dd && O($dp.dd) != "none" && $dp.dd.style.left != "-970px")) { - try { - N.el["My97Mark"] = false - } catch (C) { - } - return - } - I(N); - if (J && N.el.nodeType == 1 && N.el["My97Mark"] === undefined) { - var A, D; - if (J.type == "focus") { - A = "onclick"; - D = "onfocus" - } else { - A = "onfocus"; - D = "onclick" - } - E(N.el, A, N.el[D]) - } - } - function L() { - if (R && U != X && U[M].readyState != "complete")return false; - return true - } - - function H() { - if (G) { - func = H.caller; - while (func != null) { - var $ = func.arguments[0]; - if ($ && ($ + "").indexOf("Event") >= 0)return $; - func = func.caller - } - return null - } - return event - } - } - - function Q(_, $) { - return _.currentStyle ? _.currentStyle[$] : document.defaultView.getComputedStyle(_, false)[$] - } - - function O(_, $) { - if (_)if ($ != null)_.style.display = $; else return Q(_, "display") - } - - function I(G, _) { - var D = G.el ? G.el.nodeName : "INPUT"; - if (_ || G.eCont || new RegExp(/input|textarea|div|span|p|a/ig).test(D))G.elProp = D == "INPUT" ? "value" : "innerHTML"; else return; - if (G.lang == "auto")G.lang = R ? navigator.browserLanguage.toLowerCase() : navigator.language.toLowerCase(); - if (!G.eCont)for (var C in G)$dp[C] = G[C]; - if (!$dp.dd || G.eCont || ($dp.dd && (G.getRealLang().name != $dp.dd.lang || G.skin != $dp.dd.skin))) { - if (G.eCont)E(G.eCont, G); else { - $dp.dd = U[M].createElement("DIV"); - $dp.dd.style.cssText = "position:absolute"; - U[M].body.appendChild($dp.dd); - E($dp.dd, G); - if (_)$dp.dd.style.left = $dp.dd.style.top = "-970px"; else { - $dp.show(); - B($dp) - } - } - } else if ($dp.cal) { - $dp.show(); - $dp.cal.init(); - if (!$dp.eCont)B($dp) - } - function E(F, E) { - F.innerHTML = ""; - var D = F.lastChild.contentWindow[M], _ = $.$langList, C = $.$skinList, H = E.getRealLang(); - F.lang = H.name; - F.skin = E.skin; - var G = [""]; - for (var I = 0; I < C.length; I++)if (C[I].name == E.skin)G.push(""); - G.push(""); - G.push(""); - G.push(""); - E.setPos = B; - E.onload = Y; - D.write(""); - D.cfg = E; - D.write(G.join("")) - } - - function B(I) { - var G = I.position.left, B = I.position.top, C = I.el; - if (C == S)return; - if (C != I.srcEl && (O(C) == "none" || C.type == "hidden"))C = I.srcEl; - var H = V(C), $ = F(X), D = L(U), A = Z(U), E = $dp.dd.offsetHeight, _ = $dp.dd.offsetWidth; - if (isNaN(B))B = 0; - if (($.topM + H.bottom + E > D.height) && ($.topM + H.top - E > 0))B += A.top + $.topM + H.top - E - 2; else B += A.top + $.topM + Math.min(H.bottom, D.height - E) + 2; - if (isNaN(G))G = 0; - G += A.left + Math.min($.leftM + H.left, D.width - _ - 5) - (R ? 2 : 0); - I.dd.style.top = B + "px"; - I.dd.style.left = G + "px" - } - } -})() \ No newline at end of file diff --git a/public/plugin/datepicker/calendar.js b/public/plugin/datepicker/calendar.js deleted file mode 100644 index 69b42e4..0000000 --- a/public/plugin/datepicker/calendar.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * My97 DatePicker 4.8 Beta2 - * License: http://www.my97.net/dp/license.asp - */ -eval(function (p, a, c, k, e, d) { - e = function (c) { - return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)) - }; - if (!''.replace(/^/, String)) { - while (c--)d[e(c)] = k[c] || e(c); - k = [function (e) { - return d[e] - }]; - e = function () { - return '\\w+' - }; - c = 1; - } - ; - while (c--)if (k[c])p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]); - return p; -}('k($4j.3X){$f={};19(o p 4i $2l)k(5Z $2l[p]=="6d"){$f[p]={};19(o 4B 4i $2l[p])$f[p][4B]=$2l[p][4B]}q $f[p]=$2l[p]}q $f=$2l;19(p 4i $4j)$f[p]=$4j[p];o $c;k($62){6o.2N.7c("6W",l($){k(!$)h.2h();t $});6o.2N.7b("6N",l(){o $=h.6K;3l($.5f!=1)$=$.7e;t $});7a.2N.2T=l($,b){o A=$.1l(/6C/,"");b.6B=l($){6M.1Q=$;t b()};h.7g(A,b.6B,1n)}}l 5n(){$c=h;h.2F=[];$d=1P.75("x");$d.1d="4r";$d.1I="<1t Y=3Y><1t Y=3Y><1x 2t=0 2r=0 2u=0><1j><18 7V=2><4k 1E=7W>&4A;<1t Y=7u 4g=2><1t 1f=\\":\\" Y=6i 6p><1t Y=6q 4g=2><1t 1f=\\":\\" Y=6i 6p><1t Y=6q 4g=2><18><1N 1E=7s><1j><18><1N 1E=7r><1t Y=4h 1E=7y 3a=1N><1t Y=4h 1E=7C 3a=1N><1t Y=4h 1E=73 3a=1N>";6S($d,l(){3x()});A();h.5o();$f.22=[1P,$d.1K,$d.1v,$d.2B,$d.2Q,$d.2S,$d.2W,$d.2d,$d.1X];19(o B=0;B<$f.22.u;B++){o b=$f.22[B];b.34=B==$f.22.u-1?$f.22[1]:$f.22[B+1];$f.2T(b,"56",4P)}$();4K("y,M,H,m,s");$d.5s.1r=l(){58(1)};$d.5t.1r=l(){58(-1)};$d.4s.1r=l(){k($d.1F.1c.2g!="6t"){$c.4I();3v($d.1F)}q 1m($d.1F)};1P.6G.4x($d);l A(){o b=$("a");1q=$("x"),1M=$("1t"),4n=$("1N"),5q=$("4k");$d.3R=b[0];$d.3H=b[1];$d.3E=b[3];$d.3G=b[2];$d.41=1q[9];$d.1K=1M[0];$d.1v=1M[1];$d.4z=1q[0];$d.3C=1q[4];$d.3g=1q[6];$d.1F=1q[10];$d.2Y=1q[11];$d.2V=1q[12];$d.6F=1q[13];$d.6I=1q[14];$d.6T=1q[15];$d.4s=1q[16];$d.3Z=1q[17];$d.2B=1M[2];$d.2Q=1M[4];$d.2S=1M[6];$d.2W=1M[7];$d.2d=1M[8];$d.1X=1M[9];$d.5s=4n[0];$d.5t=4n[1];$d.5w=5q[0];l $($){t $d.6P($)}}l $(){$d.3R.1r=l(){$1L=$1L<=0?$1L-1:-1;k($1L%5==0){$d.1v.1U();t}$d.1v.1f=$n.y-1;$d.1v.2m()};$d.3H.1r=l(){$n.2q("M",-1);$d.1K.2m()};$d.3E.1r=l(){$n.2q("M",1);$d.1K.2m()};$d.3G.1r=l(){$1L=$1L>=0?$1L+1:1;k($1L%5==0){$d.1v.1U();t}$d.1v.1f=$n.y+1;$d.1v.2m()}}}5n.2N={5o:l(){$1L=0;$f.5h=h;k($f.3L&&$f.z.3L!=1h){$f.z.3L=1a;$f.z.4d()}h.4w();$n=h.5J=1b 1G();$1B=1b 1G();$1u=h.2A=1b 1G();h.1A=h.3j($f.1A);h.2L=$f.2L==1h?($f.Z.25&&$f.Z.25?1n:1a):$f.2L;$f.3r=$f.3r==1h?($f.4t&&$f.Z.d?1n:1a):$f.3r;h.4a=h.3p("7A");h.5S=h.3p("7G");h.5U=h.3p("7H");h.5O=h.3p("7F");h.1T=h.3s($f.1T,$f.1T!=$f.5A?$f.1Z:$f.2G,$f.5A);h.1W=h.3s($f.1W,$f.1W!=$f.5B?$f.1Z:$f.2G,$f.5B);k(h.1T.2z(h.1W)>0)$f.4o=$1k.7D;k(h.1R()){h.5C();h.3F=$f.z[$f.1y]}q h.35(1n,2);4H($n);$d.5w.1I=$1k.7q;$d.2W.1f=$1k.7o;$d.2d.1f=$1k.7p;$d.1X.1f=$1k.7w;$d.1X.28=!$c.1w($1u);h.5Y();h.6O();k($f.4o)7v($f.4o);h.4F();k($f.z.5f==1&&$f.z["3z"]===6J){$f.2T($f.z,"56",4P);$f.2T($f.z,"2m",l(){k($f&&$f.1J.1c.2g=="2s"){$c.3I();k($f.5h.3F!=$f.z[$f.1y]&&$f.z.7t)4J($f.z,"7I")}});$f.z["3z"]=1n}$c.1i=$f.z;3x()},5C:l(){o b=h.3f();k(b!=0){o $;k(b>0)$=h.1W;q $=h.1T;k($f.Z.3T){$n.y=$.y;$n.M=$.M;$n.d=$.d}k($f.Z.25){$n.H=$.H;$n.m=$.m;$n.s=$.s}}},3i:l(J,C,Q,E,B,G,F,K,L){o $;k(J&&J.1R)$=J;q{$=1b 1G();k(J!=""){C=C||$f.1A;o H,P=0,O,A=/3d|2n|3m|y|2w|3b|3K|M|1J|d|%2i|4O|H|4U|m|4V|s|3h|D|4Z|W|w/g,b=C.2Z(A);A.2C=0;k(L)O=J.43(/\\W+/);q{o D=0,M="^";3l((O=A.3k(C))!==1h){k(D>=0)M+=C.1D(D,O.3Q);D=A.2C;2R(O[0]){1e"3d":M+="(\\\\d{4})";1g;1e"2n":M+="(\\\\d{3})";1g;1e"2w":1e"3b":1e"3h":1e"D":M+="(\\\\D+)";1g;63:M+="(\\\\d\\\\d?)";1g}}M+=".*$";O=1b 4u(M).3k(J);P=1}k(O){19(H=0;H=0){A=A.1l(/%2i/g,"0");$.d=0;$.M=2e($.M)+1}$.1S()}t $},1R:l(){o b,$;k($f.7R||($f.6c!=""&&$f.z[$f.1y]=="")){b=h.3j($f.6c);$=$f.1Z}q{b=$f.z[$f.1y];$=h.1A}$n.2k(h.3i(b,$));k(b!=""){o A=1;k($f.Z.3T&&!h.4l($n)){$n.y=$1B.y;$n.M=$1B.M;$n.d=$1B.d;A=0}k($f.Z.25&&!h.4m($n)){$n.H=$1B.H;$n.m=$1B.m;$n.s=$1B.s;A=0}t A&&h.1w($n)}t 1},4l:l($){k($.y!=1h)$=2I($.y,4)+"-"+$.M+"-"+$.d;t $.2Z(/^((\\d{2}(([6f][7Q])|([6e][26]))[\\-\\/\\s]?((((0?[6b])|(1[68]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[67])))|(((0?[69])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([6f][7P])|([6e][72]))[\\-\\/\\s]?((((0?[6b])|(1[68]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[67])))|(((0?[69])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$/)},4m:l($){k($.H!=1h)$=$.H+":"+$.m+":"+$.s;t $.2Z(/^([0-9]|([0-1][0-9])|([2][0-3])):([0-9]|([0-5][0-9])):([0-9]|([0-5][0-9]))$/)},3f:l($,A){$=$||$n;o b=$.2z(h.1T,A);k(b>0){b=$.2z(h.1W,A);k(b<0)b=0}t b},1w:l($,A,B){A=A||$f.Z.49;o b=h.3f($,A);k(b==0){b=1;k(A=="d"&&B==1h)B=24.5F((1b 1z($.y,$.M-1,$.d).1H()-$f.3M+7)%7);b=!h.5T(B)&&!h.5M($,A)}q b=0;t b},5L:l(){o b=$f.z,A=h,$=$f.z[$f.1y];k($f.4q>=0&&$f.4q<=2&&$!=1h){k($!="")A.2A.2k(A.3i($,A.1A));k($==""||(A.4l(A.2A)&&A.4m(A.2A)&&A.1w(A.2A))){k($!=""){A.5J.2k(A.2A);A.3D()}q A.3W("")}q t 1n}t 1a},3I:l($){3x();k(h.5L()){h.35(1a);$f.1m()}q{k($){2J($);h.35(1n,2)}q h.35(1n);$f.20()}},44:l(){o E,C,D,K,A,H=1b 2p(),F=$1k.5l,G=$f.3M,I="",$="",b=1b 1G($n.y,$n.M,$n.d,0,0,0),J=b.y,B=b.M;A=1-1b 1z(J,B-1,1).1H()+G;k(A>1)A-=7;H.a("<1x Y=5E 2U=33% 2u=0 2t=0 2r=0>");H.a("<1j Y=5H 4D=5P>");k($f.5G)H.a("<18>"+F[0]+"");19(E=0;E<7;E++)H.a("<18>"+F[(G+E)%7+1]+"");H.a("");19(E=1,C=A;E<7;E++){H.a("<1j>");19(D=0;D<7;D++){b.1R(J,B,C++);b.1S();k(b.M==B){K=1a;k(b.2z($1u,"d")==0)I="74";q k(b.2z($1B,"d")==0)I="6X";q I=($f.5D&&(0==(G+D)%7||6==(G+D)%7)?"7i":"7j");$=($f.5D&&(0==(G+D)%7||6==(G+D)%7)?"7h":"7k")}q k($f.5y){K=1a;I="7l";$="7f"}q K=1n;k($f.5G&&D==0&&(E<4||K))H.a("<18 Y=77>"+4v(b,$f.3M==0?1:0)+"");H.a("<18 ");k(K){k(h.1w(b,"d",D)){k(h.5R(24.5F((1b 1z(b.y,b.M-1,b.d).1H()-$f.3M+7)%7))||h.5V(b))I="78";H.a("1r=\\"2K("+b.y+","+b.M+","+b.d+");\\" ");H.a("2y=\\"h.1d=\'"+$+"\'\\" ");H.a("2v=\\"h.1d=\'"+I+"\'\\" ")}q I="7d";H.a("Y="+I);H.a(">"+b.d+"")}q H.a(">")}H.a("")}H.a("");t H.j()},5M:l(b,A){o $=h.4e(b,h.4a,A);t(h.4a&&$f.5N)?!$:$},5T:l($){t h.4f($,h.5S)},5V:l($){t h.4e($,h.5U)},5R:l($){t h.4f($,h.5O)},4e:l($,B,A){o b=A=="d"?$f.4E:$f.1Z;t B?B.4Q(h.3J(b,$)):0},4f:l(b,$){t $?$.4Q(b):0},2H:l(p,c,r,e,2b){o s=1b 2p(),4c=2b?"r"+p:p;5Q=$n[p];s.a("<1x 2t=0 2r=3 2u=0");19(o i=0;i");19(o j=0;j"+(p=="M"?$1k.29[$n[p]-1]:$n[p])+"")}s.a("")}s.a("");$n[p]=5Q;t s.j()},4C:l($,b){k($){o A=$.7n;k($6y)A=$.7m().2D;b.1c.2D=A}},6Z:l($){h.4C($,$d.3C);$d.3C.1I=h.2H("M",2,6,"i+j*6+1",$==$d.2c)},4b:l(b,B,A){o $=1b 2p();A=A||b==$d.2o;B=3e(B,$n.y-5);$.a(h.2H("y",2,5,B+"+i+j*5",A));$.a("<1x 2t=0 2r=3 2u=0 4D=5P><1j><18 ");$.a(h.1T.y\\91<18 Y=\'1C\' 2y=\\"h.1d=\'2E\'\\" 2v=\\"h.1d=\'1C\'\\" 3N=\\"1m($d.3g);$d.1v.4d();\\">\\5I<18 ");$.a(h.1W.y>B+10?"Y=\'1C\' 2y=\\"h.1d=\'2E\'\\" 2v=\\"h.1d=\'1C\'\\" 3N=\'k(1Q.2h)1Q.2h();1Q.4X=1a;$c.4b(0,"+(B+10)+","+A+")\'":"Y=\'4p\'");$.a(">\\8S");h.4C(b,$d.3g);$d.3g.1I=$.j()},3S:l(A,b,$){$d[A+"D"].1I=h.2H(A,6,b,$)},8P:l(){h.3S("H",4,"i * 6 + j")},8T:l(){h.3S("m",2,"i * 30 + j * 5")},8X:l(){h.3S("s",1,"j * 10")},4I:l(C,A){h.6m();o $=A?">a/<94 8U>8V=8O \\"8Q:8R\\"=97 \\"98.95.99//:8Z\\"=93 a<".43("").92().6s(""):$1k.90,B=h.2F,E=B.1c,b=1b 2p();b.a("<1x Y=5E 2U=33% 2f=33% 2u=0 2t=0 2r=0>");b.a("<1j Y=5H><18>"+$+"");k(!C)b.a("\\5I");b.a("");19(o D=0;D<18 1c=\'4M-4D:2D\' 2M=\'2M\' Y=\'1C\' 2y=\\"h.1d=\'2E\'\\" 2v=\\"h.1d=\'1C\'\\" 1r=\\"");b.a("2K("+B[D].y+", "+B[D].M+", "+B[D].d+","+B[D].H+","+B[D].m+","+B[D].s+");\\">");b.a("&4A;"+h.3J(1h,B[D]));b.a("")}q b.a("<1j><18 Y=\'1C\'>&4A;");b.a("");$d.1F.1I=b.j()},4w:l(){$(/w/);$(/4Z|W/);$(/3h|D/);$(/3d|2n|3m|y/);$(/2w|3b|3K|M/);$(/1J|d/);$(/4O|H/);$(/4U|m/);$(/4V|s/);$f.Z.3T=($f.Z.y||$f.Z.M||$f.Z.d)?1a:1n;$f.Z.25=($f.Z.H||$f.Z.m||$f.Z.s)?1a:1n;$f.2G=$f.2G.1l(/%1z/,$f.4E).1l(/%8N/,$f.66);k($f.Z.3T){k($f.Z.25)$f.1Z=$f.2G;q $f.1Z=$f.4E}q $f.1Z=$f.66;l $(b){o $=(b+"").5c(1,2);$f.Z[$]=b.3k($f.1A)?($f.Z.49=$,1a):1n}},5Y:l(){o $=0;$f.Z.y?($=1,20($d.1v,$d.3R,$d.3G)):1m($d.1v,$d.3R,$d.3G);$f.Z.M?($=1,20($d.1K,$d.3H,$d.3E)):1m($d.1K,$d.3H,$d.3E);$?20($d.4z):1m($d.4z);k($f.Z.25){20($d.2V);3t($d.2B,$f.Z.H);3t($d.2Q,$f.Z.m);3t($d.2S,$f.Z.s)}q 1m($d.2V);3c($d.2W,$f.61);3c($d.2d,$f.64);3c($d.1X,$f.4t);3c($d.4s,!$f.5v&&$f.Z.d&&$f.8h);k($f.3X||!($f.61||$f.64||$f.4t))1m($d.3Z);q 20($d.3Z)},35:l(B,D){o A=$f.z,b=$62?"Y":"1d";k(B)C(A);q{k(D==1h)D=$f.4q;2R(D){1e 0:k(8f($1k.8g)){A[$f.1y]=h.3F;C(A)}q $(A);1g;1e 1:A[$f.1y]=h.3F;C(A);1g;1e 2:$(A);1g}}l C(A){o B=A.1d;k(B){o $=B.1l(/5j/g,"");k(B!=$)A.5m(b,$)}}l $($){$.5m(b,$.1d+" 5j")}},1Y:l(D,b,$){$=$||$1u;o H,C=[D+D,D],E,A=$[D],F=l($){t 2I(A,$.u)};2R(D){1e"w":A=1H($);1g;1e"D":o G=1H($)+1;F=l($){t $.u==2?$1k.8k[G]:$1k.5l[G]};1g;1e"W":A=4v($);1g;1e"y":C=["3d","2n","3m","y"];b=b||C[0];F=l(b){t 2I((b.u<4)?(b.u<3?$.y%33:($.y+5g-$f.5i)%8o):A,b.u)};1g;1e"M":C=["2w","3b","3K","M"];F=l($){t($.u==4)?$1k.5k[A-1]:($.u==3)?$1k.29[A-1]:2I(A,$.u)};1g}b=b||D+D;k("3n".1p(D)>-1&&D!="y"&&!$f.Z[D])k("8p".1p(D)>-1)A=0;q A=1;o B=[];19(H=0;H=0){B[H]=F(E);b=b.1l(E,"{"+H+"}")}}19(H=0;H=0){o A=1b 1G();A.2k($);A.d=0;A.M=2e(A.M)+1;A.1S();b=b.1l(/%2i/g,A.d)}o B="8n";19(o D=0;D<1j><18 5z=5u>");$.a(h.44());$.a("<18 5z=5u>");$n.2q("M",1);$.a(h.44());$d.2c=$d.1K.5p(1a);$d.2o=$d.1v.5p(1a);$d.41.4x($d.2c);$d.41.4x($d.2o);$d.2c.1f=$1k.29[$n.M-1];$d.2c["3u"]=$n.M;$d.2o.1f=$n.y;4K("6D,6u");$d.2c.1d=$d.2o.1d="3Y";$n.2q("M",-1);$.a("");$d.2Y.1I=$.j()}q{$d.1d="4r";$d.2Y.1I=h.44()}k(!$f.Z.d||$f.84){h.4I(1a);3v($d.1F)}q 1m($d.1F);h.5e()},5e:l(){o b=88.1P.6P("8c");19(o C=0;C=B){A+=B;$d.1c.2f=A}q $d.1c.2f=$;b[C].1c.2f=24.65(A,$d.36)+"6Q"}}$d.1F.1c.2U=$d.2Y.6V;$d.1F.1c.2f=$d.2Y.36},4R:l(){$n.d=24.8a(1b 1z($n.y,$n.M,0).3o(),$n.d);$1u.2k($n);h.3D();k(!$f.3X)k(h.1w($n)){4G();1m($f.1J)}k($f.6H)2j("6H")},6O:l(){$d.2W.1r=l(){k(!2j("8F")){$f.z[$f.1y]="";$c.3W("");4G();1m($f.1J);k($f.6E)2j("6E")}};$d.1X.1r=l(){2K()};k(h.1w($1B)){$d.2d.28=1n;$d.2d.1r=l(){$n.2k($1B);2K()}}q $d.2d.28=1a},6m:l(){o H,G,A,F,C=[],$=5,E=$f.6g.u,b=$f.Z.49;k(E>$)E=$;q k(b=="m"||b=="s")C=[-60,-30,0,30,60,-15,15,-45,45];q 19(H=0;H<$;H++)C[H]=$n[b]-2+H;19(H=G=0;H=0)$=3q(A,0,59);k($1u[b]!=A&&!2j(b+"8v")){o C=$c.3f();k(C==0)21(b,$);q k(C<0)B($c.1T);q k(C>0)B($c.1W);$d.1X.28=!$c.1w($1u);k("8A".1p(b)>=0)$c.4F();2j(b+"8y")}l B($){4H($c.1w($)?$:$1u)}}l 4H($){21("y",$.y);21("M",$.M);21("d",$.d);21("H",$.H);21("m",$.m);21("s",$.s)}l 2K(F,B,b,D,C,A){o $=1b 1G($n.y,$n.M,$n.d,$n.H,$n.m,$n.s);$n.1R(F,B,b,D,C,A);k(!2j("8w")){o E=$.y==F&&$.M==B&&$.d==b;k(!E&&2O.u!=0){c("y",F);c("M",B);c("d",b);$c.1i=$f.z;3V()}k($c.2L||E||2O.u==0)$c.4R()}q $n=$}l 3V(){k($f.3r){$c.3D();$f.z.1U()}}l 2j($){o b;k($f[$])b=$f[$].4W($f.z,$f);t b}l 21(b,$){k($==1h)$=$n[b];$1u[b]=$n[b]=$;k("8x".1p(b)>=0)$d[b+"I"].1f=$;k(b=="M"){$d.1K["3u"]=$;$d.1K.1f=$1k.29[$-1]}}l 3q(b,$,A){k(b<$)b=$;q k(b>A)b=A;t b}l 6S($,b){$f.2T($,"56",l(){o $=1Q,A=($.52==6J)?$.54:$.52;k(A==9)b()})}l 2I($,b){$=$+"";3l($.u=0?C:5;19(o D=0;D<=C;D++){B=A.1O(D);b=h[B]-$[B];k(b>0)t 1;q k(b<0)t-1}t 0},1S:l(){o $=1b 1z(h.y,h.M-1,h.d,h.H,h.m,h.s);h.y=$.5d();h.M=$.5b()+1;h.d=$.3o();h.H=$.5a();h.m=$.4Y();h.s=$.4N();t!6r(h.y)},2q:l(b,$){k("3n".1p(b)>=0){o A=h.d;k(b=="M")h.d=1;h[b]+=$;h.1S();h.d=A}}};l 2e($){t 8z($,10)}l 3w($,b){t 3e(2e($),b)}l 1s($,A,b){t 3w($,3e(A,b))}l 3e($,b){t $==1h||6r($)?b:$}l 4J(A,$){k($6y)A.4J("6C"+$);q{o b=1P.8q("8s");b.8t($,1a,1a);A.8I(b)}}l 42($){o A,B,b="y,M,H,m,s,6u,6D".43(",");19(B=0;B=0?6l(v):$n[p];k(p=="y"){2b=h==$d.2o;k(2b&&$n.M==12)$n.y-=1}q k(p=="M"){2b=h==$d.2c;k(2b){4T=$1k.29[$n[p]-1];k(6h==12)$n.y+=1;$n.2q("M",-1)}k($1u.M==$n.M)h.1f=4T||$1k.29[$n[p]-1];k(($1u.y!=$n.y))c("y",$n.y)}47("c(\\""+p+"\\","+$n[p]+")");k(6n!==1a){k(p=="y"||p=="M")h.1d="3Y";1m($d[p+"D"])}3V()}l 2J($){k($.2h){$.2h();$.8G()}q{$.4X=1a;$.6W=1n}k($5x)$.54=0}l 4K($){o A=$.43(",");19(o B=0;B=96&&Q<=83)Q-=48;k($f.85&&53){k(!H.34){H.34=$f.22[1];$c.1i=$f.z}k(H==$f.z)$c.1i=$f.z;k(Q==27)k(H==$f.z){$c.3I();t}q $f.z.1U();k(Q>=37&&Q<=40){o U;k($c.1i==$f.z||$c.1i==$d.1X)k($f.Z.d){U="d";k(Q==38)$n[U]-=7;q k(Q==39)$n[U]+=1;q k(Q==37)$n[U]-=1;q $n[U]+=7;$n.1S();c("y",$n["y"]);c("M",$n["M"]);c("d",$n[U]);2J(M);t}q{U=$f.Z.49;$d[U+"I"].1U()}U=U||42($c.1i);k(U){k(Q==38||Q==39)$n[U]+=1;q $n[U]-=1;$n.1S();$c.1i.1f=$n[U];3U.4W($c.1i,1a);$c.1i.51()}}q k(Q==9){o D=H.34;19(o R=0;R<$f.22.u;R++)k(D.28==1a||D.36==0)D=D.34;q 1g;k($c.1i!=D){$c.1i=D;D.1U()}}q k(Q==13){3U.4W($c.1i);k($c.1i.3a=="1N")$c.1i.8e();q $c.4R();$c.1i=$f.z}}q k(Q==9&&H==$f.z)$c.3I();k($f.8m&&!$5x&&!$f.3L&&$c.1i==$f.z&&(Q>=48&&Q<=57)){o T=$f.z,S=T.1f,F=E(T),I={1V:"",1o:[]},R=0,K,N=0,X=0,O=0,J,b=/3d|2n|3m|y|3K|M|1J|d|%2i|4O|H|4U|m|4V|s|4Z|W|w/g,L=$f.1A.2Z(b),B,A,$,V,W,G,J=0;k(S!=""){O=S.2Z(/[0-9]/g);O=O==1h?0:O.u;19(R=0;R=0?1:0;k(O==1&&F>=S.u)F=S.u-1}S=S.1D(0,F)+8j.8i(Q)+S.1D(F+O);F++;19(R=0;R=0){S+=$f.1A.1D(N,X);k(F>=N+J&&F<=X+J)F+=X-N}N=b.2C;G=N-X;B=I.1V.1D(0,G);A=K[0].1O(0);$=2e(B.1O(0));k(I.1V.u>1){V=I.1V.1O(1);W=$*10+2e(V)}q{V="";W=$}k(I.1o[X+1]||A=="M"&&W>12||A=="d"&&W>31||A=="H"&&W>23||"6a".1p(A)>=0&&W>59){k(K[0].u==2)B="0"+$;q B=$;F++}q k(G==1){B=W;G++;J++}S+=B;I.1V=I.1V.1D(G);k(I.1V=="")1g}T.1f=S;P(T,F);2J(M)}k(53&&$c.1i!=$f.z&&!((Q>=48&&Q<=57)||Q==8||Q==46))2J(M);l E(A){o b=0;k($f.4L.1P.5X){o B=$f.4L.1P.5X.82(),$=B.4M.u;B.6z("4S",-A.1f.u);b=B.4M.u-$}q k(A.55||A.55=="0")b=A.55;t b}l P(b,A){k(b.5r){b.1U();b.5r(A,A)}q k(b.6U){o $=b.6U();$.7B(1a);$.7x("4S",A);$.6z("4S",A);$.51()}}}1P.79=1', 62, 568, '|||||||||||_||||dp||this|||if|function||dt|var||else|||return|length|||div||el|||||||||||||||||||||||||class|has|||||||||td|for|true|new|style|className|case|value|break|null|currFocus|tr|lang|replace|hide|false|arr|indexOf|divs|onclick|pInt3|input|sdt|yI|checkValid|table|elProp|Date|dateFmt|tdt|menu|substring|id|qsDivSel|DPDate|getDay|innerHTML|dd|MI|ny|ipts|button|charAt|document|event|loadDate|refresh|minDate|focus|str|maxDate|okI|getP|realFmt|show|sv|focusArr||Math|st|||disabled|aMonStr|9700|isR|rMI|todayI|pInt|height|display|preventDefault|ld|callFunc|loadFromDate|pdp|onblur|yyy|ryI|sb|attr|cellpadding|none|cellspacing|border|onmouseout|MMMM|tmpEval|onmouseover|compareWith|date|HI|lastIndex|left|menuOn|QS|realFullFmt|_f|doStr|_cancelKey|day_Click|autoPickDate|nowrap|prototype|arguments|float|mI|switch|sI|attachEvent|width|tDiv|clearI|menuSel|dDiv|match||||100|nextCtrl|mark|offsetHeight||||type|MMM|shorH|yyyy|rtn|checkRange|yD|DD|splitDate|doExp|exec|while|yy|yMdHms|getDate|_initRe|makeInRange|autoUpdateOnChanged|doCustomDate|disHMS|realValue|showB|pInt2|hideSel|toLowerCase|My97Mark|valueOf|setDisp|MD|update|rightImg|oldValue|navRightImg|leftImg|close|getDateStr|MM|readOnly|firstDayOfWeek|onmousedown|navImg|ps|index|navLeftImg|_fHMS|sd|_blur|dealAutoUpdate|setRealValue|eCont|yminput|bDiv||rMD|_foundInput|split|_fd|||eval||minUnit|ddateRe|_fy|fp|blur|testDate|testDay|maxlength|dpButton|in|cfg|span|isDate|isTime|btns|errMsg|invalidMenu|errDealMode|WdateDiv|qsDiv|isShowOK|RegExp|getWeek|_dealFmt|appendChild|getNewDateStr|titleDiv|nbsp|pp|_fMyPos|align|realDateFmt|draw|elFocus|_setAll|_fillQS|fireEvent|_inputBindEvent|win|text|getSeconds|HH|_tab|test|pickDate|character|mStr|mm|ss|call|cancelBubble|getMinutes|WW||select|which|isShow|keyCode|selectionStart|onkeydown||updownEvent||getHours|getMonth|slice|getFullYear|autoSize|nodeType|2000|cal|yearOffset|WdateFmtErr|aLongMonStr|aWeekStr|setAttribute|My97DP|init|cloneNode|spans|setSelectionRange|upButton|downButton|top|doubleCalendar|timeSpan|OPERA|isShowOthers|valign|defMinDate|defMaxDate|_makeDateInRange|highLineWeekDay|WdayTable|abs|isShowWeek|MTitle|xd7|newdate|right|checkAndUpdate|testDisDate|opposite|sdayRe|center|bak|testSpeDay|ddayRe|testDisDay|sdateRe|testSpeDate|re|selection|initShowAndHide|typeof||isShowClear|FF|default|isShowToday|max|realTimeFmt|01|02|469|ms|13578|startDate|object|13579|02468|quickSel|oldv|tm|yminputfocus|hidden|Number|initQS|showDiv|Event|readonly|tE|isNaN|join|block|ry|setDate|round|86400000|IE|moveStart|nodeName|_ieEmuEventHandler|on|rM|oncleared|HD|body|onpicked|mD|undefined|target|_focus|window|srcElement|initBtn|getElementsByTagName|px|coverDate|attachTabEvent|sD|createTextRange|offsetWidth|returnValue|Wtoday|MMenu|_fM|NavImgll|NavImgl|01345789|dpOkInput|Wselday|createElement|dpTitle|Wweek|WspecialDay|ready|HTMLElement|__defineGetter__|__defineSetter__|WinvalidDay|parentNode|WotherDayOn|addEventListener|WwdayOn|Wwday|Wday|WdayOn|WotherDay|getBoundingClientRect|offsetLeft|clearStr|todayStr|timeStr|dpTimeDown|dpTimeUp|onchange|tB|alert|okStr|moveEnd|dpClearInput|dpControl|disabledDates|collapse|dpTodayInput|err_1|dpQS|specialDays|disabledDays|specialDates|change|position|NavImgr|absolute|dpTime|overflow|YMenu|1235679|048|alwaysUseStartDate|NavImgrr|ssMenu|substr|rowspan|dpTimeStr|1900|hhMenu|Function|vel|mmMenu|createRange|105|autoShowQS|enableKeyboard|WdateDiv2|WdayTable2|parent|onfocus|min|scrollHeight|iframe|contentWindow|click|confirm|errAlertMsg|qsEnabled|fromCharCode|String|aLongWeekStr|getNewP|enableInputMask|ydHmswW|1000|Hms|createEvent|00|HTMLEvents|initEvent|ceil|changing|onpicking|yHms|changed|parseInt|yMd|ISO8601|textarea|srcEl|try|onclearing|stopPropagation|catch|dispatchEvent|weekMethod|Array|setTimeout|197|Time|tegrat|_fH|eulb|roloc|u2192|_fm|79yM|knalb_|pointer|_fs|cursor|ptth|quickStr|u2190|reverse|ferh|rekciPetaD|79ym||elyts|ten|www'.split('|'), 0, {})) \ No newline at end of file diff --git a/public/plugin/datepicker/lang/zh-cn.js b/public/plugin/datepicker/lang/zh-cn.js deleted file mode 100644 index 13bfdef..0000000 --- a/public/plugin/datepicker/lang/zh-cn.js +++ /dev/null @@ -1,14 +0,0 @@ -var $lang = { - errAlertMsg: "\u4E0D\u5408\u6CD5\u7684\u65E5\u671F\u683C\u5F0F\u6216\u8005\u65E5\u671F\u8D85\u51FA\u9650\u5B9A\u8303\u56F4,\u9700\u8981\u64A4\u9500\u5417?", - aWeekStr: ["\u5468", "\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"], - aLongWeekStr: ["\u5468", "\u661F\u671F\u65E5", "\u661F\u671F\u4E00", "\u661F\u671F\u4E8C", "\u661F\u671F\u4E09", "\u661F\u671F\u56DB", "\u661F\u671F\u4E94", "\u661F\u671F\u516D"], - aMonStr: ["\u4E00\u6708", "\u4E8C\u6708", "\u4E09\u6708", "\u56DB\u6708", "\u4E94\u6708", "\u516D\u6708", "\u4E03\u6708", "\u516B\u6708", "\u4E5D\u6708", "\u5341\u6708", "\u5341\u4E00", "\u5341\u4E8C"], - aLongMonStr: ["\u4E00\u6708", "\u4E8C\u6708", "\u4E09\u6708", "\u56DB\u6708", "\u4E94\u6708", "\u516D\u6708", "\u4E03\u6708", "\u516B\u6708", "\u4E5D\u6708", "\u5341\u6708", "\u5341\u4E00\u6708", "\u5341\u4E8C\u6708"], - clearStr: "\u6E05\u7A7A", - todayStr: "\u4ECA\u5929", - okStr: "\u786E\u5B9A", - updateStr: "\u786E\u5B9A", - timeStr: "\u65F6\u95F4", - quickStr: "\u5FEB\u901F\u9009\u62E9", - err_1: '\u6700\u5C0F\u65E5\u671F\u4E0D\u80FD\u5927\u4E8E\u6700\u5927\u65E5\u671F!' -} \ No newline at end of file diff --git a/public/plugin/datepicker/skin/WdatePicker.css b/public/plugin/datepicker/skin/WdatePicker.css deleted file mode 100644 index e9e5a54..0000000 --- a/public/plugin/datepicker/skin/WdatePicker.css +++ /dev/null @@ -1,9 +0,0 @@ -.Wdate { - border: #999 1px solid; - height: 20px; - background: #fff url(datePicker.gif) no-repeat right; -} -.WdateFmtErr { - font-weight: bold; - color: red; -} \ No newline at end of file diff --git a/public/plugin/datepicker/skin/datePicker.gif b/public/plugin/datepicker/skin/datePicker.gif deleted file mode 100644 index d6bf40c9f290161c87230787a1056d977d36c821..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1043 zcmd_p?QatW0LSs$R_K_-G(2dKnG6Nuloy5QzR9KEUo-T(>!P_I?XFKgvWtyr!WO4UlCn14~uDIk;oTK<^AT9>DEW?Q;pCx%I$O#N5 zF>!(7;)FBL?Y2>G#rVB@JJbtu9J~xNLUPnSUmhJPocq3fC#2n zf`T_#pxG40CJ;6a(?x<#)R9FWBOz>(W+;^9Jhbd%GBC47(G=xRz)Xgu8JJFcnCB3k z@%ssgmJo`6N-16{1yh`x7M3Z+cUmh9yt+9ezELo|GlGq&y6dm!P^77 zPxRDwnT=eC+BI(eaA zI@!?n@xITu?I(aA-qe2m>HYp*Ct=)U(OjDOa0{Y6er~AynCY7C-e-;9YJLGubiCfY z-F!#~Ha30Gckz2A(6j&ITSo^hZ7n9PzT@zN^LON3>zCUv7|#s8^X2uC{2FFF`}1xc GaQqdg9U6)N diff --git a/public/plugin/datepicker/skin/default/datepicker.css b/public/plugin/datepicker/skin/default/datepicker.css deleted file mode 100644 index 2ee8b44..0000000 --- a/public/plugin/datepicker/skin/default/datepicker.css +++ /dev/null @@ -1,211 +0,0 @@ -/* - * My97 DatePicker 4.7 - */ - -.WdateDiv { - width: 180px; - background-color: #FFFFFF; - border: #bbb 1px solid; - padding: 2px; -} -.WdateDiv2 { - width: 360px; -} -.WdateDiv * { font-size: 9pt; } -.WdateDiv .NavImg a { - display: block; - cursor: pointer; - height: 16px; - width: 16px; -} -.WdateDiv .NavImgll a { - float: left; - background: transparent url(img.gif) no-repeat scroll 0 0; -} -.WdateDiv .NavImgl a { - float: left; - background: transparent url(img.gif) no-repeat scroll -16px 0; -} -.WdateDiv .NavImgr a { - float: right; - background: transparent url(img.gif) no-repeat scroll -32px 0; -} -.WdateDiv .NavImgrr a { - float: right; - background: transparent url(img.gif) no-repeat scroll -48px 0; -} -.WdateDiv #dpTitle { - height: 24px; - margin-bottom: 2px; - padding: 1px; -} -.WdateDiv .yminput { - margin-top: 2px; - text-align: center; - height: 20px; - border: 0px; - width: 50px; - cursor: pointer; -} -.WdateDiv .yminputfocus { - margin-top: 2px; - text-align: center; - font-weight: bold; - height: 20px; - color: blue; - border: #ccc 1px solid; - width: 50px; -} -.WdateDiv .menuSel { - z-index: 1; - position: absolute; - background-color: #FFFFFF; - border: #ccc 1px solid; - display: none; -} -.WdateDiv .menu { - cursor: pointer; - background-color: #fff; -} -.WdateDiv .menuOn { - cursor: pointer; - background-color: #BEEBEE; -} -.WdateDiv .invalidMenu { - color: #aaa; -} -.WdateDiv .YMenu { - margin-top: 20px; -} -.WdateDiv .MMenu { - margin-top: 20px; - *width: 62px; -} -.WdateDiv .hhMenu { - margin-top: -90px; - margin-left: 26px; -} -.WdateDiv .mmMenu { - margin-top: -46px; - margin-left: 26px; -} -.WdateDiv .ssMenu { - margin-top: -24px; - margin-left: 26px; -} -.WdateDiv .Wweek { - text-align: center; - background: #DAF3F5; - border-right: #BDEBEE 1px solid; -} -.WdateDiv .MTitle { - background-color: #BDEBEE; -} -.WdateDiv .WdayTable2 { - border-collapse: collapse; - border: #c5d9e8 1px solid; -} -.WdateDiv .WdayTable2 table { - border: 0; -} -.WdateDiv .WdayTable { - line-height: 20px; - border: #c5d9e8 1px solid; -} -.WdateDiv .WdayTable td { - text-align: center; -} -.WdateDiv .Wday { - cursor: pointer; -} -.WdateDiv .WdayOn { - cursor: pointer; - background-color: #C0EBEF; -} -.WdateDiv .Wwday { - cursor: pointer; - color: #FF2F2F; -} -.WdateDiv .WwdayOn { - cursor: pointer; - color: #000; - background-color: #C0EBEF; -} -.WdateDiv .Wtoday { - cursor: pointer; - color: blue; -} -.WdateDiv .Wselday { - background-color: #A9E4E9; -} -.WdateDiv .WspecialDay { - background-color: #66F4DF; -} -.WdateDiv .WotherDay { - cursor: pointer; - color: #6A6AFF; -} -.WdateDiv .WotherDayOn { - cursor: pointer; - background-color: #C0EBEF; -} -.WdateDiv .WinvalidDay { - color: #aaa; -} -.WdateDiv #dpTime { - float: left; - margin-top: 3px; - margin-right: 30px; -} -.WdateDiv #dpTime #dpTimeStr { - margin-left: 1px; -} -.WdateDiv #dpTime input { - width: 18px; - height: 20px; - text-align: center; - border: #ccc 1px solid; -} -.WdateDiv #dpTime .tB { - border-right: 0px; -} -.WdateDiv #dpTime .tE { - border-left: 0; - border-right: 0; -} -.WdateDiv #dpTime .tm { - width: 7px; - border-left: 0; - border-right: 0; -} -.WdateDiv #dpTime #dpTimeUp { - height: 10px; - width: 13px; - border: 0px; - background: url(img.gif) no-repeat -32px -16px; -} -.WdateDiv #dpTime #dpTimeDown { - height: 10px; - width: 13px; - border: 0px; - background: url(img.gif) no-repeat -48px -16px; -} -.WdateDiv #dpQS { - float: left; - margin-right: 3px; - margin-top: 3px; - background: url(img.gif) no-repeat 0px -16px; - width: 20px; - height: 20px; - cursor: pointer; -} -.WdateDiv #dpControl { - text-align: right; -} -.WdateDiv .dpButton { - height: 20px; - width: 45px; - border: #ccc 1px solid; - margin-top: 2px; - margin-right: 1px; -} \ No newline at end of file diff --git a/public/plugin/datepicker/skin/default/img.gif b/public/plugin/datepicker/skin/default/img.gif deleted file mode 100644 index 053205d8201a3a59fb9870c6a4743fc3efd305fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1578 zcmeH`+f$MW0L8yg4A8uwQi_*?EFI0Au-(}$Yf8m?W;EG$nKo@ja+NL1Tea4jcp*!p z#xz<>P`7c+`wa^*R6tZzP(V!)H8t;$A?U37?Y7VRC+vARFX!bq=gjdB^gDF;iYKra z&;wtkQmNQ%c1R(COeQ~NGC!@X-L1IYFxXP4D45X9#Y#vG{O;&z3Z#Z4<8oSFA+x?V za{Tnn%#2>IZ&|L*t7Y8jifd|ntJ0009XO#-C~j&(iloKy>DgkjSTe29LF*P4Rz)>s zlR9lubIjD_(#1+*k9=rmZLzSbQZ@E*V{5&c-;ph)iRPts9Bz{4%o&bnk3?Qo|85>y zMIwzWCRiN`>GJZjNYwRAl_gh=>pw%8Y^n}|dKO1%w5(5CQ?kLa&MyMBe*G!`@#xgd zJhad%8%mfwUD?7RB_zwV-9n+TxcJZfD#rb>n2O#SVXyRsGKWe{k5&JiHju`7&x;;8 zX=mqRn${|1)AHbwV-H`x zWY%!VBNy&>$JYxurQC8-S!nN6-*1bd6|*Ju(cDTdpE7Z_rH{*QdZ*AU9yjDPi^cyi z|GV@5_8$%4)(t@fzyjR9W?w%6AR&NYWFJt?Y^5TtTrY{LS?!r9$Do3Mnj+tHLpYh# zWD(Jxy+9w6;6n2p`)^?{Gzp6(j7}kA52j9FckK z_pNGC_oRe{N_n`k2GUqo4!bS;JdZ}SXJWpEJ0%`;tcmOnfo~ZVB$@0wis7A)&MkWM zi*YID8j|kVk!5t)N%RVZt>u|lIMbyk;q*oOM#8Ggz|}RD(+*3UbrN{e+QSKMPF@3v zDP#4WQG>fSsFZ~d&gGDXaJhrW5q?=5zR9HK2Kv92L|Fi_6X_w) z3=Pz_Az@HIUwBEX>aLiJ}kGM#j_wVX#(Snb-z}VN@=1p54MEab$wzRB5iw+%tE;Dk0?L@ zv$zET51d@btHYeFN*gCB%_}aFXzq$FKxLJL`=i}s=>mrw;z5yPuqV?SbTmW(rq3r4 zj0k$d_6uYKheSrC(y}WR_1tYwhRL&8&;ZHAYXr91JTJH@D4IrLBe73-MzA#r((I7< zMjF_^iT80P&5jUlujaOj>=0Od2RaT}lmYt2HyiBPT|JH`94~m1k0}_Z^U?mLEWb97 zS diff --git a/public/plugin/datepicker/skin/ext/datepicker.css b/public/plugin/datepicker/skin/ext/datepicker.css deleted file mode 100644 index 9d9a7a1..0000000 --- a/public/plugin/datepicker/skin/ext/datepicker.css +++ /dev/null @@ -1,304 +0,0 @@ -/* - * My97 DatePicker 4.7 - * Ƥ�����:ext - * Ƥ������:CssRain - * ����blog:http://www.CssRain.cn - * ��������:cssrain@gmail.com - */ - -/* ����ѡ������ DIV */ -.WdateDiv { - width: 180px; - background-color: #fff; - border: 1px solid #718BB7; -} -/* ˫������Ŀ�� */ -.WdateDiv2 { - width: 360px; -} -.WdateDiv * { font-size: 9pt; } -/**************************** - * ����ͼ�� ȫ����A��ǩ - ***************************/ -.WdateDiv .NavImg a { - margin-top: 3px; - cursor: pointer; - display: block; - width: 15px; - height: 15px; -} -.WdateDiv .NavImgll a { - background: url(left-btn2.gif) no-repeat center center; - float: left; - margin-left: 2px; -} -.WdateDiv .NavImgl a { - background: url(left-btn.gif) no-repeat center center; - float: left; - margin-left: 2px; -} -.WdateDiv .NavImgr a { - background: url(right-btn.gif) no-repeat center center; - float: right; - margin-right: 2px; -} -.WdateDiv .NavImgrr a { - background: url(right-btn2.gif) no-repeat center center; - float: right; - margin-right: 2px; -} -/**************************** - * ����·���� - ***************************/ -/* ����·��� DIV */ -.WdateDiv #dpTitle { - height: 22px; - background: transparent url(hd-sprite.gif) repeat-x scroll 0 -83px; - color: #FFFFFF; - font-family: "sans serif", tahoma, verdana, helvetica; - font-size: 12px; - font-size-adjust: none; - font-stretch: normal; - font-style: normal; - font-variant: normal; - font-weight: bold; - padding-top: 2px; -} -/* ����·������ INPUT */ -.WdateDiv .yminput { - margin-top: 2px; - text-align: center; - border: 0px; - height: 20px; - width: 50px; - color: #FFF; - background-color: transparent; - cursor: pointer; -} -/* ����·�������ý���ʱ����ʽ INPUT */ -.WdateDiv .yminputfocus { - margin-top: 2px; - text-align: center; - border: #939393 1px solid; - font-weight: bold; - color: #034c50; - height: 16px; - width: 50px; -} -/* �˵�ѡ��� DIV */ -.WdateDiv .menuSel { - z-index: 1; - position: absolute; - background-color: #FFFFFF; - border: 1px solid #718BB7; - display: none; -} -/* �˵�����ʽ TD */ -.WdateDiv .menu { - cursor: pointer; - background-color: #fff; - color: #11777C; -} -/* �˵���mouseover��ʽ TD */ -.WdateDiv .menuOn { - cursor: pointer; - background-color: #B3CEEF; -} -/* �˵���Чʱ����ʽ TD */ -.WdateDiv .invalidMenu { - color: #aaa; -} -/* ��ѡ����ƫ�� DIV */ -.WdateDiv .YMenu { - margin-top: 16px; -} -/* ��ѡ����ƫ�� DIV */ -.WdateDiv .MMenu { - margin-top: 16px; - *width: 62px; -} -/* ʱѡ����λ�� DIV */ -.WdateDiv .hhMenu { - margin-top: -90px; - margin-left: 26px; -} -/* ��ѡ����λ�� DIV */ -.WdateDiv .mmMenu { - margin-top: -46px; - margin-left: 26px; -} -/* ��ѡ����λ�� DIV */ -.WdateDiv .ssMenu { - margin-top: -24px; - margin-left: 26px; -} -/**************************** - * ����� - ***************************/ -.WdateDiv .Wweek { - text-align: center; - background: #DAF3F5; - border-right: #BDEBEE 1px solid; -} -/**************************** - * ����,������� - ***************************/ -/* ������ TR */ -.WdateDiv .MTitle { - color: #233D6D; - background: #DFECFB url(glass-bg.gif) repeat-x scroll left top; - color: #233D6D; - cursor: default; - font-size: 10px; - padding-top: 2px; -} -.WdateDiv .MTitle td { - border-bottom: 1px solid #A3BAD9; -} -.WdateDiv .WdayTable2 { - border-collapse: collapse; - border: black 1px solid; -} -.WdateDiv .WdayTable2 table { - border: 0; -} -/* ��������� TABLE */ -.WdateDiv .WdayTable { - line-height: 20px; - color: black; -} -.WdateDiv .WdayTable td { - text-align: center; -} -/* ���ڸ����ʽ TD */ -.WdateDiv .Wday { - cursor: pointer; -} -/* ���ڸ��mouseover��ʽ TD */ -.WdateDiv .WdayOn { - cursor: pointer; - background-color: #B3CEEF; -} -/* ��ĩ���ڸ����ʽ TD */ -.WdateDiv .Wwday { - cursor: pointer; - color: #ab1e1e; -} -/* ��ĩ���ڸ��mouseover��ʽ TD */ -.WdateDiv .WwdayOn { - cursor: pointer; - background-color: #B3CEEF; -} -.WdateDiv .Wtoday { - cursor: pointer; - color: red; -} -.WdateDiv .Wselday { - background-color: #B3CEEF; -} -.WdateDiv .WspecialDay { - background-color: #66F4DF; -} -/* �����·ݵ����� */ -.WdateDiv .WotherDay { - cursor: pointer; - color: #AAAAAA; -} -/* �����·ݵ�����mouseover��ʽ */ -.WdateDiv .WotherDayOn { - cursor: pointer; - background-color: #B3CEEF; -} -/* ��Ч���ڵ���ʽ,�������ڷ�Χ�������ڸ����ʽ,����ѡ������� */ -.WdateDiv .WinvalidDay { - color: #aaa; -} -/**************************** - * ʱ����� - ***************************/ -/* ʱ���� DIV */ -.WdateDiv #dpTime { - width: 120px; - text-align: left; - margin-left: 32px; - height: 20px; - line-height: 20px; - padding-top: 1px; -} -/* ʱ������ SPAN */ -.WdateDiv #dpTime #dpTimeStr { - margin-left: 1px; - color: #233D6D; -} -/* ʱ������� INPUT */ -.WdateDiv #dpTime input { - height: 16px; - width: 18px; - text-align: center; - color: #333; - border: #A3BAD9 1px solid; -} -/* ʱ�� ʱ INPUT */ -.WdateDiv #dpTime .tB { - border-right: 0px; -} -/* ʱ�� �ֺͼ���� ':' INPUT */ -.WdateDiv #dpTime .tE { - border-left: 0; - border-right: 0; -} -/* ʱ�� �� INPUT */ -.WdateDiv #dpTime .tm { - width: 7px; - border-left: 0; - border-right: 0; -} -/* ʱ���ұߵ����ϰ�ť BUTTON */ -.WdateDiv #dpTime #dpTimeUp { - height: 8px; - width: 13px; - border: 0px; - background: url(img.gif) no-repeat -32px -16px; - cursor: pointer; - margin-bottom: 0; - padding-bottom: 0; -} -/* ʱ���ұߵ����°�ť BUTTON */ -.WdateDiv #dpTime #dpTimeDown { - height: 8px; - width: 13px; - border: 0px; - background: url(img.gif) no-repeat -48px -16px; - cursor: pointer; - margin-top: 0; - padding-top: 0; -} -/**************************** - * ���� - ***************************/ -.WdateDiv #dpQS { - float: left; - margin-left: 3px; - margin-top: 9px; - background: url(dateselect.gif) no-repeat; - width: 20px; - height: 20px; - cursor: pointer; -} -.WdateDiv #dpControl { - text-align: right; - margin-top: 3px; - background: #DFECFB url(glass-bg.gif) repeat-x scroll left top; - border-top: 1px solid #A3BAD9; - padding: 4px; -} -.WdateDiv .dpButton { - width: 44px; - height: 22px; - background: #083772 none repeat scroll 0 0; - border-color: #3366CC #000055 #000055 #3366CC; - border-style: solid; - border-width: 1px; - color: white; - cursor: pointer; -} \ No newline at end of file diff --git a/public/plugin/datepicker/skin/ext/dateselect.gif b/public/plugin/datepicker/skin/ext/dateselect.gif deleted file mode 100644 index 9e3996fe47d1ba180207800cdca1c096ad68013f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 zcmZ?wbhEHb6k!ly*vtR||NsAAcjR69r0wf3JlSyJ$;Jy$PThXC?!x1B7azAUFx$)}_ zxqe~ax=&gbo=Gz<>@3^IV9+R`G_T`ePnxvD`ipnpRUCHewaL9MJ=bq-%7=U?9r>3)q+w@6G_xop)#NygPUI-MM=} z^!_{$-T!dm{)dbAKU@Mb9(=g)@WaK2A1*!oaQVT<%a1-@ehfsPt~~sB_0h*Gk3U^| z^yxZ~`{dJA5c+)e>E~-e^z6&^=U;C;`E>K?=UY!d-+uP_&hsxfUVOdx;_KT_KNv>A zXb8|f1QdU=0PXzGpaZfQlqVQC+!&%a1WaT)$|)>om2)9Mk%@&tK#^^Rgu{V`ZWgW# wlLCgu<17lIIuQpJG%~aEtN6@tSlD!$TihV!!H0*;9Rf;j6Erp|DKJJSK2bm`zya0vPFVPO+Hzo=EoiUW<# zt-R7&85aT+o!hu13_^AkENo)sW?~Im5RiDNg-b{!q(fjK6AOo^oXv^{2OL}3c(n`? z0um24adC-+cuZKp#Ka=XC$l2qfI}-2tCoO5K;nT0E+&=`4uJ(sK-Uz9X;c_IJk-Xo z?6;=E@bR%edFMWzN~5Qzrs*f2TT>bQ{@gtKWw+(i!R!IjKB)<%j$y1Z!Zof6-y9;DGq~5NJ}7gDVJu-S5NBXy HWUvMRItY+| diff --git a/public/plugin/datepicker/skin/ext/img.gif b/public/plugin/datepicker/skin/ext/img.gif deleted file mode 100644 index d45b8e261c1862033a501e9c199829db7aea1210..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1604 zcmb`G>sQiu0EfR^R4_8Ur88TZ<}9tW+|u+If_62BS*<*7Q90Ymc8;2v?YJGhRIbd( z$}ZDFE3@T=RKfz3>kmapR6t5VMIiN{{5A=4%h>im?DOh*^}Kn`XXox6F|o%8AOtu} zU`uwk)9G~BKgG3i?EjM839_?w`tgsS7Oaj1yK`Y~Zq96;BC~oO4u{rgHqF9Sih<;& z)?;kp)(&QL3p0wzlF4L$I$()xP-k29+2!iAa6Y_5_&zD(#d7_@CK}Z4e0c3 zy-a|?nm<^s)YWB=9?57Wzx!m&mdKOaxJJWl_W-w~zrbv?Ze&SXChAQ#ox-GkZ5%kj z5nmZn>&BK?rQ_-FVEx-$4BbqwB1>uO@0%BY*C_v^rJr^fNX?tk);?KysDl94F^muR<_qCAP4-=h}y+|M=!5 zan-Bt^8?y@vXQfW@}HzrY+3LiKD|Qk0-{MVrHQ|vBzRn+lCuhm}KBt;aXR4>J4py*5e7Vh<@+hHFCOd0Ln{mGHU~^lC zCr@%E@jZP=7ayAT=9pdEt5n{4J6!}P-fp`)XK^sz%*53~QlhGiZ zH8;veYTEDqA`-g0dlg7Wa;?XeHfL35S)N4xK(5LVO8!mu|1M|&jR3#|BL36<_X&V; zf_`k^E(V=nhVfpX*~_RGUcv|OsonLwA^8Gu&CcrbJRz)F85MxXP>e(naGv=pK9>-osuFQyTg6?m6Qj=0K zJk4*)e%)M9lL0LMz`WQ73C3#_6eg>B9Y#qK4GZ@ zDi3+FdK=|oB(>Ca^9k)?O+1ablvIIU9BfR&Vpbh$#zioSB5(MH-+7!^x^^dZ)FXdO zZRmRc2y!7*m%lt1D#xP2mHy?w4mBS$(01=0qVov|1e&t7)?SXGG+8`+9iBC`HXPsvfgpNpIh`r1nGoQ zQQ;{zcfDDcMa4V9Ke7vGktG$JMl7j_4E{>~cFnyp4^soRRv_~b1|Yq-rJg%$OQf!=LIQcng}Ht*64A^npT!3JGc9k6DVI$)ZE;v4R!wQfGP`FIG3yQVx2WH}1 zrtXEiUu|wFCOD8m9nI;OEgbcr1TlDHOJZo>j-L06)=XR)YwR)<`6Va}v`tk!1Jq3-Bme*a diff --git a/public/plugin/datepicker/skin/ext/left-btn.gif b/public/plugin/datepicker/skin/ext/left-btn.gif deleted file mode 100644 index a0ddd9ee8203b9fc45eb5ee78ae6bcb7e57aed7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 870 zcmZ?wbhEHbSKV^zd-BO3vC604f{{R1d4Yk$n}L-sZYVSj)zmI o(Q}fL|Dq=uMNdw3X~iE>$=vYlK$lteqcf2P3=A_Zn3))?0bn93t^fc4 diff --git a/public/plugin/datepicker/skin/ext/left-btn2.gif b/public/plugin/datepicker/skin/ext/left-btn2.gif deleted file mode 100644 index 4f3706d1e1052f6f797d94b72c8d3813e00d78cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmZ?wbhEHbSKV^zd-BO3vC604f{{R1d4Yk$hk=zr!efJiBO@aVPsE804;fk*WxQe}6c#pgOBlzkIk8cxsZYUC>4${T q6OT!%mh)U@eo8sjryPH%CUe8H16^j>kIqCIFfh!NVPs)pum%9ETq}wI diff --git a/public/plugin/datepicker/skin/ext/right-btn2.gif b/public/plugin/datepicker/skin/ext/right-btn2.gif deleted file mode 100644 index 2da998cfaf3461c6d138d94b9764e8614e137c65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmZ?wbhEHb', - frame = [ - '

' + ico + '' + dialog.msg + '
', - '
' + html + '
', - '', - '', - '
' + config.tips.msg + '
' - ], - shade = '', border = '', zIndex = config.zIndex + times, - shadeStyle = 'z-index:' + zIndex + '; background-color:' + config.shade[1] + '; opacity:' + config.shade[0] + '; filter:alpha(opacity=' + config.shade[0] * 100 + ');'; - config.shade[2] && (shade = '
'); - config.zIndex = zIndex; - var title = '', closebtn = '', borderStyle = "z-index:" + (zIndex - 1) + "; background-color: " + config.border[2] + "; opacity:" + config.border[1] + "; filter:alpha(opacity=" + config.border[1] * 100 + "); top:-" + config.border[0] + "px; left:-" + config.border[0] + "px;"; - config.border[3] && (border = '
'); - config.closeBtn[1] && (closebtn = ''); - config.title[1] && (title = '

' + config.title[0] + '

') - var boxhtml = '
' - + '
' - + frame[config.type] - + title - + closebtn - + '' - + '
' + border + '
'; - return [shade, boxhtml]; - }; -//缓存字符 - Class.pt.dom = { - lay: 'xubox_layer', - ifr: 'xubox_iframe' - }; -//创建骨架 - Class.pt.creat = function () { - var that = this, space = '', config = this.config, dialog = config.dialog, title = that.config.title, dom = that.dom, times = that.index; - ; - title.constructor === Array || (that.config.title = [title, true]); - title === false && (that.config.title = [title, false]); - var page = config.page, body = $("body"), setSpace = function (html) { - var html = html || '' - space = that.space(html); - body.append(space[0]); - }; - switch (config.type) { - case 1: - if (page.html !== '') { - setSpace('
' + page.html + '
'); - body.append(space[1]); - } else if (page.url !== '') { - setSpace('
' + page.html + '
'); - body.append(space[1]); - $.get(page.url, function (datas) { - $('#xuboxPageHtml' + times).html(datas.toString()); - page.ok && page.ok(datas); - }); - } else { - if ($(page.dom).parents('.xubox_page').length == 0) { - setSpace(); - $(page.dom).show().wrap(space[1]); - } else { - return; - } - } - break; - case 2: - setSpace(); - body.append(space[1]); - break; - case 3: - config.title = ['', false]; - config.area = ['auto', 'auto']; - config.closeBtn = ['', false]; - $('.xubox_loading')[0] && layer.close($('.xubox_loading').parents('.' + dom.lay).attr('times')); - setSpace(); - body.append(space[1]); - break; - case 4: - config.title = ['', false]; - config.area = ['auto', 'auto']; - config.fix = false; - config.border = false; - $('.xubox_tips')[0] && layer.close($('.xubox_tips').parents('.' + dom.lay).attr('times')); - setSpace(); - body.append(space[1]); - $('#' + dom.lay + times).find('.xubox_close').css({top: 6, right: 7}); - break; - default: - config.title[1] || (config.area = ['auto', 'auto']); - $('.xubox_dialog')[0] && layer.close($('.xubox_dialog').parents('.' + dom.lay).attr('times')); - setSpace(); - body.append(space[1]); - break; - } - ; - this.layerS = $('#xubox_shade' + times); - this.layerB = $('#xubox_border' + times); - this.layerE = $('#' + dom.lay + times); - var layerE = this.layerE; - this.layerMian = layerE.find('.xubox_main'); - this.layerTitle = layerE.find('.xubox_title'); - this.layerText = layerE.find('.xubox_text'); - this.layerPage = layerE.find('.xubox_page'); - this.layerBtn = layerE.find('.xubox_botton'); - //设置layer面积坐标等数据 - if (config.offset[1].indexOf("px") != -1) { - var _left = parseInt(config.offset[1]); - } else { - if (config.offset[1] == '50%') { - var _left = config.offset[1]; - } else { - var _left = parseInt(config.offset[1]) / 100 * win.width(); - } - } - ; - layerE.css({left: _left + config.border[0], width: config.area[0], height: config.area[1]}); - config.fix ? layerE.css({top: parseInt(config.offset[0]) + config.border[0]}) : layerE.css({top: parseInt(config.offset[0]) + win.scrollTop() + config.border[0], position: 'absolute'}); - //配置按钮 - if (config.title[1] && (config.type !== 3 || config.type !== 4)) { - var confbtn = config.type === 0 ? dialog : config; - confbtn.btn = config.btn || dialog.btn; - switch (confbtn.btns) { - case 0: - that.layerBtn.html('').hide(); - break; - case 1: - that.layerBtn.html('' + confbtn.btn[0] + ''); - break; - case 2: - that.layerBtn.html('' + confbtn.btn[0] + '' + '' + confbtn.btn[1] + ''); - break; - } - } - if (layerE.css('left') === 'auto') { - layerE.hide(); - setTimeout(function () { - layerE.show(); - that.set(times); - }, 500); - } else { - that.set(times); - } - config.time <= 0 || that.autoclose(); - this.callback(); - }; -//初始化骨架 - Class.pt.set = function (times) { - var that = this, layerE = that.layerE, config = that.config, dialog = config.dialog, page = config.page, loading = config.loading, dom = that.dom; - that.autoArea(times); - if (config.title[1]) { - layer.ie6 && that.layerTitle.css({width: layerE.outerWidth()}); - } else { - config.type != 4 && layerE.find('.xubox_close').addClass('xubox_close1'); - } - ; - layerE.attr({'type': that.type[config.type]}); - switch (config.type) { - case 1: - layerE.find(page.dom).addClass('layer_pageContent'); - config.shade[2] && layerE.css({zIndex: config.zIndex + 1}); - config.title[1] && that.layerPage.css({top: that.layerTitle.outerHeight()}); - break; - case 2: - var iframe = layerE.find('.' + dom.ifr), heg = layerE.height(); - iframe.addClass('xubox_load').css({width: layerE.width()}); - config.title[1] ? iframe.css({top: that.layerTitle.height(), height: heg - that.layerTitle.height()}) : iframe.css({top: 0, height: heg}); - layer.ie6 && iframe.attr('src', config.iframe.src); - break; - case 3: - break; - case 4 : - var layArea = [0, layerE.outerHeight()], fow = $(config.tips.follow), fowo = { - width: fow.outerWidth(), - height: fow.outerHeight(), - top: fow.offset().top, - left: fow.offset().left - }, tipsG = layerE.find('.layerTipsG'); - config.tips.isGuide || tipsG.remove(); - layerE.outerWidth() > config.maxWidth && layerE.width(config.maxWidth); - fowo.tipColor = config.tips.style[1]; - layArea[0] = layerE.outerWidth(); - //辨别tips的方位 - fowo.where = [function () { //上 - fowo.tipLeft = fowo.left; - fowo.tipTop = fowo.top - layArea[1] - 10; - tipsG.removeClass('layerTipsB').addClass('layerTipsT').css({'border-right-color': fowo.tipColor}); - }, function () { //右 - fowo.tipLeft = fowo.left + fowo.width + 10; - fowo.tipTop = fowo.top; - tipsG.removeClass('layerTipsL').addClass('layerTipsR').css({'border-bottom-color': fowo.tipColor}); - }, function () { //下 - fowo.tipLeft = fowo.left; - fowo.tipTop = fowo.top + fowo.height + 10; - tipsG.removeClass('layerTipsT').addClass('layerTipsB').css({'border-right-color': fowo.tipColor}); - }, function () { //左 - fowo.tipLeft = fowo.left - layArea[0] + 10; - fowo.tipTop = fowo.top; - tipsG.removeClass('layerTipsR').addClass('layerTipsL').css({'border-bottom-color': fowo.tipColor}); - }]; - fowo.where[config.tips.guide](); - /* 8*2为小三角形占据的空间 */ - if (config.tips.guide === 0) { - fowo.top - (win.scrollTop() + layArea[1] + 8 * 2) < 0 && fowo.where[2](); - } else if (config.tips.guide === 1) { - win.width() - (fowo.left + fowo.width + layArea[0] + 8 * 2) > 0 || fowo.where[3]() - } else if (config.tips.guide === 2) { - (fowo.top - win.scrollTop() + fowo.height + layArea[1] + 8 * 2) - win.height() > 0 && fowo.where[0](); - } else if (config.tips.guide === 3) { - layArea[0] + 8 * 2 - fowo.left > 0 && fowo.where[1]() - } - layerE.css({left: fowo.tipLeft, top: fowo.tipTop}); - break; - default: - that.layerMian.css({'background-color': '#fff'}); - if (config.title[1]) { - that.layerText.css({paddingTop: 18 + that.layerTitle.outerHeight()}); - } else { - layerE.find('.xubox_msgico').css({top: 8}); - that.layerText.css({marginTop: 11}); - } - break; - } - ; - config.fadeIn && layerE.css({opacity: 0}).animate({opacity: 1}, config.fadeIn); - that.move(); - }; -//自适应宽高 - Class.pt.autoArea = function (times) { - var that = this, layerE = that.layerE, config = that.config, page = config.page, - layerMian = that.layerMian, layerBtn = that.layerBtn, layerText = that.layerText, - layerPage = that.layerPage, layerB = that.layerB, titHeight, outHeight, btnHeight = 0, - load = $(".xubox_loading"); - if (config.area[0] === 'auto' && layerMian.outerWidth() >= config.maxWidth) { - layerE.css({width: config.maxWidth}); - } - config.title[1] ? titHeight = that.layerTitle.innerHeight() : titHeight = 0; - switch (config.type) { - case 0: - var aBtn = layerBtn.find('a'); - outHeight = layerText.outerHeight() + 20; - if (aBtn.length > 0) { - btnHeight = aBtn.outerHeight() + 20; - } - break; - case 1: - outHeight = $(page.dom).outerHeight(); - config.area[0] === 'auto' && layerE.css({width: layerPage.outerWidth()}); - if (page.html !== '' || page.url !== '') { - outHeight = layerPage.outerHeight(); - } - break; - case 3: - outHeight = load.outerHeight(); - layerMian.css({width: load.width()}); - break; - } - ; - (config.area[1] === 'auto') && layerMian.css({height: titHeight + outHeight + btnHeight}); - layerB.css({width: layerE.outerWidth() + 2 * config.border[0], height: layerE.outerHeight() + 2 * config.border[0]}); - (layer.ie6 && config.area[0] != 'auto') && layerMian.css({width: layerE.outerWidth()}); - (config.offset[1] === '50%' || config.offset[1] == '') && (config.type !== 4) ? layerE.css({marginLeft: -layerE.outerWidth() / 2}) : layerE.css({marginLeft: 0}); - }; -//拖拽层 - Class.pt.move = function () { - var that = this, config = this.config, dom = that.dom, conf = { - setY: 0, - moveLayer: function () { - if (parseInt(conf.layerE.css('margin-left')) == 0) { - var lefts = parseInt(conf.move.css('left')); - } else { - var lefts = parseInt(conf.move.css('left')) + (-parseInt(conf.layerE.css('margin-left'))) - } - if (conf.layerE.css('position') !== 'fixed') { - lefts = lefts - conf.layerE.parent().offset().left; - conf.setY = 0 - } - conf.layerE.css({left: lefts, top: parseInt(conf.move.css('top')) - conf.setY}); - } - }; - config.move[1] && that.layerE.find(config.move[0]).attr('move', 'ok'); - config.move[1] ? that.layerE.find(config.move[0]).css({cursor: 'move'}) : that.layerE.find(config.move[0]).css({cursor: 'auto'}); - $(config.move[0]).on('mousedown', function (M) { - M.preventDefault(); - if ($(this).attr('move') === 'ok') { - conf.ismove = true; - conf.layerE = $(this).parents('.' + dom.lay); - var xx = conf.layerE.offset().left, yy = conf.layerE.offset().top, ww = conf.layerE.width() - 6, hh = conf.layerE.height() - 6; - if (!$('#xubox_moves')[0]) { - $('body').append('
'); - } - conf.move = $('#xubox_moves'); - config.moveType && conf.move.css({opacity: 0}); - conf.moveX = M.pageX - conf.move.position().left; - conf.moveY = M.pageY - conf.move.position().top; - conf.layerE.css('position') !== 'fixed' || (conf.setY = win.scrollTop()); - } - }); - $(document).mousemove(function (M) { - if (conf.ismove) { - var offsetX = M.pageX - conf.moveX, offsetY = M.pageY - conf.moveY; - M.preventDefault(); - //控制元素不被拖出窗口外 - if (!config.moveOut) { - conf.setY = win.scrollTop(); - var setRig = win.width() - conf.move.outerWidth() - config.border[0], setTop = config.border[0] + conf.setY; - offsetX < config.border[0] && (offsetX = config.border[0]); - offsetX > setRig && (offsetX = setRig); - offsetY < setTop && (offsetY = setTop); - offsetY > win.height() - conf.move.outerHeight() - config.border[0] + conf.setY && (offsetY = win.height() - conf.move.outerHeight() - config.border[0] + conf.setY); - } - conf.move.css({left: offsetX, top: offsetY}); - config.moveType && conf.moveLayer(); - offsetX = null; - offsetY = null; - setRig = null; - setTop = null - } - }).mouseup(function () { - try { - if (conf.ismove) { - conf.moveLayer(); - conf.move.remove(); - } - conf.ismove = false; - } catch (e) { - conf.ismove = false; - } - config.moveEnd && config.moveEnd(); - }); - }; -//自动关闭layer - Class.pt.autoclose = function () { - var that = this, time = this.config.time, maxLoad = function () { - time--; - if (time === 0) { - layer.close(that.index); - clearInterval(that.autotime); - } - }; - this.autotime = setInterval(maxLoad, 1000); - }; - ready.config = { - end: {} - }; - Class.pt.callback = function () { - var that = this, layerE = that.layerE, config = that.config, dialog = config.dialog; - that.openLayer(); - that.config.success(layerE); - layer.ie6 && that.IE6(); - layerE.find('.xubox_close').off('click').on('click', function (e) { - e.preventDefault(); - config.close(that.index); - }); - layerE.find('.xubox_yes').off('click').on('click', function (e) { - e.preventDefault(); - config.yes ? config.yes(that.index) : dialog.yes(that.index); - }); - layerE.find('.xubox_no').off('click').on('click', function (e) { - e.preventDefault(); - config.no ? config.no(that.index) : dialog.no(that.index); - }); - this.layerS.off('click').on('click', function (e) { - e.preventDefault(); - that.config.shadeClose && layer.close(that.index); - }); - ready.config.end[that.index] = config.end; - }; - Class.pt.IE6 = function () { - var that = this, layerE = that.layerE, select = $('select'), dom = that.dom; - var _ieTop = layerE.offset().top; - //ie6的固定与相对定位 - if (that.config.fix) { - var ie6Fix = function () { - layerE.css({top: $(document).scrollTop() + _ieTop}); - }; - } else { - var ie6Fix = function () { - layerE.css({top: _ieTop}); - }; - } - ie6Fix(); - win.scroll(ie6Fix); - //隐藏select - $.each(select, function (index, value) { - var sthis = $(this); - if (!sthis.parents('.' + dom.lay)[0]) { - sthis.css('display') == 'none' || sthis.attr({'layer': '1'}).hide(); - } - sthis = null; - }); - //恢复select - that.reselect = function () { - $.each(select, function (index, value) { - var sthis = $(this); - if (!sthis.parents('.' + dom.lay)[0]) { - (sthis.attr('layer') == 1 && $('.' + dom.lay).length < 1) && sthis.removeAttr('layer').show(); - } - sthis = null; - }); - }; - }; -//给layer对象拓展方法 - Class.pt.openLayer = function () { - var that = this, dom = that.dom; - //自适应宽高 - layer.autoArea = function (index) { - return that.autoArea(index); - }; - //获取layer当前索引 - layer.getIndex = function (selector) { - return $(selector).parents('.' + dom.lay).attr('times'); - }; - //获取子iframe的DOM - layer.getChildFrame = function (selector, index) { - index = index || $('.' + dom.ifr).parents('.' + dom.lay).attr('times'); - return $('#' + dom.lay + index).find('.' + dom.ifr).contents().find(selector); - }; - //得到当前iframe层的索引,子iframe时使用 - layer.getFrameIndex = function (name) { - return $(name ? '#' + name : '.' + dom.ifr).parents('.' + dom.lay).attr('times'); - }; - //iframe层自适应宽高 - layer.iframeAuto = function (index) { - index = index || $('.' + dom.ifr).parents('.' + dom.lay).attr('times'); - var heg = this.getChildFrame('body', index).outerHeight(), - lbox = $('#' + dom.lay + index), tit = lbox.find('.xubox_title'), titHt = 0; - !tit || (titHt = tit.height()); - lbox.css({height: heg + titHt}); - var bs = -parseInt($('#xubox_border' + index).css('top')); - $('#xubox_border' + index).css({height: heg + 2 * bs + titHt}); - $('#' + dom.ifr + index).css({height: heg}); - }; - //关闭layer - layer.close = function (index) { - var layerNow = $('#' + dom.lay + index), shadeNow = $('#xubox_moves, #xubox_shade' + index); - if (layerNow.attr('type') == that.type[1]) { - if (layerNow.find('.xuboxPageHtml')[0]) { - layerNow.remove(); - } else { - layerNow.find('.xubox_close,.xubox_botton,.xubox_title,.xubox_border').remove(); - for (var i = 0; i < 3; i++) { - layerNow.find('.layer_pageContent').unwrap().hide(); - } - } - } else { - document.all && layerNow.find('#' + dom.ifr + index).remove(); - layerNow.remove(); - } - shadeNow.remove(); - layer.ie6 && that.reselect(); - typeof ready.config.end[index] === 'function' && ready.config.end[index](); - delete ready.config.end[index]; - }; - //关闭加载层 - layer.loadClose = function () { - var parent = $('.xubox_loading').parents('.' + dom.lay), - index = parent.attr('times'); - layer.close(index); - }; - //出场内置动画 - layer.shift = function (type, rate) { - var config = that.config, iE6 = layer.ie6, layerE = that.layerE, cutWth = 0, ww = win.width(), wh = win.height(); - (config.offset[1] == '50%' || config.offset[1] == '') ? cutWth = layerE.outerWidth() / 2 : cutWth = layerE.outerWidth(); - var anim = { - t: {top: 50 + config.border[0]}, - b: {top: wh - layerE.outerHeight() - config.border[0]}, - cl: cutWth + config.border[0], - ct: -layerE.outerHeight(), - cr: ww - cutWth - config.border[0], - fn: function () { - iE6 && that.IE6(); - } - }; - switch (type) { - case 'left-top': - layerE.css({left: anim.cl, top: anim.ct}).animate(anim.t, rate, anim.fn); - break; - case 'top': - layerE.css({top: anim.ct}).animate(anim.t, rate, anim.fn); - break; - case 'right-top': - layerE.css({left: anim.cr, top: anim.ct}).animate(anim.t, rate, anim.fn); - break; - case 'right-bottom': - layerE.css({left: anim.cr, top: wh}).animate(anim.b, rate, anim.fn); - break; - case 'bottom': - layerE.css({top: wh}).animate(anim.b, rate, anim.fn); - break; - case 'left-bottom': - layerE.css({left: anim.cl, top: wh}).animate(anim.b, rate, anim.fn); - break; - case 'left': - layerE.css({left: -layerE.outerWidth(), marginLeft: 0}).animate({left: anim.t.top}, rate, anim.fn); - break; - } - ; - }; - //初始化拖拽元素 - layer.setMove = function () { - return that.move(); - }; - //给指定层重置属性 - layer.area = function (index, options) { - var nowobect = [$('#' + dom.lay + index), $('#xubox_border' + index)], - type = nowobect[0].attr('type'), main = nowobect[0].find('.xubox_main'), - title = nowobect[0].find('.xubox_title'); - if (type === that.type[1] || type === that.type[2]) { - nowobect[0].css(options); - main.css({height: options.height}); - if (type === that.type[2]) { - var iframe = nowobect[0].find('iframe'); - iframe.css({width: options.width, height: title ? options.height - title.outerHeight() : options.height}); - } - if (nowobect[0].css('margin-left') !== '0px') { - options.hasOwnProperty('top') && nowobect[0].css({top: options.top - (nowobect[1][0] && parseInt(nowobect[1].css('top')))}); - options.hasOwnProperty('left') && nowobect[0].css({left: options.left + nowobect[0].outerWidth() / 2 - (nowobect[1][0] && parseInt(nowobect[1].css('left')))}) - nowobect[0].css({marginLeft: -nowobect[0].outerWidth() / 2}); - } - if (nowobect[1][0]) { - nowobect[1].css({ - width: parseFloat(options.width) - 2 * parseInt(nowobect[1].css('left')), - height: parseFloat(options.height) - 2 * parseInt(nowobect[1].css('top')) - }); - } - } - }; - //关闭所有层 - layer.closeAll = function () { - var layerObj = $('.' + dom.lay); - $.each(layerObj, function () { - var i = $(this).attr('times'); - layer.close(i); - }); - }; - //关闭tips层 - layer.closeTips = function () { - var tips = $('.xubox_tips'); - if (tips[0]) { - layer.close(tips.parents('.xubox_layer').attr('times')); - } - }; - //重置iframe url - layer.iframeSrc = function (index, url) { - $('#' + dom.lay + index).find('iframe').attr('src', url); - }; - //置顶当前窗口 - layer.zIndex = that.config.zIndex; - layer.setTop = function (layerNow) { - var setZindex = function () { - layer.zIndex++; - layerNow.css('z-index', layer.zIndex + 1); - }; - layer.zIndex = parseInt(layerNow[0].style.zIndex); - layerNow.on('mousedown', setZindex); - return layer.zIndex; - }; - }; -//主入口 - ready.run = function () { - $ = jQuery; - win = $(window); - layer.use('skin/layer.css'); - $.layer = function (deliver) { - var o = new Class(deliver); - return o.index; - }; - }; -//为支持CMD规范的模块加载器 - var require = '../../init/jquery'; //若采用seajs,需正确配置jquery的相对路径。未用可无视此处。 - if (window.seajs) { - define([require], function (require, exports, module) { - ready.run(); - exports.layer = [window.layer, window['$'].layer]; - }); - } else { - ready.run(); - } -}(window); \ No newline at end of file diff --git a/public/plugin/layer/skin/default/Thumbs.db b/public/plugin/layer/skin/default/Thumbs.db deleted file mode 100644 index 69b55dcaeb1e719b739dd521ebe5527247a1850e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37376 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 diff --git a/public/plugin/layer/skin/default/xubox_ico0.png b/public/plugin/layer/skin/default/xubox_ico0.png deleted file mode 100644 index eed069ecb86469e81f571dbe752d84e7e5538f1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31945 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 E7yK}JPyhe` diff --git a/public/plugin/layer/skin/default/xubox_loading0.gif b/public/plugin/layer/skin/default/xubox_loading0.gif deleted file mode 100644 index 6f3c9539a22171cc2f12639492e346d97a9078e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5793 zcmbW5cU)6v_rUK>LIz0)&0r|DVJRw*1lb}G2peR}lqQ5=SV;(BqpU!Hu=ge)A|fDV zMnRUdimSG+R*hC$tpn_M)!Noy@U8Xr_u=>c@ykEC&%Mt%=lMS8oadZ--8@{aZCG}I z7BGebe);m?iyNnY9jWG}WkHcomKiq!H0N%y|Z(D%p z&!6kQMelS83UsFXxtN(!p&$SN%3Gm6eq;tq#8Up-Ib;Y}>;#U89L?Di$J?Q|JUypJ zj*Ho$7h>T<^$|F8xN+`TLQY`T&LDPH0^24=&%vH-mtmWcBuL_jSmcbPL|%$*#tuDJ z3_qGbmPg=R{n2;a?F<$EvXb!`@oxrOAC@qIqx7OHD=~%h?tzbwt*>(NaXeNcgU?P);_yTs zj2(JP5!0Bs7+botGlM~Q-9~dUqgq7#Gp{&N*f5hJVTgrf5z5FMWl!JeAk;7BEPN>W@@a$hKj`T51l^7Cg;pZxUr(T_hoeDMAKdy2bvZh!aft(!NlU;F0kt6yEY zeCgtarSs>$JbUK!sgoxb7v|??kIzgWJ1U==oERS){bJ+si%9kF8k6S;vF#VRPfpm*grT3@NznT%W8z&^0I1iq1 zj*rNPMweK>GA`*DO`eBg%K8@tCk?c27+bQEO&Y!{TcDfPVYTzqE~xuK?(#{@;q5>Z z(6*O&vWbUBr=^*b5ZMVnctozJ6vr0Fa!Ih#a2TP|i=bK;tE$nQ(AK`4AWPlf8`gJ_ zc4&a3(KOVGw;7>8JIB;|Btw|$ifL~`?LY(ngd6+}b_tvdCWJJz@PaeJ=fq39OK)AD zet^GQzaD}NN9L2P4?>GcKo>_f!+`{P`T9s1vR|?ip}2 z$a)n$tFoXul~e= zC^aO}=v3E2A(9YXvSti?^8ub|RLLgm__XSM=_GX2;V;VWJg%Mzb)q_wS?QlB1Vz10 zEaZwoiHuk>0!uvOy0Gv}h@Ckh%ITMlLXX@6$>8agNrP&iq3fppMEfDn^00{XD5fqt zN07P4tuS6yk6#iflv-EBSJ&3z8?2h5^uX4Dow$xIU6ECK`{@LDYC%(xZuEXmN-Fly z0bS6c7IqvL>Nc7_t_Nv_kbq-n#J+QaMNQN(=owYvReQSgiHoP)ptpVP(5MHSQTHGD zn$a>>e*4$USENtYa`T;!NPCG$x7Ll0M^WxNo9L4UKEqGkpX`D_*zP)d8cohTKdx=+ z>|K4o!F49`cch34`m-tZ@WT*K^3-p~Qc!XC6Aj6R^8D=OvlU*kB9}NkGbfuVHV7&R zMsBo`@Kmq}Q=p;}53p*Z>KhH4TNqWi_N>lGnQ3`1rY`|IaJa!Czoo2rywm}41e5D| zsB@nKC>JFY+QU1U-42izH!_|JG~xx+405hzOs% z%hYX0mWLKAKtaab9jC7){q~Tt#G1=0)2F^K?#}XKqo3P}>_~mj%(0n;$=C=(FwX^A zm|29N0A&^#70hh^YQx$(OhaQ-vqP&vX-By%s>-PYQ*cPFNMe}U(N)poU{f*#mkHRt z6h@hQQs%t>-dIR(=omQLRD_(4rG?UM?UE5eu^WN=z}@vA3h@|Wta$c(dF6#-O|PE& z2r;CZY_!EVMyi6;zm!tj;=JF=882^C$#?ypM0AIG)!wj4w^SIo){}H@7;CJk+s$F~ z$0HiB<6Hz8k*3x-%$lg#IW>1hL$)NpHj$Wa3w1?Eg#Yu$AbR9K=GVqv6CN#j6$+2 z?7TJHQrPyUkkIUeC>TLlz=k@|pd|@>d~_vSpij%Hj|d6GHMjWo7<6>WFg?8oum{^Q z%EKuncKAS>UUAq!S@{uvhYU<-y}KtKT*NYKB=u2)M4toDY5h~!Gm%&K5z$9u#6ge{ z*!XUD3^I)bFSrpz1Zn2x4;@kYSm@SYjpt=_h2vx%lCUN6?8rSaa;>aYe6#`KWU_aw zo`>UXh*Q7F(|{9=JcjlK3!VIpFtHX53cR&>=jGE2FU_onZ#*F%>haVl?9Uj<07toQ zh36fE)bGo)$K4O!#0-!xeqJ`178Vh?568-3>#OF6sU)VLOLC$C;}FZn6n80ddh z`pS6lW@7iZK7JY(zqp~G^)5pvpKrH0`_OY8I$dm%MfC)8g}n8EI2|jY212B4s7_jS zSZ$qY1-yyf+OG6D9<@JOr>ZZcv#X+U&|jx;M6KTxz?V%THgMY$W{AkiS^3BeW|6?! ze|bZ&Sk<-Pg9J$yB8+0&Lg7Z%U4bO@KDKDbPd5``=d~Pwm&@A5yUkwzg@dRgiOuB8 zbIOXeWpHi!Up~+)+YuLBY-vT}0R#(? zwh0aX2%gkHf0v2;X~(vLgmW);_=IDqm;SX{uxM)+tQ#L(uTUbZi;d(+W#EfPdLyZ~ zQZ&Z-%lJ*L98jQDrRFj+s(76xKFw+k?IWHYJh6pt*IhAU-7eD}ztzrIDXO@O1>^It ztuwkv(Yg4L_#}(~COKsDl`qhF?sSwGQ_P3zmPuVJs%rT4jc(22R<`b*j);VoZfqU7 zw}Svw`FEFmChABhWcnW3t22}rkE;}q7LRXf-~!&q>`(FK=DA_23k4VK`H1sQcm`Yn zKTbeLiILZCo1;-TP>+AQ4MF{i625r#`u8_FYo6^(A7GWO*Ml)6qGw<+AU>~qsSM;o z7M|L5%{1mM(v9(?e6OA}Wb<`9Z{v)@FcqOiQph8lF2yFgjr3)V(In+W$AjptiLAU$L)s!3F*;_q#rUVzQ0r%Z5$?`=3M&BB*c)sUz@#oimLOwh(AIeXOAN*j&Lv}5r#(cnGsoYp1ek4OY?XBBYe1%6G$ zg^zp~%7o-k0mh!f{Ci8|Y%XN+sh#eOmSfT*KL9Uzp!Q<{wA)i>?#;N@c>qU6UtI+ z4@9S;52Zx<59MLu#I77)e>~V8glKh&4Uaob2n@2MjCwmG0nE&*w?!2aRlKXTR1X(OR#DL`yw3Ai)jgd>n zg^GeLeSt29hc4*J0;peX0qf5{y&mF2^itzL1Kkn6BbnZ?oV^S}ez>^ELQ>*gCf$}> z=~+lksY%1dRPLe1Ns}S<7zZl4X4`IjduFGjlhl;}mcWunipGfOA#dbiKO88MYuL;| z78Y@6BWIJPudaUm&9&=VYl2++0HPq3$8ZbKiowDCTIV;j=?OTkU7U7fZn+FoMa~ZHJE)d>7*qHu zC>Y&Jgvnr=j)aUh;NzQzHp1KLJV=NN1RX$(v`@v&M)}h<(5k|V+7Q%36z?_(4G*I} zUOo-~8UAQR`Revs^Bt4RI&qgylU+xZi{6bqmwDql9u-#z}NQsG@MJ^i638u*#| bWW^%>x7XlHV^#Q1uOX^B?ki3(VEg|7!QHuF diff --git a/public/plugin/layer/skin/default/xubox_loading1.gif b/public/plugin/layer/skin/default/xubox_loading1.gif deleted file mode 100644 index db3a483e4b74971fbfb1cc0fb6499852cedfe650..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 701 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
-
-
-
-

{$msgname}{$msgtitle}提示

-

{$message}

-
-
-
- {if $waitsecond} -
- - {/if} -
- - \ No newline at end of file diff --git a/template/default/config.ini b/template/default/config.ini deleted file mode 100644 index ae0b741..0000000 --- a/template/default/config.ini +++ /dev/null @@ -1,6 +0,0 @@ -name=默认模版 -description="这里填写模版简介" -author=杰少Pakey -version=1.0.0 -email=admin@ptcms.com -url=http://www.ptcms.com \ No newline at end of file diff --git a/template/default/config.php b/template/default/config.php deleted file mode 100644 index 2590d64..0000000 --- a/template/default/config.php +++ /dev/null @@ -1,28 +0,0 @@ - - array ( - 'name' => '焦点图', - 'value' => '大主宰|完美世界|莽荒纪|绝世唐门', - ), - 'bjtjtop' => - array ( - 'name' => '编辑推荐头条', - 'value' => '天醒之路', - ), - 'bjtj' => - array ( - 'name' => '编辑推荐列表', - 'value' => '魔天记|我欲封天|绝世武神|择天记|武极天下|灵域|永夜君王|校花的贴身高手|星战风暴', - ), - 'viptop' => - array ( - 'name' => 'vip推荐头条', - 'value' => '英雄联盟之谁与争锋|星河大帝', - ), - 'vip' => - array ( - 'name' => 'vip推荐列表', - 'value' => '剑道独尊|傲世九重天|最强弃少|天骄无双', - ), -); \ No newline at end of file diff --git a/template/default/demo.jpg b/template/default/demo.jpg deleted file mode 100644 index f354ed88bb209a8d24f3fcc0389fb26a8f00b518..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19610 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ð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 YiRz_xhDaH`i(kq%B*o@HStq0a0!s7P6aWAK diff --git a/template/default/index/index_index.html b/template/default/index/index_index.html deleted file mode 100644 index f127558..0000000 --- a/template/default/index/index_index.html +++ /dev/null @@ -1,9 +0,0 @@ -

Hello World By PTcms Framework!

-
-

友情链接展示

-{block method="friendlink" name=list num=10} -{loop=$list} -{$loop.showname} -{/loop} -
-

广告展示

\ No newline at end of file