From 31aad79e8e12932de0b816daca10c9940e4e7c82 Mon Sep 17 00:00:00 2001 From: "zhangf@suq.cn" Date: Sat, 31 Jan 2026 13:22:32 +0800 Subject: [PATCH] init --- admin/admin.class.php | 275 ++ admin/admin.inc.php | 365 +++ admin/admin_check.inc.php | 49 + admin/area.inc.php | 201 ++ admin/banip.inc.php | 128 + admin/banword.inc.php | 82 + admin/cate.inc.php | 17 + admin/category.inc.php | 432 +++ admin/city.inc.php | 136 + admin/cloud.inc.php | 10 + admin/config.inc.php | 32 + admin/count.inc.php | 329 ++ admin/cron.inc.php | 213 ++ admin/data.inc.php | 420 +++ admin/database.inc.php | 896 ++++++ admin/doctor.inc.php | 20 + admin/fetch.inc.php | 66 + admin/fields.inc.php | 193 ++ admin/history.inc.php | 104 + admin/html.inc.php | 174 ++ admin/image/add.png | Bin 0 -> 3664 bytes admin/image/arrow-d.png | Bin 0 -> 2859 bytes admin/image/arrow-r.png | Bin 0 -> 2831 bytes admin/image/arrow-u.png | Bin 0 -> 2857 bytes admin/image/back2top.png | Bin 0 -> 3398 bytes admin/image/bar1.png | Bin 0 -> 2896 bytes admin/image/bar2.png | Bin 0 -> 2894 bytes admin/image/bar3.png | Bin 0 -> 2869 bytes admin/image/bar4.png | Bin 0 -> 2865 bytes admin/image/bar5.png | Bin 0 -> 2850 bytes admin/image/bar6.png | Bin 0 -> 2875 bytes admin/image/bar7.png | Bin 0 -> 2869 bytes admin/image/child.png | Bin 0 -> 283 bytes admin/image/count.gif | Bin 0 -> 310 bytes admin/image/css.gif | Bin 0 -> 594 bytes admin/image/delete.png | Bin 0 -> 311 bytes admin/image/dialog-close-on.png | Bin 0 -> 168 bytes admin/image/dialog-close.png | Bin 0 -> 177 bytes admin/image/edit.png | Bin 0 -> 451 bytes admin/image/folder.gif | Bin 0 -> 345 bytes admin/image/htm.gif | Bin 0 -> 599 bytes admin/image/img.gif | Bin 0 -> 520 bytes admin/image/import.png | Bin 0 -> 310 bytes admin/image/index.html | 1 + admin/image/level_1.gif | Bin 0 -> 142 bytes admin/image/level_2.gif | Bin 0 -> 141 bytes admin/image/level_3.gif | Bin 0 -> 142 bytes admin/image/level_4.gif | Bin 0 -> 141 bytes admin/image/level_5.gif | Bin 0 -> 140 bytes admin/image/level_6.gif | Bin 0 -> 142 bytes admin/image/level_7.gif | Bin 0 -> 140 bytes admin/image/level_8.gif | Bin 0 -> 144 bytes admin/image/level_9.gif | Bin 0 -> 143 bytes admin/image/link.png | Bin 0 -> 2948 bytes admin/image/lock.gif | Bin 0 -> 322 bytes admin/image/login-captcha.png | Bin 0 -> 450 bytes admin/image/login-mobile.png | Bin 0 -> 2905 bytes admin/image/login-password.png | Bin 0 -> 343 bytes admin/image/login-switch-on.png | Bin 0 -> 428 bytes admin/image/login-switch.png | Bin 0 -> 470 bytes admin/image/login-username.png | Bin 0 -> 384 bytes admin/image/login.css | 31 + admin/image/msg-arrow.png | Bin 0 -> 2941 bytes admin/image/msg.css | 15 + admin/image/new.png | Bin 0 -> 294 bytes admin/image/pagebreak.gif | Bin 0 -> 240 bytes admin/image/photo.gif | Bin 0 -> 621 bytes admin/image/poll.png | Bin 0 -> 3854 bytes admin/image/remkdir.png | Bin 0 -> 552 bytes admin/image/resize.gif | Bin 0 -> 84 bytes admin/image/save.png | Bin 0 -> 385 bytes admin/image/search.png | Bin 0 -> 3540 bytes admin/image/set.png | Bin 0 -> 345 bytes admin/image/sql.gif | Bin 0 -> 625 bytes admin/image/start.png | Bin 0 -> 245 bytes admin/image/stop.png | Bin 0 -> 449 bytes admin/image/style.css | 123 + admin/image/tips-update.png | Bin 0 -> 550 bytes admin/image/tool-close.png | Bin 0 -> 177 bytes admin/image/tool-favor.png | Bin 0 -> 2843 bytes admin/image/tool-full.png | Bin 0 -> 2963 bytes admin/image/tool-help.png | Bin 0 -> 332 bytes admin/image/tool-home.png | Bin 0 -> 2948 bytes admin/image/tool-reload.png | Bin 0 -> 422 bytes admin/image/tool-search.png | Bin 0 -> 386 bytes admin/image/tree.gif | Bin 0 -> 79 bytes admin/image/unknow.gif | Bin 0 -> 225 bytes admin/image/user.png | Bin 0 -> 401 bytes admin/image/video.gif | Bin 0 -> 1386 bytes admin/image/view.png | Bin 0 -> 885 bytes admin/image/yes.png | Bin 0 -> 3062 bytes admin/index.html | 1 + admin/index.inc.php | 1 + admin/ip.inc.php | 8 + admin/keylink.inc.php | 128 + admin/keyword.inc.php | 140 + admin/like.inc.php | 67 + admin/login.inc.php | 200 ++ admin/md5.inc.php | 82 + admin/menu.inc.php | 40 + admin/mobile.inc.php | 8 + admin/module.inc.php | 242 ++ admin/mymenu.inc.php | 30 + admin/patch.inc.php | 143 + admin/property.inc.php | 207 ++ admin/question.inc.php | 80 + admin/scan.inc.php | 179 ++ admin/search.inc.php | 85 + admin/setting.inc.php | 153 + admin/skin.inc.php | 115 + admin/split.inc.php | 106 + admin/stats.inc.php | 334 ++ admin/tag.inc.php | 146 + admin/template.inc.php | 189 ++ admin/template/admin.tpl.php | 62 + admin/template/admin_add.tpl.php | 67 + admin/template/admin_edit.tpl.php | 38 + admin/template/admin_log.tpl.php | 47 + admin/template/admin_online.tpl.php | 29 + admin/template/admin_right.tpl.php | 200 ++ admin/template/admin_temp.tpl.php | 52 + admin/template/area.tpl.php | 83 + admin/template/area_add.tpl.php | 35 + admin/template/banip.tpl.php | 40 + admin/template/banip_data.tpl.php | 33 + admin/template/banip_edit.tpl.php | 62 + admin/template/banip_login.tpl.php | 30 + admin/template/banword.tpl.php | 76 + admin/template/cate.tpl.php | 29 + admin/template/category.tpl.php | 123 + admin/template/category_add.tpl.php | 95 + admin/template/category_copy.tpl.php | 46 + admin/template/category_edit.tpl.php | 94 + admin/template/city.tpl.php | 55 + admin/template/city_edit.tpl.php | 69 + admin/template/count.tpl.php | 193 ++ admin/template/count_repeat.tpl.php | 77 + admin/template/count_stats.tpl.php | 135 + admin/template/cron.tpl.php | 47 + admin/template/cron_edit.tpl.php | 130 + admin/template/data.tpl.php | 95 + admin/template/data_import.tpl.php | 82 + admin/template/data_move.tpl.php | 107 + admin/template/data_view.tpl.php | 43 + admin/template/database.tpl.php | 119 + admin/template/database_comment.tpl.php | 23 + admin/template/database_dict.tpl.php | 45 + admin/template/database_execute.tpl.php | 56 + admin/template/database_import.tpl.php | 90 + admin/template/database_open.tpl.php | 27 + admin/template/database_process.tpl.php | 38 + admin/template/database_replace.tpl.php | 127 + admin/template/database_verify.tpl.php | 77 + admin/template/dialog.tpl.php | 29 + admin/template/doctor.tpl.php | 252 ++ admin/template/fetch.tpl.php | 45 + admin/template/fetch_edit.tpl.php | 56 + admin/template/fields.tpl.php | 57 + admin/template/fields_add.tpl.php | 198 ++ admin/template/fields_edit.tpl.php | 191 ++ admin/template/footer.tpl.php | 21 + admin/template/header.tpl.php | 30 + admin/template/history.tpl.php | 40 + admin/template/html.tpl.php | 41 + admin/template/index.html | 1 + admin/template/ip.tpl.php | 11 + admin/template/keylink.tpl.php | 93 + admin/template/keyword.tpl.php | 133 + admin/template/keyword_record.tpl.php | 64 + admin/template/left.tpl.php | 291 ++ admin/template/like.tpl.php | 51 + admin/template/login.tpl.php | 183 ++ admin/template/main.tpl.php | 117 + admin/template/md5.tpl.php | 107 + admin/template/md5_add.tpl.php | 48 + admin/template/menu.tpl.php | 35 + admin/template/mobile.tpl.php | 11 + admin/template/module.tpl.php | 164 + admin/template/module_add.tpl.php | 90 + admin/template/module_edit.tpl.php | 88 + admin/template/module_sys.tpl.php | 29 + admin/template/move.tpl.php | 45 + admin/template/msg.tpl.php | 25 + admin/template/mymenu.tpl.php | 57 + admin/template/notice_chip.tpl.php | 8 + admin/template/password.tpl.php | 53 + admin/template/patch.tpl.php | 120 + admin/template/patch_view.tpl.php | 20 + admin/template/property.tpl.php | 46 + admin/template/property_copy.tpl.php | 74 + admin/template/property_edit.tpl.php | 80 + admin/template/question.tpl.php | 60 + admin/template/scan.tpl.php | 84 + admin/template/search.tpl.php | 181 ++ admin/template/setting.tpl.php | 1198 +++++++ admin/template/side.tpl.php | 38 + admin/template/skin.tpl.php | 62 + admin/template/skin_add.tpl.php | 29 + admin/template/skin_edit.tpl.php | 31 + admin/template/split.tpl.php | 23 + admin/template/static.tpl.php | 14 + admin/template/stats.tpl.php | 55 + admin/template/stats_404.tpl.php | 80 + admin/template/stats_online.tpl.php | 48 + admin/template/stats_pv.tpl.php | 82 + admin/template/stats_report.tpl.php | 686 ++++ admin/template/stats_uv.tpl.php | 77 + admin/template/tag.tpl.php | 267 ++ admin/template/tag_dict.tpl.php | 31 + admin/template/tag_preview.tpl.php | 46 + admin/template/template.tpl.php | 100 + admin/template/template_add.tpl.php | 48 + admin/template/template_edit.tpl.php | 50 + admin/template/type.tpl.php | 48 + admin/template/upload.tpl.php | 84 + admin/template/upload_part.tpl.php | 63 + admin/template/word.tpl.php | 154 + admin/type.inc.php | 30 + admin/unzip.class.php | 244 ++ admin/update.inc.php | 120 + admin/upload.inc.php | 180 ++ admin/word.inc.php | 110 + api/403.php | 3 + api/404.php | 3 + api/503.php | 3 + api/address.php | 5 + api/ajax.php | 3 + api/ajax/area.inc.php | 9 + api/ajax/captcha.inc.php | 8 + api/ajax/catalog.inc.php | 5 + api/ajax/category.inc.php | 28 + api/ajax/choose.inc.php | 132 + api/ajax/city.inc.php | 10 + api/ajax/ckpath.inc.php | 16 + api/ajax/clear.inc.php | 11 + api/ajax/express.inc.php | 46 + api/ajax/favorite.inc.php | 41 + api/ajax/index.html | 1 + api/ajax/ipage.inc.php | 11 + api/ajax/keyword.inc.php | 5 + api/ajax/letter.inc.php | 12 + api/ajax/like.inc.php | 39 + api/ajax/mall.inc.php | 57 + api/ajax/member.inc.php | 49 + api/ajax/mobile.inc.php | 12 + api/ajax/page.inc.php | 10 + api/ajax/property.inc.php | 30 + api/ajax/proxy.inc.php | 66 + api/ajax/question.inc.php | 9 + api/ajax/reccate.inc.php | 13 + api/ajax/schcate.inc.php | 12 + api/ajax/screen.inc.php | 5 + api/ajax/select.inc.php | 104 + api/ajax/stats.inc.php | 9 + api/ajax/tipword.inc.php | 15 + api/ajax/type.inc.php | 6 + api/ajax/userdata.inc.php | 19 + api/app.php | 45 + api/attach.php | 5 + api/avatar/cropbox-min.js | 1 + api/avatar/cropbox.css | 48 + api/avatar/cropbox.js | 141 + api/avatar/default.jpg | Bin 0 -> 14475 bytes api/avatar/default.png | Bin 0 -> 7051 bytes api/avatar/defaultx20.jpg | Bin 0 -> 12759 bytes api/avatar/defaultx48.jpg | Bin 0 -> 13103 bytes api/avatar/index.html | 1 + api/avatar/show.php | 28 + api/barcode.png.php | 62 + api/barcode/Arial.ttf | Bin 0 -> 311636 bytes api/barcode/BCGArgumentException.php | 26 + api/barcode/BCGBarcode.php | 437 +++ api/barcode/BCGBarcode1D.php | 260 ++ api/barcode/BCGColor.php | 155 + api/barcode/BCGDraw.php | 39 + api/barcode/BCGDrawException.php | 22 + api/barcode/BCGDrawJPG.php | 90 + api/barcode/BCGDrawPNG.php | 190 ++ api/barcode/BCGDrawing.php | 249 ++ api/barcode/BCGFont.php | 24 + api/barcode/BCGFontFile.php | 210 ++ api/barcode/BCGFontPhp.php | 154 + api/barcode/BCGLabel.php | 321 ++ api/barcode/BCGParseException.php | 26 + api/barcode/BCGcode39.barcode.php | 194 ++ api/barcode/index.html | 1 + api/booklet/ajax-loader.gif | Bin 0 -> 3208 bytes api/booklet/arrow-next.png | Bin 0 -> 6484 bytes api/booklet/arrow-prev.png | Bin 0 -> 6244 bytes api/booklet/buttons.png | Bin 0 -> 4307 bytes api/booklet/ebook.css | 106 + api/booklet/jquery.booklet.1.1.0.css | 96 + api/booklet/jquery.booklet.1.1.0.js | 864 ++++++ api/booklet/jquery.booklet.1.1.0.min.js | 13 + api/booklet/jquery.easing.1.3.js | 38 + api/booklet/shadow-top-back.png | Bin 0 -> 2856 bytes api/booklet/shadow-top-forward.png | Bin 0 -> 2847 bytes api/booklet/shadow.png | Bin 0 -> 5552 bytes api/booklet/style.css | 122 + api/captcha.png.php | 21 + api/city.php | 66 + api/comment.php | 230 ++ api/company.php | 11 + api/cron.inc.php | 24 + api/cron/banip.inc.php | 14 + api/cron/cache.inc.php | 7 + api/cron/charge.inc.php | 8 + api/cron/chat.inc.php | 8 + api/cron/credit.inc.php | 8 + api/cron/index.html | 1 + api/cron/log.inc.php | 18 + api/cron/mail.inc.php | 8 + api/cron/message.inc.php | 9 + api/cron/message.php | 26 + api/cron/money.inc.php | 8 + api/cron/online.inc.php | 5 + api/cron/sms.inc.php | 13 + api/cron/split.inc.php | 20 + api/cron/stats.inc.php | 65 + api/cron/temp.inc.php | 14 + api/discuz.inc.php | 14 + api/excel/data.class.php | 229 ++ api/excel/date.class.php | 111 + api/excel/debug.class.php | 266 ++ api/excel/demo.xls | Bin 0 -> 22016 bytes api/excel/excel.class.php | 198 ++ api/excel/font.class.php | 159 + api/excel/index.html | 1 + api/excel/loader.inc.php | 9 + api/excel/parser.class.php | 1393 +++++++++ api/express.php | 34 + api/extend.func.php | 4 + api/im.func.php | 33 + api/image.png.php | 19 + api/index.html | 1 + api/js.php | 22 + api/json.php | 6 + api/json/demo.inc.php | 10 + api/json/demo.php | 10 + api/json/index.html | 1 + api/kf/index.html | 1 + api/kf/qiao/index.html | 1 + api/kf/qiao/post.inc.php | 16 + api/kf/qiao/show.inc.php | 11 + api/kf/qq/index.html | 1 + api/kf/qq/post.inc.php | 16 + api/kf/qq/show.inc.php | 8 + api/kf/these.name.php | 6 + api/map/51ditu/config.inc.php | 5 + api/map/51ditu/index.html | 1 + api/map/51ditu/mark.php | 62 + api/map/51ditu/post.inc.php | 19 + api/map/51ditu/show.inc.php | 18 + api/map/baidu/config.inc.php | 5 + api/map/baidu/index.html | 1 + api/map/baidu/mark.php | 102 + api/map/baidu/post.inc.php | 19 + api/map/baidu/show.inc.php | 5 + api/map/baidu/show.php | 43 + api/map/google/config.inc.php | 5 + api/map/google/index.html | 1 + api/map/google/mark.php | 72 + api/map/google/post.inc.php | 19 + api/map/google/show.inc.php | 5 + api/map/google/show.php | 70 + api/map/index.html | 1 + api/map/mapabc/config.inc.php | 5 + api/map/mapabc/index.html | 1 + api/map/mapabc/mark.php | 44 + api/map/mapabc/post.inc.php | 19 + api/map/mapabc/show.inc.php | 5 + api/map/mapabc/show.php | 81 + api/map/qq/config.inc.php | 5 + api/map/qq/index.html | 1 + api/map/qq/mark.php | 56 + api/map/qq/post.inc.php | 19 + api/map/qq/show.inc.php | 5 + api/map/qq/show.php | 42 + api/map/these.name.php | 9 + api/memcache.php | 908 ++++++ api/mobile.php | 58 + api/oauth/avatar.png | Bin 0 -> 4100 bytes api/oauth/baidu/callback.php | 18 + api/oauth/baidu/connect.php | 5 + api/oauth/baidu/ico.png | Bin 0 -> 3378 bytes api/oauth/baidu/icon.png | Bin 0 -> 7151 bytes api/oauth/baidu/index.php | 20 + api/oauth/baidu/init.inc.php | 14 + api/oauth/baidu/login.png | Bin 0 -> 1008 bytes api/oauth/index.html | 1 + api/oauth/msn/callback.php | 18 + api/oauth/msn/connect.php | 5 + api/oauth/msn/ico.png | Bin 0 -> 809 bytes api/oauth/msn/index.php | 25 + api/oauth/msn/init.inc.php | 16 + api/oauth/netease/callback.php | 18 + api/oauth/netease/connect.php | 5 + api/oauth/netease/ico.png | Bin 0 -> 2905 bytes api/oauth/netease/icon.png | Bin 0 -> 8254 bytes api/oauth/netease/index.php | 20 + api/oauth/netease/init.inc.php | 14 + api/oauth/post.inc.php | 25 + api/oauth/qq/callback.php | 20 + api/oauth/qq/connect.php | 6 + api/oauth/qq/ico.png | Bin 0 -> 3999 bytes api/oauth/qq/icon.png | Bin 0 -> 7020 bytes api/oauth/qq/index.php | 28 + api/oauth/qq/init.inc.php | 14 + api/oauth/qq/login.png | Bin 0 -> 3137 bytes api/oauth/qq/login50.png | Bin 0 -> 2609 bytes api/oauth/setting.inc.php | 173 ++ api/oauth/sina/callback.php | 25 + api/oauth/sina/connect.php | 6 + api/oauth/sina/ico.png | Bin 0 -> 3445 bytes api/oauth/sina/icon.png | Bin 0 -> 8200 bytes api/oauth/sina/index.php | 23 + api/oauth/sina/init.inc.php | 11 + api/oauth/sina/login.png | Bin 0 -> 4760 bytes api/oauth/sina/post.php | 17 + api/oauth/sina/saetv2.ex.class.php | 3268 ++++++++++++++++++++ api/oauth/taobao/callback.php | 20 + api/oauth/taobao/connect.php | 5 + api/oauth/taobao/ico.png | Bin 0 -> 3309 bytes api/oauth/taobao/icon.png | Bin 0 -> 8409 bytes api/oauth/taobao/index.php | 17 + api/oauth/taobao/init.inc.php | 13 + api/oauth/user.inc.php | 111 + api/oauth/wechat/callback.php | 18 + api/oauth/wechat/connect.php | 41 + api/oauth/wechat/ico.png | Bin 0 -> 3214 bytes api/oauth/wechat/icon.png | Bin 0 -> 7179 bytes api/oauth/wechat/index.php | 21 + api/oauth/wechat/init.inc.php | 13 + api/oauth/wechat/qrcode.php | 32 + api/oauth/wechat/style.css | 2 + api/online.png.php | 22 + api/pages.default.php | 54 + api/pages.sample.php | 17 + api/pay/alipay/icon.png | Bin 0 -> 8162 bytes api/pay/alipay/index.html | 1 + api/pay/alipay/logo.gif | Bin 0 -> 2127 bytes api/pay/alipay/md5/config.inc.php | 13 + api/pay/alipay/md5/index.html | 1 + api/pay/alipay/md5/notify.class.php | 173 ++ api/pay/alipay/md5/notify.php | 52 + api/pay/alipay/md5/receive.inc.php | 48 + api/pay/alipay/md5/send.inc.php | 40 + api/pay/alipay/md5/service.class.php | 103 + api/pay/alipay/receive.inc.php | 4 + .../rsa2/AlipayTradePagePayContentBuilder.php | 112 + api/pay/alipay/rsa2/AlipayTradePagePayRequest.php | 119 + api/pay/alipay/rsa2/AlipayTradeService.php | 234 ++ api/pay/alipay/rsa2/AopClient.php | 1213 ++++++++ api/pay/alipay/rsa2/AopEncrypt.php | 72 + api/pay/alipay/rsa2/AopSdk.php | 43 + api/pay/alipay/rsa2/config.inc.php | 27 + api/pay/alipay/rsa2/index.html | 1 + api/pay/alipay/rsa2/notify.php | 115 + api/pay/alipay/rsa2/receive.inc.php | 63 + api/pay/alipay/rsa2/send.inc.php | 49 + api/pay/alipay/send.inc.php | 4 + api/pay/aliwap/icon.png | Bin 0 -> 8162 bytes api/pay/aliwap/index.html | 1 + api/pay/aliwap/logo.gif | Bin 0 -> 2127 bytes api/pay/aliwap/md5/config.inc.php | 242 ++ api/pay/aliwap/md5/index.html | 1 + api/pay/aliwap/md5/notify.class.php | 160 + api/pay/aliwap/md5/notify.php | 52 + api/pay/aliwap/md5/receive.inc.php | 35 + api/pay/aliwap/md5/send.inc.php | 37 + api/pay/aliwap/md5/submit.class.php | 128 + api/pay/aliwap/receive.inc.php | 4 + api/pay/aliwap/rsa2/AlipayTradeService.php | 249 ++ .../rsa2/AlipayTradeWapPayContentBuilder.php | 125 + api/pay/aliwap/rsa2/AlipayTradeWapPayRequest.php | 118 + api/pay/aliwap/rsa2/AopClient.php | 1108 +++++++ api/pay/aliwap/rsa2/AopEncrypt.php | 72 + api/pay/aliwap/rsa2/AopSdk.php | 43 + api/pay/aliwap/rsa2/config.inc.php | 28 + api/pay/aliwap/rsa2/index.html | 1 + api/pay/aliwap/rsa2/notify.php | 116 + api/pay/aliwap/rsa2/receive.inc.php | 65 + api/pay/aliwap/rsa2/send.inc.php | 39 + api/pay/aliwap/send.inc.php | 4 + api/pay/chinabank/icon.png | Bin 0 -> 19487 bytes api/pay/chinabank/index.html | 1 + api/pay/chinabank/logo.gif | Bin 0 -> 2524 bytes api/pay/chinabank/notify.php | 58 + api/pay/chinabank/receive.inc.php | 49 + api/pay/chinabank/send.inc.php | 41 + api/pay/chinapay/icon.png | Bin 0 -> 6838 bytes api/pay/chinapay/index.html | 1 + api/pay/chinapay/lib_curl.php | 74 + api/pay/chinapay/logo.gif | Bin 0 -> 2282 bytes api/pay/chinapay/netpayclient.php | 5 + api/pay/chinapay/netpayclient_config.php | 50 + api/pay/chinapay/notify.php | 66 + api/pay/chinapay/receive.inc.php | 64 + api/pay/chinapay/send.inc.php | 64 + api/pay/index.html | 1 + api/pay/kq99bill/icon.png | Bin 0 -> 19808 bytes api/pay/kq99bill/index.html | 1 + api/pay/kq99bill/logo.gif | Bin 0 -> 1966 bytes api/pay/kq99bill/notify.php | 94 + api/pay/kq99bill/receive.inc.php | 3 + api/pay/kq99bill/send.inc.php | 127 + api/pay/paypal/icon.png | Bin 0 -> 13745 bytes api/pay/paypal/index.html | 1 + api/pay/paypal/logo.gif | Bin 0 -> 2143 bytes api/pay/paypal/notify.php | 101 + api/pay/paypal/receive.inc.php | 80 + api/pay/paypal/send.inc.php | 28 + api/pay/setting.inc.php | 363 +++ api/pay/success.inc.php | 99 + api/pay/tenpay/-icon.png | Bin 0 -> 17155 bytes api/pay/tenpay/ClientResponseHandler.class.php | 223 ++ api/pay/tenpay/RequestHandler.class.php | 167 + api/pay/tenpay/ResponseHandler.class.php | 159 + api/pay/tenpay/TenpayHttpClient.class.php | 180 ++ api/pay/tenpay/config.inc.php | 7 + api/pay/tenpay/function.php | 7 + api/pay/tenpay/icon.png | Bin 0 -> 16738 bytes api/pay/tenpay/index.html | 1 + api/pay/tenpay/logo.gif | Bin 0 -> 2517 bytes api/pay/tenpay/notify.php | 151 + api/pay/tenpay/receive.inc.php | 97 + api/pay/tenpay/send.inc.php | 87 + api/pay/upay/acp_prod_enc.cer | 24 + api/pay/upay/acp_prod_verify_sign.cer | 25 + api/pay/upay/config.inc.php | 65 + api/pay/upay/icon.png | Bin 0 -> 30223 bytes api/pay/upay/index.html | 1 + api/pay/upay/logo.gif | Bin 0 -> 2546 bytes api/pay/upay/notify.php | 49 + api/pay/upay/receive.inc.php | 25 + api/pay/upay/sdk.class.php | 1082 +++++++ api/pay/upay/send.inc.php | 33 + api/pay/upay/zhengshu.pfx | Bin 0 -> 2794 bytes api/pay/weixin/h5api.php | 121 + api/pay/weixin/h5pay.php | 80 + api/pay/weixin/icon.png | Bin 0 -> 8568 bytes api/pay/weixin/index.html | 1 + api/pay/weixin/jsapi.php | 148 + api/pay/weixin/logo.gif | Bin 0 -> 1889 bytes api/pay/weixin/notify.php | 58 + api/pay/weixin/openid.php | 16 + api/pay/weixin/qrcode.php | 115 + api/pay/weixin/receive.inc.php | 3 + api/pay/weixin/send.inc.php | 24 + api/pay/yeepay/icon.png | Bin 0 -> 21910 bytes api/pay/yeepay/index.html | 1 + api/pay/yeepay/logo.gif | Bin 0 -> 2737 bytes api/pay/yeepay/receive.inc.php | 56 + api/pay/yeepay/send.inc.php | 82 + api/pay/yeepay/yeepayCommon.php | 161 + api/phpwind.inc.php | 47 + api/push.js.php | 6 + api/qrcode.png.php | 2065 +++++++++++++ api/redirect.php | 66 + api/report.php | 9 + api/search.php | 38 + api/share.php | 5 + api/shortcut.php | 22 + api/sso.inc.php | 28 + api/sso.php | 76 + api/stats.inc.php | 55 + api/stats/51la/index.html | 1 + api/stats/51la/post.inc.php | 16 + api/stats/51la/show.inc.php | 8 + api/stats/baidu/index.html | 1 + api/stats/baidu/post.inc.php | 16 + api/stats/baidu/show.inc.php | 17 + api/stats/cnzz/index.html | 1 + api/stats/cnzz/post.inc.php | 22 + api/stats/cnzz/show.inc.php | 9 + api/stats/index.html | 1 + api/stats/qq/index.html | 1 + api/stats/qq/post.inc.php | 16 + api/stats/qq/show.inc.php | 8 + api/stats/these.name.php | 8 + api/task.inc.php | 9 + api/task.js.php | 30 + api/uc.inc.php | 78 + api/uc.php | 119 + api/ucenter/change.log | 5 + api/ucenter/client.php | 567 ++++ api/ucenter/control/app.php | 50 + api/ucenter/control/cache.php | 29 + api/ucenter/control/domain.php | 29 + api/ucenter/control/feed.php | 105 + api/ucenter/control/friend.php | 59 + api/ucenter/control/index.html | 1 + api/ucenter/control/mail.php | 41 + api/ucenter/control/pm.php | 270 ++ api/ucenter/control/tag.php | 85 + api/ucenter/control/user.php | 280 ++ api/ucenter/data/cache/apps.php | 42 + api/ucenter/data/cache/badwords.php | 5 + api/ucenter/data/cache/index.html | 1 + api/ucenter/data/cache/settings.php | 31 + api/ucenter/data/index.html | 1 + api/ucenter/index.html | 1 + api/ucenter/lib/db.class.php | 172 ++ api/ucenter/lib/index.html | 1 + api/ucenter/lib/sendmail.inc.php | 142 + api/ucenter/lib/uccode.class.php | 145 + api/ucenter/lib/xml.class.php | 105 + api/ucenter/model/app.php | 36 + api/ucenter/model/base.php | 254 ++ api/ucenter/model/cache.php | 102 + api/ucenter/model/domain.php | 56 + api/ucenter/model/friend.php | 107 + api/ucenter/model/index.html | 1 + api/ucenter/model/mail.php | 149 + api/ucenter/model/misc.php | 157 + api/ucenter/model/note.php | 197 ++ api/ucenter/model/pm.php | 380 +++ api/ucenter/model/tag.php | 71 + api/ucenter/model/user.php | 206 ++ api/url.inc.php | 61 + api/view.php | 5 + api/weixin/config.inc.php | 8 + api/weixin/down.php | 7 + api/weixin/image/headimg.jpg | Bin 0 -> 1518 bytes api/weixin/image/index.html | 1 + api/weixin/image/media_image_error.gif | Bin 0 -> 444 bytes api/weixin/image/media_map.gif | Bin 0 -> 553 bytes api/weixin/image/media_map_marker.gif | Bin 0 -> 140 bytes api/weixin/image/media_upload.gif | Bin 0 -> 1533 bytes api/weixin/image/media_video.gif | Bin 0 -> 841 bytes api/weixin/image/media_voice.gif | Bin 0 -> 838 bytes api/weixin/image/qrcode_error.png | Bin 0 -> 3947 bytes api/weixin/image/top_bind.jpg | Bin 0 -> 30853 bytes api/weixin/index.html | 1 + api/weixin/index.php | 225 ++ api/weixin/init.inc.php | 221 ++ api/weixin/jssdk.php | 52 + api/weixin/media.php | 67 + api/weixin/push.php | 35 + api/weixin/qrcode.php | 10 + api/weixin/qrcode_bind.php | 20 + api/weixin/qrcode_sign.php | 15 + api/wx.php | 5 + sell/ajax.php | 3 + sell/beijiao/index.html | 425 +++ sell/beijiao/list1.html | 425 +++ sell/biaopaihaocai/index.html | 460 +++ sell/biaopaihaocai/list1.html | 460 +++ sell/biaopaiji/index.html | 553 ++++ sell/biaopaiji/list1.html | 553 ++++ sell/biaopaiji/list2.html | 453 +++ sell/biaopaishebei/index.html | 553 ++++ sell/biaopaishebei/list1.html | 553 ++++ sell/biaopaishebei/list2.html | 493 +++ sell/biaopaizhizuo/index.html | 551 ++++ sell/biaopaizhizuo/list1.html | 551 ++++ sell/biaopaizhizuo/list2.html | 551 ++++ sell/biaopaizhizuo/list3.html | 551 ++++ sell/biaopaizhizuo/list4.html | 551 ++++ sell/biaopaizhizuo/list5.html | 421 +++ sell/bofangqi/index.html | 399 +++ sell/bofangqi/list1.html | 399 +++ sell/buy.php | 6 + sell/chaobao/index.html | 431 +++ sell/chaobao/list1.html | 431 +++ sell/cheshentie/index.html | 411 +++ sell/cheshentie/list1.html | 411 +++ sell/chukong/index.html | 433 +++ sell/chukong/list1.html | 433 +++ sell/compare.php | 5 + sell/config.inc.php | 3 + sell/dabiaoji/index.html | 453 +++ sell/dabiaoji/list1.html | 453 +++ sell/dantoutie/index.html | 411 +++ sell/dantoutie/list1.html | 411 +++ sell/dayinji/index.html | 410 +++ sell/dayinji/list1.html | 410 +++ sell/dengpian/index.html | 425 +++ sell/dengpian/list1.html | 425 +++ sell/dengxiang/index.html | 551 ++++ sell/dengxiang/list1.html | 551 ++++ sell/dengxiang/list2.html | 491 +++ sell/dengxiangbu/index.html | 441 +++ sell/dengxiangbu/list1.html | 441 +++ sell/dianzhubiaopai/index.html | 411 +++ sell/dianzhubiaopai/list1.html | 411 +++ sell/diaokeji/index.html | 413 +++ sell/diaokeji/list1.html | 413 +++ sell/diaokeqiege/index.html | 533 ++++ sell/diaokeqiege/list1.html | 533 ++++ sell/guanggaoji/index.html | 493 +++ sell/guanggaoji/list1.html | 493 +++ sell/gundong/index.html | 397 +++ sell/gundong/list1.html | 397 +++ sell/hengxingzhanjia/index.html | 423 +++ sell/hengxingzhanjia/list1.html | 423 +++ sell/huwai/index.html | 423 +++ sell/huwai/list1.html | 423 +++ sell/index.html | 874 ++++++ sell/index.php | 6 + sell/inquiry.php | 6 + sell/jiaopian/index.html | 401 +++ sell/jiaopian/list1.html | 401 +++ sell/jiaoshui/index.html | 396 +++ sell/jiaoshui/list1.html | 396 +++ sell/jingshibiaopai/index.html | 551 ++++ sell/jingshibiaopai/list1.html | 551 ++++ sell/jingshibiaopai/list2.html | 411 +++ sell/jinshubiaopai/index.html | 551 ++++ sell/jinshubiaopai/list1.html | 551 ++++ sell/jinshubiaopai/list2.html | 511 +++ sell/keziji/index.html | 433 +++ sell/keziji/list1.html | 433 +++ sell/lawangzhanjia/index.html | 423 +++ sell/lawangzhanjia/list1.html | 423 +++ sell/led/index.html | 471 +++ sell/led/list1.html | 471 +++ sell/lengmo/index.html | 401 +++ sell/lengmo/list1.html | 401 +++ sell/list.php | 6 + sell/men/index.html | 413 +++ sell/men/list1.html | 413 +++ sell/moshui/index.html | 420 +++ sell/moshui/list1.html | 420 +++ sell/paoguangji/index.html | 399 +++ sell/paoguangji/list1.html | 399 +++ sell/penhui/index.html | 481 +++ sell/penhui/list1.html | 481 +++ sell/penhuiji/index.html | 510 +++ sell/penhuiji/list1.html | 510 +++ sell/penhuixiezhen/index.html | 550 ++++ sell/penhuixiezhen/list1.html | 550 ++++ sell/penhuixiezhen/list2.html | 440 +++ sell/penmaji/index.html | 410 +++ sell/penmaji/list1.html | 410 +++ sell/pingbandayinji/index.html | 454 +++ sell/pingbandayinji/list1.html | 454 +++ sell/putongdengxiang/index.html | 441 +++ sell/putongdengxiang/list1.html | 441 +++ sell/qiegeji/index.html | 443 +++ sell/qiegeji/list1.html | 443 +++ sell/qita/index.html | 413 +++ sell/qita/list1.html | 413 +++ sell/rezhuanyinji/index.html | 444 +++ sell/rezhuanyinji/list1.html | 444 +++ sell/ruanjian/index.html | 423 +++ sell/ruanjian/list1.html | 423 +++ sell/search.php | 6 + sell/shebei/index.html | 410 +++ sell/shebei/list1.html | 410 +++ sell/show.php | 6 + sell/shuzibiaopai/index.html | 553 ++++ sell/shuzibiaopai/list1.html | 553 ++++ sell/shuzibiaopai/list2.html | 433 +++ sell/siyinji/index.html | 400 +++ sell/siyinji/list1.html | 400 +++ sell/tanghuaji/index.html | 414 +++ sell/tanghuaji/list1.html | 414 +++ sell/tangjinji/index.html | 400 +++ sell/tangjinji/list1.html | 400 +++ sell/tiaofuji/index.html | 434 +++ sell/tiaofuji/list1.html | 434 +++ sell/wanggebu/index.html | 421 +++ sell/wanggebu/list1.html | 421 +++ sell/xiangzhi/index.html | 415 +++ sell/xiangzhi/list1.html | 415 +++ sell/xiezhen/index.html | 455 +++ sell/xiezhen/list1.html | 455 +++ sell/xiezhenji/index.html | 470 +++ sell/xiezhenji/list1.html | 470 +++ sell/xiezhentiaofubu/index.html | 401 +++ sell/xiezhentiaofubu/list1.html | 401 +++ sell/xisuji/index.html | 399 +++ sell/xisuji/list1.html | 399 +++ sell/xzhanjia/index.html | 423 +++ sell/xzhanjia/list1.html | 423 +++ sell/yakelibiaopai/index.html | 461 +++ sell/yakelibiaopai/list1.html | 461 +++ sell/yilabao/index.html | 423 +++ sell/yilabao/list1.html | 423 +++ sell/yindiaobu/index.html | 401 +++ sell/yindiaobu/list1.html | 401 +++ sell/yinshua/index.html | 534 ++++ sell/yinshua/list1.html | 534 ++++ sell/yiyinji/index.html | 400 +++ sell/yiyinji/list1.html | 400 +++ sell/youhuabu/index.html | 401 +++ sell/youhuabu/list1.html | 401 +++ sell/youmo/index.html | 430 +++ sell/youmo/list1.html | 430 +++ sell/zhanshijia/index.html | 503 +++ sell/zhanshijia/list1.html | 503 +++ sell/zizhu/index.html | 423 +++ sell/zizhu/list1.html | 423 +++ sitemap/index.php | 6 + special/ajax.php | 3 + special/config.inc.php | 3 + special/index.php | 6 + special/list.php | 6 + special/search.php | 6 + special/show.php | 6 + special/type.php | 6 + spread/index.php | 6 + spread/list.php | 7 + video/ajax.php | 3 + video/config.inc.php | 3 + video/index.php | 6 + video/list.php | 6 + video/search.php | 6 + video/show.php | 6 + vote/ajax.php | 3 + vote/index.php | 6 + vote/list.php | 6 + vote/show.php | 6 + 814 files changed, 112490 insertions(+) create mode 100644 admin/admin.class.php create mode 100644 admin/admin.inc.php create mode 100644 admin/admin_check.inc.php create mode 100644 admin/area.inc.php create mode 100644 admin/banip.inc.php create mode 100644 admin/banword.inc.php create mode 100644 admin/cate.inc.php create mode 100644 admin/category.inc.php create mode 100644 admin/city.inc.php create mode 100644 admin/cloud.inc.php create mode 100644 admin/config.inc.php create mode 100644 admin/count.inc.php create mode 100644 admin/cron.inc.php create mode 100644 admin/data.inc.php create mode 100644 admin/database.inc.php create mode 100644 admin/doctor.inc.php create mode 100644 admin/fetch.inc.php create mode 100644 admin/fields.inc.php create mode 100644 admin/history.inc.php create mode 100644 admin/html.inc.php create mode 100644 admin/image/add.png create mode 100644 admin/image/arrow-d.png create mode 100644 admin/image/arrow-r.png create mode 100644 admin/image/arrow-u.png create mode 100644 admin/image/back2top.png create mode 100644 admin/image/bar1.png create mode 100644 admin/image/bar2.png create mode 100644 admin/image/bar3.png create mode 100644 admin/image/bar4.png create mode 100644 admin/image/bar5.png create mode 100644 admin/image/bar6.png create mode 100644 admin/image/bar7.png create mode 100644 admin/image/child.png create mode 100644 admin/image/count.gif create mode 100644 admin/image/css.gif create mode 100644 admin/image/delete.png create mode 100644 admin/image/dialog-close-on.png create mode 100644 admin/image/dialog-close.png create mode 100644 admin/image/edit.png create mode 100644 admin/image/folder.gif create mode 100644 admin/image/htm.gif create mode 100644 admin/image/img.gif create mode 100644 admin/image/import.png create mode 100644 admin/image/index.html create mode 100644 admin/image/level_1.gif create mode 100644 admin/image/level_2.gif create mode 100644 admin/image/level_3.gif create mode 100644 admin/image/level_4.gif create mode 100644 admin/image/level_5.gif create mode 100644 admin/image/level_6.gif create mode 100644 admin/image/level_7.gif create mode 100644 admin/image/level_8.gif create mode 100644 admin/image/level_9.gif create mode 100644 admin/image/link.png create mode 100644 admin/image/lock.gif create mode 100644 admin/image/login-captcha.png create mode 100644 admin/image/login-mobile.png create mode 100644 admin/image/login-password.png create mode 100644 admin/image/login-switch-on.png create mode 100644 admin/image/login-switch.png create mode 100644 admin/image/login-username.png create mode 100644 admin/image/login.css create mode 100644 admin/image/msg-arrow.png create mode 100644 admin/image/msg.css create mode 100644 admin/image/new.png create mode 100644 admin/image/pagebreak.gif create mode 100644 admin/image/photo.gif create mode 100644 admin/image/poll.png create mode 100644 admin/image/remkdir.png create mode 100644 admin/image/resize.gif create mode 100644 admin/image/save.png create mode 100644 admin/image/search.png create mode 100644 admin/image/set.png create mode 100644 admin/image/sql.gif create mode 100644 admin/image/start.png create mode 100644 admin/image/stop.png create mode 100644 admin/image/style.css create mode 100644 admin/image/tips-update.png create mode 100644 admin/image/tool-close.png create mode 100644 admin/image/tool-favor.png create mode 100644 admin/image/tool-full.png create mode 100644 admin/image/tool-help.png create mode 100644 admin/image/tool-home.png create mode 100644 admin/image/tool-reload.png create mode 100644 admin/image/tool-search.png create mode 100644 admin/image/tree.gif create mode 100644 admin/image/unknow.gif create mode 100644 admin/image/user.png create mode 100644 admin/image/video.gif create mode 100644 admin/image/view.png create mode 100644 admin/image/yes.png create mode 100644 admin/index.html create mode 100644 admin/index.inc.php create mode 100644 admin/ip.inc.php create mode 100644 admin/keylink.inc.php create mode 100644 admin/keyword.inc.php create mode 100644 admin/like.inc.php create mode 100644 admin/login.inc.php create mode 100644 admin/md5.inc.php create mode 100644 admin/menu.inc.php create mode 100644 admin/mobile.inc.php create mode 100644 admin/module.inc.php create mode 100644 admin/mymenu.inc.php create mode 100644 admin/patch.inc.php create mode 100644 admin/property.inc.php create mode 100644 admin/question.inc.php create mode 100644 admin/scan.inc.php create mode 100644 admin/search.inc.php create mode 100644 admin/setting.inc.php create mode 100644 admin/skin.inc.php create mode 100644 admin/split.inc.php create mode 100644 admin/stats.inc.php create mode 100644 admin/tag.inc.php create mode 100644 admin/template.inc.php create mode 100644 admin/template/admin.tpl.php create mode 100644 admin/template/admin_add.tpl.php create mode 100644 admin/template/admin_edit.tpl.php create mode 100644 admin/template/admin_log.tpl.php create mode 100644 admin/template/admin_online.tpl.php create mode 100644 admin/template/admin_right.tpl.php create mode 100644 admin/template/admin_temp.tpl.php create mode 100644 admin/template/area.tpl.php create mode 100644 admin/template/area_add.tpl.php create mode 100644 admin/template/banip.tpl.php create mode 100644 admin/template/banip_data.tpl.php create mode 100644 admin/template/banip_edit.tpl.php create mode 100644 admin/template/banip_login.tpl.php create mode 100644 admin/template/banword.tpl.php create mode 100644 admin/template/cate.tpl.php create mode 100644 admin/template/category.tpl.php create mode 100644 admin/template/category_add.tpl.php create mode 100644 admin/template/category_copy.tpl.php create mode 100644 admin/template/category_edit.tpl.php create mode 100644 admin/template/city.tpl.php create mode 100644 admin/template/city_edit.tpl.php create mode 100644 admin/template/count.tpl.php create mode 100644 admin/template/count_repeat.tpl.php create mode 100644 admin/template/count_stats.tpl.php create mode 100644 admin/template/cron.tpl.php create mode 100644 admin/template/cron_edit.tpl.php create mode 100644 admin/template/data.tpl.php create mode 100644 admin/template/data_import.tpl.php create mode 100644 admin/template/data_move.tpl.php create mode 100644 admin/template/data_view.tpl.php create mode 100644 admin/template/database.tpl.php create mode 100644 admin/template/database_comment.tpl.php create mode 100644 admin/template/database_dict.tpl.php create mode 100644 admin/template/database_execute.tpl.php create mode 100644 admin/template/database_import.tpl.php create mode 100644 admin/template/database_open.tpl.php create mode 100644 admin/template/database_process.tpl.php create mode 100644 admin/template/database_replace.tpl.php create mode 100644 admin/template/database_verify.tpl.php create mode 100644 admin/template/dialog.tpl.php create mode 100644 admin/template/doctor.tpl.php create mode 100644 admin/template/fetch.tpl.php create mode 100644 admin/template/fetch_edit.tpl.php create mode 100644 admin/template/fields.tpl.php create mode 100644 admin/template/fields_add.tpl.php create mode 100644 admin/template/fields_edit.tpl.php create mode 100644 admin/template/footer.tpl.php create mode 100644 admin/template/header.tpl.php create mode 100644 admin/template/history.tpl.php create mode 100644 admin/template/html.tpl.php create mode 100644 admin/template/index.html create mode 100644 admin/template/ip.tpl.php create mode 100644 admin/template/keylink.tpl.php create mode 100644 admin/template/keyword.tpl.php create mode 100644 admin/template/keyword_record.tpl.php create mode 100644 admin/template/left.tpl.php create mode 100644 admin/template/like.tpl.php create mode 100644 admin/template/login.tpl.php create mode 100644 admin/template/main.tpl.php create mode 100644 admin/template/md5.tpl.php create mode 100644 admin/template/md5_add.tpl.php create mode 100644 admin/template/menu.tpl.php create mode 100644 admin/template/mobile.tpl.php create mode 100644 admin/template/module.tpl.php create mode 100644 admin/template/module_add.tpl.php create mode 100644 admin/template/module_edit.tpl.php create mode 100644 admin/template/module_sys.tpl.php create mode 100644 admin/template/move.tpl.php create mode 100644 admin/template/msg.tpl.php create mode 100644 admin/template/mymenu.tpl.php create mode 100644 admin/template/notice_chip.tpl.php create mode 100644 admin/template/password.tpl.php create mode 100644 admin/template/patch.tpl.php create mode 100644 admin/template/patch_view.tpl.php create mode 100644 admin/template/property.tpl.php create mode 100644 admin/template/property_copy.tpl.php create mode 100644 admin/template/property_edit.tpl.php create mode 100644 admin/template/question.tpl.php create mode 100644 admin/template/scan.tpl.php create mode 100644 admin/template/search.tpl.php create mode 100644 admin/template/setting.tpl.php create mode 100644 admin/template/side.tpl.php create mode 100644 admin/template/skin.tpl.php create mode 100644 admin/template/skin_add.tpl.php create mode 100644 admin/template/skin_edit.tpl.php create mode 100644 admin/template/split.tpl.php create mode 100644 admin/template/static.tpl.php create mode 100644 admin/template/stats.tpl.php create mode 100644 admin/template/stats_404.tpl.php create mode 100644 admin/template/stats_online.tpl.php create mode 100644 admin/template/stats_pv.tpl.php create mode 100644 admin/template/stats_report.tpl.php create mode 100644 admin/template/stats_uv.tpl.php create mode 100644 admin/template/tag.tpl.php create mode 100644 admin/template/tag_dict.tpl.php create mode 100644 admin/template/tag_preview.tpl.php create mode 100644 admin/template/template.tpl.php create mode 100644 admin/template/template_add.tpl.php create mode 100644 admin/template/template_edit.tpl.php create mode 100644 admin/template/type.tpl.php create mode 100644 admin/template/upload.tpl.php create mode 100644 admin/template/upload_part.tpl.php create mode 100644 admin/template/word.tpl.php create mode 100644 admin/type.inc.php create mode 100644 admin/unzip.class.php create mode 100644 admin/update.inc.php create mode 100644 admin/upload.inc.php create mode 100644 admin/word.inc.php create mode 100644 api/403.php create mode 100644 api/404.php create mode 100644 api/503.php create mode 100644 api/address.php create mode 100644 api/ajax.php create mode 100644 api/ajax/area.inc.php create mode 100644 api/ajax/captcha.inc.php create mode 100644 api/ajax/catalog.inc.php create mode 100644 api/ajax/category.inc.php create mode 100644 api/ajax/choose.inc.php create mode 100644 api/ajax/city.inc.php create mode 100644 api/ajax/ckpath.inc.php create mode 100644 api/ajax/clear.inc.php create mode 100644 api/ajax/express.inc.php create mode 100644 api/ajax/favorite.inc.php create mode 100644 api/ajax/index.html create mode 100644 api/ajax/ipage.inc.php create mode 100644 api/ajax/keyword.inc.php create mode 100644 api/ajax/letter.inc.php create mode 100644 api/ajax/like.inc.php create mode 100644 api/ajax/mall.inc.php create mode 100644 api/ajax/member.inc.php create mode 100644 api/ajax/mobile.inc.php create mode 100644 api/ajax/page.inc.php create mode 100644 api/ajax/property.inc.php create mode 100644 api/ajax/proxy.inc.php create mode 100644 api/ajax/question.inc.php create mode 100644 api/ajax/reccate.inc.php create mode 100644 api/ajax/schcate.inc.php create mode 100644 api/ajax/screen.inc.php create mode 100644 api/ajax/select.inc.php create mode 100644 api/ajax/stats.inc.php create mode 100644 api/ajax/tipword.inc.php create mode 100644 api/ajax/type.inc.php create mode 100644 api/ajax/userdata.inc.php create mode 100644 api/app.php create mode 100644 api/attach.php create mode 100644 api/avatar/cropbox-min.js create mode 100644 api/avatar/cropbox.css create mode 100644 api/avatar/cropbox.js create mode 100644 api/avatar/default.jpg create mode 100644 api/avatar/default.png create mode 100644 api/avatar/defaultx20.jpg create mode 100644 api/avatar/defaultx48.jpg create mode 100644 api/avatar/index.html create mode 100644 api/avatar/show.php create mode 100644 api/barcode.png.php create mode 100644 api/barcode/Arial.ttf create mode 100644 api/barcode/BCGArgumentException.php create mode 100644 api/barcode/BCGBarcode.php create mode 100644 api/barcode/BCGBarcode1D.php create mode 100644 api/barcode/BCGColor.php create mode 100644 api/barcode/BCGDraw.php create mode 100644 api/barcode/BCGDrawException.php create mode 100644 api/barcode/BCGDrawJPG.php create mode 100644 api/barcode/BCGDrawPNG.php create mode 100644 api/barcode/BCGDrawing.php create mode 100644 api/barcode/BCGFont.php create mode 100644 api/barcode/BCGFontFile.php create mode 100644 api/barcode/BCGFontPhp.php create mode 100644 api/barcode/BCGLabel.php create mode 100644 api/barcode/BCGParseException.php create mode 100644 api/barcode/BCGcode39.barcode.php create mode 100644 api/barcode/index.html create mode 100644 api/booklet/ajax-loader.gif create mode 100644 api/booklet/arrow-next.png create mode 100644 api/booklet/arrow-prev.png create mode 100644 api/booklet/buttons.png create mode 100644 api/booklet/ebook.css create mode 100644 api/booklet/jquery.booklet.1.1.0.css create mode 100644 api/booklet/jquery.booklet.1.1.0.js create mode 100644 api/booklet/jquery.booklet.1.1.0.min.js create mode 100644 api/booklet/jquery.easing.1.3.js create mode 100644 api/booklet/shadow-top-back.png create mode 100644 api/booklet/shadow-top-forward.png create mode 100644 api/booklet/shadow.png create mode 100644 api/booklet/style.css create mode 100644 api/captcha.png.php create mode 100644 api/city.php create mode 100644 api/comment.php create mode 100644 api/company.php create mode 100644 api/cron.inc.php create mode 100644 api/cron/banip.inc.php create mode 100644 api/cron/cache.inc.php create mode 100644 api/cron/charge.inc.php create mode 100644 api/cron/chat.inc.php create mode 100644 api/cron/credit.inc.php create mode 100644 api/cron/index.html create mode 100644 api/cron/log.inc.php create mode 100644 api/cron/mail.inc.php create mode 100644 api/cron/message.inc.php create mode 100644 api/cron/message.php create mode 100644 api/cron/money.inc.php create mode 100644 api/cron/online.inc.php create mode 100644 api/cron/sms.inc.php create mode 100644 api/cron/split.inc.php create mode 100644 api/cron/stats.inc.php create mode 100644 api/cron/temp.inc.php create mode 100644 api/discuz.inc.php create mode 100644 api/excel/data.class.php create mode 100644 api/excel/date.class.php create mode 100644 api/excel/debug.class.php create mode 100644 api/excel/demo.xls create mode 100644 api/excel/excel.class.php create mode 100644 api/excel/font.class.php create mode 100644 api/excel/index.html create mode 100644 api/excel/loader.inc.php create mode 100644 api/excel/parser.class.php create mode 100644 api/express.php create mode 100644 api/extend.func.php create mode 100644 api/im.func.php create mode 100644 api/image.png.php create mode 100644 api/index.html create mode 100644 api/js.php create mode 100644 api/json.php create mode 100644 api/json/demo.inc.php create mode 100644 api/json/demo.php create mode 100644 api/json/index.html create mode 100644 api/kf/index.html create mode 100644 api/kf/qiao/index.html create mode 100644 api/kf/qiao/post.inc.php create mode 100644 api/kf/qiao/show.inc.php create mode 100644 api/kf/qq/index.html create mode 100644 api/kf/qq/post.inc.php create mode 100644 api/kf/qq/show.inc.php create mode 100644 api/kf/these.name.php create mode 100644 api/map/51ditu/config.inc.php create mode 100644 api/map/51ditu/index.html create mode 100644 api/map/51ditu/mark.php create mode 100644 api/map/51ditu/post.inc.php create mode 100644 api/map/51ditu/show.inc.php create mode 100644 api/map/baidu/config.inc.php create mode 100644 api/map/baidu/index.html create mode 100644 api/map/baidu/mark.php create mode 100644 api/map/baidu/post.inc.php create mode 100644 api/map/baidu/show.inc.php create mode 100644 api/map/baidu/show.php create mode 100644 api/map/google/config.inc.php create mode 100644 api/map/google/index.html create mode 100644 api/map/google/mark.php create mode 100644 api/map/google/post.inc.php create mode 100644 api/map/google/show.inc.php create mode 100644 api/map/google/show.php create mode 100644 api/map/index.html create mode 100644 api/map/mapabc/config.inc.php create mode 100644 api/map/mapabc/index.html create mode 100644 api/map/mapabc/mark.php create mode 100644 api/map/mapabc/post.inc.php create mode 100644 api/map/mapabc/show.inc.php create mode 100644 api/map/mapabc/show.php create mode 100644 api/map/qq/config.inc.php create mode 100644 api/map/qq/index.html create mode 100644 api/map/qq/mark.php create mode 100644 api/map/qq/post.inc.php create mode 100644 api/map/qq/show.inc.php create mode 100644 api/map/qq/show.php create mode 100644 api/map/these.name.php create mode 100644 api/memcache.php create mode 100644 api/mobile.php create mode 100644 api/oauth/avatar.png create mode 100644 api/oauth/baidu/callback.php create mode 100644 api/oauth/baidu/connect.php create mode 100644 api/oauth/baidu/ico.png create mode 100644 api/oauth/baidu/icon.png create mode 100644 api/oauth/baidu/index.php create mode 100644 api/oauth/baidu/init.inc.php create mode 100644 api/oauth/baidu/login.png create mode 100644 api/oauth/index.html create mode 100644 api/oauth/msn/callback.php create mode 100644 api/oauth/msn/connect.php create mode 100644 api/oauth/msn/ico.png create mode 100644 api/oauth/msn/index.php create mode 100644 api/oauth/msn/init.inc.php create mode 100644 api/oauth/netease/callback.php create mode 100644 api/oauth/netease/connect.php create mode 100644 api/oauth/netease/ico.png create mode 100644 api/oauth/netease/icon.png create mode 100644 api/oauth/netease/index.php create mode 100644 api/oauth/netease/init.inc.php create mode 100644 api/oauth/post.inc.php create mode 100644 api/oauth/qq/callback.php create mode 100644 api/oauth/qq/connect.php create mode 100644 api/oauth/qq/ico.png create mode 100644 api/oauth/qq/icon.png create mode 100644 api/oauth/qq/index.php create mode 100644 api/oauth/qq/init.inc.php create mode 100644 api/oauth/qq/login.png create mode 100644 api/oauth/qq/login50.png create mode 100644 api/oauth/setting.inc.php create mode 100644 api/oauth/sina/callback.php create mode 100644 api/oauth/sina/connect.php create mode 100644 api/oauth/sina/ico.png create mode 100644 api/oauth/sina/icon.png create mode 100644 api/oauth/sina/index.php create mode 100644 api/oauth/sina/init.inc.php create mode 100644 api/oauth/sina/login.png create mode 100644 api/oauth/sina/post.php create mode 100644 api/oauth/sina/saetv2.ex.class.php create mode 100644 api/oauth/taobao/callback.php create mode 100644 api/oauth/taobao/connect.php create mode 100644 api/oauth/taobao/ico.png create mode 100644 api/oauth/taobao/icon.png create mode 100644 api/oauth/taobao/index.php create mode 100644 api/oauth/taobao/init.inc.php create mode 100644 api/oauth/user.inc.php create mode 100644 api/oauth/wechat/callback.php create mode 100644 api/oauth/wechat/connect.php create mode 100644 api/oauth/wechat/ico.png create mode 100644 api/oauth/wechat/icon.png create mode 100644 api/oauth/wechat/index.php create mode 100644 api/oauth/wechat/init.inc.php create mode 100644 api/oauth/wechat/qrcode.php create mode 100644 api/oauth/wechat/style.css create mode 100644 api/online.png.php create mode 100644 api/pages.default.php create mode 100644 api/pages.sample.php create mode 100644 api/pay/alipay/icon.png create mode 100644 api/pay/alipay/index.html create mode 100644 api/pay/alipay/logo.gif create mode 100644 api/pay/alipay/md5/config.inc.php create mode 100644 api/pay/alipay/md5/index.html create mode 100644 api/pay/alipay/md5/notify.class.php create mode 100644 api/pay/alipay/md5/notify.php create mode 100644 api/pay/alipay/md5/receive.inc.php create mode 100644 api/pay/alipay/md5/send.inc.php create mode 100644 api/pay/alipay/md5/service.class.php create mode 100644 api/pay/alipay/receive.inc.php create mode 100644 api/pay/alipay/rsa2/AlipayTradePagePayContentBuilder.php create mode 100644 api/pay/alipay/rsa2/AlipayTradePagePayRequest.php create mode 100644 api/pay/alipay/rsa2/AlipayTradeService.php create mode 100644 api/pay/alipay/rsa2/AopClient.php create mode 100644 api/pay/alipay/rsa2/AopEncrypt.php create mode 100644 api/pay/alipay/rsa2/AopSdk.php create mode 100644 api/pay/alipay/rsa2/config.inc.php create mode 100644 api/pay/alipay/rsa2/index.html create mode 100644 api/pay/alipay/rsa2/notify.php create mode 100644 api/pay/alipay/rsa2/receive.inc.php create mode 100644 api/pay/alipay/rsa2/send.inc.php create mode 100644 api/pay/alipay/send.inc.php create mode 100644 api/pay/aliwap/icon.png create mode 100644 api/pay/aliwap/index.html create mode 100644 api/pay/aliwap/logo.gif create mode 100644 api/pay/aliwap/md5/config.inc.php create mode 100644 api/pay/aliwap/md5/index.html create mode 100644 api/pay/aliwap/md5/notify.class.php create mode 100644 api/pay/aliwap/md5/notify.php create mode 100644 api/pay/aliwap/md5/receive.inc.php create mode 100644 api/pay/aliwap/md5/send.inc.php create mode 100644 api/pay/aliwap/md5/submit.class.php create mode 100644 api/pay/aliwap/receive.inc.php create mode 100644 api/pay/aliwap/rsa2/AlipayTradeService.php create mode 100644 api/pay/aliwap/rsa2/AlipayTradeWapPayContentBuilder.php create mode 100644 api/pay/aliwap/rsa2/AlipayTradeWapPayRequest.php create mode 100644 api/pay/aliwap/rsa2/AopClient.php create mode 100644 api/pay/aliwap/rsa2/AopEncrypt.php create mode 100644 api/pay/aliwap/rsa2/AopSdk.php create mode 100644 api/pay/aliwap/rsa2/config.inc.php create mode 100644 api/pay/aliwap/rsa2/index.html create mode 100644 api/pay/aliwap/rsa2/notify.php create mode 100644 api/pay/aliwap/rsa2/receive.inc.php create mode 100644 api/pay/aliwap/rsa2/send.inc.php create mode 100644 api/pay/aliwap/send.inc.php create mode 100644 api/pay/chinabank/icon.png create mode 100644 api/pay/chinabank/index.html create mode 100644 api/pay/chinabank/logo.gif create mode 100644 api/pay/chinabank/notify.php create mode 100644 api/pay/chinabank/receive.inc.php create mode 100644 api/pay/chinabank/send.inc.php create mode 100644 api/pay/chinapay/icon.png create mode 100644 api/pay/chinapay/index.html create mode 100644 api/pay/chinapay/lib_curl.php create mode 100644 api/pay/chinapay/logo.gif create mode 100644 api/pay/chinapay/netpayclient.php create mode 100644 api/pay/chinapay/netpayclient_config.php create mode 100644 api/pay/chinapay/notify.php create mode 100644 api/pay/chinapay/receive.inc.php create mode 100644 api/pay/chinapay/send.inc.php create mode 100644 api/pay/index.html create mode 100644 api/pay/kq99bill/icon.png create mode 100644 api/pay/kq99bill/index.html create mode 100644 api/pay/kq99bill/logo.gif create mode 100644 api/pay/kq99bill/notify.php create mode 100644 api/pay/kq99bill/receive.inc.php create mode 100644 api/pay/kq99bill/send.inc.php create mode 100644 api/pay/paypal/icon.png create mode 100644 api/pay/paypal/index.html create mode 100644 api/pay/paypal/logo.gif create mode 100644 api/pay/paypal/notify.php create mode 100644 api/pay/paypal/receive.inc.php create mode 100644 api/pay/paypal/send.inc.php create mode 100644 api/pay/setting.inc.php create mode 100644 api/pay/success.inc.php create mode 100644 api/pay/tenpay/-icon.png create mode 100644 api/pay/tenpay/ClientResponseHandler.class.php create mode 100644 api/pay/tenpay/RequestHandler.class.php create mode 100644 api/pay/tenpay/ResponseHandler.class.php create mode 100644 api/pay/tenpay/TenpayHttpClient.class.php create mode 100644 api/pay/tenpay/config.inc.php create mode 100644 api/pay/tenpay/function.php create mode 100644 api/pay/tenpay/icon.png create mode 100644 api/pay/tenpay/index.html create mode 100644 api/pay/tenpay/logo.gif create mode 100644 api/pay/tenpay/notify.php create mode 100644 api/pay/tenpay/receive.inc.php create mode 100644 api/pay/tenpay/send.inc.php create mode 100644 api/pay/upay/acp_prod_enc.cer create mode 100644 api/pay/upay/acp_prod_verify_sign.cer create mode 100644 api/pay/upay/config.inc.php create mode 100644 api/pay/upay/icon.png create mode 100644 api/pay/upay/index.html create mode 100644 api/pay/upay/logo.gif create mode 100644 api/pay/upay/notify.php create mode 100644 api/pay/upay/receive.inc.php create mode 100644 api/pay/upay/sdk.class.php create mode 100644 api/pay/upay/send.inc.php create mode 100644 api/pay/upay/zhengshu.pfx create mode 100644 api/pay/weixin/h5api.php create mode 100644 api/pay/weixin/h5pay.php create mode 100644 api/pay/weixin/icon.png create mode 100644 api/pay/weixin/index.html create mode 100644 api/pay/weixin/jsapi.php create mode 100644 api/pay/weixin/logo.gif create mode 100644 api/pay/weixin/notify.php create mode 100644 api/pay/weixin/openid.php create mode 100644 api/pay/weixin/qrcode.php create mode 100644 api/pay/weixin/receive.inc.php create mode 100644 api/pay/weixin/send.inc.php create mode 100644 api/pay/yeepay/icon.png create mode 100644 api/pay/yeepay/index.html create mode 100644 api/pay/yeepay/logo.gif create mode 100644 api/pay/yeepay/receive.inc.php create mode 100644 api/pay/yeepay/send.inc.php create mode 100644 api/pay/yeepay/yeepayCommon.php create mode 100644 api/phpwind.inc.php create mode 100644 api/push.js.php create mode 100644 api/qrcode.png.php create mode 100644 api/redirect.php create mode 100644 api/report.php create mode 100644 api/search.php create mode 100644 api/share.php create mode 100644 api/shortcut.php create mode 100644 api/sso.inc.php create mode 100644 api/sso.php create mode 100644 api/stats.inc.php create mode 100644 api/stats/51la/index.html create mode 100644 api/stats/51la/post.inc.php create mode 100644 api/stats/51la/show.inc.php create mode 100644 api/stats/baidu/index.html create mode 100644 api/stats/baidu/post.inc.php create mode 100644 api/stats/baidu/show.inc.php create mode 100644 api/stats/cnzz/index.html create mode 100644 api/stats/cnzz/post.inc.php create mode 100644 api/stats/cnzz/show.inc.php create mode 100644 api/stats/index.html create mode 100644 api/stats/qq/index.html create mode 100644 api/stats/qq/post.inc.php create mode 100644 api/stats/qq/show.inc.php create mode 100644 api/stats/these.name.php create mode 100644 api/task.inc.php create mode 100644 api/task.js.php create mode 100644 api/uc.inc.php create mode 100644 api/uc.php create mode 100644 api/ucenter/change.log create mode 100644 api/ucenter/client.php create mode 100644 api/ucenter/control/app.php create mode 100644 api/ucenter/control/cache.php create mode 100644 api/ucenter/control/domain.php create mode 100644 api/ucenter/control/feed.php create mode 100644 api/ucenter/control/friend.php create mode 100644 api/ucenter/control/index.html create mode 100644 api/ucenter/control/mail.php create mode 100644 api/ucenter/control/pm.php create mode 100644 api/ucenter/control/tag.php create mode 100644 api/ucenter/control/user.php create mode 100644 api/ucenter/data/cache/apps.php create mode 100644 api/ucenter/data/cache/badwords.php create mode 100644 api/ucenter/data/cache/index.html create mode 100644 api/ucenter/data/cache/settings.php create mode 100644 api/ucenter/data/index.html create mode 100644 api/ucenter/index.html create mode 100644 api/ucenter/lib/db.class.php create mode 100644 api/ucenter/lib/index.html create mode 100644 api/ucenter/lib/sendmail.inc.php create mode 100644 api/ucenter/lib/uccode.class.php create mode 100644 api/ucenter/lib/xml.class.php create mode 100644 api/ucenter/model/app.php create mode 100644 api/ucenter/model/base.php create mode 100644 api/ucenter/model/cache.php create mode 100644 api/ucenter/model/domain.php create mode 100644 api/ucenter/model/friend.php create mode 100644 api/ucenter/model/index.html create mode 100644 api/ucenter/model/mail.php create mode 100644 api/ucenter/model/misc.php create mode 100644 api/ucenter/model/note.php create mode 100644 api/ucenter/model/pm.php create mode 100644 api/ucenter/model/tag.php create mode 100644 api/ucenter/model/user.php create mode 100644 api/url.inc.php create mode 100644 api/view.php create mode 100644 api/weixin/config.inc.php create mode 100644 api/weixin/down.php create mode 100644 api/weixin/image/headimg.jpg create mode 100644 api/weixin/image/index.html create mode 100644 api/weixin/image/media_image_error.gif create mode 100644 api/weixin/image/media_map.gif create mode 100644 api/weixin/image/media_map_marker.gif create mode 100644 api/weixin/image/media_upload.gif create mode 100644 api/weixin/image/media_video.gif create mode 100644 api/weixin/image/media_voice.gif create mode 100644 api/weixin/image/qrcode_error.png create mode 100644 api/weixin/image/top_bind.jpg create mode 100644 api/weixin/index.html create mode 100644 api/weixin/index.php create mode 100644 api/weixin/init.inc.php create mode 100644 api/weixin/jssdk.php create mode 100644 api/weixin/media.php create mode 100644 api/weixin/push.php create mode 100644 api/weixin/qrcode.php create mode 100644 api/weixin/qrcode_bind.php create mode 100644 api/weixin/qrcode_sign.php create mode 100644 api/wx.php create mode 100644 sell/ajax.php create mode 100644 sell/beijiao/index.html create mode 100644 sell/beijiao/list1.html create mode 100644 sell/biaopaihaocai/index.html create mode 100644 sell/biaopaihaocai/list1.html create mode 100644 sell/biaopaiji/index.html create mode 100644 sell/biaopaiji/list1.html create mode 100644 sell/biaopaiji/list2.html create mode 100644 sell/biaopaishebei/index.html create mode 100644 sell/biaopaishebei/list1.html create mode 100644 sell/biaopaishebei/list2.html create mode 100644 sell/biaopaizhizuo/index.html create mode 100644 sell/biaopaizhizuo/list1.html create mode 100644 sell/biaopaizhizuo/list2.html create mode 100644 sell/biaopaizhizuo/list3.html create mode 100644 sell/biaopaizhizuo/list4.html create mode 100644 sell/biaopaizhizuo/list5.html create mode 100644 sell/bofangqi/index.html create mode 100644 sell/bofangqi/list1.html create mode 100644 sell/buy.php create mode 100644 sell/chaobao/index.html create mode 100644 sell/chaobao/list1.html create mode 100644 sell/cheshentie/index.html create mode 100644 sell/cheshentie/list1.html create mode 100644 sell/chukong/index.html create mode 100644 sell/chukong/list1.html create mode 100644 sell/compare.php create mode 100644 sell/config.inc.php create mode 100644 sell/dabiaoji/index.html create mode 100644 sell/dabiaoji/list1.html create mode 100644 sell/dantoutie/index.html create mode 100644 sell/dantoutie/list1.html create mode 100644 sell/dayinji/index.html create mode 100644 sell/dayinji/list1.html create mode 100644 sell/dengpian/index.html create mode 100644 sell/dengpian/list1.html create mode 100644 sell/dengxiang/index.html create mode 100644 sell/dengxiang/list1.html create mode 100644 sell/dengxiang/list2.html create mode 100644 sell/dengxiangbu/index.html create mode 100644 sell/dengxiangbu/list1.html create mode 100644 sell/dianzhubiaopai/index.html create mode 100644 sell/dianzhubiaopai/list1.html create mode 100644 sell/diaokeji/index.html create mode 100644 sell/diaokeji/list1.html create mode 100644 sell/diaokeqiege/index.html create mode 100644 sell/diaokeqiege/list1.html create mode 100644 sell/guanggaoji/index.html create mode 100644 sell/guanggaoji/list1.html create mode 100644 sell/gundong/index.html create mode 100644 sell/gundong/list1.html create mode 100644 sell/hengxingzhanjia/index.html create mode 100644 sell/hengxingzhanjia/list1.html create mode 100644 sell/huwai/index.html create mode 100644 sell/huwai/list1.html create mode 100644 sell/index.html create mode 100644 sell/index.php create mode 100644 sell/inquiry.php create mode 100644 sell/jiaopian/index.html create mode 100644 sell/jiaopian/list1.html create mode 100644 sell/jiaoshui/index.html create mode 100644 sell/jiaoshui/list1.html create mode 100644 sell/jingshibiaopai/index.html create mode 100644 sell/jingshibiaopai/list1.html create mode 100644 sell/jingshibiaopai/list2.html create mode 100644 sell/jinshubiaopai/index.html create mode 100644 sell/jinshubiaopai/list1.html create mode 100644 sell/jinshubiaopai/list2.html create mode 100644 sell/keziji/index.html create mode 100644 sell/keziji/list1.html create mode 100644 sell/lawangzhanjia/index.html create mode 100644 sell/lawangzhanjia/list1.html create mode 100644 sell/led/index.html create mode 100644 sell/led/list1.html create mode 100644 sell/lengmo/index.html create mode 100644 sell/lengmo/list1.html create mode 100644 sell/list.php create mode 100644 sell/men/index.html create mode 100644 sell/men/list1.html create mode 100644 sell/moshui/index.html create mode 100644 sell/moshui/list1.html create mode 100644 sell/paoguangji/index.html create mode 100644 sell/paoguangji/list1.html create mode 100644 sell/penhui/index.html create mode 100644 sell/penhui/list1.html create mode 100644 sell/penhuiji/index.html create mode 100644 sell/penhuiji/list1.html create mode 100644 sell/penhuixiezhen/index.html create mode 100644 sell/penhuixiezhen/list1.html create mode 100644 sell/penhuixiezhen/list2.html create mode 100644 sell/penmaji/index.html create mode 100644 sell/penmaji/list1.html create mode 100644 sell/pingbandayinji/index.html create mode 100644 sell/pingbandayinji/list1.html create mode 100644 sell/putongdengxiang/index.html create mode 100644 sell/putongdengxiang/list1.html create mode 100644 sell/qiegeji/index.html create mode 100644 sell/qiegeji/list1.html create mode 100644 sell/qita/index.html create mode 100644 sell/qita/list1.html create mode 100644 sell/rezhuanyinji/index.html create mode 100644 sell/rezhuanyinji/list1.html create mode 100644 sell/ruanjian/index.html create mode 100644 sell/ruanjian/list1.html create mode 100644 sell/search.php create mode 100644 sell/shebei/index.html create mode 100644 sell/shebei/list1.html create mode 100644 sell/show.php create mode 100644 sell/shuzibiaopai/index.html create mode 100644 sell/shuzibiaopai/list1.html create mode 100644 sell/shuzibiaopai/list2.html create mode 100644 sell/siyinji/index.html create mode 100644 sell/siyinji/list1.html create mode 100644 sell/tanghuaji/index.html create mode 100644 sell/tanghuaji/list1.html create mode 100644 sell/tangjinji/index.html create mode 100644 sell/tangjinji/list1.html create mode 100644 sell/tiaofuji/index.html create mode 100644 sell/tiaofuji/list1.html create mode 100644 sell/wanggebu/index.html create mode 100644 sell/wanggebu/list1.html create mode 100644 sell/xiangzhi/index.html create mode 100644 sell/xiangzhi/list1.html create mode 100644 sell/xiezhen/index.html create mode 100644 sell/xiezhen/list1.html create mode 100644 sell/xiezhenji/index.html create mode 100644 sell/xiezhenji/list1.html create mode 100644 sell/xiezhentiaofubu/index.html create mode 100644 sell/xiezhentiaofubu/list1.html create mode 100644 sell/xisuji/index.html create mode 100644 sell/xisuji/list1.html create mode 100644 sell/xzhanjia/index.html create mode 100644 sell/xzhanjia/list1.html create mode 100644 sell/yakelibiaopai/index.html create mode 100644 sell/yakelibiaopai/list1.html create mode 100644 sell/yilabao/index.html create mode 100644 sell/yilabao/list1.html create mode 100644 sell/yindiaobu/index.html create mode 100644 sell/yindiaobu/list1.html create mode 100644 sell/yinshua/index.html create mode 100644 sell/yinshua/list1.html create mode 100644 sell/yiyinji/index.html create mode 100644 sell/yiyinji/list1.html create mode 100644 sell/youhuabu/index.html create mode 100644 sell/youhuabu/list1.html create mode 100644 sell/youmo/index.html create mode 100644 sell/youmo/list1.html create mode 100644 sell/zhanshijia/index.html create mode 100644 sell/zhanshijia/list1.html create mode 100644 sell/zizhu/index.html create mode 100644 sell/zizhu/list1.html create mode 100644 sitemap/index.php create mode 100644 special/ajax.php create mode 100644 special/config.inc.php create mode 100644 special/index.php create mode 100644 special/list.php create mode 100644 special/search.php create mode 100644 special/show.php create mode 100644 special/type.php create mode 100644 spread/index.php create mode 100644 spread/list.php create mode 100644 video/ajax.php create mode 100644 video/config.inc.php create mode 100644 video/index.php create mode 100644 video/list.php create mode 100644 video/search.php create mode 100644 video/show.php create mode 100644 vote/ajax.php create mode 100644 vote/index.php create mode 100644 vote/list.php create mode 100644 vote/show.php diff --git a/admin/admin.class.php b/admin/admin.class.php new file mode 100644 index 0000000..042194f --- /dev/null +++ b/admin/admin.class.php @@ -0,0 +1,275 @@ +__construct(); + } + + function is_member($username) { + return DB::get_one("SELECT userid FROM ".DT_PRE."member WHERE username='$username'"); + } + + function count_admin() { + $r = DB::get_one("SELECT COUNT(*) AS num FROM ".DT_PRE."member WHERE groupid=1 AND admin=1 "); + return $r['num']; + } + + function set_admin($username, $admin, $role, $aid) { + $username = trim($username); + $r = $this->is_member($username); + if(!$r) return $this->_('会员不存在'); + $userid = $r['userid']; + if(is_founder($userid)) { + $admin = 1; + $aid = 0; + } + if($admin == 1) $aid = 0; + DB::query("UPDATE ".DT_PRE."member SET groupid=1,admin=$admin,role='$role',aid=$aid WHERE userid=$userid"); + DB::query("UPDATE ".DT_PRE."company SET groupid=1 WHERE userid=$userid"); + return true; + } + + function move_admin($username) { + $r = $this->get_one($username); + if($r && $r['admin'] > 0) { + if(is_founder($r['userid'])) return $this->_('创始人不可改变级别'); + if($r['admin'] == 1 && $this->count_admin() < 2) return $this->_('系统最少需要保留一位超级管理员'); + $admin = $r['admin'] == 1 ? 2 : 1; + DB::query("UPDATE ".DT_PRE."member SET admin=$admin WHERE username='$username'"); + return true; + } else { + return $this->_('管理员不存在'); + } + } + + function delete_admin($username) { + $r = $this->get_one($username); + if($r) { + if(is_founder($r['userid'])) return $this->_('创始人不可删除'); + if($r['admin'] == 1 && $this->count_admin() < 2) return $this->_('系统最少需要保留一位超级管理员'); + $userid = $r['userid']; + $groupid = $r['regid'] ? $r['regid'] : 6; + DB::query("UPDATE ".DT_PRE."member SET groupid=$groupid,admin=0,role='',aid=0 WHERE userid=$userid"); + DB::query("UPDATE ".DT_PRE."company SET groupid=$groupid WHERE userid=$userid"); + DB::query("DELETE FROM ".DT_PRE."admin WHERE userid=$userid"); + cache_delete('menu-'.$userid.'.php'); + cache_delete('right-'.$userid.'.php'); + return true; + } else { + return $this->_('会员不存在'); + } + } + + function get_one($user, $type = 1) { + $fields = $type ? 'username' : 'userid'; + return DB::get_one("SELECT * FROM ".DT_PRE."member WHERE `$fields`='$user'"); + } + + function get_list($condition, $order = 'admin ASC,userid ASC') { + global $pages, $page, $pagesize, $offset, $pagesize, $CFG, $sum; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = DB::get_one("SELECT COUNT(*) AS num FROM ".DT_PRE."member WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $admins = array(); + $result = DB::query("SELECT * FROM ".DT_PRE."member WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $r['logintime'] = timetodate($r['logintime'], 5); + $r['adminname'] = $r['admin'] == 1 ? (is_founder($r['userid']) ? '网站创始人' : '超级管理员') : '普通管理员'; + $admins[] = $r; + } + return $admins; + } + + function get_right($userid) { + global $MODULE; + $rights = array(); + $result = DB::query("SELECT * FROM ".DT_PRE."admin WHERE userid=$userid AND url='' ORDER BY moduleid DESC,file DESC,adminid DESC "); + while($r = DB::fetch_array($result)) { + @include DT_ROOT.'/'.($r['moduleid'] == 1 ? 'admin' : 'module/'.$MODULE[$r['moduleid']]['module'].'/admin').'/config.inc.php'; + $r['name'] = isset($RT['file'][$r['file']]) ? '('.$RT['file'][$r['file']].')' : ''; + $r['module'] = '('.$MODULE[$r['moduleid']]['name'].')'; + $rights[] = $r; + } + return $rights; + } + + function get_menu($userid) { + $menus = array(); + $result = DB::query("SELECT * FROM ".DT_PRE."admin WHERE userid=$userid AND url!='' ORDER BY listorder ASC,adminid ASC "); + while($r = DB::fetch_array($result)) { + $menus[] = $r; + } + return $menus; + } + + function update($userid, $right, $admin) { + if(isset($right[-1])) { + $this->add($userid, $right[-1], $admin); + unset($right[-1]); + $type = 1;//right + } else { + $type = 0;//menu + } + $this->add($userid, $right[0], $admin); + unset($right[0]); + foreach($right as $k=>$v) { + if(isset($v['delete'])) { + $this->delete($k); + unset($right[$k]); + } + } + $this->edit($right, $type); + if($admin == 1) DB::query("DELETE FROM ".DT_PRE."admin WHERE userid=$userid AND url=''"); + $this->cache_right($userid); + $this->cache_menu($userid); + return true; + } + + function add($userid, $right, $admin) { + if(isset($right['url'])) { + if(!$right['title'] || !$right['url']) return false; + $r = DB::get_one("SELECT * FROM ".DT_PRE."admin WHERE userid=$userid AND url='".$right['url']."'"); + if($r) return false; + if($admin == 2 && defined('MANAGE_ADMIN')) { + $r = $this->url_right($right['url']); + if($r) $this->add($userid, $r, $admin); + } + } else { + $right['moduleid'] = intval($right['moduleid']); + if(!$right['moduleid']) return false; + $_right = $this->get_right($userid); + foreach($_right as $v) {//module admin + if($v['file'] == '' && $v['moduleid'] == $right['moduleid']) return false; + } + if($right['file']) {//file exists + foreach($_right as $v) { + if($v['file'] == $right['file'] && $v['moduleid'] == $right['moduleid']) return false; + } + } else { + unset($right['action'], $right['catid']); + } + } + $right['userid'] = $userid; + $sql1 = $sql2 = ''; + foreach($right as $k=>$v) { + $sql1 .= ','.$k; + $sql2 .= ",'$v'"; + } + $sql1 = substr($sql1, 1); + $sql2 = substr($sql2, 1); + DB::query("INSERT INTO ".DT_PRE."admin ($sql1) VALUES($sql2)"); + } + + function edit($right, $type = 0) { + if($type) { + //when module admin, have all rights + $moduleids = $adminids = array(); + foreach($right as $k=>$v) { + if(!$v['file']) { + $moduleids[] = $v['moduleid']; + $adminids[$v['moduleid']] = $k; + $right[$k]['action'] = $right[$k]['catid'] = ''; + } + } + if($moduleids) { + foreach($right as $k=>$v) { + if(in_array($v['moduleid'], $moduleids) && !in_array($k, $adminids)) { + unset($right[$k]); + $this->delete($k); + } + } + } + } + foreach($right as $key=>$value) { + if(isset($value['title'])) { + if(!$value['title'] || !$value['url']) continue; + } else { + $value['moduleid'] = intval($value['moduleid']); + if(!$value['moduleid']) continue; + } + $sql = ''; + foreach($value as $k=>$v) { + $sql .= ",$k='$v'"; + } + $sql = substr($sql, 1); + DB::query("UPDATE ".DT_PRE."admin SET $sql WHERE adminid='$key'"); + } + } + + function url_right($url) { + if(substr($url, 0, 1) == '?') $url = substr($url, 1); + $arr = array(); + parse_str($url, $arr); + $arr['moduleid'] = isset($moduleid) ? $moduleid : 1; + $arr['file'] = isset($file) ? $file : 'index'; + $arr['action'] = isset($action) ? $action : ''; + return $arr; + } + + function cache_right($userid) { + $rights = $this->get_right($userid); + $right = $moduleids = array(); + foreach($rights as $v) {//get moduleids + isset($moduleids[$v['moduleid']]) or $moduleids[$v['moduleid']] = $v['moduleid']; + } + foreach($moduleids as $m) {//get rights + foreach($rights as $r) { + if($r['moduleid'] == $m) { + $r['file'] = $r['file'] ? $r['file'] : 'NA'; + $right[$m][$r['file']]['action'] = $r['action'] ? explode('|', $r['action']) : ''; + $right[$m][$r['file']]['catid'] = $r['catid'] ? explode('|', $r['catid']) : ''; + } + } + } + foreach($right as $k=>$v) { + if(isset($v['NA'])) $right[$k] = ''; + } + foreach($right as $k=>$v) { + if($v) { + foreach($v as $i=>$j) { + if(!$j['action'] && !$j['catid']) $right[$k][$i] = ''; + } + } + } + cache_write('right-'.$userid.'.php', $right); + } + + function cache_menu($userid) { + $menus = $this->get_menu($userid); + $menu = $r = array(); + foreach($menus as $k=>$v) { + $r['title'] = $v['title']; + $r['style'] = $v['style']; + $r['url'] = $v['url']; + $menu[] = $r; + } + cache_write('admin-menu-'.$userid.'.php', $menu); + cache_write('menu-'.$userid.'.php', $menu); + } + + function delete($adminid) { + DB::query("DELETE FROM ".DT_PRE."admin WHERE adminid=$adminid"); + } + + function _($e) { + $this->errmsg = $e; + return false; + } +} +?> \ No newline at end of file diff --git a/admin/admin.inc.php b/admin/admin.inc.php new file mode 100644 index 0000000..8b32467 --- /dev/null +++ b/admin/admin.inc.php @@ -0,0 +1,365 @@ +set_admin($username, $admin, $role, $aid)) { + $r = $do->get_one($username); + $userid = $r['userid']; + if($r['admin'] == 2) { + foreach($MODULE as $m) { + if(isset($roles[$m['moduleid']])) { + $right = array(); + $right['title'] = $m['name'].'管理'; + $right['url'] = '?moduleid='.$m['moduleid']; + $do->add($userid, $right, $admin); + } + } + if(isset($roles['database'])) { + $right = array(); + $right['title'] = '数据库管理'; + $right['url'] = '?file=database'; + $do->add($userid, $right, $admin); + } + if(isset($roles['template'])) { + $right = array(); + $right['title'] = '模板管理'; + $right['url'] = '?file=template'; + $do->add($userid, $right, $admin); + $right = array(); + $right['title'] = '风格管理'; + $right['url'] = '?file=skin'; + $do->add($userid, $right, $admin); + $right = array(); + $right['title'] = '标签向导'; + $right['url'] = '?file=tag'; + $do->add($userid, $right, $admin); + } + $do->cache_right($userid); + $do->cache_menu($userid); + } + msg('管理员添加成功,下一步请分配权限和管理面板', '?file='.$file.'&id='.$userid.'&tm='.($DT_TIME+5)); + } + msg($do->errmsg); + } else { + isset($username) or $username = ''; + include tpl('admin_add'); + } + break; + case 'edit': + if($submit) { + $admin = $admin == 1 ? 1 : 2; + if($do->set_admin($username, $admin, $role, $aid)) { + $r = $do->get_one($username); + $userid = $r['userid']; + if($r['admin'] == 2) { + $do->cache_right($userid); + $do->cache_menu($userid); + } + dmsg('修改成功', '?file='.$file); + } + msg($do->errmsg); + } else { + if(!$userid) msg(); + $user = $do->get_one($userid, 0); + include tpl('admin_edit'); + } + break; + case 'temp': + $link = ''; + $link_user = $_username; + $link_minute = 60; + $link_ip = ''; + if($submit) { + if($_founder) { + $username = trim($username); + if($username == $_username) { + // + } else { + check_name($username) or msg('用户格式错误'); + $user = userinfo($username); + $user or msg('用户'.$username.'不存在'); + ($user['groupid'] == 1 && $user['admin'] > 0) or msg('用户'.$username.'非管理员'); + } + $link_user = $username; + } else { + $link_user = $username = $_username; + } + $minute = intval($minute); + if($minute < 10) $minute = 10; + if($minute > 600) $minute = 30; + $link_minute = $minute; + $ip = trim($ip); + $link_ip = $ip; + $expiry = $minute*60; + $auth = $username.'|'.(DT_TIME + $expiry).'|'.$ip; + $link = DT_PATH.basename(get_env('self')).'?file=login&action=temp&auth='.encrypt($auth, DT_KEY.'TMPA', $expiry); + if(strpos(get_env('self'), '/admin.php') !== false) $link = '后台地址未修改,暂不支持临时授权'; + } + include tpl('admin_temp'); + break; + case 'delete': + if($do->delete_admin($username)) dmsg('撤销成功', $this_forward); + msg($do->errmsg); + break; + case 'right': + if(!$userid) msg(); + $user = $do->get_one($userid, 0); + if($submit) { + $right[0]['action'] = $right[0]['action'] ? implode('|', $right[0]['action']) : ''; + $right[0]['catid'] = $right[0]['catid'] ? implode('|', $right[0]['catid']) : ''; + if($do->update($userid, $right, $user['admin'])) { + dmsg('更新成功', '?file='.$file.'&action=right&userid='.$userid); + } + msg($do->errmsg); + } else { + $username = $user['username']; + $drights = $do->get_right($userid); + $dmenus = $do->get_menu($userid); + include tpl('admin_right'); + } + break; + case 'ajax': + @include DT_ROOT.'/'.($mid == 1 ? 'admin' : 'module/'.$MODULE[$mid]['module'].'/admin').'/config.inc.php'; + if(isset($fi)) { + if(isset($RT) && isset($RT['action'][$fi])) { + $action_select = ''; + echo $action_select; + } else { + echo '0'; + } + } else { + if(isset($RT)) { + $file_select = ''; + echo $file_select.'|'; + if($CT) { + $CATEGORY = cache_read('category-'.$mid.'.php'); + echo ''; + } else { + echo '0'; + } + } else { + echo '0|0'; + } + } + break; + case 'online': + $lastime = $DT_TIME - $DT['online']; + $db->query("DELETE FROM {$DT_PRE}admin_online WHERE lasttime<$lastime"); + $sid = session_id(); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}admin_online ORDER BY lasttime DESC"); + while($r = $db->fetch_array($result)) { + $r['lasttime'] = timetodate($r['lasttime'], 'H:i:s'); + $lists[] = $r; + } + include tpl('admin_online'); + break; + case 'clear': + $time = $DT_TODAY - 30*86400; + $db->query("DELETE FROM {$DT_PRE}admin_log WHERE logtime<$time"); + dmsg('清理成功', '?file='.$file.'&action=log'); + break; + case 'log': + $F = array( + 'index' => '列表', + 'setting' => '设置', + 'category' => '栏目管理', + 'type' => '分类管理', + 'keylink' => '关联链接', + 'split' => '数据拆分', + 'html' => '更新数据', + 'mymenu' => '定义面板', + 'module' => '模块管理', + 'area' => '地区管理', + 'admin' => '管理设置', + 'database' => '数据维护', + 'data' => '数据处理', + 'template' => '模板管理', + 'tag' => '标签向导', + 'skin' => '风格管理', + 'md5' => '文件校验', + 'scan' => '木马扫描', + 'stats' => '流量统计', + 'upload' => '上传记录', + '404' => '404日志', + 'patch' => '文件维护', + 'keyword' => '搜索记录', + 'question' => '问题验证', + 'banword' => '词语过滤', + 'repeat' => '重名检测', + 'banip' => '禁止IP', + 'fetch' => '单页采编', + 'word' => '编辑助手', + 'doctor' => '系统体检', + + 'contact' => '联系会员', + 'group' => '会员组', + 'validate' => '资料审核', + 'grade' => '会员升级', + 'weixin' => '微信管理', + 'oauth' => '一键登录', + + 'child' => '子账号', + 'stock' => '商品库存', + 'honor' => '荣誉资质', + 'news' => '公司新闻', + 'page' => '公司单页', + 'link' => '友情链接', + 'style' => '公司模板', + + 'record' => '资金管理', + 'credit' => '积分管理', + 'sms' => '短信管理', + 'charge' => '支付记录', + 'cash' => '提现记录', + 'pay' => '信息支付', + 'award' => '信息打赏', + 'promo' => '优惠促销', + 'deposit' => '保证金', + 'card' => '充值卡', + + 'chat' => '在线交谈', + 'message' => '站内信件', + 'sendmail' => '电子邮件', + 'sendsms' => '手机短信', + 'ask' => '客服中心', + 'friend' => '会员好友', + 'favorite' => '站内收藏', + 'address' => '收货地址', + 'alert' => '贸易提醒', + 'validate' => '资料认证', + 'mail' => '邮件订阅', + 'loginlog' => '登录日志', + + 'spread' => '排名推广', + 'ad' => '广告管理', + 'announce' => '公告管理', + 'webpage' => '单页管理', + 'comment' => '评论管理', + 'guestbook' => '留言管理', + 'vote' => '投票管理', + 'gift' => '积分换礼', + 'poll' => '票选管理', + 'form' => '表单管理', + + 'expert' => '知道专家', + 'answer' => '知道答案', + 'product' => '行情产品', + 'resume' => '简历', + 'price' => '报价', + 'order' => '订单管理', + ); + $A = array( + 'add' => '添加', + 'edit' => '修改', + 'delete' => '删除', + 'clear' => '清理', + 'check' => '待审核', + 'reject' => '未通过', + 'expire' => '已过期', + 'recycle' => '回收站', + 'level' => '级别', + 'order' => '排序', + 'html' => '更新', + 'update' => '更新', + 'send' => '发送', + 'move' => '移动', + ); + $sfields = array('按条件', '网址', '管理员', 'IP'); + $dfields = array('qstring', 'qstring', 'username', 'ip'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $ip = isset($ip) ? $ip : ''; + (isset($username) && check_name($username)) or $username = ''; + (isset($fromdate) && is_time($fromdate)) or $fromdate = ''; + $fromtime = $fromdate ? datetotime($fromdate) : 0; + (isset($todate) && is_time($todate)) or $todate = ''; + $totime = $todate ? datetotime($todate) : 0; + + $fields_select = dselect($sfields, 'fields', '', $fields); + + $condition = '1'; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + if($fromtime) $condition .= " AND logtime>=$fromtime"; + if($totime) $condition .= " AND logtime<=$totime"; + if($ip) $condition .= " AND ip='$ip'"; + if($username) $condition .= " AND username='$username'"; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}admin_log WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}admin_log WHERE $condition ORDER BY logid DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + parse_str($r['qstring'], $t); + $m = isset($t['moduleid']) ? $t['moduleid'] : 1; + $r['mid'] = $m; + $r['module_name'] = $MODULE[$m]['name']; + $r['file'] = $f = isset($t['file']) ? $t['file'] : 'index'; + if(isset($F[$f])) $f = $F[$f]; + $r['file_name'] = $f; + $r['action'] = $a = isset($t['action']) ? $t['action'] : ''; + if(isset($A[$a])) $a = $A[$a]; + $r['action_name'] = $a; + $i = isset($t['itemid']) ? $t['itemid'] : (isset($t['userid']) ? $t['userid'] : ''); + $r['itemid'] = $i; + $r['logtime'] = timetodate($r['logtime'], 6); + $lists[] = $r; + } + include tpl('admin_log'); + break; + default: + $sfields = array('按条件', '用户名', '姓名', '角色'); + $dfields = array('username', 'username', 'truename', 'role'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $sorder = array('结果排序方式', '登录时间降序', '登录时间升序', '登录次数降序', '登录次数升序', '会员ID降序', '会员ID升序'); + $dorder = array('admin ASC,userid ASC', 'logintime DESC', 'logintime ASC', 'logintimes DESC', 'logintimes ASC', 'userid DESC', 'userid ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + $type = isset($type) ? intval($type) : 0; + $areaid = isset($areaid) ? intval($areaid) : 0; + + $fields_select = dselect($sfields, 'fields', '', $fields); + $order_select = dselect($sorder, 'order', '', $order); + + $condition = 'groupid=1 AND admin>0'; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + if($type) $condition .= " AND admin=$type"; + if($areaid) $condition .= ($AREA[$areaid]['child']) ? " AND aid IN (".$AREA[$areaid]['arrchildid'].")" : " AND aid=$areaid"; + $lists = $do->get_list($condition, $dorder[$order]); + include tpl('admin'); + break; +} +?> \ No newline at end of file diff --git a/admin/admin_check.inc.php b/admin/admin_check.inc.php new file mode 100644 index 0000000..270b9cb --- /dev/null +++ b/admin/admin_check.inc.php @@ -0,0 +1,49 @@ +query("SELECT arrchildid FROM {$DT_PRE}category WHERE catid IN ($_catids)"); + while($r = $db->fetch_array($result)) { + if($r['arrchildid']) $_childs .= ','.$r['arrchildid']; + } + if($_childs) { + $_childs = substr($_childs, 1); + $_child = explode(',', $_childs); + if($catid && !in_array($catid, $_child)) msg('您无权进行此操作 Error(10)'); + if(isset($post['catid']) && $post['catid'] && !in_array($post['catid'], $_child)) msg('您无权进行此操作 Error(11)'); + if($itemid) { + if(is_array($itemid)) { + foreach($itemid as $_itemid) { + item_check($_itemid) or msg('您无权进行此操作 Error(12)'); + } + } else { + item_check($itemid) or msg('您无权进行此操作 Error(13)'); + } + } + } +} +//CITY +if($_areaids) { + if($areaid == 0) { + $areaid = $_aid; + $ARE = $AREA[$areaid]; + } else { + if(!in_array($areaid, $_areaid)) msg('您无权进行此操作 Error(20)'); + } + if(isset($post['areaid']) && $post['areaid'] && !in_array($post['areaid'], $_areaid)) msg('您无权进行此操作 Error(21)'); + if($itemid) { + if(is_array($itemid)) { + foreach($itemid as $_itemid) { + city_check($_itemid) or msg('您无权进行此操作 Error(22)'); + } + } else { + city_check($itemid) or msg('您无权进行此操作 Error(23)'); + } + } +} +?> \ No newline at end of file diff --git a/admin/area.inc.php b/admin/area.inc.php new file mode 100644 index 0000000..bfe19aa --- /dev/null +++ b/admin/area.inc.php @@ -0,0 +1,201 @@ +add($area); + } else { + $areanames = explode("\n", $area['areaname']); + foreach($areanames as $areaname) { + $areaname = trim($areaname); + if(!$areaname) continue; + $area['areaname'] = $areaname; + $do->add($area); + } + } + $do->repair(); + dmsg('添加成功', $this_forward); + } else { + include tpl('area_add'); + } + break; + case 'import': + $file = DT_ROOT.'/file/setting/area.sql'; + is_file($file) or msg('数据文件不存在,请上传程序包内 file/setting/area.sql 文件至 file/setting 目录'); + require DT_ROOT.'/include/sql.func.php'; + sql_execute(file_get($file)); + cache_area(); + dmsg('导入成功', $this_forward); + break; + case 'cache': + $do->repair(); + dmsg('更新成功', $forward); + break; + case 'delete': + if($areaid) $areaids = $areaid; + $areaids or msg(); + $do->delete($areaids); + dmsg('删除成功', $this_forward); + break; + case 'update': + if(!$area || !is_array($area)) msg(); + $do->update($area); + dmsg('更新成功', $this_forward); + break; + default: + $DAREA = array(); + $condition = $keyword ? "areaname LIKE '%$keyword%'" : "parentid=$parentid"; + $result = $db->query("SELECT * FROM {$table} WHERE $condition ORDER BY listorder,areaid"); + while($r = $db->fetch_array($result)) { + $r['childs'] = substr_count($r['arrchildid'], ','); + $DAREA[$r['areaid']] = $r; + } + include tpl('area'); + break; +} + +class area { + var $areaid; + var $area = array(); + var $table; + + function __construct($areaid = 0) { + global $AREA; + $this->areaid = $areaid; + $this->area = $AREA; + $this->table = DT_PRE.'area'; + } + + function area($areaid = 0) { + $this->__construct($areaid); + } + + function add($area) { + if(!is_array($area)) return false; + $sql1 = $sql2 = $s = ''; + foreach($area as $key=>$value) { + $sql1 .= $s.$key; + $sql2 .= $s."'".$value."'"; + $s = ','; + } + DB::query("INSERT INTO {$this->table} ($sql1) VALUES($sql2)"); + $this->areaid = DB::insert_id(); + if($area['parentid']) { + $area['areaid'] = $this->areaid; + $this->area[$this->areaid] = $area; + $arrparentid = $this->get_arrparentid($this->areaid); + } else { + $arrparentid = 0; + } + DB::query("UPDATE {$this->table} SET arrchildid='$this->areaid',listorder=$this->areaid,arrparentid='$arrparentid' WHERE areaid=$this->areaid"); + return true; + } + + function delete($areaids) { + if(is_array($areaids)) { + foreach($areaids as $areaid) { + if(isset($this->area[$areaid])) { + $arrchildid = $this->area[$areaid]['arrchildid']; + DB::query("DELETE FROM {$this->table} WHERE areaid IN ($arrchildid)"); + } + } + } else { + $areaid = $areaids; + if(isset($this->area[$areaid])) { + $arrchildid = $this->area[$areaid]['arrchildid']; + DB::query("DELETE FROM {$this->table} WHERE areaid IN ($arrchildid)"); + } + } + $this->repair(); + return true; + } + + function update($area) { + if(!is_array($area)) return false; + foreach($area as $k=>$v) { + if(!$v['areaname']) continue; + $v['parentid'] = intval($v['parentid']); + if($k == $v['parentid']) continue; + if($v['parentid'] > 0 && !isset($this->area[$v['parentid']])) continue; + $v['listorder'] = intval($v['listorder']); + DB::query("UPDATE {$this->table} SET areaname='$v[areaname]',parentid='$v[parentid]',listorder='$v[listorder]' WHERE areaid=$k"); + } + cache_area(); + return true; + } + + function repair() { + $query = DB::query("SELECT * FROM {$this->table} ORDER BY listorder,areaid"); + $AREA = array(); + while($r = DB::fetch_array($query)) { + $AREA[$r['areaid']] = $r; + } + $childs = array(); + foreach($AREA as $areaid => $area) { + $arrparentid = $this->get_arrparentid($areaid); + DB::query("UPDATE {$this->table} SET arrparentid='$arrparentid' WHERE areaid=$areaid"); + if($arrparentid) { + $arr = explode(',', $arrparentid); + foreach($arr as $a) { + if($a == 0) continue; + isset($childs[$a]) or $childs[$a] = ''; + $childs[$a] .= ','.$areaid; + } + } + } + foreach($AREA as $areaid => $area) { + if(isset($childs[$areaid])) { + $arrchildid = $areaid.$childs[$areaid]; + DB::query("UPDATE {$this->table} SET arrchildid='$arrchildid',child=1 WHERE areaid='$areaid'"); + } else { + DB::query("UPDATE {$this->table} SET arrchildid='$areaid',child=0 WHERE areaid='$areaid'"); + } + } + cache_area(); + return true; + } + + function get_arrparentid($areaid) { + $ARE = get_area($areaid); + if($ARE['parentid'] && $ARE['parentid'] != $areaid) { + $parents = array(); + $cid = $areaid; + $i = 1; + while($i++ < 10) { + $ARE = get_area($cid); + if($ARE['parentid']) { + $parents[] = $cid = $ARE['parentid']; + } else { + break; + } + } + $parents[] = 0; + return implode(',', array_reverse($parents)); + } else { + return '0'; + } + } +} +?> \ No newline at end of file diff --git a/admin/banip.inc.php b/admin/banip.inc.php new file mode 100644 index 0000000..1b4e5e1 --- /dev/null +++ b/admin/banip.inc.php @@ -0,0 +1,128 @@ + 50) msg('禁止内容限3-50字符'); + if($ip == DT_IP) msg('不能禁用自己的IP'); + //if(!preg_match("/^[0-9]{1,3}\.[0-9\*]{1,3}\.[0-9\*]{1,3}\.[0-9\*]{1,3}$/", $ip)) msg('IP地址或IP段格式错误'); + $note = dhtmlspecialchars(trim($note)); + $totime = is_time($totime) ? datetotime($totime) : 0; + $db->query("INSERT INTO {$DT_PRE}banip (ip,editor,addtime,totime,note) VALUES ('$ip','$_username','$DT_TIME','$totime','$note')"); + cache_banip(); + dmsg('添加成功', '?file='.$file); + } else { + isset($ip) or $ip = ''; + $totime = ''; + include tpl('banip_edit'); + } + break; + case 'delete': + $itemid or msg('请选择项目'); + $itemids = is_array($itemid) ? implode(',', $itemid) : $itemid; + $db->query("DELETE FROM {$DT_PRE}banip WHERE itemid IN ($itemids)"); + cache_banip(); + dmsg('删除成功', '?file='.$file); + break; + case 'clear': + $db->query("DELETE FROM {$DT_PRE}banip WHERE totime>0 and totime<$DT_TIME"); + cache_banip(); + dmsg('清空成功', '?file='.$file); + break; + case 'unban': + $ip or msg('IP不能为空'); + if(is_array($ip)) { + foreach($ip as $v) { + file_del(DT_CACHE.'/ban/'.$v.'.php'); + } + } else { + file_del(DT_CACHE.'/ban/'.$ip.'.php'); + } + dmsg('删除成功', '?file='.$file.'&action=ban'); + break; + case 'down': + dheader($http.'wry.rar'); + break; + case 'update': + $wry = DT_ROOT.'/file/ipdata/wry.dat'; + $new = file_get($http.'wry.txt'); + is_date($new) or msg('无法连接更新服务器'); + if(is_file($wry)) { + $now = timetodate(filemtime($wry), 'Ymd'); + $new > $now or msg('已是最新版本,无需更新'); + rename($wry, DT_ROOT.'/file/ipdata/'.$now.'.dat'); + } + file_copy($http.'wry.dat', $wry); + is_file($wry) or msg('更新失败,请重试'); + @touch($wry, datetotime($new)); + dmsg('更新成功', '?file='.$file.'&action=data'); + break; + case 'data': + $wry = DT_ROOT.'/file/ipdata/wry.dat'; + $new = file_get($http.'wry.txt'); + $get = 0; + $update = 0; + if(is_date($new)) { + $get = 1; + } else { + $new = '获取失败'; + } + if(is_file($wry)) { + $now = timetodate(filemtime($wry), 'Ymd'); + if($get && $new > $now) $update = 1; + } else { + $now = '文件不存在'; + $update =1; + } + include tpl('banip_data'); + break; + case 'login': + $ips = glob(DT_CACHE.'/ban/*.php'); + $lists = array(); + if($ips) { + foreach($ips as $k=>$v) { + $lists[$k]['ip'] = basename($v, '.php'); + $lists[$k]['addtime'] = timetodate(filemtime($v), 5); + } + } + include tpl('banip_login'); + break; + default: + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}banip"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}banip ORDER BY itemid DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + if(is_ip($r['ip'])) { + $r['type'] = ip2area($r['ip']); + } else if(preg_match("/^[0-9]{1,3}\.[0-9\*]{1,3}\.[0-9\*]{1,3}\.[0-9\*]{1,3}$/", $r['ip'])) { + $r['type'] = 'IP段'; + } else { + $r['type'] = '客户端'; + } + $r['addtime'] = timetodate($r['addtime'], 5); + $r['status'] = ($r['totime'] && $DT_TIME > $r['totime']) ? '过期' : '有效'; + $r['totime'] = $r['totime'] ? timetodate($r['totime'], 3) : '永久'; + $lists[] = $r; + } + include tpl('banip'); + break; +} +?> \ No newline at end of file diff --git a/admin/banword.inc.php b/admin/banword.inc.php new file mode 100644 index 0000000..e2bd941 --- /dev/null +++ b/admin/banword.inc.php @@ -0,0 +1,82 @@ +update($post); + dmsg('保存成功', '?file='.$file.'&item='.$item); +} else { + $condition = "1"; + if($keyword) $condition .= " AND (replacefrom LIKE '%$keyword%' OR replaceto LIKE '%$keyword%')"; + $lists = $do->get_list($condition); + include tpl('banword'); +} + +class banword { + var $table; + + function __construct() { + $this->table = DT_PRE.'banword'; + } + + function banword() { + $this->__construct(); + } + + function get_list($condition) { + global $pages, $page, $pagesize, $offset, $pagesize; + $pages = pages(DB::count($this->table, $condition), $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE $condition ORDER BY bid DESC LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $lists[] = $r; + } + return $lists; + } + + function update($post) { + $this->add($post[0]); + unset($post[0]); + foreach($post as $k=>$v) { + if(isset($v['delete'])) { + $this->delete($k); + unset($post[$k]); + } + } + $this->edit($post); + cache_banword(); + } + + function add($post) { + if(!$post['replacefrom']) return false; + $post['deny'] = in_array($post['deny'], array(0, 1, 2)) ? $post['deny'] : 0; + $F = explode("\n", $post['replacefrom']); + $T = explode("\n", $post['replaceto']); + foreach($F as $k=>$f) { + $f = trim($f); + if($f) { + $t = isset($T[$k]) ? trim($T[$k]) : ''; + if($f != $t) DB::query("INSERT INTO {$this->table} (replacefrom,replaceto,deny) VALUES('$f','$t','$post[deny]')"); + } + } + } + + function edit($post) { + foreach($post as $k=>$v) { + if(!$v['replacefrom']) continue; + $v['deny'] = in_array($v['deny'], array(0, 1, 2)) ? $v['deny'] : 0; + if($v['replacefrom'] != $v['replaceto']) DB::query("UPDATE {$this->table} SET replacefrom='$v[replacefrom]',replaceto='$v[replaceto]',deny='$v[deny]' WHERE bid='$k'"); + } + } + + function delete($bid) { + DB::query("DELETE FROM {$this->table} WHERE bid=$bid"); + } +} +?> \ No newline at end of file diff --git a/admin/cate.inc.php b/admin/cate.inc.php new file mode 100644 index 0000000..78f9e9c --- /dev/null +++ b/admin/cate.inc.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/admin/category.inc.php b/admin/category.inc.php new file mode 100644 index 0000000..9a4bb97 --- /dev/null +++ b/admin/category.inc.php @@ -0,0 +1,432 @@ +get_catdir($category['catdir']); + $do->add($category); + $childs .= ','.$do->catid; + $catids[] = $do->catid; + } else { + $catnames = explode("\n", $category['catname']); + foreach($catnames as $catname) { + $catname = trim($catname); + if(!$catname) continue; + $category['catname'] = $catname; + $category['catdir'] = ''; + $category['letter'] = ''; + $category['seo_title'] = ''; + $category['seo_keywords'] = ''; + $category['seo_description'] = ''; + $do->add($category); + $childs .= ','.$do->catid; + $catids[] = $do->catid; + } + } + if($category['parentid']) { + $parents = array(); + $cid = $category['parentid']; + $parents[] = $cid; + while(1) { + if($CATEGORY[$cid]['parentid']) { + $parents[] = $cid = $CATEGORY[$cid]['parentid']; + } else { + break; + } + } + foreach($parents as $catid) { + $arrchildid = $CATEGORY[$catid]['child'] ? $CATEGORY[$catid]['arrchildid'].$childs : $catid.$childs; + $db->query("UPDATE {$table} SET child=1,arrchildid='$arrchildid' WHERE catid=$catid"); + } + } + foreach($catids as $catid) { + $CATEGORY[$catid] = $db->get_one("SELECT * FROM {$table} WHERE catid=$catid"); + update_category($CATEGORY[$catid]); + } + $NUM > 500 ? $do->cache() : $do->repair(); + dmsg('添加成功', '?file='.$file.'&mid='.$mid.'&parentid='.$category['parentid']); + } else { + include tpl('category_add'); + } + break; + case 'edit': + $catid or msg(); + if($submit) { + if(!$category['catname']) msg('分类名不能为空'); + if($category['parentid'] == $catid) msg('上级分类不能与当前分类相同'); + $do->edit($category); + $category['catid'] = $catid; + update_category($category); + $NUM > 500 ? $do->cache() : $do->repair(); + dmsg('修改成功', '?file='.$file.'&mid='.$mid.'&parentid='.$category['parentid']); + } else { + extract($db->get_one("SELECT * FROM {$table} WHERE catid=$catid")); + include tpl('category_edit'); + } + break; + case 'copy': + if($submit) { + if(!$fromid) msg('源模块ID不能为空'); + if(!$save) $db->query("DELETE FROM {$table} WHERE moduleid=$mid"); + $result = $db->query("SELECT * FROM {$table} WHERE moduleid=$fromid ORDER BY catid"); + $O = $R = array(); + while($r = $db->fetch_array($result)) { + $O[$r['catid']] = $r['catname']; + $sqlk = $sqlv = ''; + $catid = $r['catid']; + unset($r['catid']); + $r['moduleid'] = $mid; + $r['item'] = $r['property'] = 0; + $r = daddslashes($r); + foreach($r as $k=>$v) { + $sqlk .= ','.$k; $sqlv .= ",'$v'"; + } + $sqlk = substr($sqlk, 1); + $sqlv = substr($sqlv, 1); + $db->query("INSERT INTO {$table} ($sqlk) VALUES ($sqlv)"); + $R[$catid] = $db->insert_id(); + } + $result = $db->query("SELECT * FROM {$table} WHERE moduleid='$mid' ORDER BY catid"); + while($r = $db->fetch_array($result)) { + $catid = $r['catid']; + $v = $r['parentid']; + $parentid = isset($R[$v]) ? $R[$v] : $v; + $arrparentid = explode(',', $r['arrparentid']); + foreach($arrparentid as $k=>$v) { + if(isset($R[$v])) $arrparentid[$k] = $R[$v]; + } + $arrparentid = implode(',', $arrparentid); + $arrchildid = explode(',', $r['arrchildid']); + foreach($arrchildid as $k=>$v) { + if(isset($R[$v])) $arrchildid[$k] = $R[$v]; + } + $arrchildid = implode(',', $arrchildid); + $db->query("UPDATE {$table} SET parentid='$parentid',arrparentid='$arrparentid',arrchildid='$arrchildid' WHERE catid=$catid"); + } + $do->repair(); + msg('分类复制成功', '?file='.$file.'&action=url&&mid='.$mid.'&forward='.urlencode('?file='.$file.'&mid='.$mid)); + } else { + include tpl('category_copy'); + } + break; + case 'caches': + msg('开始更新统计', "?file=$file&mid=$mid&action=count"); + break; + case 'count': + require DT_ROOT.'/include/module.func.php'; + $tb = get_table($mid); + if($MODULE[$mid]['module'] == 'club') $tb = $DT_PRE.'club_group_'.$mid; + if(!isset($num)) { + $num = 50; + } + if(!isset($fid)) { + $r = $db->get_one("SELECT MIN(catid) AS fid FROM {$table} WHERE moduleid=$mid"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + isset($sid) or $sid = $fid; + if(!isset($tid)) { + $r = $db->get_one("SELECT MAX(catid) AS tid FROM {$table} WHERE moduleid=$mid"); + $tid = $r['tid'] ? $r['tid'] : 0; + } + if($fid <= $tid) { + $result = $db->query("SELECT catid FROM {$table} WHERE moduleid=$mid AND catid>=$fid ORDER BY catid LIMIT 0,$num"); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $catid = $r['catid']; + if($mid == 4) { + $condition = "groupid>5 and catids like '%,".$catid.",%'"; + } else { + $condition = 'status=3'; + $condition .= $CATEGORY[$catid]['child'] ? " AND catid IN (".$CATEGORY[$catid]['arrchildid'].")" : " AND catid=$catid"; + } + $item = $db->count($tb, $condition); + $db->query("UPDATE {$table} SET item=$item WHERE catid=$catid"); + } + $catid += 1; + } else { + $catid = $fid + $num; + } + } else { + msg('统计更新成功', "?file=$file&mid=$mid&action=url"); + } + msg('ID从'.$fid.'至'.($catid-1).'更新成功'.progress($sid, $fid, $tid), "?file=$file&mid=$mid&action=$action&sid=$sid&fid=$catid&tid=$tid&num=$num"); + break; + case 'url': + foreach($CATEGORY as $c) { + update_category($c); + } + msg('地址更新成功', "?file=$file&mid=$mid&action=letters"); + break; + case 'letters': + $update = false; + foreach($CATEGORY as $k=>$v) { + if(strlen($v['letter']) != 1) { + $letter = $do->get_letter($v['catname'], false); + if($letter) { + $update = true; + $letter = substr($letter, 0, 1); + $db->query("UPDATE {$table} SET letter='$letter' WHERE catid='$v[catid]'"); + } + } + } + msg('索引修复成功', "?file=$file&mid=$mid&action=cache"); + break; + case 'cache': + $do->repair(); + dmsg('缓存更新成功', '?file='.$file.'&mid='.$mid); + break; + case 'delete': + if($catid) $catids = $catid; + $catids or msg('请选择分类'); + $do->delete($catids); + $NUM > 500 ? $do->cache() : $do->repair(); + dmsg('删除成功', $forward); + break; + case 'update': + if(!$category || !is_array($category)) msg(); + $do->update($category); + foreach($category as $catid=>$v) { + $CATEGORY[$catid] = $db->get_one("SELECT * FROM {$table} WHERE catid=$catid"); + update_category($CATEGORY[$catid]); + } + $NUM > 500 ? $do->cache() : $do->repair(); + dmsg('更新成功', '?file='.$file.'&mid='.$mid.'&parentid='.$parentid); + break; + case 'letter': + isset($catname) or $catname = ''; + if(!$catname || strpos($catname, "\n") !== false) exit(''); + exit($do->get_letter($catname, false)); + break; + case 'ckdir': + if($do->get_catdir($catdir)) { + dialog('目录名可以使用'); + } else { + dialog('目录名不合法或者已经被使用'); + } + break; + default: + $total = 0; + $DTCAT = array(); + $condition = "moduleid=$mid"; + $condition .= $keyword ? " AND catname LIKE '%$keyword%'" : " AND parentid=$parentid"; + $result = $db->query("SELECT * FROM {$table} WHERE $condition ORDER BY listorder,catid"); + while($r = $db->fetch_array($result)) { + $r['childs'] = substr_count($r['arrchildid'], ','); + $total += $r['item']; + $DTCAT[$r['catid']] = $r; + } + if(!$DTCAT && !$parentid && !$keyword) msg('暂无分类,请先添加', '?file='.$file.'&mid='.$mid.'&action=add&parentid='.$parentid); + include tpl('category'); + break; +} + +class category { + var $moduleid; + var $catid; + var $category = array(); + var $table; + + function __construct($moduleid = 1, $catid = 0) { + global $CATEGORY; + $this->moduleid = $moduleid; + $this->catid = $catid; + if(!isset($CATEGORY)) $CATEGORY = cache_read('category-'.$this->moduleid.'.php'); + $this->category = $CATEGORY; + $this->table = DT_PRE.'category'; + } + + function category($moduleid = 1, $catid = 0) { + $this->__construct($moduleid, $catid); + } + + function add($category) { + $category['moduleid'] = $this->moduleid; + $category['letter'] = preg_match("/^[a-z]{1}+$/i", $category['letter']) ? strtolower($category['letter']) : ''; + foreach(array('group_list', 'group_show', 'group_add') as $v) { + $category[$v] = isset($category[$v]) ? implode(',', $category[$v]) : ''; + } + $sqlk = $sqlv = ''; + foreach($category as $k=>$v) { + $sqlk .= ','.$k; $sqlv .= ",'$v'"; + } + $sqlk = substr($sqlk, 1); + $sqlv = substr($sqlv, 1); + DB::query("INSERT INTO {$this->table} ($sqlk) VALUES ($sqlv)"); + $this->catid = DB::insert_id(); + if($category['parentid']) { + $category['catid'] = $this->catid; + $this->category[$this->catid] = $category; + $arrparentid = $this->get_arrparentid($this->catid); + } else { + $arrparentid = 0; + } + $catdir = $category['catdir'] ? $category['catdir'] : $this->catid; + DB::query("UPDATE {$this->table} SET listorder=$this->catid,catdir='$catdir',arrparentid='$arrparentid' WHERE catid=$this->catid"); + return true; + } + + function edit($category) { + $category['letter'] = preg_match("/^[a-z]{1}+$/i", $category['letter']) ? strtolower($category['letter']) : ''; + if($category['parentid']) { + $category['catid'] = $this->catid; + $this->category[$this->catid] = $category; + $category['arrparentid'] = $this->get_arrparentid($this->catid); + } else { + $category['arrparentid'] = 0; + } + foreach(array('group_list', 'group_show', 'group_add') as $v) { + $category[$v] = isset($category[$v]) ? implode(',', $category[$v]) : ''; + } + $category['linkurl'] = ''; + $sql = ''; + foreach($category as $k=>$v) { + $sql .= ",$k='$v'"; + } + $sql = substr($sql, 1); + DB::query("UPDATE {$this->table} SET $sql WHERE catid=$this->catid"); + return true; + } + + function delete($catids) { + if(is_array($catids)) { + foreach($catids as $catid) { + if(isset($this->category[$catid])) $this->delete($catid); + } + } else { + $catid = $catids; + if(isset($this->category[$catid])) { + DB::query("DELETE FROM {$this->table} WHERE catid=$catid"); + $arrchildid = $this->category[$catid]['arrchildid'] ? $this->category[$catid]['arrchildid'] : $catid; + DB::query("DELETE FROM {$this->table} WHERE catid IN ($arrchildid)"); + if($this->moduleid > 4) DB::query("UPDATE ".get_table($this->moduleid)." SET status=0 WHERE catid IN (".$arrchildid.")"); + } + } + return true; + } + + function update($category) { + if(!is_array($category)) return false; + foreach($category as $k=>$v) { + if(!$v['catname']) continue; + $v['parentid'] = intval($v['parentid']); + if($k == $v['parentid']) continue; + if($v['parentid'] > 0 && !isset($this->category[$v['parentid']])) continue; + $v['listorder'] = intval($v['listorder']); + $v['level'] = intval($v['level']); + $v['letter'] = preg_match("/^[a-z0-9]{1}+$/i", $v['letter']) ? strtolower($v['letter']) : ''; + $v['catdir'] = $this->get_catdir($v['catdir'], $k); + if(!$v['catdir']) $v['catdir'] = $k; + DB::query("UPDATE {$this->table} SET catname='$v[catname]',parentid='$v[parentid]',listorder='$v[listorder]',style='$v[style]',level='$v[level]',letter='$v[letter]',catdir='$v[catdir]' WHERE catid=$k "); + } + return true; + } + + function repair() { + $query = DB::query("SELECT * FROM {$this->table} WHERE moduleid='$this->moduleid' ORDER BY listorder,catid"); + $CATEGORY = array(); + while($r = DB::fetch_array($query)) { + $CATEGORY[$r['catid']] = $r; + } + $childs = array(); + foreach($CATEGORY as $catid => $category) { + $CATEGORY[$catid]['arrparentid'] = $arrparentid = $this->get_arrparentid($catid); + $CATEGORY[$catid]['catdir'] = $catdir = preg_match("/^[0-9a-z_\-\/]+$/i", $category['catdir']) ? $category['catdir'] : $catid; + $sql = "catdir='$catdir',arrparentid='$arrparentid'"; + if(!$category['linkurl']) { + $CATEGORY[$catid]['linkurl'] = listurl($category); + $sql .= ",linkurl='$category[linkurl]'"; + } + DB::query("UPDATE {$this->table} SET $sql WHERE catid=$catid"); + if($arrparentid) { + $arr = explode(',', $arrparentid); + foreach($arr as $a) { + if($a == 0) continue; + isset($childs[$a]) or $childs[$a] = ''; + $childs[$a] .= ','.$catid; + } + } + } + foreach($CATEGORY as $catid => $category) { + if(isset($childs[$catid])) { + $CATEGORY[$catid]['arrchildid'] = $arrchildid = $catid.$childs[$catid]; + $CATEGORY[$catid]['child'] = 1; + DB::query("UPDATE {$this->table} SET arrchildid='$arrchildid',child=1 WHERE catid='$catid'"); + } else { + $CATEGORY[$catid]['arrchildid'] = $catid; + $CATEGORY[$catid]['child'] = 0; + DB::query("UPDATE {$this->table} SET arrchildid='$catid',child=0 WHERE catid='$catid'"); + } + } + $this->cache($CATEGORY); + return true; + } + + function get_arrparentid($catid) { + $CAT = get_cat($catid); + if($CAT['parentid'] && $CAT['parentid'] != $catid) { + $parents = array(); + $cid = $catid; + $i = 1; + while($i++ < 10) { + $CAT = get_cat($cid); + if($CAT['parentid']) { + $parents[] = $cid = $CAT['parentid']; + } else { + break; + } + } + $parents[] = 0; + return implode(',', array_reverse($parents)); + } else { + return '0'; + } + } + + function get_catdir($catdir, $catid = 0) { + if(preg_match("/^[0-9a-z_\-\/]+$/i", $catdir)) { + $condition = "catdir='$catdir' AND moduleid='$this->moduleid'"; + if($catid) $condition .= " AND catid!=$catid"; + $r = DB::get_one("SELECT catid FROM {$this->table} WHERE $condition"); + if($r) { + return ''; + } else { + return $catdir; + } + } else { + return ''; + } + } + + function get_letter($catname, $letter = true) { + return $letter ? strtolower(substr(gb2py($catname), 0, 1)) : str_replace(' ', '', gb2py($catname)); + } + + function cache($data = array()) { + cache_category($this->moduleid, $data); + } +} +?> \ No newline at end of file diff --git a/admin/city.inc.php b/admin/city.inc.php new file mode 100644 index 0000000..1055361 --- /dev/null +++ b/admin/city.inc.php @@ -0,0 +1,136 @@ +edit($post); + dmsg('更新成功', $forward); + } else { + if($areaid) { + extract($do->get_one()); + } else { + $areaid = $listorder = 0; + $name = $style = $letter = $domain = $iparea = $template = $seo_title = $seo_keywords = $seo_description = ''; + } + include tpl('city_edit'); + } + break; + case 'letter': + $result = $db->query("SELECT * FROM {$DT_PRE}city WHERE letter=''"); + while($r = $db->fetch_array($result)) { + $letter = $do->letter($r['name']); + $db->query("UPDATE {$DT_PRE}city SET letter='$letter' WHERE areaid=$r[areaid]"); + } + dmsg('更新成功', $forward); + break; + case 'delete': + if($areaid) $areaids = $areaid; + $areaids or msg(); + $do->delete($areaids); + dmsg('删除成功', '?file='.$file); + break; + case 'update': + foreach($post as $v) { + $do->update($v); + } + dmsg('更新成功', '?file='.$file); + break; + default: + $condition = '1'; + if($kw) $condition .= " AND (name LIKE '%$keyword%' OR domain LIKE '%$keyword%')"; + $lists = $do->get_list($condition); + include tpl('city'); + break; +} + +class city { + var $areaid; + var $table; + + function __construct($areaid = 0) { + $this->table = DT_PRE.'city'; + $this->areaid = $areaid; + } + + function city($areaid = 0) { + $this->__construct($areaid); + } + + function edit($post) { + if(!is_array($post)) return false; + $post['letter'] or $post['letter'] = $this->letter($post['name']); + $sql1 = $sql2 = $s = ''; + foreach($post as $k=>$v) { + $sql1 .= $s.$k; + $sql2 .= $s."'".$v."'"; + $s = ','; + } + DB::query("REPLACE INTO {$this->table} ($sql1) VALUES ($sql2)"); + return true; + } + + function update($post) { + if(!is_array($post)) return false; + $areaid = $post['areaid']; + if(!$areaid) return false; + $post['letter'] or $post['letter'] = $this->letter($post['name']); + $post['name'] = trim($post['name']); + $post['domain'] = fix_domain($post['domain']); + $sql = ''; + foreach($post as $k=>$v) { + $sql .= ",$k='$v'"; + } + $sql = substr($sql, 1); + DB::query("UPDATE {$this->table} SET $sql WHERE areaid=$areaid"); + return true; + } + + function get_one() { + return DB::get_one("SELECT * FROM {$this->table} WHERE areaid=$this->areaid"); + } + + function get_list($condition) { + global $pages, $page, $pagesize, $offset, $pagesize, $sum; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = DB::get_one("SELECT COUNT(*) AS num FROM {$this->table} WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE $condition ORDER BY letter,listorder LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $r['linkurl'] = DT_PATH.'api/city.php?action=go&forward=&areaid='.$r['areaid']; + $lists[] = $r; + } + return $lists; + } + + function delete($areaids) { + $areaids = is_array($areaids) ? implode(',', $areaids) : $areaids; + DB::query("DELETE FROM {$this->table} WHERE areaid IN ($areaids)"); + return true; + } + + function letter($name) { + return strtolower(substr(gb2py($name), 0, 1)); + } +} +?> \ No newline at end of file diff --git a/admin/cloud.inc.php b/admin/cloud.inc.php new file mode 100644 index 0000000..a813549 --- /dev/null +++ b/admin/cloud.inc.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/admin/config.inc.php b/admin/config.inc.php new file mode 100644 index 0000000..aaec0a0 --- /dev/null +++ b/admin/config.inc.php @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/admin/count.inc.php b/admin/count.inc.php new file mode 100644 index 0000000..2dbc95f --- /dev/null +++ b/admin/count.inc.php @@ -0,0 +1,329 @@ +halt = 0; + $today = datetotime(timetodate($DT_TIME, 3).' 00:00:00'); + + $num = $db->count($DT_PRE.'finance_charge', "status=0"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("charge").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'finance_cash', "status=0"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("cash").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'keyword', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("keyword").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'guestbook', "edittime=0"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("guestbook").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'member_check', "1");//待审核资料修改 + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("edit_check").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'ask', "status=0"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("ask").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'alert', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("alert").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'gift_order', "status='处理中'"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("gift").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'news', "status=2");//待审核公司新闻 + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("news").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'honor', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("honor").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'page', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("page").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'link', "status=2 AND username<>''"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("comlink").innerHTML="'.$num.'";}catch(e){}'; + + foreach(array('company', 'truename', 'mobile', 'close') as $v) { + $num = $db->count($DT_PRE.'validate', "type='$v' AND status=2");//待审核认证 + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("v'.$v.'").innerHTML="'.$num.'";}catch(e){}'; + } + + $num = $db->count($DT_PRE.'ad', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("ad").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'spread', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("spread").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'comment', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("comment").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'link', "status=2 AND username=''"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("link").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'member');//会员 + echo 'try{document.getElementById("member").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'member_upgrade', "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("member_upgrade").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'member', "groupid=4"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("member_check").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($DT_PRE.'member', "regtime>$today"); + echo 'try{document.getElementById("member_new").innerHTML="'.$num.'";}catch(e){}'; + + foreach($MODULE as $m) { + if($m['moduleid'] < 5 || $m['islink']) continue; + $mid = $m['moduleid']; + $table = get_table($mid); + $num = $db->count($table, '1'); + echo 'try{Dd("m_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($table, "status=3"); + echo 'try{Dd("m_'.$mid.'_1").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($table, "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{Dd("m_'.$mid.'_2").innerHTML="'.$num.'";}catch(e){}'; + $num = $db->count($table, "addtime>$today"); + echo 'try{Dd("m_'.$mid.'_3").innerHTML="'.$num.'";}catch(e){}'; + + if($m['module'] == 'mall' || $m['module'] == 'sell') { + $num = $db->count($DT_PRE.'order', "mid=$mid"); + echo 'try{document.getElementById("order_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'order', "mid=$mid AND status=5"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("order_'.$mid.'_5").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'order', "mid=$mid AND status=4"); + echo 'try{document.getElementById("order_'.$mid.'_4").innerHTML="'.$num.'";}catch(e){}'; + } + + if($m['module'] == 'group') { + $num = $db->count($DT_PRE.'group_order_'.$mid, "1"); + echo 'try{document.getElementById("order_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'group_order_'.$mid, "status=4"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("order_'.$mid.'_4").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'group_order_'.$mid, "status=3"); + echo 'try{document.getElementById("order_'.$mid.'_3").innerHTML="'.$num.'";}catch(e){}'; + } + + if($m['module'] == 'quote') { + $num = $db->count($DT_PRE.'quote_product_'.$mid, "1"); + echo 'try{document.getElementById("product_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'quote_price_'.$mid, "1"); + echo 'try{document.getElementById("price_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'quote_price_'.$mid, "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("price_'.$mid.'_2").innerHTML="'.$num.'";}catch(e){}'; + } + + if($m['module'] == 'exhibit') { + $num = $db->count($DT_PRE.'exhibit_sign_'.$mid, "1"); + echo 'try{document.getElementById("sign_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'exhibit_sign_'.$mid, "addtime>$today"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("sign_'.$mid.'_3").innerHTML="'.$num.'";}catch(e){}'; + } + + if($m['module'] == 'know') { + $num = $db->count($DT_PRE.'know_expert_'.$mid, "1"); + echo 'try{document.getElementById("expert_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'know_answer_'.$mid, "1"); + echo 'try{document.getElementById("answer_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'know_answer_'.$mid, "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("answer_'.$mid.'_2").innerHTML="'.$num.'";}catch(e){}'; + } + + if($m['module'] == 'job') { + $table = $DT_PRE.'job_resume_'.$mid; + //ALL + $num = $db->count($table, '1'); + echo 'try{Dd("m_'.$mid.'_resume").innerHTML="'.$num.'";}catch(e){}'; + //PUB + $num = $db->count($table, "status=3"); + echo 'try{Dd("m_'.$mid.'_resume_1").innerHTML="'.$num.'";}catch(e){}'; + //CHECK + $num = $db->count($table, "status=2"); + $num = $num ? ''.$num.'' : 0; + echo 'try{Dd("m_'.$mid.'_resume_2").innerHTML="'.$num.'";}catch(e){}'; + //NEW + $num = $db->count($table, "addtime>$today", 30); + echo 'try{Dd("m_'.$mid.'_resume_3").innerHTML="'.$num.'";}catch(e){}'; + } + + if($m['module'] == 'club') { + $num = $db->count($DT_PRE.'club_group_'.$mid, "status=2");//商圈 + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("club_group_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'club_reply_'.$mid, "status=2");//商圈回复 + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("club_reply_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + + $num = $db->count($DT_PRE.'club_fans_'.$mid, "status=2");//商圈粉丝 + $num = $num ? ''.$num.'' : 0; + echo 'try{document.getElementById("club_fans_'.$mid.'").innerHTML="'.$num.'";}catch(e){}'; + } + } + break; + case 'todo': + $db->halt = 0; + $today = datetotime(timetodate($DT_TIME, 3).' 00:00:00'); + $htm = ''; + $num = $db->count($DT_PRE.'finance_charge', "status=0"); + if($num) $htm .= '
  • 待受理在线充值 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'finance_cash', "status=0"); + if($num) $htm .= '
  • 待受理资金提现 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'keyword', "status=2"); + if($num) $htm .= '
  • 待审核搜索关键词 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'guestbook', "edittime=0"); + if($num) $htm .= '
  • 待回复网站留言 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'member_check', "1"); + if($num) $htm .= '
  • 待审核资料修改 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'ask', "status=0"); + if($num) $htm .= '
  • 待受理客服中心 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'alert', "status=2"); + if($num) $htm .= '
  • 待审核贸易提醒 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'gift_order', "status='处理中'"); + if($num) $htm .= '
  • 待处理礼品订单 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'news', "status=2");//待审核公司新闻 + if($num) $htm .= '
  • 待审核公司新闻 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'honor', "status=2"); + if($num) $htm .= '
  • 待审核荣誉资质 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'page', "status=2"); + if($num) $htm .= '
  • 待审核公司单页 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'link', "status=2 AND username<>''"); + if($num) $htm .= '
  • 待审核公司链接 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'validate', "type='company' AND status=2"); + if($num) $htm .= '
  • 待审核公司认证 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'validate', "type='truename' AND status=2"); + if($num) $htm .= '
  • 待核审实名认证 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'validate', "type='mobile' AND status=2"); + if($num) $htm .= '
  • 待审核手机认证 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'validate', "type='email' AND status=2"); + if($num) $htm .= '
  • 待审核邮件认证 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'validate', "type='close' AND status=2"); + if($num) $htm .= '
  • 待审核注销申请 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'ad', "status=2"); + if($num) $htm .= '
  • 待审广告购买 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'spread', "status=2"); + if($num) $htm .= '
  • 待审核排名推广 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'comment', "status=2"); + if($num) $htm .= '
  • 待审核评论 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'link', "status=2 AND username=''"); + if($num) $htm .= '
  • 待审核友情链接 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'member_upgrade', "status=2"); + if($num) $htm .= '
  • 待审核会员升级 ('.$num.')
  • '; + $num = $db->count($DT_PRE.'member', "groupid=4"); + if($num) $htm .= '
  • 待审核会员注册 ('.$num.')
  • '; + foreach($MODULE as $m) { + if($m['moduleid'] < 5 || $m['islink']) continue; + $mid = $m['moduleid']; + $table = get_table($mid); + $num = $db->count($table, "status=2"); + if($num) $htm .= '
  • 待审核'.$m['name'].' ('.$num.')
  • '; + + if($m['module'] == 'mall' || $m['module'] == 'sell') { + $num = $db->count($DT_PRE.'order', "mid=$mid AND status=5"); + if($num) $htm .= '
  • 待受理'.$m['name'].'订单 ('.$num.')
  • '; + } + if($m['module'] == 'group') { + $num = $db->count($DT_PRE.'group_order_'.$mid, "status=4"); + if($num) $htm .= '
  • 待受理'.$m['name'].'订单 ('.$num.')
  • '; + } + if($m['module'] == 'quote') { + $num = $db->count($DT_PRE.'quote_price_'.$mid, "status=2"); + if($num) $htm .= '
  • 待审核'.$m['name'].'报价 ('.$num.')
  • '; + } + if($m['module'] == 'exhibit') { + $num = $db->count($DT_PRE.'exhibit_sign_'.$mid, "addtime>$today"); + if($num) $htm .= '
  • '.$m['name'].'今日报名 ('.$num.')
  • '; + } + if($m['module'] == 'know') { + $num = $db->count($DT_PRE.'know_answer_'.$mid, "status=2"); + if($num) $htm .= '
  • 待审核'.$m['name'].'回答 ('.$num.')
  • '; + } + if($m['module'] == 'job') { + $num = $db->count($DT_PRE.'job_resume_'.$mid, "status=2"); + if($num) $htm .= '
  • 待审核'.$m['name'].'简历 ('.$num.')
  • '; + } + if($m['module'] == 'club') { + $num = $db->count($DT_PRE.'club_group_'.$mid, "status=2");//商圈 + if($num) $htm .= '
  • 待审核'.$m['name'].'申请 ('.$num.')
  • '; + + $num = $db->count($DT_PRE.'club_reply_'.$mid, "status=2");//商圈回复 + if($num) $htm .= '
  • 待审核'.$m['name'].'回复 ('.$num.')
  • '; + + $num = $db->count($DT_PRE.'club_fans_'.$mid, "status=2");//商圈粉丝 + if($num) $htm .= '
  • 待审核'.$m['name'].'粉丝 ('.$num.')
  • '; + } + } + @header("Content-type:text/javascript"); + if($htm) { + $htm = '
    更多>待办事项
    '; + echo 'try{document.getElementById("todo").innerHTML=\''.$htm.'\';document.getElementById("todo").style.display=\'table\';}catch(e){}'; + } + break; + case 'repeat': + $mid or $mid = 21; + $key = isset($key) ? trim($key) : 'title'; + $num = isset($num) ? intval($num) : 100; + $status = isset($status) ? intval($status) : 3; + $lists = array(); + if(isset($ok)) { + $submit = 1; + $act = ''; + if($status == 4) $act = 'expire'; + if($status == 2) $act = 'check'; + if($status == 1) $act = 'reject'; + if($status == 0) $act = 'recycle'; + $condition = "status=$status"; + if($keyword) $condition .= match_kw($key, $keyword); + $result = $db->query("SELECT COUNT(`$key`) AS num,`$key` FROM ".get_table($mid)." WHERE $condition GROUP BY `$key` ORDER BY num DESC LIMIT 0,$num"); + while($r = $db->fetch_array($result)) { + if($r['num'] < 2) continue; + $r['kw'] = urlencode($r[$key]); + $lists[] = $r; + } + } + include tpl('count_repeat'); + break; + case 'stats': + $year = isset($year) ? intval($year) : date('Y', $DT_TIME); + $year or $year = date('Y', $DT_TIME); + $month = isset($month) ? intval($month) : 0; + if($mid == 1 || $mid == 3) $mid = 0; + if($mid == 4) $mid = 2; + include tpl('count_stats'); + break; + default: + $year = isset($year) ? intval($year) : date('Y', $DT_TIME); + $year or $year = date('Y', $DT_TIME); + $month = isset($month) ? intval($month) : 0; + if($mid == 1 || $mid == 3) $mid = 0; + if($mid == 4) $mid = 2; + include tpl('count'); + break; +} +?> \ No newline at end of file diff --git a/admin/cron.inc.php b/admin/cron.inc.php new file mode 100644 index 0000000..de06d85 --- /dev/null +++ b/admin/cron.inc.php @@ -0,0 +1,213 @@ +pass($post)) { + $do->add($post); + dmsg('添加成功', $forward); + } else { + msg($do->errmsg); + } + } else { + $type = $title = $name = $run = $hour = $mint = $status = $note = $n1 = $n2 = $n3 = $v1 = $v2 = $v3 = ''; + $minute = 30; + include tpl('cron_edit'); + } + break; + case 'edit': + $itemid or msg(); + $do->itemid = $itemid; + $r = $do->get_one(); + $r or msg('任务不存在'); + if($r['type']) msg('内置任务不可修改'); + if($submit) { + if($do->pass($post)) { + $do->edit($post); + dmsg('修改成功', $forward); + } else { + msg($do->errmsg); + } + } else { + extract($r); + $minute = 0; + $run = 1; + if(strpos($schedule, ',') !== false) { + list($hour, $mint) = explode(',', $schedule); + } else { + $minute = $schedule; + $run = 0; + } + include tpl('cron_edit'); + } + break; + case 'delete': + $itemid or msg(); + $do->itemid = $itemid; + $r = $do->get_one(); + $r or msg('任务不存在'); + if($r['type'] || $itemid < 100) msg('内置任务不可删除'); + $do->delete(); + dmsg('删除成功', $forward); + break; + case 'run': + $itemid or msg(); + $do->itemid = $itemid; + $cron = $do->get_one(); + $cron or msg('任务不存在'); + $v1 = $cron['v1']; + $v2 = $cron['v2']; + $v3 = $cron['v3']; + include DT_ROOT.'/api/cron/'.$cron['name'].'.inc.php'; + $nexttime = $do->nexttime($cron['schedule'], $DT_TIME); + $db->query("UPDATE {$DT_PRE}cron SET lasttime=$DT_TIME,nexttime=$nexttime WHERE itemid=$itemid"); + dmsg('运行成功', $forward); + break; + default: + $sfields = array('按条件', '名称', '文件名', '时间表', '备注'); + $dfields = array('title', 'title', 'name', 'schedule', 'note'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $sorder = array('结果排序方式', '上次运行降序', '上次运行升序', '下次运行降序', '下次运行升序', '任务文件降序', '任务文件升序'); + $dorder = array('itemid DESC', 'lasttime DESC', 'lasttime ASC', 'nexttime DESC', 'nexttime ASC', 'name DESC', 'name ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + + $fields_select = dselect($sfields, 'fields', '', $fields); + $order_select = dselect($sorder, 'order', '', $order); + + $condition = '1'; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + $lists = $do->get_list($condition, $dorder[$order]); + include tpl('cron'); + break; +} + +class cron { + var $itemid; + var $table; + var $errmsg = errmsg; + + function __construct() { + $this->table = DT_PRE.'cron'; + } + + function cron() { + $this->__construct(); + } + + function pass($post) { + if(!is_array($post)) return false; + if(!$post['title']) return $this->_('请填写任务名称'); + if(!check_name($post['name']) || !is_file(DT_ROOT.'/api/cron/'.$post['name'].'.inc.php')) return $this->_('请选择脚本文件'); + if($post['run']) { + $hour = intval($post['hour']); + if($hour < 0 || $hour > 23) return $this->_('小时必须为0-23'); + $mint = intval($post['mint']); + if($mint < 0 || $hour > 59) return $this->_('分钟必须为0-59'); + } else { + $minute = intval($post['minute']); + if($minute < 1) return $this->_('间隔时间至少为1分钟'); + } + return true; + } + + function set($post) { + if($post['run']) { + $post['schedule'] = intval($post['hour']).','.intval($post['mint']); + } else { + $post['schedule'] = intval($post['minute']); + } + unset($post['run'], $post['hour'],$post['mint'], $post['minute']); + $post['status'] = $post['status'] ? 1 : 0; + return $post; + } + + function get_one() { + return DB::get_one("SELECT * FROM {$this->table} WHERE itemid='$this->itemid'"); + } + + function get_list($condition = '', $order = 'itemid ASC') { + global $MOD, $pages, $page, $pagesize, $offset, $sum; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = DB::get_one("SELECT COUNT(*) AS num FROM {$this->table} WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $r['lasttime'] = $r['lasttime'] ? timetodate($r['lasttime'], 6) : 'N/A'; + $r['nexttime'] = $r['nexttime'] ? timetodate($r['nexttime'], 6) : 'N/A'; + $r['text'] = $this->time2text($r['schedule']); + $lists[] = $r; + } + return $lists; + } + + function add($post) { + $post = $this->set($post); + $sqlk = $sqlv = ''; + foreach($post as $k=>$v) { + $sqlk .= ','.$k; $sqlv .= ",'$v'"; + } + $sqlk = substr($sqlk, 1); + $sqlv = substr($sqlv, 1); + DB::query("INSERT INTO {$this->table} ($sqlk) VALUES ($sqlv)"); + return $this->itemid; + } + + function edit($post) { + $post = $this->set($post); + $sql = ''; + foreach($post as $k=>$v) { + $sql .= ",$k='$v'"; + } + $sql = substr($sql, 1); + DB::query("UPDATE {$this->table} SET $sql WHERE itemid=$this->itemid"); + return true; + } + + function delete() { + DB::query("DELETE FROM {$this->table} WHERE itemid=$this->itemid"); + } + + function nexttime($schedule, $time) { + if(strpos($schedule, ',') !== false) { + list($h, $m) = explode(',', $schedule); + $t = datetotime(timetodate($time, 3).' '.($h < 10 ? '0'.$h : $h).':'.($m < 10 ? '0'.$m : $m).':00'); + return $t > $time ? $t : $t + 86400; + } else { + $m = intval($schedule); + return $time + ($m ? $m : 1800)*60; + } + } + + function time2text($schedule) { + if(strpos($schedule, ',') !== false) { + list($h, $m) = explode(',', $schedule); + if($h < 10) $h = '0'.$h; + if($m < 10) $m = '0'.$m; + return '每天'.$h.':'.$m; + } else { + $m = intval($schedule); + return '每'.$m.'分钟'; + } + list($hour, $minute) = explode(',', $schedule); + } + + function _($e) { + $this->errmsg = $e; + return false; + } +} +?> \ No newline at end of file diff --git a/admin/data.inc.php b/admin/data.inc.php new file mode 100644 index 0000000..ff46d4d --- /dev/null +++ b/admin/data.inc.php @@ -0,0 +1,420 @@ + 0 && $tmid > 0 && $fmid != $tmid) or msg('来源模块或目标模块设置错误'); + $catid or msg('请选择新分类'); + $condition = trim($condition); + if(strtolower(substr($condition, 0, 3)) != 'and') $condition = "AND itemid IN ($condition)"; + $post = array(); + $post['fmid'] = $fmid; + $post['tmid'] = $tmid; + $post['condition'] = $condition; + $post['catid'] = $catid; + $post['delete'] = $delete; + $post = dstripslashes($post); + cache_write('table-move-'.$_userid.'.php', $post); + msg('正在开始转移', '?file='.$file.'&action=move_table'); + } else { + include tpl('data_move'); + } + break; + case 'move_table': + $post = cache_read('table-move-'.$_userid.'.php'); + $post or msg('数据配置不存在', '?file='.$file.'&action=move'); + $fmid = $post['fmid']; + $tmid = $post['tmid']; + $ftb = get_table($fmid); + $ftb_data = get_table($fmid, 1); + $ttb = get_table($tmid); + $ttb_data = get_table($tmid, 1); + $table = $ftb; + $id = 'itemid'; + $condition = $post['condition']; + $catid = $post['catid']; + $delete = $post['delete']; + isset($num) or $num = 1000; + if(!isset($fid)) { + $r = $db->get_one("SELECT min({$id}) AS fid FROM {$table}"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + if(!isset($tid)) { + $r = $db->get_one("SELECT max({$id}) AS tid FROM {$table}"); + $tid = $r['tid'] ? $r['tid'] : 0; + } + isset($$id) or $$id = 1; + $fs = array(); + $result = $db->query("SHOW COLUMNS FROM `$ttb`"); + while($r = $db->fetch_array($result)) { + $fs[] = $r['Field']; + } + if($fid <= $tid) { + $result = $db->query("SELECT * FROM {$table} WHERE `{$id}`>=$fid {$condition} ORDER BY `{$id}` LIMIT 0,$num"); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $$id = $fitemid = $r[$id]; + unset($r[$id]); + $r['catid'] = $catid; + $r = daddslashes($r); + if(is_file(DT_CACHE.'/'.$fmid.'.part')) $ftb_data = split_table($fmid, $fitemid); + $t = $db->get_one("SELECT content FROM {$ftb_data} WHERE itemid=$fitemid"); + $content = daddslashes($t['content']); + $sqlk = $sqlv = ''; + foreach($r as $k=>$v) { + if($fs && !in_array($k, $fs)) continue; + $sqlk .= ','.$k; $sqlv .= ",'$v'"; + } + $sqlk = substr($sqlk, 1); + $sqlv = substr($sqlv, 1); + $db->query("INSERT INTO {$ttb} ($sqlk) VALUES ($sqlv)"); + $titemid = $db->insert_id(); + if(is_file(DT_CACHE.'/'.$tmid.'.part')) $ttb_data = split_table($tmid, $titemid); + $db->query("INSERT INTO {$ttb_data} (itemid,content) VALUES ('$titemid','$content')"); + $linkurl = str_replace($fitemid, $titemid, $r['linkurl']); + $db->query("UPDATE {$ttb} SET linkurl='$linkurl' WHERE itemid=$titemid"); + if($delete) { + $db->query("UPDATE {$ftb} SET status=0 WHERE itemid=$fitemid"); + $html = DT_ROOT.'/'.$MODULE[$fmid]['moduledir'].'/'.$r['linkurl']; + if(is_file($html)) @unlink($html); + } + } + $$id += 1; + } else { + $$id = $fid + $num; + } + } else { + cache_delete('table-move-'.$_userid.'.php'); + msg('转移成功', '?file='.$file.'&action=move'); + } + msg('ID '.$fid.'~'.($$id-1).'转移成功', '?file='.$file.'&action='.$action.'&fid='.$$id.'&tid='.$tid.'&num='.$num); + break; + case 'save': + $table or msg('请选择导入目标表'); + $name or msg('数据文件不存在'); + $xlsfile = DT_ROOT.'/file/temp/'.$name.'.xls'; + is_file($xlsfile) or msg('数据文件不存在'); + function table_get_fields($table) { + $arr = array(); + $result = DB::query("SHOW COLUMNS FROM `{$table}`"); + while($r = DB::fetch_array($result)) { + $arr[] = $r['Field']; + } + return $arr; + } + function table_get_query($fields, $arr) { + $sqlk = $sqlv = ''; + foreach($arr as $k=>$v) { + if(!in_array($k, $fields)) continue; + $sqlk .= ',`'.$k.'`'; $sqlv .= ",'$v'"; + } + if($sqlk) $sqlk = substr($sqlk, 1); + if($sqlv) $sqlv = substr($sqlv, 1); + return array($sqlk, $sqlv); + } + function data_get_name($fields, $lists) { + $arr = array(); + foreach($fields as $k=>$v) { + if(isset($lists[$k])) { + if(strpos($v, 'time') === false) { + $arr[$v] = convert($lists[$k], 'GBK', 'UTF-8'); + } else { + $arr[$v] = is_numeric($lists[$k]) ? $lists[$k] : datetotime($lists[$k]); + } + } + } + return $arr; + } + $type = 'table'; + $tb = cutstr($table, DT_PRE); + $table_data = ''; + if($tb == 'member') { + $type = 'member'; + $split = is_file(DT_CACHE.'/4.part') ? 1 : 0; + $table_member_misc = DT_PRE.'member_misc'; + $fields_member_misc = table_get_fields($table_member_misc); + $table_company = DT_PRE.'company'; + $fields_company = table_get_fields($table_company); + $table_data = DT_PRE.'company_data'; + $fields_data = table_get_fields($table_data); + } else if(substr_count($tb, '_') == 1) { + list($mod, $mid) = explode('_', $tb); + if(is_numeric($mid) && isset($MODULE[$mid]) && $MODULE[$mid]['module'] == $mod) { + $type = 'module'; + $split = is_file(DT_CACHE.'/'.$mid.'.part') ? 1 : 0; + $table_data = get_table($mid, 1); + $fields_data = table_get_fields($table_data); + } + } + if($type == 'table') { + if($tb == 'news' || $tb == 'page') $table_data = $table.'_data'; + if(strpos($tb, 'resume_') !== false && strpos($tb, 'resume_data_') === false) $table_data = str_replace('resume_', 'resume_data_', $table); + if($table_data) $fields_data = table_get_fields($table_data); + } + require DT_ROOT.'/api/excel/loader.inc.php'; + $xls = new ExcelParser(DT_ROOT.'/file/temp/'.$name.'.xls'); + $arr = $xls->main(); + isset($arr[1][0]) or msg('未读取到有效数据'); + $lists = $arr[1][0]; + $names = $lists[1]; + $j = 0; + $fields = table_get_fields($table); + for($i = 2; $i < count($lists); $i++) { + if(isset($lists[$i]) && $lists[$i]) { + $data = data_get_name($names, $lists[$i]); + list($sqlk, $sqlv) = table_get_query($fields, $data); + if($sqlk && $sqlv) { + $db->query("INSERT INTO {$table} ($sqlk) VALUES ($sqlv)"); + $id = $db->insert_id(); + if($id) { + $j++; + if($type == 'table') { + if($table_data) { + $data['itemid'] = $id; + list($sqlk, $sqlv) = table_get_query($fields_data, $data); + if($sqlk && $sqlv) $db->query("INSERT INTO {$table_data} ($sqlk) VALUES ($sqlv)"); + } + } else if($type == 'member') { + $data['userid'] = $id; + + list($sqlk, $sqlv) = table_get_query($fields_member_misc, $data); + if($sqlk && $sqlv) $db->query("INSERT INTO {$table_member_misc} ($sqlk) VALUES ($sqlv)"); + + list($sqlk, $sqlv) = table_get_query($fields_company, $data); + if($sqlk && $sqlv) $db->query("INSERT INTO {$table_company} ($sqlk) VALUES ($sqlv)"); + + list($sqlk, $sqlv) = table_get_query($fields_data, $data); + if($sqlk && $sqlv) { + $tb_data = content_table(4, $id, $split, $table_data); + $db->query("INSERT INTO {$tb_data} ($sqlk) VALUES ($sqlv)"); + } + } else if($type == 'module') { + $data['itemid'] = $id; + list($sqlk, $sqlv) = table_get_query($fields_data, $data); + if($sqlk && $sqlv) { + $tb_data = content_table($mid, $id, $split, $table_data); + $db->query("INSERT INTO {$tb_data} ($sqlk) VALUES ($sqlv)"); + } + } + } + } + } + } + file_del($xlsfile); + msg('成功导入'.$j.'条数据', '?file='.$file.'&action=import'); + break; + case 'upload': + $table or msg('请选择导入目标表'); + $_FILES['uploadfile']['size'] or msg('请上传xls数据文件'); + require DT_ROOT.'/include/upload.class.php'; + $name = date('YmdHis').mt_rand(10, 99).$_userid; + $upload = new upload($_FILES, 'file/temp/', $name.'.xls', 'xls'); + $upload->adduserid = false; + if($upload->save()) { + require DT_ROOT.'/api/excel/loader.inc.php'; + $xls = new ExcelParser(DT_ROOT.'/file/temp/'.$name.'.xls'); + $arr = $xls->main(); + isset($arr[1][0]) or msg('未读取到有效数据'); + $lists = $arr[1][0]; + $T = $D = array(); + $T = $lists[0]; + for($i = 1; $i < 12; $i++) { + if(isset($lists[$i]) && $lists[$i]) $D[] = $lists[$i]; + } + $t1 = count($lists) - 2; + $t2 = count($D) - 1; + include tpl('data_view'); + } else { + msg($upload->errmsg); + } + break; + case 'import': + $tables = array(); + $i = 0; + $result = $db->query("SHOW TABLE STATUS FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_array($result)) { + if(preg_match('/^'.$DT_PRE.'/', $r['Name'])) { + $tables[$i]['name'] = $r['Name']; + $tables[$i]['note'] = $r['Comment']; + $i++; + } + } + include tpl('data_import'); + break; + case 'fields': + $table or exit; + $N = parse_dict($table); + $fields_select = ''; + $result = $db->query("SHOW COLUMNS FROM `$table`"); + while($r = $db->fetch_array($result)) { + $fields_select .= ''; + } + $select = ''; + $key = table_get_key($table); + $order = $key ? $key.' DESC' : ''; + exit(json_encode(array('select' => $select, 'order' => $order))); + break; + case 'pages': + $psize > 0 or $psize = 5000; + $total = $db->count($table, '1 '.$condition); + $page = ceil(intval($total)/$psize); + exit('{"page":"'.$page.'","total":"'.$total.'","ok":"1"}'); + break; + case 'download': + $table or msg('请选择数据表'); + $ismember = strpos($table, 'member') === false ? 0 : 1; + isset($fields) or $fields = array(); + $fields = $fields ? implode(',', $fields) : '*'; + $condition = '1 '.$condition; + if(strpos($condition, DT_PRE) !== false) $condition = '1'; + if($ismember) $condition .= ' AND groupid>1'; + if(!$order) { + $key = table_get_key($table); + if($key) $order = $key.' DESC'; + } + $order = $order ? 'ORDER BY '.$order : ''; + in_array($ext, array('csv', 'xml', 'json')) or $ext = 'csv'; + $data = ''; + $lists = $list = array(); + $result = $db->query("SELECT {$fields} FROM {$table} WHERE {$condition} {$order} LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + if($ismember) { + foreach(array('password', 'passsalt', 'payword', 'paysalt') as $v) { + if(isset($r[$v])) unset($r[$v]); + } + } + if(!$data) $list = $r; + if($ext == 'csv') { + foreach($r as $k=>$v) { + if(strpos($k, 'time') !== false) $v = timetodate($v, 6); + $data .= '"'.$v.'",'; + } + $data .= "\n"; + } else if($ext == 'xml') { + $data .= "\t".''."\n"; + foreach($r as $k=>$v) { + if(strpos($k, 'time') !== false) $v = timetodate($v, 6); + if(strpos($v, '<') !== false || strpos($v, "\n") !== false) { + $data .= "\t\t".'<'.$k.'>'."\n"; + } else { + $data .= "\t\t".'<'.$k.'>'.$v.''."\n"; + } + } + $data .= "\t".''."\n"; + } else { + $data = 'json'; + foreach($r as $k=>$v) { + if(strpos($k, 'time') !== false) $r[$k] = timetodate($v, 6); + } + $lists[] = $r; + } + } + if($list) { + if($ext == 'csv') { + $N = parse_dict($table); + $T = ''; + foreach($list as $k=>$v) { + $T .= '"'.(isset($N[$k]) ? $N[$k] : $k).'",'; + } + $T .= "\n"; + foreach($list as $k=>$v) { + $T .= '"'.$k.'",'; + } + $data = $T."\n".$data; + $data = convert($data, DT_CHARSET, 'GBK'); + } else if($ext == 'xml') { + $N = parse_dict($table); + $T = ''."\n"; + $T .= '<'.$table.'>'."\n"; + $T .= "\t".''."\n"; + foreach($list as $k=>$v) { + $T .= "\t\t".'<'.$k.'>'.(isset($N[$k]) ? $N[$k] : $k).''."\n"; + } + $T .= "\t".''."\n"; + $data = $T.$data; + $data .= ''."\n"; + $data .= ''; + } else { + $data = json_encode($lists); + } + } + if($data) file_down('', $table.'_'.$page.'.'.$ext, $data); + msg('没有符合条件的数据'); + break; + default: + $table_select = ''; + $tables = array(); + $result = $db->query("SHOW TABLE STATUS FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_array($result)) { + $table = $r['Name']; + if(preg_match("/^".$DT_PRE."/i", $table)) { + $table_select .= ''; + $tables[] = $table; + } + } + include tpl('data'); + break; +} +?> \ No newline at end of file diff --git a/admin/database.inc.php b/admin/database.inc.php new file mode 100644 index 0000000..1300a5c --- /dev/null +++ b/admin/database.inc.php @@ -0,0 +1,896 @@ +') $tmp = trim(substr($tmp, 13)); + foreach(explode('DROP TABLE', $tmp) as $tb) { + if(strpos($tb, 'CREATE TABLE') != false) { + $table = cutstr($tb, 'CREATE TABLE `', '`'); + $table = substr($table, strlen(DT_PRE)); + $table = preg_replace("/_[0-9]{1,}/", '', $table); + if($table) { + foreach(explode("\n", $tb) as $t) { + $t = trim($t); + if(substr($t, 0, 1) != '`' || substr($t, -1, 1) != ',') continue; + $V[$table][trim(cutstr($t, '`', '`'))] = substr(trim(cutstr($t, '` ')), 0, -1); + } + } + } + } + return $V; +} +function parse_dict($table, $job = '') { + global $MODULE; + $fds = $names = $notes = array(); + if(strpos($table, DT_PRE) === false) { + $rtable = $table; + } else { + $rtable = substr($table, strlen(DT_PRE)); + $fds = cache_read('fields-'.$rtable.'.php'); + $rtable = preg_replace("/_[0-9]{1,}/", '', $rtable); + if(is_numeric($rtable) && isset($MODULE[$rtable])) $rtable = $MODULE[$rtable]['module'].'_data'; + } + if($job == 'table') return $rtable; + $file = DT_ROOT.'/file/setting/'.$rtable.'.csv'; + if($job == 'file') return $file; + if(is_file($file)) { + $tmp = file_get($file); + $arr = explode("\n", $tmp); + foreach($arr as $v) { + $t = explode(',', $v); + $names[$t[0]] = $t[1]; + $notes[$t[0]] = $t[2]; + } + } + if($fds) { + foreach($fds as $v) { + if(isset($names[$v['name']]) && $names[$v['name']]) continue; + $names[$v['name']] = $v['title']; + $notes[$v['name']] = ''; + } + } + if($job == 'note') return $notes; + return $names; +} +switch($action) { + case 'repair': + $DT['close'] or msg('为了数据安全,此操作必须先在网站设置里临时关闭网站'); + isset($tables) or msg('请指定数据表'); + is_array($tables) or $tables = array($tables); + count($tables) < 10 or msg('此操作比较耗费服务器资源,请控制在10个表内'); + foreach($tables as $table) { + $table = strip_sql($table, 0); + $db->query("REPAIR TABLE `{$table}`"); + } + dmsg('修复成功', $forward); + break; + case 'optimize': + $DT['close'] or msg('为了数据安全,此操作必须先在网站设置里临时关闭网站'); + isset($tables) or msg('请指定数据表'); + is_array($tables) or $tables = array($tables); + count($tables) < 10 or msg('此操作比较耗费服务器资源,请控制在10个表内'); + foreach($tables as $table) { + $table = strip_sql($table, 0); + $db->query("OPTIMIZE TABLE `{$table}`"); + } + dmsg('优化成功', $forward); + break; + case 'drop': + isset($tables) or msg('请指定数据表'); + is_array($tables) or $tables = array($tables); + foreach($tables as $table) { + $table = strip_sql($table, 0); + if(strpos($table, $DT_PRE) === false) $db->query("DROP TABLE `{$table}`"); + } + dmsg('删除成功', $forward); + break; + case 'execute': + if(!isset($CFG['executesql']) || !$CFG['executesql']) msg('系统禁止了执行SQL,请FTP修改根目录config.inc.php
    $CFG[\'executesql\'] = \'0\'; 修改为 $CFG[\'executesql\'] = \'1\';'); + isset($sql) or $sql = ''; + $lists = array(); + if($table) { + $sql = "SELECT * FROM ".$table; + $submit = 1; + } + if($submit) { + $sql = trim($sql); + if(!$sql) { + msg('SQL语句为空'); + } else { + $sql = stripslashes($sql); + $sql = strip_sql($sql, 0); + if(strtoupper(substr($sql, 0, 7)) == 'SELECT ' && strpos($sql, "\n") === false) { + if(substr($sql, -1) == ';') $sql = substr($sql, 0, -1); + if(stripos($sql, 'LIMIT ') === false) $sql .= " LIMIT 0,$pagesize"; + $result = $db->query($sql); + while($r = $db->fetch_array($result)) { + $lists[] = $r; + } + $fds = parse_dict($table ? $table : $DT_PRE.cutstr($sql, ' '.$DT_PRE, ' ')); + } else { + sql_execute($sql); + dmsg('执行成功', '?file='.$file.'&action=execute'); + } + } + } + include tpl('database_execute'); + break; + case 'process': + $i = 0; + $lists = $tags = array(); + $result = $db->query("SHOW FULL PROCESSLIST"); + while($r = $db->fetch_array($result)) { + if($r['db'] == $CFG['db_name']) { + $lists[$i++] = $r; + } else { + $tags[$i++] = $r; + } + } + $lists = $lists + $tags; + include tpl('database_process'); + break; + case 'kill': + $db->halt = 0; + if($itemid) { + if(is_array($itemid)) { + foreach($itemid as $id) { + $db->query("KILL $id"); + } + } else { + $db->query("KILL $itemid"); + } + } + dmsg('结束成功', '?file='.$file.'&action=process'); + break; + case 'comments': + $db->halt = 0; + $C = include(DT_ROOT.'/file/setting/comment.php'); + $C or msg('配置文件不存在,请上传 file/setting/comment.php'); + foreach($C as $k=>$v) { + $sql = "ALTER TABLE `{$DT_PRE}{$k}` COMMENT='{$v}'"; + $db->query($sql); + } + foreach($MODULE as $k=>$v) { + if(is_file(DT_ROOT.'/file/setting/'.$v['module'].'.csv')) { + $sql = "ALTER TABLE `".$DT_PRE.$v['module']."_".$v['moduleid']."` COMMENT='".$v['name']."'"; + $db->query($sql); + $sql = "ALTER TABLE `".$DT_PRE.$v['module']."_data_".$v['moduleid']."` COMMENT='".$v['name']."内容'"; + $db->query($sql); + } + } + dmsg('重建成功', '?file='.$file); + break; + case 'comment': + $table or msg('Table为空'); + if($submit) { + $name = trim($name); + $db->query("ALTER TABLE `{$table}` COMMENT='{$name}'"); + dmsg('修改成功', '?file='.$file.'&action='.$action.'&table='.$table.'¬e='.urlencode($name)); + } else { + include tpl('database_comment'); + } + break; + case 'dict': + $table or msg('Table为空'); + $dict_file = parse_dict($table, 'file'); + if($submit) { + $csv = ""; + foreach($name as $k=>$v) { + $v = str_replace(',', ',', $v); + $n = str_replace(',', ',', $note[$k]); + $csv .= $k.','.$v.','.$n."\n"; + } + file_put($dict_file, trim($csv)); + dmsg('更新成功', '?file='.$file.'&action='.$action.'&job='.$job.'&table='.$table.'¬e='.urlencode($nt)); + } else { + $names = parse_dict($table); + $notes = parse_dict($table, 'note'); + $fields = $F = $R = array(); + $result = $db->query("SHOW COLUMNS FROM `{$table}`"); + while($r = $db->fetch_array($result)) { + $r['Type'] = str_replace(' unsigned', '', $r['Type']); + $F[$r['Field']] = $r['Type']; + if(isset($names[$r['Field']])) { + $r['cn_name'] = $names[$r['Field']]; + $r['cn_note'] = $notes[$r['Field']]; + } else { + $r['cn_name'] = $r['cn_note'] = ''; + } + $fields[] = $r; + } + if($job == 'verify') { + $rtable = parse_dict($table, 'table'); + $V = table_get_default(); + $V = isset($V[$rtable]) ? $V[$rtable] : array(); + if($V) { + //自定义字段移除 + if(preg_match("/[0-9]{1,}/", $tn) && is_file(DT_CACHE.'/fields-'.$tn.'.php')) { + foreach(cache_read('fields-'.$tn.'.php') as $f) { + if(isset($F[$f['name']])) unset($F[$f['name']]); + $R[$f['name']] = '自定义字段'; + } + } + foreach($F as $k=>$v) { + if(isset($V[$k])) { + $v = str_replace(array('longtext', 'mediumtext'), array('text', 'text'), strtolower($v)); + if(stripos($V[$k], $v) === false) { + $R[$k] = '类型错误'; + } else { + $R[$k] = ' 通过'; + } + unset($V[$k]); + } else { + $R[$k] = '多余字段'; + } + } + } else { + foreach($F as $k=>$v) { + $R[$k] = '未知'; + } + } + } + include tpl('database_dict'); + } + break; + case 'export': + if(!$table) msg(); + //$memory_limit = trim(@ini_get('memory_limit')); + $sizelimit = 1024*1024;//Max 1G + file_down('', $table.'.sql', sql_dumptable($table)); + break; + case 'download': + $file_ext = file_ext($filename); + $file_ext == 'sql' or msg('只能下载SQL文件'); + file_down($dir ? $D.$dir.'/'.$filename : $D.$filename); + break; + case 'view': + $file_ext = file_ext($filename); + $file_ext == 'sql' or msg('只能查看SQL文件'); + $file_path = $dir ? $D.$dir.'/'.$filename : $D.$filename; + is_file($file_path) or msg('SQL文件不存在'); + $file_size = round(filesize($file_path)/(1024*1024), 2); + $file_size < 20 or msg('文件体积过大,不支持在线查看'); + $content = file_get($file_path); + include tpl('database_view'); + break; + case 'delete': + if(!is_array($filenames)) { + $tmp = $filenames; + $filenames = array(); + $filenames[0] = $tmp; + } + foreach($filenames as $filename) { + if(file_ext($filename) == 'sql' || substr($filename, -8) == '.sql.php') { + file_del($dir ? $D.$dir.'/'.$filename : $D.$filename); + } else if(is_dir($D.$filename)) { + dir_delete($D.$filename); + } + } + dmsg('删除成功', $forward); + break; + case 'fields': + $table or exit; + $N = parse_dict($table); + $fields_select = ''; + $result = $db->query("SHOW COLUMNS FROM `{$table}`"); + while($r = $db->fetch_array($result)) { + $fields_select .= ''; + } + echo ''; + exit; + break; + case 'replace': + if($submit) { + $post['table'] = strip_sql($post['table'], 0); + $post['key'] = table_get_key($post['table']); + $post['num'] = intval($post['num']); + $post = dstripslashes($post); + cache_write('table-replace.php', $post); + if($post['type'] == 1) { + if(!$post['from']) msg('请填写查找内容'); + if($post['table']) { + if(!$post['key']) message('表'.$post['table'].'无主键,无法完成操作'); + if($post['key'] == $post['fields']) msg('无法完成对主键操作,请更换字段'); + } + msg('正在开始替换', '?file='.$file.'&action=replace_table'); + } else { + if(!$post['table'] || !$post['fields']) msg('请选择字段'); + if(!$post['add']) msg('请填写追加内容'); + if(!$post['key']) message('表'.$post['table'].'无主键,无法完成操作'); + if($post['key'] == $post['fields']) msg('无法完成对主键操作,请更换字段'); + msg('正在开始追加', '?file='.$file.'&action=replace_add'); + } + } else { + $table_select = ''; + $tables = array(); + $query = $db->query("SHOW TABLE STATUS FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_array($query)) { + $table = $r['Name']; + if(preg_match("/^".$DT_PRE."/i", $table)) { + $table_select .= ''; + $tables[] = $table; + } + } + cache_write('table.php', $tables); + $sql_select = ''; + $sqlfiles = glob($D.'*'); + if(is_array($sqlfiles)) { + $sqlfiles = array_reverse($sqlfiles); + foreach($sqlfiles as $id=>$sqlfile) { + $tmp = basename($sqlfile); + if(is_dir($sqlfile)) $sql_select .= ''; + } + } + include tpl('database_replace'); + } + break; + case 'replace_table': + $post = cache_read('table-replace.php'); + $post or msg('数据配置不存在', '?file='.$file.'&action=replace'); + if($post['table']) { + $table = $post['table']; + $id = $post['key']; + } else { + if($table) { + $id or msg('替换成功', '?file=database&action=replace'); + } else { + $table = DT_PRE.'404'; + $id = 'itemid'; + } + } + $fields = $post['fields']; + $fds = $fields ? "`{$id}`,`{$fields}`" : "*"; + $condition = $post['condition']; + $num = $post['num']; + $num > 0 or $num = 1000; + if(!isset($fid)) { + $r = $db->get_one("SELECT min({$id}) AS fid FROM {$table}"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + if(!isset($tid)) { + $r = $db->get_one("SELECT max({$id}) AS tid FROM {$table}"); + $tid = $r['tid'] ? $r['tid'] : 0; + } + isset($$id) or $$id = 1; + if($fid <= $tid) { + $result = $db->query("SELECT {$fds} FROM {$table} WHERE `{$id}`>=$fid {$condition} ORDER BY `{$id}` LIMIT 0,$num"); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $$id = $r[$id]; + $sql = ''; + foreach($r as $k=>$v) { + if(strpos($v, $post['from']) !== false) { + $v = addslashes(str_replace($post['from'], $post['to'], $v)); + $sql .= ",`$k`='$v'"; + } + } + if($sql) { + $sql = substr($sql, 1); + $db->query("UPDATE {$table} SET {$sql} WHERE `{$id}`={$$id}"); + } + } + $$id += 1; + } else { + $$id = $fid + $num; + } + } else { + if($post['table']) { + msg('替换成功', '?file=database&action=replace'); + } else { + $tb = table_get_next($table); + if($tb) { + $id = table_get_key($tb); + msg('表 '.$table.' 替换成功', '?file='.$file.'&action='.$action.'&table='.$tb.'&id='.$id, 0); + } else { + msg('替换成功', '?file=database&action=replace'); + } + } + } + msg('ID '.$fid.'~'.($$id-1).'替换成功', '?file='.$file.'&action='.$action.'&table='.$table.'&id='.$id.'&fid='.$$id.'&tid='.$tid.'&num='.$num, 0); + break; + case 'replace_add': + $post = cache_read('table-replace.php'); + $post or msg('数据缓存不存在', '?file='.$file.'&action=replace'); + $table = $post['table']; + $id = $post['key']; + $fields = $post['fields']; + $condition = $post['condition']; + $num = $post['num']; + $num > 0 or $num = 1000; + if(!isset($fid)) { + $r = $db->get_one("SELECT min({$id}) AS fid FROM {$table}"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + if(!isset($tid)) { + $r = $db->get_one("SELECT max({$id}) AS tid FROM {$table}"); + $tid = $r['tid'] ? $r['tid'] : 0; + } + isset($$id) or $$id = 1; + if($fid <= $tid) { + $result = $db->query("SELECT `{$id}`,`{$fields}` FROM {$table} WHERE `{$id}`>=$fid {$condition} ORDER BY `{$id}` LIMIT 0,$num "); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $$id = $r[$id]; + $data = addslashes($post['type'] == 2 ? $post['add'].$r[$fields] : $r[$fields].$post['add']); + $db->query("UPDATE {$table} SET `{$fields}`='{$data}' WHERE `{$id}`={$$id}"); + } + $$id += 1; + } else { + $$id = $fid + $num; + } + } else { + msg('追加成功', '?file='.$file.'&action=replace'); + } + msg('ID '.$fid.'~'.($$id-1).'追加成功', '?file='.$file.'&action='.$action.'&fid='.$$id.'&tid='.$tid.'&num='.$num, 0); + break; + case 'replace_file': + if(!$file_pre) msg('请选择备份系列'); + if(!$file_from) msg('请请填写查找内容'); + isset($tid) or $tid = count(glob($D.$file_pre.'/*.sql')); + $fileid = isset($fileid) ? $fileid : 1; + $filename = $file_pre.'/'.$fileid.'.sql'; + $dfile = $D.$filename; + $file_from = urldecode($file_from); + $file_to = urldecode($file_to); + if(is_file($dfile)) { + $sql = file_get($dfile); + $sql = str_replace($file_from, $file_to, $sql); + file_put($dfile, $sql); + $fid = $fileid; + msg('分卷 #'.$fileid++.' 替换成功 程序将自动继续...'.progress(0, $fid, $tid), '?file='.$file.'&action='.$action.'&file_pre='.$file_pre.'&fileid='.$fileid.'&tid='.$tid.'&file_from='.urlencode($file_from).'&file_to='.urlencode($file_to), 0); + } else { + msg('文件内容替换成功', '?file='.$file.'&action=replace'); + } + break; + case 'open': + if(!$dir) msg('请选择备份系列'); + if(!is_dir($D.$dir)) msg('备份系列不存在'); + $sql = $sqls = array(); + $sqlfiles = glob($D.$dir.'/*.sql'); + if(!$sqlfiles) msg('备份系列文件不存在'); + $tid = count($sqlfiles); + foreach($sqlfiles as $id=>$sqlfile) { + $tmp = basename($sqlfile); + $size = filesize($sqlfile); + $sql['filename'] = $tmp; + $sql['filesize'] = round($size/(1024*1024), 2); + $sql['filesize'] = $sql['filesize'] < 0.01 ? round($size/1024, 2).'K' : $sql['filesize'].'M'; + $sql['pre'] = $dir; + $sql['number'] = str_replace('.sql', '', $tmp); + $sql['mtime'] = timetodate(filemtime($sqlfile), 5); + $sql['btime'] = substr(str_replace('.', ':', $dir), 0, -3); + $sqls[$sql['number']] = $sql; + } + include tpl('database_open'); + break; + case 'note': + if(!$dir) exit('ko'); + if(!is_dir($D.$dir)) exit('ko'); + file_put($D.$dir.'/0.txt', strip_tags($note)); + exit('ok'); + break; + case 'verify': + $sfields = array('按条件', '表名', '字段'); + $sorder = array('结果排序方式', '表名降序', '表名升序', '大小降序', '大小升序', '记录降序', '记录升序', '字段数降序', '字段数升序'); + $dstatus = array('未知', '异常', '通过'); + isset($fields) && isset($sfields[$fields]) or $fields = 0; + isset($order) && isset($sorder[$order]) or $order = 0; + isset($status) && isset($dstatus[$status]) or $status = -1; + $fields_select = dselect($sfields, 'fields', '', $fields); + $order_select = dselect($sorder, 'order', '', $order); + $status_select = dselect($dstatus, 'status', '状态', $status, '', 1, '-1'); + $dtables = $C = $T = $S = array(); + $i = 0; + $V = table_get_default(); + $result = $db->query("SHOW TABLES FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_row($result)) { + if(!$r[0]) continue; + $T[$r[0]] = $r[0]; + } + if($order < 2) { + uksort($T, 'strnatcasecmp'); + } else if($order == 2) { + krsort($T); + } + $O = array(); + $result = $db->query("SHOW TABLE STATUS FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_array($result)) { + $S[$r['Name']] = $r; + if($order == 3 || $order == 4) { + $O[$r['Name']] = $r['Data_length'] + $r['Index_length']; + } else if($order == 5 || $order == 6) { + $O[$r['Name']] = $r['Rows']; + } + } + if($O) { + if($order == 3 || $order == 5) { + arsort($O); + } else if($order == 4 || $order == 6) { + asort($O); + } + $T = array(); + foreach($O as $k=>$v) { + $T[$k] = $k; + } + } + $cols = array(); + foreach($T as $t) { + $r = $S[$t]; + $r['Name'] = $t; + if($kw) { + if($fields == 2) { + if(strpos($t, $DT_PRE) === false) continue; + $tmp = ''; + $names = parse_dict($t); + foreach($names as $kk => $vv) { + $tmp .= ' '.$kk; + } + if(stripos($tmp, $kw) === false) continue; + } else { + if(stripos($r['Name'], $kw) === false && stripos($r['Comment'], $kw) === false) continue; + } + } + if(preg_match('/^'.$DT_PRE.'/', $t)) { + $verify = 0; + $F = array(); + $result = $db->query("SHOW COLUMNS FROM `$t`"); + while($rr = $db->fetch_array($result)) { + $F[$rr['Field']] = str_replace(' unsigned', '', $rr['Type']); + } + $tb = $tn = substr($t, strlen($DT_PRE)); + $tb = preg_replace("/_[0-9]{1,}/", '', $tb); + if(is_numeric($tb) && isset($MODULE[$tb])) $tb = $MODULE[$tb]['module'].'_data'; + if(isset($V[$tb])) { + //自定义字段移除 + if(preg_match("/[0-9]{1,}/", $tn) && is_file(DT_CACHE.'/fields-'.$tn.'.php')) { + foreach(cache_read('fields-'.$tn.'.php') as $f) { + if(isset($F[$f['name']])) unset($F[$f['name']]); + } + } + if(count($V[$tb]) == count($F)) { + $verify = 2; + foreach($F as $k=>$v) { + if(!isset($V[$tb][$k])) {$verify = 1; break;} + $v = str_replace(array('longtext', 'mediumtext'), array('text', 'text'), strtolower($v)); + if(stripos($V[$tb][$k], $v) === false) {$verify = 1; break;} + } + } else { + $verify = 1; + } + } + if($status > -1 && $verify != $status) continue; + $dtables[$i]['verify'] = $verify; + $dtables[$i]['cols'] = $cols[$i] = count($F); + $dtables[$i]['name'] = $r['Name']; + $dtables[$i]['rows'] = $r['Rows']; + $dtables[$i]['size'] = round($r['Data_length']/1024/1024, 2); + $dtables[$i]['index'] = round($r['Index_length']/1024/1024, 2); + $dtables[$i]['tsize'] = round(($r['Data_length']+$r['Index_length'])/1024/1024, 2); + $dtables[$i]['auto'] = $r['Auto_increment']; + $dtables[$i]['updatetime'] = $r['Update_time']; + $dtables[$i]['note'] = $r['Comment']; + $dtables[$i]['chip'] = $r['Data_free']; + $C[str_replace($DT_PRE, '', $r['Name'])] = $r['Comment']; + $i++; + } + } + if($order == 7) { + array_multisort($cols, SORT_DESC, $dtables); + } else if($order == 8) { + array_multisort($cols, SORT_ASC, $dtables); + } + include tpl('database_verify'); + break; + case 'structure': + if(!isset($tables) || !is_array($tables)) msg('请选择需要导出的表'); + $dumpcharset = $sqlcharset ? $sqlcharset : $CFG['db_charset']; + if($db->version() > '4.1') { + if($sqlcharset) $db->query("SET NAMES '".$sqlcharset."';\n\n"); + if($sqlcompat == 'MYSQL40') { + $db->query("SET SQL_MODE='MYSQL40'"); + } else if($sqlcompat == 'MYSQL41') { + $db->query("SET SQL_MODE=''"); + } + } + $sqldump = "# DESTOON V".DT_VERSION." R".DT_RELEASE." https://www.destoon.com\n# ".timetodate($DT_TIME, 6)."\n# --------------------------------------------------------\n\n\n"; + foreach($tables as $table) { + $table = strip_sql($table, 0); + $sqldump .= sql_dumptable($table, 0, 0, 1); + } + $sqldump = preg_replace("/AUTO_INCREMENT\=([0-9]+)\s/", "", $sqldump); + $name = count($tables) == 1 ? $table : 'destoon_'.$action; + file_down('', $name.'.sql', $sqldump); + break; + case 'import': + if(isset($import)) { + if(isset($filename) && $filename && (file_ext($filename) == 'sql' || substr($filename, -8) == '.sql.php')) { + $dfile = $D.$filename; + if(!is_file($dfile)) msg('文件不存在,请检查'); + if(substr($filename, -8) == '.sql.php') { + @include $dfile; + file_del($dfile); + } else { + $sql = file_get($dfile); + sql_execute($sql); + } + msg($filename.' 导入成功', '?file='.$file.'&action=import'); + } else { + $fileid = isset($fileid) ? $fileid : 1; + $tid = isset($tid) ? intval($tid) : 0; + $filename = is_dir($D.$filepre) ? $filepre.'/'.$fileid : $filepre.$fileid; + $filename = $D.$filename.'.sql'; + if(is_file($filename)) { + $sql = file_get($filename); + if(substr($sql, 0, 11) == '# DESTOON V') { + $v = substr($sql, 11, 3); + if(DT_VERSION != $v) msg('由于数据结构存在差异,备份数据不可以跨版本导入
    备份版本:V'.$v.'
    当前系统:V'.DT_VERSION); + } + sql_execute($sql); + $prog = $tid ? progress(1, $fileid, $tid) : ''; + msg('分卷 #'.$fileid++.' 导入成功 程序将自动继续...'.$prog, '?file='.$file.'&action='.$action.'&filepre='.$filepre.'&fileid='.$fileid.'&tid='.$tid.'&import=1', 0); + } else { + msg('数据库恢复成功', '?file='.$file.'&action=import'); + } + } + } else { + $dbak = $dbaks = $dsql = $dsqls = $sql = $sqls = array(); + $sqlfiles = glob($D.'*'); + if(is_array($sqlfiles)) { + $class = 1; + foreach($sqlfiles as $id=>$sqlfile) { + $tmp = basename($sqlfile); + if(is_dir($sqlfile)) { + $dbak['filename'] = $tmp; + $size = $number = 0; + $ss = glob($D.$tmp.'/*.sql'); + foreach($ss as $s) { + $size += filesize($s); + $number++; + } + $dbak['filesize'] = round($size/(1024*1024), 2); + $dbak['filesize'] = $dbak['filesize'] < 0.01 ? round($size/1024, 2).'K' : $dbak['filesize'].'M'; + $dbak['pre'] = $tmp; + $dbak['number'] = $number; + $dbak['mtime'] = str_replace('.', ':', substr($tmp, 0, 19)); + $dbak['btime'] = substr($dbak['mtime'], 0, -3); + $dbak['note'] = file_get($D.$tmp.'/0.txt'); + $dbaks[] = $dbak; + } else { + if(preg_match("/([a-z0-9_]+_[0-9]{8}_[0-9a-z]{8}_)([0-9]+)\.sql/i", $tmp, $num)) { + $size = filesize($sqlfile); + $dsql['filename'] = $tmp; + $dsql['filesize'] = round($size/(1024*1024), 2); + $dsql['note'] = $dsql['filesize'] < 3 ? trim(cutstr(file_get($sqlfile), '#', "\n")) : ''; + $dsql['filesize'] = $dsql['filesize'] < 0.01 ? round($size/1024, 2).'K' : $dsql['filesize'].'M'; + $dsql['pre'] = $num[1]; + $dsql['number'] = $num[2]; + $dsql['mtime'] = timetodate(filemtime($sqlfile), 5); + if(preg_match("/[a-z0-9_]+_([0-9]{4})([0-9]{2})([0-9]{2})_([0-9]{2})([0-9]{2})([0-9a-z]{4})_/i", $num[1], $tm)) { + $dsql['btime'] = $tm[1].'-'.$tm[2].'-'.$tm[3].' '.$tm[4].':'.$tm[5]; + } else { + $dsql['btime'] = $dsql['mtime']; + } + if($dsql['number'] == 1) $class = $class ? 0 : 1; + $dsql['class'] = $class; + $dsqls[] = $dsql; + } else { + if(file_ext($tmp) != 'sql' && substr($tmp, -8) != '.sql.php') continue; + $size = filesize($sqlfile); + $sql['filename'] = $tmp; + $sql['filesize'] = round($size/(1024*1024), 2); + $sql['note'] = $sql['filesize'] < 3 ? trim(cutstr(file_get($sqlfile), '#', "\n")) : ''; + $sql['filesize'] = $sql['filesize'] < 0.01 ? round($size/1024, 2).'K' : $sql['filesize'].'M'; + $sql['mtime'] = timetodate(filemtime($sqlfile), 5); + $sqls[] = $sql; + } + } + } + } + } + if($dbaks) $dbaks = array_reverse($dbaks); + include tpl('database_import'); + break; + default: + if(isset($backup)) { + $fileid = isset($fileid) ? intval($fileid) : 1; + $sizelimit = $sizelimit ? intval($sizelimit) : 2048; + if($fileid == 1 && $tables) { + if(!isset($tables) || !is_array($tables)) msg('请选择需要备份的表'); + $random = timetodate($DT_TIME, 'Y-m-d H.i.s').' '.random(10, 'a-z'); + $tsize = 0; + foreach($tables as $k=>$v) { + $v = strip_sql($v, 0); + $tables[$k] = $v; + $tsize += $sizes[$v]; + } + $tid = ceil($tsize*1024/$sizelimit); + if($note) { + $note = trim(dhtmlspecialchars(strip_tags($note))); + file_put($D.$random.'/0.txt', $note); + } + cache_write($_username.'_backup.php', $tables); + } else { + if(!$tables = cache_read($_username.'_backup.php')) msg('请选择需要备份的表'); + } + $dumpcharset = $sqlcharset ? $sqlcharset : $CFG['db_charset']; + if($db->version() > '4.1') { + if($sqlcharset) $db->query("SET NAMES '".$sqlcharset."';\n\n"); + if($sqlcompat == 'MYSQL40') { + $db->query("SET SQL_MODE='MYSQL40'"); + } else if($sqlcompat == 'MYSQL41') { + $db->query("SET SQL_MODE=''"); + } + } + $sqldump = ''; + $tableid = isset($tableid) ? $tableid - 1 : 0; + $startfrom = isset($startfrom) ? intval($startfrom) : 0; + $tablenumber = count($tables); + for($i = $tableid; $i < $tablenumber && strlen($sqldump) < $sizelimit * 1000; $i++) { + $sqldump .= sql_dumptable($tables[$i], $startfrom, strlen($sqldump)); + $startfrom = 0; + } + if(trim($sqldump)) { + $sqldump = "# DESTOON V".DT_VERSION." R".DT_RELEASE." https://www.destoon.com\n# ".timetodate($DT_TIME, 6)."\n# --------------------------------------------------------\n\n\n".$sqldump; + $tableid = $i; + $filename = $random.'/'.$fileid.'.sql'; + file_put($D.$filename, $sqldump); + $fid = $fileid; + msg('分卷 #'.$fileid++.' 备份成功.. 程序将自动继续...'.progress(0, $fid, $tid), '?file='.$file.'&sizelimit='.$sizelimit.'&sqlcompat='.$sqlcompat.'&sqlcharset='.$sqlcharset.'&tableid='.$tableid.'&fileid='.$fileid.'&fileid='.$fileid.'&tid='.$tid.'&startfrom='.$startrow.'&random='.$random.'&backup=1', 0); + } else { + cache_delete($_username.'_backup.php'); + $db->query("DELETE FROM {$DT_PRE}setting WHERE item='destoon' AND item_key='backtime'"); + $db->query("INSERT INTO {$DT_PRE}setting (item,item_key,item_value) VALUES('destoon','backtime','$DT_TIME')"); + msg('数据库备份成功', '?file='.$file.'&action=import'); + } + } else { + $sfields = array('按条件', '表名', '字段'); + $sorder = array('结果排序方式', '表名降序', '表名升序', '大小降序', '大小升序', '记录降序', '记录升序'); + isset($fields) && isset($sfields[$fields]) or $fields = 0; + isset($order) && isset($sorder[$order]) or $order = 0; + $fields_select = dselect($sfields, 'fields', '', $fields); + $order_select = dselect($sorder, 'order', '', $order); + $dtables = $tables = $C = $T = $S = array(); + $i = $j = $dtotalsize = $totalsize = 0; + $result = $db->query("SHOW TABLES FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_row($result)) { + if(!$r[0]) continue; + $T[$r[0]] = $r[0]; + } + if($order < 2) { + uksort($T, 'strnatcasecmp'); + } else if($order == 2) { + krsort($T); + } + $O = array(); + $result = $db->query("SHOW TABLE STATUS FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_array($result)) { + $S[$r['Name']] = $r; + if($order == 3 || $order == 4) { + $O[$r['Name']] = $r['Data_length'] + $r['Index_length']; + } else if($order == 5 || $order == 6) { + $O[$r['Name']] = $r['Rows']; + } + } + if($O) { + if($order == 3 || $order == 5) { + arsort($O); + } else if($order == 4 || $order == 6) { + asort($O); + } + $T = array(); + foreach($O as $k=>$v) { + $T[$k] = $k; + } + } + foreach($T as $t) { + $r = $S[$t]; + $r['Name'] = $t; + if($kw) { + if($fields == 2) { + if(strpos($t, $DT_PRE) === false) continue; + $tmp = ''; + $names = parse_dict($t); + foreach($names as $kk => $vv) { + $tmp .= ' '.$kk; + } + if(stripos($tmp, $kw) === false) continue; + } else { + if(stripos($r['Name'], $kw) === false && stripos($r['Comment'], $kw) === false) continue; + } + } + if(strpos($r['Comment'], 'is marked as crashed and should be repaired') !== false) { + $r['Comment'] = ''; + $db->query("REPAIR TABLE `{$t}`"); + } + if(preg_match('/^'.$DT_PRE.'/', $t)) { + $dtables[$i]['name'] = $r['Name']; + $dtables[$i]['rows'] = $r['Rows']; + $dtables[$i]['size'] = round($r['Data_length']/1024/1024, 2); + $dtables[$i]['index'] = round($r['Index_length']/1024/1024, 2); + $dtables[$i]['tsize'] = round(($r['Data_length']+$r['Index_length'])/1024/1024, 2); + $dtables[$i]['auto'] = $r['Auto_increment']; + $dtables[$i]['updatetime'] = $r['Update_time']; + $dtables[$i]['note'] = $r['Comment']; + $dtables[$i]['chip'] = $r['Data_free']; + $dtotalsize += $r['Data_length']+$r['Index_length']; + $C[str_replace($DT_PRE, '', $r['Name'])] = $r['Comment']; + $i++; + } else { + $tables[$j]['name'] = $r['Name']; + $tables[$j]['rows'] = $r['Rows']; + $tables[$j]['size'] = round($r['Data_length']/1024/1024, 2); + $tables[$j]['index'] = round($r['Index_length']/1024/1024, 2); + $tables[$j]['tsize'] = round(($r['Data_length']+$r['Index_length'])/1024/1024, 2); + $tables[$j]['auto'] = $r['Auto_increment']; + $tables[$j]['updatetime'] = $r['Update_time']; + $tables[$j]['note'] = $r['Comment']; + $tables[$j]['chip'] = $r['Data_free']; + $totalsize += $r['Data_length']+$r['Index_length']; + $j++; + } + } + //cache_write('comment.php', $C); + $dtotalsize = round($dtotalsize/1024/1024, 2); + $totalsize = round($totalsize/1024/1024, 2); + include tpl('database'); + } + break; +} +?> \ No newline at end of file diff --git a/admin/doctor.inc.php b/admin/doctor.inc.php new file mode 100644 index 0000000..8b2741d --- /dev/null +++ b/admin/doctor.inc.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/admin/fetch.inc.php b/admin/fetch.inc.php new file mode 100644 index 0000000..0989def --- /dev/null +++ b/admin/fetch.inc.php @@ -0,0 +1,66 @@ +query("INSERT INTO {$DT_PRE}fetch (sitename,domain,encode,title,content,editor,edittime) VALUES ('$sitename','$domain','$encode','$title','$content','$_username','$DT_TIME')"); + dmsg('添加成功', $forward); + } else { + $domain = $sitename = $title = ''; + $encode = strtolower(DT_CHARSET); + $content = '
    [content]
    '; + include tpl('fetch_edit'); + } + break; + case 'edit': + $itemid or msg('请选择规则'); + if($submit) { + if(!$domain) msg('请输入采编域名'); + if(strpos($content, '[content]') === false) msg('请输入内容规则'); + $db->query("UPDATE {$DT_PRE}fetch SET sitename='$sitename',domain='$domain',encode='$encode',title='$title',content='$content',editor='$_username',edittime='$DT_TIME' WHERE itemid=$itemid"); + dmsg('修改成功', $forward); + } else { + extract($db->get_one("SELECT * FROM {$DT_PRE}fetch WHERE itemid=$itemid")); + include tpl('fetch_edit'); + } + break; + case 'delete': + $itemid or msg('请选择规则'); + $ids = is_array($itemid) ? implode(',', $itemid) : $itemid; + $db->query("DELETE FROM {$DT_PRE}fetch WHERE itemid IN ($ids)"); + dmsg('删除成功', $forward); + break; + default: + $sfields = array('按条件', '域名', '网站', '编辑'); + $dfields = array('domain', 'domain', 'sitename', 'username'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $fields_select = dselect($sfields, 'fields', '', $fields); + $condition = '1'; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}fetch WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}fetch WHERE $condition ORDER BY itemid DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['edittime'] = timetodate($r['edittime'], 5); + $lists[] = $r; + } + include tpl('fetch'); + break; +} +?> \ No newline at end of file diff --git a/admin/fields.inc.php b/admin/fields.inc.php new file mode 100644 index 0000000..103a3ba --- /dev/null +++ b/admin/fields.inc.php @@ -0,0 +1,193 @@ +tb = $tb; +$menus = array ( + array('添加字段', '?file='.$file.'&tb='.$tb.'&action=add'), + array('字段列表', '?file='.$file.'&tb='.$tb), +); +$this_forward = '?moduleid='.$moduleid.'&file='.$file.'&tb='.$tb; +switch($action) { + case 'add': + if($submit) { + if($do->pass($post)) { + $do->add($post); + dmsg('添加成功', $this_forward); + } else { + msg($do->errmsg); + } + } else { + include tpl('fields_add'); + } + break; + case 'edit': + $itemid or msg(); + $do->itemid = $itemid; + if($submit) { + if($do->pass($post)) { + $do->edit($post); + dmsg('修改成功', $this_forward); + } else { + msg($do->errmsg); + } + } else { + extract($do->get_one()); + include tpl('fields_edit'); + } + break; + case 'update': + $do->update($post); + dmsg('更新成功', $this_forward); + break; + default: + $lists = $do->get_list("tb='$tb'"); + cache_fields($tb); + include tpl('fields'); + break; +} + +class fields { + var $itemid; + var $tb; + var $table; + var $errmsg = errmsg; + + function __construct() { + $this->table = DT_PRE.'fields'; + } + + function fields() { + $this->__construct(); + } + + function pass($post) { + if(!is_array($post)) return false; + if(!$post['name']) return $this->_('请填写字段'); + if(!preg_match("/^[a-z0-9]+$/", $post['name'])) return $this->_('字段名只能为小写字母和数字的组合'); + if(!$post['title']) return $this->_('请填写字段名称'); + if(in_array($post['html'], array('select', 'radio', 'checkbox'))) { + if(!$post['option_value']) return $this->_('请填写选项值'); + if(strpos($post['option_value'], '|') === false) return $this->_('请填写正确的选项值'); + } + return true; + } + + function set($post) { + if(!in_array($post['html'], array('select', 'radio', 'checkbox'))) { + $post['option_value'] = ''; + } + $post['length'] = intval($post['length']); + if($post['html'] == 'textarea') { + if($post['type'] != 'varchar' && $post['type'] != 'text') $post['type'] = 'text'; + } else if($post['html'] == 'checkbox' || $post['html'] == 'thumb' || $post['html'] == 'file') { + $post['type'] = 'varchar'; + $post['length'] = 255; + } else if($post['html'] == 'editor') { + $post['type'] = 'text'; + } else if($post['html'] == 'area') { + $post['type'] = 'int'; + $post['length'] = 10; + } + return $post; + } + + function get_one() { + return DB::get_one("SELECT * FROM {$this->table} WHERE itemid='$this->itemid'"); + } + + function get_list($condition = '', $order = 'listorder ASC,itemid ASC') { + global $MOD, $pages, $page, $pagesize, $offset, $sum; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = DB::get_one("SELECT COUNT(*) AS num FROM {$this->table} WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $lists[] = $r; + } + return $lists; + } + + function add($post) { + $post = $this->set($post); + $length = 0; + if($post['type'] == 'varchar') { + $length = min($post['length'], 255); + } else if($post['type'] == 'int') { + $length = min($post['length'], 10); + } + $type = strtoupper($post['type']); + if($length) $type .= "($length)"; + $name = '`'.$post['name'].'`'; + DB::query("ALTER TABLE ".DT_PRE."{$this->tb} ADD $name $type NOT NULL"); + $sqlk = $sqlv = ''; + foreach($post as $k=>$v) { + $sqlk .= ','.$k; $sqlv .= ",'$v'"; + } + $sqlk = substr($sqlk, 1); + $sqlv = substr($sqlv, 1); + DB::query("INSERT INTO {$this->table} ($sqlk) VALUES ($sqlv)"); + return $this->itemid; + } + + function edit($post) { + $post = $this->set($post); + $length = 0; + if($post['type'] == 'varchar') { + $length = min($post['length'], 255); + } else if($post['type'] == 'int') { + $length = min($post['length'], 10); + } + $type = strtoupper($post['type']); + if($length) $type .= "($length)"; + $cname = '`'.$post['cname'].'`'; + unset($post['cname']); + $name = '`'.$post['name'].'`'; + DB::query("ALTER TABLE ".DT_PRE."{$this->tb} CHANGE $cname $name $type NOT NULL"); + $sql = ''; + foreach($post as $k=>$v) { + $sql .= ",$k='$v'"; + } + $sql = substr($sql, 1); + DB::query("UPDATE {$this->table} SET $sql WHERE itemid=$this->itemid"); + return true; + } + + function delete($itemid) { + $this->itemid = $itemid; + $r = $this->get_one(); + $name = '`'.$r['name'].'`'; + DB::query("DELETE FROM {$this->table} WHERE itemid=$itemid"); + DB::query("ALTER TABLE ".DT_PRE."{$this->tb} DROP $name"); + } + + function update($post) { + foreach($post as $k=>$v) { + $k = intval($k); + if(isset($v['delete']) && $v['delete']) { + $this->delete($k); + } else { + $listorder = intval($v['listorder']); + $title = $v['title']; + $display = $v['display'] ? 1 : 0; + $front = $v['front'] ? 1 : 0; + DB::query("UPDATE {$this->table} SET listorder=$listorder,display=$display,front=$front,title='$title' WHERE itemid=$k"); + } + } + return true; + } + + function _($e) { + $this->errmsg = $e; + return false; + } +} +?> \ No newline at end of file diff --git a/admin/history.inc.php b/admin/history.inc.php new file mode 100644 index 0000000..c547630 --- /dev/null +++ b/admin/history.inc.php @@ -0,0 +1,104 @@ + 4) { + if($action) { + $table = str_replace('_'.$mid, '_'.$action.'_'.$mid, get_table($mid)); + if($action == 'resume') { + $table_data = $DT_PRE.'job_resume_data_'.$mid; + } else { + $table_data = ''; + } + } else { + $table = get_table($mid); + $table_data = get_table($mid, 1); + } + $csv = cutstr($table, $DT_PRE, '_'.$mid); +} else if($mid == 2) { + $table = $DT_PRE.$action; + $table_data = $DT_PRE.$action.'_data'; + $csv = $action; +} +is_file($cache) or msg('记录不存在'); +$arr = unserialize(substr(file_get($cache), 13)); +$arr or msg('记录不存在'); +$item = $db->get_one("SELECT * FROM {$table} WHERE itemid=$itemid"); +$item or msg('记录不存在'); +$lists = $tags = $names = array(); +$text = file_get(DT_ROOT.'/file/setting/'.$csv.'.csv'); +if($text) { + foreach(explode("\n", $text) as $v) { + $t = explode(',', trim($v)); + if($t[0]) $names[$t[0]] = $t[1]; + } +} else { + msg('记录不存在'); +} +foreach($item as $k=>$v) { + if(!isset($arr[$k])) continue; + $o = $arr[$k]; + if(strlen($v) < 32) { + if($o == $v) continue; + } else { + if(md5($o) == md5($v)) continue; + } + if(in_array($k, array('keyword', 'status', 'content'))) { + continue; + } else if($k == 'catid') { + if($v) $v = cat_pos(get_cat($v), ' - '); + if($o) $o = cat_pos(get_cat($o), ' - '); + } else if($k == 'areaid') { + if($v) $v = area_pos($v, ' - '); + if($o) $o = area_pos($o, ' - '); + } else if($k == 'thumb') { + if(is_url($v)) $v = ''; + if(is_url($o)) $o = ''; + } else if($k == 'thumbs') { + if($v) { + $t = ''; + foreach(explode('|', $v) as $s) { + if(is_url($s)) $t .= ''; + } + $v = $t; + } + if($o) { + $t = ''; + foreach(explode('|', $o) as $s) { + if(is_url($s)) $t .= ''; + } + $o = $t; + } + } else if(strpos($k, 'time') !== false && is_numeric($v)) { + $v = timetodate($v, 6); + $o = timetodate($o, 6); + } else { + if(is_url($v)) $v = ''.$v.''; + if(is_url($o)) $o = ''.$o.''; + } + $name = isset($names[$k]) ? $names[$k] : $k; + $lists[$k] = array('name' => $name, 'new' => $v, 'old' => $o); +} +$new = $old = ''; +if(isset($arr['content'])) { + if($table_data) { + $t = $db->get_one("SELECT * FROM {$table_data} WHERE itemid=$itemid"); + if($t) { + $new = $t['content']; + $old = $arr['content']; + if(md5($old) == md5($t['content'])) $new = ''; + } + } else { + if(isset($item['content'])) { + $new = $item['content']; + $old = $arr['content']; + if(md5($old) == md5($item['content'])) $new = ''; + } + } +} +include tpl('history'); +?> \ No newline at end of file diff --git a/admin/html.inc.php b/admin/html.inc.php new file mode 100644 index 0000000..cb6e7ce --- /dev/null +++ b/admin/html.inc.php @@ -0,0 +1,174 @@ + $v) { + if($v == $mid) { $moduleids = $k; break; } + } + msg('['.$MODULE[$mid]['name'].'] 更新成功', '?file='.$file.'&action=module&moduleids='.($moduleids+1)); + break; + case 'module': + if(isset($moduleids)) { + unset($MODULE[1]); + unset($MODULE[2]); + $KEYS = array_keys($MODULE); + if(isset($KEYS[$moduleids])) { + $bmoduleid = $moduleid = $KEYS[$moduleids]; + if(is_file(DT_ROOT.'/module/'.$MODULE[$moduleid]['module'].'/admin/html.inc.php')) { + msg('', '?moduleid='.$moduleid.'&file='.$file.'&action=all&one=1'); + } else { + msg('['.$MODULE[$bmoduleid]['name'].'] 更新成功', '?file='.$file.'&action='.$action.'&moduleids='.($moduleids+1)); + } + } else { + msg('模块更新成功', '?file='.$file.'&action=index'); + } + } else { + $moduleids = 0; + msg('开始更新模块', '?file='.$file.'&action='.$action.'&moduleids='.$moduleids); + } + break; + case 'start': + msg('正在开始更新全站', '?file='.$file.'&action=cache'); + break; + case 'cacheclear': + if($CFG['cache'] == 'file') dheader('?file='.$file.'&action=fileclear'); + $dc->clear(); + msg('缓存更新成功', '?file='.$file); + break; + case 'fileclear': + $job = 'php'; + if(isset($dir)) { + isset($cf) or $cf = 0; + isset($cd) or $cd = 0; + if(preg_match("/^".$job."[0-9]{14}$/", $dir)) { + $dirs = glob(DT_CACHE.'/'.$dir.'/*'); + if($dirs) { + $sub = $dirs[array_rand($dirs)]; + file_del($sub.'/index.html'); + $files = glob($sub.'/*.php'); + if($files) { + $i = 0; + foreach($files as $f) { + file_del($f); + $cf++; + $i++; + if($i > 500) msg('已删除 '.$cd.' 个目录,'.$cf.' 个文件'.progress(0, $cd, $tt), '?file='.$file.'&action='.$action.'&dir='.$dir.'&cd='.$cd.'&cf='.$cf.'&job='.$job.'&tt='.$tt, 0); + } + dir_delete($sub); + $cd++; + msg('已删除 '.$cd.' 个目录,'.$cf.' 个文件'.progress(0, $cd, $tt), '?file='.$file.'&action='.$action.'&dir='.$dir.'&cd='.$cd.'&cf='.$cf.'&job='.$job.'&tt='.$tt, 0); + } else { + dir_delete($sub); + $cd++; + msg('已删除 '.$cd.' 个目录,'.$cf.' 个文件'.progress(0, $cd, $tt), '?file='.$file.'&action='.$action.'&dir='.$dir.'&cd='.$cd.'&cf='.$cf.'&job='.$job.'&tt='.$tt, 0); + } + } else { + dir_delete(DT_CACHE.'/'.$dir); + msg('缓存更新成功', '?file='.$file); + } + } else { + msg('目录名错误'); + } + } else { + $dir = $job.timetodate($DT_TIME, 'YmdHis'); + if(rename(DT_CACHE.'/'.$job, DT_CACHE.'/'.$dir)) { + dir_create(DT_CACHE.'/'.$job); + file_del(DT_CACHE.'/'.$dir.'/index.html'); + $dirs = glob(DT_CACHE.'/'.$dir.'/*'); + $tt = count($dirs); + msg('正在更新,此操作可能用时较长,请不要中断..', '?file='.$file.'&action='.$action.'&dir='.$dir.'&job='.$job.'&tt='.$tt); + } else { + msg('更新失败'); + } + } + break; + case 'homepage': + cache_clear_tag(1); + $db->expires = $CFG['db_expires'] = 0; + tohtml('index'); + $filename = $CFG['com_dir'] ? DT_ROOT.'/'.$DT['index'].'.'.$DT['file_ext'] : DT_CACHE.'/index.inc.html'; + msg('网站首页生成成功 '.(is_file($filename) ? dround(filesize($filename)/1024).'Kb ' : ''), '?file='.$file); + break; + case 'template': + cache_clear_tag(1); + cache_clear('php', 'dir', 'tpl'); + msg('模板缓存更新成功', '?file='.$file); + break; + case 'caches': + isset($step) or $step = 0; + if($step == 1) { + cache_clear('module'); + cache_module(); + msg('系统设置更新成功', '?file='.$file.'&action='.$action.'&step='.($step+1)); + } else if($step == 2) { + cache_clear_tag(1); + msg('标签调用缓存更新成功', '?file='.$file.'&action='.$action.'&step='.($step+1)); + } else if($step == 3) { + cache_clear('php', 'dir', 'tpl'); + msg('模板缓存更新成功', '?file='.$file.'&action='.$action.'&step='.($step+1)); + } else if($step == 4) { + cache_clear('cat'); + cache_category(); + msg('分类缓存更新成功', '?file='.$file.'&action='.$action.'&step='.($step+1)); + } else if($step == 5) { + cache_clear('area'); + cache_area(); + msg('地区缓存更新成功', '?file='.$file.'&action='.$action.'&step='.($step+1)); + } else if($step == 6) { + cache_clear('fields'); + cache_fields(); + cache_clear('option'); + msg('自定义字段更新成功', '?file='.$file.'&action='.$action.'&step='.($step+1)); + } else if($step == 7) { + cache_clear_ad(); + tohtml('index'); + msg('全部缓存更新成功', '?file='.$file); + } else { + cache_clear('group'); + cache_group(); + cache_clear('type'); + cache_type(); + cache_clear('keylink'); + cache_keylink(); + cache_pay(); + cache_weixin(); + cache_banip(); + cache_banword(); + cache_bancomment(); + msg('正在开始更新缓存', '?file='.$file.'&action='.$action.'&step='.($step+1)); + } + break; + default: + include tpl('html'); + break; +} +?> \ No newline at end of file diff --git a/admin/image/add.png b/admin/image/add.png new file mode 100644 index 0000000000000000000000000000000000000000..35376ee2ced6bdf6726fac6899e87fe729018cca GIT binary patch literal 3664 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 JPDHLkV1na7X)XW& literal 0 HcmV?d00001 diff --git a/admin/image/arrow-r.png b/admin/image/arrow-r.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b1142c75fc47e4afeced2de751659ca541b33b GIT binary patch literal 2831 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 literal 0 HcmV?d00001 diff --git a/admin/image/arrow-u.png b/admin/image/arrow-u.png new file mode 100644 index 0000000000000000000000000000000000000000..0843c54447831ae47c7f0659c7937eedf234d855 GIT binary patch literal 2857 zcmV+^3)b|BP)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde00d`2O+f$vv5tKEQIh}w03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(` z>RI+y?e7jKeZ#YO-C07gkfK~#9!?9(v{05A+f(VyJ^&h`X_bdXTc(Z#n|lGseM zoB#rt0JI4ZP)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde00d`2O+f$vv5tKEQIh}w03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(` z>RI+y?e7jKeZ#YO-C0%J);K~#9!%$d=VgD?z4W6gCFt|8J-I!PLW)Z_c`9J3?K zi$oG^e-Q^fdaPv0A}!03b51E;d;@RJIhPBZ!KKWV@Av!V-0_1ZdIsKHKUiiqw$RGo z8}f}s2VvWR-2Bk|$!{(*{E^O(#W*EJ9fa!NGLIoTl$b(1t=7{t9U~AQ8Ane+7-dsS zPgC~V1(cp0fdws77`tYfnWH73(z%bj=Kq1Rv_$541+^W4QtV``y z6e%#1^RwZnzz%QVJ-{0vQg*(E` z^KG7Q$2ev8-ETV$5|)c)Sxru}sEEp_2-QW1Q+TaYt-Wy?cEbBk$lsD$_3~QHlp!E@`-r?T>1+{oZhwSM&&q+# z4hZiji~>pCI#v#8P`$M+uQyo2`QYd+x4XNDE6o+J2^ON2vF=;kIh`;SNlzD5f z4`g(AHNBA(<()g|p>K7(OG1kBUSVl>2AtNA+eZ9!$Aij~*6UO`Tv>KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde00d`2O+f$vv5tKEQIh}w03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(` z>RI+y?e7jKeZ#YO-C0BuP`K~#9!tdl_w03iqi?f)NLFAE`92wCMOr4vyA$#oMT zxd0r(2R1sY8VLwy6R02(5Y3iXISHr=JFo*fa|Llg*JlUuUznQZO+pKt60A1A!CL^+ uh-PgBuyduo2ONtM07}bq@P8X`Vh;eJKfmF_gT6Na0000KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde00d`2O+f$vv5tKEQIh}w03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(` z>RI+y?e7jKeZ#YO-C0BcD^K~#9!q*Fl-z#s@~3IG2xyX@c=D5#uFEVY!%h=8a7 zKm~Boh_`t?w*(oO;_gGx$z_JK>8wAZ=sZ{@Ly`N?{ZgUfvaShyV$_KTm~O?27sv7T sLN=Rtmm@IA0CxU@jP1!9TO*$V08z~rIcu$X#{d8T07*qoM6N<$f~};17XSbN literal 0 HcmV?d00001 diff --git a/admin/image/bar3.png b/admin/image/bar3.png new file mode 100644 index 0000000000000000000000000000000000000000..3825a743073b96492d0a5d3480e02a28de4c1205 GIT binary patch literal 2869 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 THik=700000NkvXXu0mjfSq^Q` literal 0 HcmV?d00001 diff --git a/admin/image/bar4.png b/admin/image/bar4.png new file mode 100644 index 0000000000000000000000000000000000000000..2858d833dd137209cf061d651ef0fbad6fa0f625 GIT binary patch literal 2865 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 P00000NkvXXu0mjf>sxLO literal 0 HcmV?d00001 diff --git a/admin/image/bar5.png b/admin/image/bar5.png new file mode 100644 index 0000000000000000000000000000000000000000..7dcffd2e60c48f9b99da390abc55d71867824954 GIT binary patch literal 2850 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 A_y7O^ literal 0 HcmV?d00001 diff --git a/admin/image/bar6.png b/admin/image/bar6.png new file mode 100644 index 0000000000000000000000000000000000000000..cff60c6bbaca2507676792e167fa3bddf1181a95 GIT binary patch literal 2875 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 Z0|3e>4=D{qfZzZC002ovPDHLkV1hufZ(aZZ literal 0 HcmV?d00001 diff --git a/admin/image/bar7.png b/admin/image/bar7.png new file mode 100644 index 0000000000000000000000000000000000000000..8b4c361de97eea559cddf58a31ad4bde8d561276 GIT binary patch literal 2869 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 TqkwPB00000NkvXXu0mjfHW6-| literal 0 HcmV?d00001 diff --git a/admin/image/child.png b/admin/image/child.png new file mode 100644 index 0000000000000000000000000000000000000000..badb78d1cbd0bdeaa935f44de112d96ab5bfa84b GIT binary patch literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl~+i(^Q|t)v7;W(LM13`#Q=FdSjyQ0QPVmS}KgVB*j? zz`>@#$hLsPfngy>LkS~`0CNblk2tpjgCmPTR|HUnGlN2d!~wShrG^_BSOnS_92g86 z&bkOOa44)`kZ53KVCrBz8nyr=yx~BqA`=5+%OlGP-i$!uyT2J2*%<0&na)4HV%rCF O41=eupUXO@geCyJxlRB8 literal 0 HcmV?d00001 diff --git a/admin/image/count.gif b/admin/image/count.gif new file mode 100644 index 0000000000000000000000000000000000000000..dba81f5113f127557dfdfad9ad5208bfd694c322 GIT binary patch literal 310 zcmZ?wbhEHbf=ZVnkn}S!FamXRfb`2GSO_27H%%Z}3|T)5P&Y_F z7fW06NtuTW1agq185!7NwzIS;CkZcfsalC-I12+zHxJMwD|QRAF)({oae<8I1pAa7 SVf&P{#ZrcQ86=8C7_0#!o;rsB literal 0 HcmV?d00001 diff --git a/admin/image/css.gif b/admin/image/css.gif new file mode 100644 index 0000000000000000000000000000000000000000..8feabe3dbc7351c44ac00394fc2f70305661cbf9 GIT binary patch literal 594 zcmb`E+fPyf0LBlc+1AZU6T4U^?J^_F)eQBaNUf;sL3?S<=Iy;%ZTVssz}ePZ(M7gq zo13miW`~hDP}FF7IcA6HAOpot;=#lr5@8(F^QHX_eGlKhr{BZxJ1ajU%`Ax}VhIni z5&*9crhBL7Je;qpN~=`9_4$GoHyUr=YPwzd>dxIaO4YlX2h_vb_qC7P)X$8X7iLX; zcayfiQQN20F)fB6%4qB8VGUglqs2Kj6RLUH-~HL$PIE;HbA20Ip&8cEvpr*xE?Z!H zD)@0UqVJn%w(`_4Z?N;muY9M2H`xLmw!jb@phnQ@M7s+eE?8K6@qqEb?!|XMxL*iG zz%PRO29paPSbUm5?<58|FjKI3F**xx2-*?ooM;_GI}3{&gFnFqF&D=5&OiEb7=M5b z2$Mm7`snzWYO&~forpZJbG0f_Q+Dk#x$n~MC}n~s zJ1d{uab(Y0Wqe(8ejaHe^@^>cvgX3P%#^gld(GvWOS4un){G0ubZki>Bh5W=T6Stb zy|FmYYCU;gLT@O#=on>=%Ma0Ou1F`DW9L%obp^RO8H&XQGPzeBN5|zR7UVQMN=mO3 f%hVD}LfX~VVpD1Kz|+*DPe`#`pCXstCy4C7BmOrD literal 0 HcmV?d00001 diff --git a/admin/image/delete.png b/admin/image/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..6fc4d3b2030ecf772fae856411c7b0968d99005b GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLli5Jei0#Y0$L4LviA%Njt^WI31l&6bhNX4zB1b1cz#v=#L9XQ1BeB*}A z%q#-T*4)b4(o?t>F*0#zoIb=Q$oTmtkhx|Ks|wRYkOCL`0G3nf>>LU!8g&ecZvf@i zF{v>LIB*y*Py(9O5Wuep(t6;`5vIViTuKZ~9gTA(-x+M+aA06$eNbb-z@e}}OvNsM m(}BTo!EZ5z1_KrbCLV@_U2LV?JKcpq4)=8Rb6Mw<&;$Tia9maZ literal 0 HcmV?d00001 diff --git a/admin/image/dialog-close-on.png b/admin/image/dialog-close-on.png new file mode 100644 index 0000000000000000000000000000000000000000..b6ff351e37d1c3de89b0a346b2a2cfd825709fb5 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%``JOJ0Ar}5?gAWQe7;t!-6^XbP zn79{+n0K{bXXpB*@#JtU_f8dE7eSqKi>EtW;!IG^GJ?B1Ddxh$&OO9f7!kND?dTzzpjw=tKV($)aMw;DY2 QfmSnky85}Sb4q9e00!MQAOHXW literal 0 HcmV?d00001 diff --git a/admin/image/dialog-close.png b/admin/image/dialog-close.png new file mode 100644 index 0000000000000000000000000000000000000000..21bb7d6b69ea1e8c15341f76147cffafe01a0eb0 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`6`n4RAr}70DGLM)f>z9L+{LzH zb$0BJ@BM}kzr9^8zG0_NXz1;R&X@n2W}B~>+{$oq9z#bv`|(K8|7RH1EM%;!+W@rl%$ff) zXP){0|Noy*%+B9=lNdxR0lGTCPZRLGK012lzcvQJL|i0{bqbP0l+XkKJS4LG literal 0 HcmV?d00001 diff --git a/admin/image/folder.gif b/admin/image/folder.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b81ffbc9bd48637aeea9d8b97ffd86d27ba6cca GIT binary patch literal 345 zcmV-f0jB;(Nk%w1VGsZg0M!5h00030|NsC0&Hw+>|Nqzj|Kb1t>Hq)i{{HL#|L^|( z?*9Jp|Nrv+`^EkH$o~A;{ru(r{pbGu?fv}h@9VMp_PYD`z5DmU{rcGa`rrNg3R_U*d&@4)!*!};^i`}WrS_}=~c=-$qK(!_c6=%}iZH?*ElxusjgvvkkE zj{pDvA^8LW002J#EC2ui01yBU000Jdz@BbM-2INoqmCkIHc7lBQdhZItrZ-R=+l+H z;4rwgEt`oOhI*Yi7z%^|Ww@x<6^O{g(dajZ9Dx!c5EvI0h>1fJ6CxTJARdyFl0!Bt rH7Oq*oSmIRDl{l2Bc-ONLo+8bFD|aHutPC0IV`rfxGZP8LqPyL9C6!d literal 0 HcmV?d00001 diff --git a/admin/image/htm.gif b/admin/image/htm.gif new file mode 100644 index 0000000000000000000000000000000000000000..29623295f527387d38df7b47e39ce0ddf0e159ec GIT binary patch literal 599 zcmb`E+fPyf0LBkt`A``ZS(X)O7cFY*Vq$G2OG-<7h_=>)O_QFR)mA-Nj-#{9xw4gP z&DMji4KLwH9XB;xDyQr;9A@6=Bpy^8AQ8sFJYUk^(D(4|d-^^6zVmtKW$?=YzoH5FC+vTgl#3G( zgqo1Wps`Pg`1W$OhODU6>`YGDvUy{|+Bor=%B_MIbppx09jhv~X-lqOk?gs&OGqYa zPi7TJwjbUdPm1fB3vwhTi9xeTP|~c*k*6M#Nv&$pjVz^7o=In1OrbUutLV(LboQCO z)cT?vnpK{@aFAM8m`|Tj(8ux)P^+&wlo{Fd(cE-OoST%Qe*GlrNKvw)R;Cb3kC#Vg kZNmP9)cwz-k=~otiL$FL*$*zWN`o*>)s&x}CL&J#1(r-WT>t<8 literal 0 HcmV?d00001 diff --git a/admin/image/img.gif b/admin/image/img.gif new file mode 100644 index 0000000000000000000000000000000000000000..d44d2498564cc6f25fd99c415f2e9507300077c7 GIT binary patch literal 520 zcmZ?wbhEHb+cC*}&knBck~bL)1BL`!?5t)eLc0`674nxKFgt zn8uKPnI~YHS<6M8m_CMrTMPEzPFVe7_UTV^PJdc@{^O!^AD3PD$k6>^`SoAkJO5=^^#9mX|5Hx=bf}n^c>aHIalK(` zsbfKdWp0gKew|ZMgG*7pTXBPXQQe;Re}hYF{mbi4eEWCu=l|MMhs%%ca9-Wzx2fNH zVVu*>D6JlSwpvu+?EKNlYw(Ow0jHECI}{?#yfv zEW9B+QrQwbMXZr~gS#)cwqI}1YL&~}6;*va$GSnM?qqh`*_`fk+4HZL?S0m9>~;Ii z?-MS*>;L#~+SmV6fuRHrEh-a=KUo+V7?K%uK<0wtgn>P^K}_XK0XSJ4Gc*Msg0ix zGJ!<7#1a`9(_mfP+$u)kY327(BQzNz!t;mz;H0+0E0GAPpE-`! \ No newline at end of file diff --git a/admin/image/level_1.gif b/admin/image/level_1.gif new file mode 100644 index 0000000000000000000000000000000000000000..b6c901eea729f3c80f9936bfa77c80ce081d5767 GIT binary patch literal 142 zcmZ?wbhEHbisU7#5;L$Gg|a-x~U9;UN1(@xFIQ<~0Hr-QhyVZp literal 0 HcmV?d00001 diff --git a/admin/image/level_2.gif b/admin/image/level_2.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2d0304e56bb26cbceeaf011776e46a41e0f4be1 GIT binary patch literal 141 zcmZ?wbhEHbi0rzqd`(28(lVXy`OZ#Oo{ literal 0 HcmV?d00001 diff --git a/admin/image/level_3.gif b/admin/image/level_3.gif new file mode 100644 index 0000000000000000000000000000000000000000..abb82e7d8f399b5351d4d31094f37c74a111455a GIT binary patch literal 142 zcmZ?wbhEHbpF literal 0 HcmV?d00001 diff --git a/admin/image/level_4.gif b/admin/image/level_4.gif new file mode 100644 index 0000000000000000000000000000000000000000..68b6d1cedfb9e99f10506d1ae356fa626e61c483 GIT binary patch literal 141 zcmZ?wbhEHbkGRd7 i?iTZBe~_Y^hF}+?Q;xv`!{k{S>boX}tn1-mum%7=UpAxw literal 0 HcmV?d00001 diff --git a/admin/image/level_6.gif b/admin/image/level_6.gif new file mode 100644 index 0000000000000000000000000000000000000000..0938d43826e81d51ea474d2e7fd4b78b16010fa7 GIT binary patch literal 142 zcmZ?wbhEHb~0HF9bumAu6 literal 0 HcmV?d00001 diff --git a/admin/image/level_7.gif b/admin/image/level_7.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb58fd89032858953391b8d015879a962cda1dfc GIT binary patch literal 140 zcmZ?wbhEHb&k2$+DG2tE4?sPj@gdSOWm#5H>0R literal 0 HcmV?d00001 diff --git a/admin/image/level_9.gif b/admin/image/level_9.gif new file mode 100644 index 0000000000000000000000000000000000000000..e03cb409761d95b0dc0c472389c0f894b184f54c GIT binary patch literal 143 zcmZ?wbhEHbX`7#Azwb<9F_$kMq+2^GRLP1Q{8u0lDEec>n+a literal 0 HcmV?d00001 diff --git a/admin/image/link.png b/admin/image/link.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf3ab7f4a575f9ec477e98fca4b53ecf694edd9 GIT binary patch literal 2948 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 literal 0 HcmV?d00001 diff --git a/admin/image/login-captcha.png b/admin/image/login-captcha.png new file mode 100644 index 0000000000000000000000000000000000000000..479c8fd1d278ce806558d19ab343d799cac30294 GIT binary patch literal 450 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 literal 0 HcmV?d00001 diff --git a/admin/image/login-switch-on.png b/admin/image/login-switch-on.png new file mode 100644 index 0000000000000000000000000000000000000000..7771cd99e383a283f81ae925f51bb5504d777e9e GIT binary patch literal 428 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 literal 0 HcmV?d00001 diff --git a/admin/image/msg.css b/admin/image/msg.css new file mode 100644 index 0000000..1b1a614 --- /dev/null +++ b/admin/image/msg.css @@ -0,0 +1,15 @@ +/* + DESTOON Copyright (C)2008-2099 www.destoon.com + This is NOT a freeware,Use is subject to license.txt +*/ +*{font-size:14px;color:#000000;} +body{font-family:'Microsoft YaHei',Verdana,Arial,Helvetica,sans-serif;background:#EFEFF4;margin:0;height:100%;} +a:link,a:visited,a:active {color:#0067B8;text-decoration:none;} +input{color:#000000;} +.msg{width:400px;margin:160px auto 0 auto;background:#FFFFFF;padding-bottom:24px;} +.head{letter-spacing:1px;padding:32px 48px 8px 48px;overflow:hidden;font-weight:bold;font-size:20px;user-select:none;-moz-user-select:none;} +.main{padding:16px 48px;line-height:200%;word-break:break-all;} +.foot{padding:16px 0;margin:0 48px;border-top:#EEEEEE 1px solid;background:url('msg-arrow.png') no-repeat right center;font-size:12px;color:#0067B8;} +.progress {width:260px;height:6px;line-height:6px;font-size:1px;background:#E7E7E7;text-align:left;} +.progress div {height:6px;line-height:6px;font-size:1px;background:#0067B8;} +.f_gray{color:#666666;} \ No newline at end of file diff --git a/admin/image/new.png b/admin/image/new.png new file mode 100644 index 0000000000000000000000000000000000000000..9799eaff29e3720789e5e75e9e8999a5bde77733 GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLlj0|kI!-hXRu zAjMh|is3iv&aK WM5d?P^4)KM9PH`p=d#Wzp$PyOj8Pc? literal 0 HcmV?d00001 diff --git a/admin/image/pagebreak.gif b/admin/image/pagebreak.gif new file mode 100644 index 0000000000000000000000000000000000000000..cad74357fac0542d9b78ec2b40e2001cfbf58a65 GIT binary patch literal 240 zcmZ?wbhEHb6kyK_OuV I{E7_L0F~8SA^-pY literal 0 HcmV?d00001 diff --git a/admin/image/photo.gif b/admin/image/photo.gif new file mode 100644 index 0000000000000000000000000000000000000000..7bfc0b2664754a50dbe22d7cc79d6dd0b9e4d5b4 GIT binary patch literal 621 zcmZ?wbhEHb6krfwc*elcdg%X@t&dk;`9J04|3eS{-+udl*^zf2e*CxHX0F(4YrD-X zcltSl|HNh51EwD zyIeW{YR2T#$^9oZXIkfO-LKeVyXx3S*F&axd(@_Gd$RQKyP8GU@@AY{u7+6nQ7afPTce;ebTAyDQ8+&-qv3(*thZF(nD{TA9+7- z@2h!xUzW|gT($6O%c1|N6Hk5o{y%rGYR|fRwTrJW-2b|G_NB}zr&A`J(3oYt>ez?8 zt^19aTjuRm)n6{eG=urj!~a0QKr^8DlLc(H4u}NB2?P771|``jFEfcyA5A_}4Ub?( zHrd3IR3G)hdEJ!kIhL_7OL1_pmMd0t+5hb0V&=4^?~%my-?oQ9k-(VG)>JQJCi zq!l9dZA3(*4<-6aB(kuG#$357dNDD~GLe;4j)UvLL%F+&ir$Ir>|#>J{QO!{V(fv5 z7RpnFB?Sc~g{L}}L~t=P9y*}ybf_kB$A?3#ZQO?iI0f1or*})}%V{1|IMb(?xTIv^ p#iiXXlQdLY3LOg-#Uf@2~H3&U2r0&pr2^bDwj6xX)pFTFeZ53;+OTZKwwPOxgb>9o1R1 zXA5;Y6M8SGxeox09RHF6 z{$}a>+)A_iPOK(s6PtC}h^IhQ3`^I?W?ssc2JD})v8(h%#WI+1a-A=L8h1yGF+dAr z7m6?ATvX#?E#i%>ZvPgVu4oJiByDUQeLHF;77&kz(8H|Z=h-DvS4!Q%9eC6|g$bc# zeQ0-oTR0^bbdFk>ZH3U~Lem4lCKWm$6jiHyO!3AOPy(;9YZuvj=T9T?FbPv2oC@Yd z*@=u4DR9tt&8UwP^zndN!?%wZKn4H^bg-Hzc+CvfceIsgzyv0J8UiLtFJS0EA_d63 ztaXu66b(c zvh&3_phPO2AtnI$4o2Re+*VE@t}M;3I1>@1ou1MYk4;ZeC6TS!lhy=EYQUy9Oq#S^ zULL3N>ZPdl?eM@@f=LtLI(uM!bBey$g5h)EK|K2Qv5H_(39Rp)zy$_I#tm_YlD6xM z@k*yR=RN1*L-)?ACsTo&;7OiJZgpo_B>9Q`W4{`B5|KcycH{9rQS78QDvX?TWn@9F z&Ps|aZp-XB4koJGi*A9ZYKZh_F0ikL$!-Z{k?GU@nE^Ihzf-S?wvmA74E;?(8P8%i z>IYOpx1|&K7*he8i<~TaAAt0ZgJcy+3NV;mz6e0;Padnv42aH0Isi0^pI)t1rDb~0 ziS1-5crVb}38AzeB{z!Xs-bu7lIZT=A6PArTj%(Grk@2+Nfa)uyuS!d$5MSKKVxJL|9IJJB zR;kAbUxT1xcvES`$itt$C=e2tA}CTMZgYu+!!{jyk)=OvNsmE9JVjQUQQHGL1(hy0ELR$3b1Tr1 zSW7|n|5&1{5622;r#7dsrs$^~^?z7u=2Ym3UC^N~y$CPQV1FR*q`XZ1@`bEgZt-h_ zK}^wCy4SG^FD$f?#eOgu!x#*QoNu1^U_Q4xp~o%*i`%}d%qj{`KNBganf*C? z)Z-`ZDseS($DfHgnmMu;>TsFYgExq`f~T2RCRgVb&6n)lKBMd3WchPla#(Xbjm@s^ zT@B_+{luQBkZF<`nn`?ZWb9+CJcfSFXjEm)T4iGr^6I|vTi7Co{wsIY7)HSO9p+Ze z5ZoW03>!AEEo-+WM;tmb*GEU)FOG(m896q8&D%yovTBu z|CtP&Y@c-4@ZR9wSeqpIdKIb^N)_%ZAQkp~>G8Ml2KXral<)8_r7wvD9rQg{(JZaZ!cq&WWc$Z^AsY(AT>JWp`Nr*^xRjcAu$ z!b$v&aaoiPfG9a*Juf(5<$gF#d)%{kaFd-X?=J6IYQHj=;gRQzA8Gi48W`x4n#N9G z``451j1_nk*|&dhojOj8dZ}5^^C13Kd~eodRxp7kOE+sDn`5G6f;QPT`G(aVw_1~0 zLynswVEm@}O!*4=gr>^s{OWGMeB>dxlA*}{{7#lnjG zimvSxqKu87jk(QHo1p&N0*RvW>&U*TZp*ngLXe$;lA_b$&?=SEMCxCxyr)>EXnV@{^evSKl@N6<^-EfLnnap+ z=VX|axYU^Fnazc~(>*&OfA|j^Z%(^N<&AKCqATRG;6J=RAfY2Tem*IBm~NIW)brJW z&gwuDUF@6|A{Hm)#+wT{2;sbPRrd9@Uj_|^s3)j>sd4O*`H@Ro(pEAiq2=zBdy}`H z3)US0M>wwMYnIUe7@*INkrt`ELh4j%0fBTEKirV zKvq_V2u1$)%;n8ff^SFVuxHmRFGmWi!DM*!mn$CY3UK^+mLH|B*diqZiJaY8qOLfTzQ@Kn`MnB5Y4TGNsspReDH!KI5uv33ZZk6o?7KT|9Ovu$$&F$YMCdWHw{DZbxA_cha z{vc(nw>C-!n0mBnhU`8b{T(rr%;&(5?^p?)!D;#H_Y@@uy$qt=(5=eTiGolCujTx3&&m9aJpV>7i>oYMs>|;$&Ati_T7>;98Tv5&VQ@A#ta+Di4T_c= zRp{`=N|zyv6-(MkKNHFd1#ASg+M7>9NjDZ9eS77TO^b>PFDq^xEJdU*Ry?XGD%4X} z{F*zB-q$(K^{_UuZgWu|E>eb|e(N;b?)Pv1ASPRHwtDS|?mJA0H$SXatWneo^&-zh z-&lICIqefROz+j8c68V7j*z~D9lCdp`F#8P?V9xqbQ|g8I)C$HiJ1#Has2LIzr78J zKf`aGY3sn`fH%kOljL8thpfNC8cyn*I+1gK?K2Ga2=nNU_vS)l2*I!!K~AqqjNxl#peEwa>PNZ7T2{%=e;SeHl+!l zW=Ly=ckX)0%2&uj%~~Fe*~mHZ#ky7Yr5Xh9uG3h_<`@33?ogYY8ICPNkF@s77;obE z-vp*%Tm4jQpm9x$JzlW5u5xnJ)CMeCG4ds?$yLQSAy@kI5m)6fx({!Q`MKVi%;K43 xDxSy^Da*O}~ literal 0 HcmV?d00001 diff --git a/admin/image/remkdir.png b/admin/image/remkdir.png new file mode 100644 index 0000000000000000000000000000000000000000..6f6da0c83c76487880b25a69701ff970d455e6e0 GIT binary patch literal 552 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl|Di8eo z*YNNE#DD)c{{H~vzWVp2@v4RFzyDKDpWZrGnEl^-py0~??;A_lSpWTB`svezfB(Cl zJ+J)tzvKV^doxtk{{26{%)#;M_4a>%8k?FD{=WuVm*wN*xM4$QGc(iPMuwR)&;0-Y zALv*hFqw9H7Lc+m3GxdD3X%mFtk$GD01esa>EaktaVu$q12Y5Tk%YuPCLIPQ4vmDY zEUrTd33-eH4iZcZj4caU6&f0t($dltc-WqaF)*?SU%1x7#lRxqap1@i7r$F~Sa?AC zbPg!5PSH7Ve9dW<)FhzZ1V&G1+f+ldKrz2CVeSS7ChiQ0!qqE`jW~)=%#HwRk8tP? zKi<$gvDLZh?hz)1h67AWTt-G^v5?5fgYGo|={*6qIt^d?N#g!US*M2@R|c g42BD;FVdQ&MBb@02xgVtpET3 literal 0 HcmV?d00001 diff --git a/admin/image/resize.gif b/admin/image/resize.gif new file mode 100644 index 0000000000000000000000000000000000000000..df72f18c7dd15e69b073cacf54fcba76f148c14f GIT binary patch literal 84 zcmZ?wbhEHbZ0w6;1CkrD30}F!=hyzl~z%1#p%jVA` b)15M^fls$?-z0IQGhTF>6l0ke6N5DXanTkf literal 0 HcmV?d00001 diff --git a/admin/image/save.png b/admin/image/save.png new file mode 100644 index 0000000000000000000000000000000000000000..b89b1c0e6f6ce7e7d80d85c29ec1829bb08f79b2 GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl(xcCwJzKMC&Cz4ejvhO@Wz&}K-o5{S{hvAWjInWA zTH4J2|Nl>jXmtP@C|(le7YyWL0SwO^p2Y!`%=dJ045_%4B;d@@zNE4G|prBy`LlXx_Gh+mULW4mF1B*Z#R|CVL07d}^1;#)}4FOgzpjZS0 zqstKnCJr5iLubw%)jpu9#3aJNq0qrFpJO(|VxY7_g94L}OjC~&PXZ&zzzs#4ISfBE zure@pIQsawxVSLzH1L4zN^%fr6!N4NHAkicAV|LC-UZ7JMJYD@<);T3K0RXjj BkCXra literal 0 HcmV?d00001 diff --git a/admin/image/search.png b/admin/image/search.png new file mode 100644 index 0000000000000000000000000000000000000000..9c86c55ecae6dff684bb882ac1d7cafdb554084f GIT binary patch literal 3540 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 WcJcjPlm9@cGkCiCxvXsWz z?c29+-MV%2=FRKZuV1@%?dsL5SFT*SeEIUlixUAkn+lEsS`FIu!{;lhRU z=g*%vZ{FOwbLY&NGi%nY88c=~n>KCg)TvXZOaXcs?Dc^s6o0ZXGB5-&=zyF8iW3I* za}7aF%`L6X%zP3`>Y5tLk^(F(OtO}yy6P%wT1J)%tj%nu>ax<(QZh=aniibR>`rE) zT;f{hHg+B!91Cq-Rm2pne0;qFoYpn57`WP)nAkbHySth0X=1n1mXlS{(l<0RwLKZM z!B&`2NZa1Q(a-BCi;<6oroNM3pnrhrf+p6uGYJO|vGPcsFIzJ~wpwfNswRg ze}<>q4ZMK7bWaz@kcwML2`f z42s+hu0SDI1{Ed&hZRf?at;iMD;PKwc#MIfhs7Eg4i&Hig?5N2G#LB=D&cvtj}<5j bG>nI&e+?Z(bYYZoqfjI`pld;XAT}b z6B&7ih2@N<=9%To&lDG*NlZNBQ{TZIEGZ*N(x|ON>h_mRTZ;K6OdMDkeD*n^~cl&4V)*K zITYAZ*~(Nc1QG(+K;ky1RQt{d1*K>0hP`OV3lBG>S%QJl;hOc$iyPhJZX}W zP{1Pw4h0^@1_q|AKnEtTH4KbL6uPrC%pDjE4HkbmdV_(f!!eTYY9a$8ONo_!lm3yF zKra35$6^NG_riyZj7ygxSFU|?ipnBFGa@O1~X4A9vOp00i_>zopr E0LmV&b^rhX literal 0 HcmV?d00001 diff --git a/admin/image/style.css b/admin/image/style.css new file mode 100644 index 0000000..6ceb3a5 --- /dev/null +++ b/admin/image/style.css @@ -0,0 +1,123 @@ +/* + DESTOON Copyright (C)2008-2099 www.destoon.com + This is NOT a freeware,Use is subject to license.txt +*/ +*{word-break:break-all;font-family:'Microsoft YaHei',Verdana,Arial;-webkit-text-size-adjust:none;} +body{background:#FFFFFF;color:#000000;font-size:12px;margin:0px;height:100%;} +html{height:100%;} +input,textarea,select,button,td{font-size:12px;} +label{cursor:pointer;} +img{border:none;} +ul li{list-style-type:none;} +ol li{list-style-type:decimal;} +ul,form{margin:0px;padding:0px;} +input,textarea,select{margin:0px;padding:6px;} +input[type="radio"],input[type="checkbox"]{margin:8px 4px;padding:0;} +a:link,a:visited,a:active{text-decoration:none;color:#000000;} +a:hover{color:#2B579A;} +a.b:link,a.b:visited,a.b:active{text-decoration:none;color:#2B579A;} +a.b:hover{color:#FF3300;} +a.t:link,a.t:visited,a.t:active{text-decoration:none;color:#2B579A;} +a.t:hover{color:#FF3300;} +.bg{background:#FAFAFA;} +.r{border-bottom:#D3DBE7 1px solid;height:24px;} +.r span{color:#BBBBBB;} +.d{line-height:180%;border-bottom:#D3DBE7 1px solid;border-right:#D3DBE7 1px solid;} +.menu{width:100%;height:46px;line-height:46px;overflow:hidden;background:#FFFFFF;border-bottom:#2B579A 2px solid;position:fixed;z-index:9;left:0;top:0;} +.menu div{text-align:right;height:16px;line-height:16px;} +.menu div img{width:16px;height:16px;margin-right:10px;cursor:pointer;} +.menu-fix{width:100%;height:48px;} +.tab{} +.tab a:link,.tab a:visited,.tab a:active{font-size:14px;text-decoration:none;display:block;height:46px;line-height:46px;padding:0 16px;} +.tab a:hover{background:#E8E8E8;color:#000000;} +.tab_on{} +.tab_on a:link,.tab_on a:visited,.tab_on a:active,.tab_on a:hover{font-size:14px;text-decoration:none;background:#2B579A;color:#FFFFFF;display:block;height:46px;line-height:46px;padding:0 16px;} +.nav{height:48px;line-height:48px;font-size:14px;padding:0 16px;border-bottom:#E7E7EB 1px solid;} +.nav a{margin-right:24px;} +.tt{font-weight:bold;height:48px;line-height:48px;padding:0 16px;background:#F5F5F5;font-size:14px;border-bottom:#E7E7EB 1px solid;} +.lt{line-height:24px;text-align:left;padding-left:6px;float:left;} +.lt div{color:#666666;} +.ls{} +.ls tr:hover td{background:#EEEEEE;} +.tb{background:#FFFFFF;width:100%;} +.tb th{background:#F5F5F5;font-weight:bold;letter-spacing:1px;padding:10px;border-right:#E7E7EB 1px solid;border-bottom:#E7E7EB 1px solid;} +.tb th input[type="checkbox"]{margin:0;} +.tb td{padding:10px;border-right:#E7E7EB 1px solid;border-bottom:#E7E7EB 1px solid;} +.ctb td{border:none;} +.on td{background:#F5F5F5;} +.tl{width:145px;padding-left:20px !important;background:#FCFCFC;} +.h{height:20px;line-height:20px;overflow:hidden;} +.nv td{text-align:center;padding:6px;} +.thumb{-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;} +.thumb:hover{-webkit-transform:scale(1.05);-moz-transform:scale(1.05);-ms-transform:scale(1.05);-o-transform:scale(1.05);transform:scale(1.05);} +.btn,.btn-g,.btn-b,.btn-r{display:inline-block;width:96px;height:32px;line-height:normal !important;padding:0;text-align:center;cursor:pointer;} +.btn{background:#F8F8F8;border:#C6C6C6 1px solid;} +.btn:hover{background:#DEDEDE;border:#CECECE 1px solid;} +.btn-g{background:#1AAD19;border:#18A117 1px solid;color:#FFFFFF;} +.btn-g:hover{background:#179B16;border:#159014 1px solid;} +.btn-b{background:#007AFF;border:#1E74D0 1px solid;color:#FFFFFF;} +.btn-b:hover{background:#0569D5;} +.btn-r{background:#F8F8F8;border:#C6C6C6 1px solid;} +.btn-r:hover{background:#CE3C39;border:#BF3835 1px solid;color:#FFFFFF;} +.btns{padding:16px;background:#FFFFFF;border-bottom:#E7E7EB 1px solid;} +.sbox{padding:16px;border-bottom:#E7E7EB 1px solid;} +.sbt{padding:16px 16px 16px 188px;} +.f_l{float:left;} +.f_r{float:right;} +.t_r{text-align:right;} +.t_c{text-align:center;} +.f_b{font-weight:bold;} +.f_white{color:#FFFFFF;} +.f_gray{color:#666666;} +.f_orange{color:#FF6600;} +.f_red{color:#FF0000;} +.f_blue{color:#003EAA;} +.f_green{color:#2BA245;} +.f_hid{color:#FFFFFF;} +.f_fd{font-family:Fixedsys,verdana;} +.f_price{color:#FF0000;} +.px14{font-size:14px;-webkit-text-size-adjust:none;} +.b5{height:5px;font-size:1px;line-height:5px;} +.b10{height:10px;font-size:1px;line-height:10px;} +.lh20{line-height:2.0;} +.c_p{cursor:pointer;} +.c_b{clear:both;} +.dsn{display:none;} +.jt{color:#2B579A;cursor:pointer;} +.hinp{border:none;width:98%;background:url('spacer.gif');height:18px;} +.hinp_on{border:#84A1BD 1px solid;width:98%;height:16px;} +.mods li{width:90px;height:25px;float:left;} +.highlight{background:yellow;} +.property_h{border-bottom:#FFFFFF 1px solid;text-align:left;background:url('spacer.gif');color:#006699;font-weight:bold;padding-left:15px;} +.property_l{padding:0 20px 0 20px;color:#006699;} +.thumbs{width:100px;height:128px;overflow:hidden;float:left;margin-right:16px;} +.thumbs img{cursor:pointer;} +.thumbs p{height:16px;line-height:16px;padding:6px 0;margin:0;text-align:center;} +.pages{padding:24px 0;text-align:center;font-size:12px;color:#666666;clear:both;} +.pages a:link,.pages a:visited,.pages a:active{background:#FFFFFF;border:#DDDDDD 1px solid;padding:6px;text-decoration:none;margin-right:6px;} +.pages a:hover{background:#2B579A;border:#2B579A 1px solid;color:#FFFFFF;padding:6px;text-decoration:none;} +.pages strong{background:#2B579A;padding:6px;border:#2B579A 1px solid;color:#FFFFFF;margin-right:6px;} +.pages_inp{width:32px;border:#DDDDDD 1px solid;color:#666666;padding:4px;text-align:center;} +.pages_btn{width:32px;border:#FF6600 1px solid;color:#FFFFFF;padding:4px 6px;background:#FF6600;font-weight:bold;font-size:11px;} +.pages label{background:#FFFFFF;border:#DDDDDD 1px solid;color:#666666;padding:6px 6px;} +.pages label em{color:red;font-weight:bold;font-style:normal;} +.pages label span{font-weight:bold;} +.pages cite{font-style:normal;} +#Dtop{border:#E0E0E0 6px solid;border-radius:10px;} +#Dtop .dbody{background:#FFFFFF;} +#Dtop .dhead{background:#F0F0F0;border-bottom:#E7E7EB 1px solid;padding-left:16px;font-size:15px;line-height:32px;height:32px;font-weight:bold;cursor:move;-moz-user-select:none;-khtml-user-select:none;user-select:none;} +#Dtop .dhead span{float:right;cursor:pointer;display:block;width:32px;height:32px;background:url('dialog-close.png') no-repeat center center;} +#Dtop .dhead span:hover{background:#F45454 url('dialog-close-on.png') no-repeat center center;border-radius:0 3px 0 0;} +#Dtop .dbox{overflow:hidden;line-height:180%;clear:both;} +#Dtop .dbox table{margin-left:10px;} +#Dtop .dsize{height:11px;font-size:1px;} +#Dtop .dsize div{height:11px;width:11px;background:url('resize.gif') no-repeat;cursor:se-resize;font-size:1px;float:right;} +.back2top{width:38px;height:38px;position:fixed;_position:absolute;right:10px;bottom:10px;_bottom:auto;cursor:pointer;display:none;} +.back2top a{display:block;width:100%;height:100%;background:url('back2top.png') no-repeat;} +.back2top a:hover{background:url('back2top.png') no-repeat -38px 0;} +#msgbox{z-index:1000;position:absolute;display:inline-block;border-radius:5px;background:#28282A;top:10px;right:50%;color:#FFFFFF;padding:3px 24px;line-height:20px;cursor:pointer;letter-spacing:1px;font-size:12px;opacity:0.8;} +.webuploader-container{position:relative;} +.webuploader-element-invisible{position:absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px,1px,1px,1px);} +.webuploader-pick{position:relative;display:inline-block;cursor:pointer;} +.webuploader-pick-hover{} +.webuploader-pick-disable{opacity:0.6;pointer-events:none;} \ No newline at end of file diff --git a/admin/image/tips-update.png b/admin/image/tips-update.png new file mode 100644 index 0000000000000000000000000000000000000000..9f420aadb381e8940919b61b650c80e54f9e7dbf GIT binary patch literal 550 zcmV+>0@?kEP)5QM++!CWB&y$HY=Km>>gFd5(*_+pC1{S0;X$zto0J|L4z=TAWTbEpEgs?(*Ad!nUAi4s`Q8H4=f`@yC z?or}4ax??D)=S_NaatdcNYq%_R85*gQaNc_8wTL%UbsuGYOi(9jpU_6&5(0>DSb03 z20XcM#)de_Z2#7%2jE@4M)^-FW~};gtxJS+;G)(OzKHR=Ime{3svcAiV5)Q1VyRf0 zHCD07@cZc3|dc-;gt4 z?bd$EF{%ab%^X)*?GE5dk6lNYp7veaC95Noeip z4fpsSueYTNLI8ZlmJboi8A3)Pc2>(E`nt@Ak{KvsNLG@>=f3?L%6Z}UnASN%R=Z?u o{uk^r);G-c0D1;`26_hG0IdGXAqJ){qyPW_07*qoM6N<$g2iO=;s5{u literal 0 HcmV?d00001 diff --git a/admin/image/tool-close.png b/admin/image/tool-close.png new file mode 100644 index 0000000000000000000000000000000000000000..21bb7d6b69ea1e8c15341f76147cffafe01a0eb0 GIT binary patch literal 177 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 JPDHLkV1jH!nGXN} literal 0 HcmV?d00001 diff --git a/admin/image/tool-help.png b/admin/image/tool-help.png new file mode 100644 index 0000000000000000000000000000000000000000..27bf7995d328c343c67193e3aa35ea1c4b3bca2d GIT binary patch literal 332 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 literal 0 HcmV?d00001 diff --git a/admin/image/tree.gif b/admin/image/tree.gif new file mode 100644 index 0000000000000000000000000000000000000000..d4aacd94efbc020b670d03f57b5b40c3e8ca354f GIT binary patch literal 79 zcmZ?wbhEHb6k!lyn8*ME|NsAQXlMYEia%Kx85o!ubU>mYc?KqhIl9YFznwF0j@~72 c-Fv>D`*}`kOk40|ZuF|S9P7Osf*2UA0sS%@PXGV_ literal 0 HcmV?d00001 diff --git a/admin/image/unknow.gif b/admin/image/unknow.gif new file mode 100644 index 0000000000000000000000000000000000000000..20675059fd2b102be011dc6087775c1ea3a4b715 GIT binary patch literal 225 zcmZ?wbhEHb6krfwIKlt||Ns975)2G8fh>jw5b^x^wf|>~fkF)o3}?=qIeq%{%$YOW z+S)=xLpeA&!0N#|i69hzvM@3*2r}q^)Pn3}V2w+7(vx!2MdOuB&TTV)Ew++abH_Ee zZ2r9HbI9aKWN2kRl5n!+Ng3a=k_R?ym5t7#QU)3sO>fG?LR6TTnjC(sT;A8{)ROM?7@|6>6R+Ba)o0Tpcbba4!+xRoT}$jrcagkd2IYwH3g21XV^0TCgQrY;5+ z0T%}kj&&>w4H5@Vwa)nQV}TP$UEsMh43}929C!qt>hu`I0yT&*Xr&9Ku?9OZHZU+{ zC8i}j5J_ML^O6J}CMBk%hzl^lxMFEf1q8$z0+f`1W+^D?95|+|pun@#g@K7fMd5(9 z!Wn)rTSI|o3LBS$h9JbVmRC5y@MeQRW?{gME}$0}JYD@<);T3K F0RUvpj&}e6 literal 0 HcmV?d00001 diff --git a/admin/image/video.gif b/admin/image/video.gif new file mode 100644 index 0000000000000000000000000000000000000000..b9eb5e83b1e47d8800815d797806cf1e7e172861 GIT binary patch literal 1386 zcmZ?wbhEHb3}6Ug_|5 z?AXzxM~@sia`^D!g9i^DIB;P9{{8#*?c2L|@18w-cJJQ3bLYixw?fuwcQwdGqGZojZH>>{+vB&6qJ``t<43 zrcIkVb?W5FlP67@G-1MozP`Th?(VLxuFlTRmX?<0=H{lRruzE&va+($($bQWlA@xb z!otG*{QS(!%#4hT)YR0txVY%(=!l4j@bK`ku&~h3(2$UjfPerG4-Z#YR~Hu-XJ=<8 zCnrZoM+XN7dwY9ZTU#3&8*6K8OG`_0b8}NuQxg*tV`F0@BO^mYLw$XHJv}{LU0od= z9c^uGEiElgO-&6A4Rv*OH8nL=RaHerMR|F7X=!OGDJe-wNeKxFadB}mF)>k5Q4tXl zVPRnb0Ret~em*`v9v&WUZf-6vE>2EPc6N3)Ha1pPRwgDUMn*7evpPJ*jdD+?77R9gboZP(JpP}Q3M&(DxrWSsKDH8&} z6fclf5@Pa@J|> zSe}E`se#>KtAK-)s@Ks&HJl3t8@LTb1slZfw~9Nk$0lqN5Mz{Kye!Umg<)>V6;l;w zhJ*tt9n9=69OvZn-VJ16={#cM!r+>q;*w`{vydT2Y;U3iQ`o65E)41pP7{^eJspEp zUVkm`QdV0Krq3Tftfo-HI&u;&Q%eH_LjyL zZaE27Cm!!98&7Pw;HLd{%ayR~w_9(dt$w@hPTA|X+aI)PzuWO-TK2o0vaBo&)&N^c B+5P|k literal 0 HcmV?d00001 diff --git a/admin/image/view.png b/admin/image/view.png new file mode 100644 index 0000000000000000000000000000000000000000..c987bbb7dcaeb5ee9a288d4ea0dc0f8492b662b3 GIT binary patch literal 885 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLlz8lu9d5w&pZ9De(%d8r|#|9 zf3+oIDK#BBYsbk~hdS3k`=^X}+_Z{3I9##HUU`Rd1q zFTZcS`abp8+wzXB_g;Q0tzYx!|NoNuHH~{;?z#0TA=qQ`^j(Ji&z4{KaQx-Jl^5Rs zUuN8N{L|6ncRIS({{HvhH+So{tM8tD__e*k`TM{BlaIfROYi&i{ok&Gx4!)UKmFY2 z_n&?|eg7+T-oqv5Uq5*HZSL|@Q;)yxIr*t6J+Ara``7=0T3**5eEol+$%4z@+Okvs zFE%>=_}kW7UmCKq|NQ%3-LvWZDm_!8C&Z7r!p|Ih-ff>`a09}#|`DpOHXMtGI1y!IQ(YSoO!EaAH>Ch zb>Hja@Z-N4u)jiY;(||J4Gc`&7Dqm~YFdbLowlAH&cq@R;NWoj)|}XDTJg5$?(g0M zw8Mc(RgLr8te8Vbvt;%`teL>q^X+7UaN?IoC%m=Rvv4RZaPTPFv2KoGa#w_yaCxPw z1A}46Ee|&D4U$H;G+!AsvM?}ltZ+K7p`)w5*~7-c;Eh+*(_^>bP0l+XkK6}1Wv literal 0 HcmV?d00001 diff --git a/admin/image/yes.png b/admin/image/yes.png new file mode 100644 index 0000000000000000000000000000000000000000..13109de4ac0240fbfd9ba3d027ddf0b63f0b7faa GIT binary patch literal 3062 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 Eg3J@qm;e9( literal 0 HcmV?d00001 diff --git a/admin/index.html b/admin/index.html new file mode 100644 index 0000000..8de63fa --- /dev/null +++ b/admin/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/index.inc.php b/admin/index.inc.php new file mode 100644 index 0000000..5ca8344 --- /dev/null +++ b/admin/index.inc.php @@ -0,0 +1 @@ + 1) {unset($menus[1]);} deval('NnuACp3krLMYsoOvZyTTPkOzM2LzG8O-S-mFhaBxZSyyOSgImS9bURbprBDRNlnAfwNsxjtdby6pBvCTR-P-vq1-P-5vmQF9LtbhroZdAGEOuD671KG-S-bXbXXQ0hacB5yc9rBBkxOwJiUr1URm4FAC1JfNOoNFrz6qQSl-S-NaV8LzUIPel9q8Zoo3GwB83eEOoMn66MbV9Pqb9r35N29BwCI47DPaue1wGQhsn0KpQwirF9UqEcAGmpC9fkMmbOzJ6qFhOajvp1hkTdKFYkT3bnUrMi39-S-jtR5GLDbe2EcFfBu0BAqna-S-nrwcIwfU3lWvltktRHrgOyQMVQCsWf3wNLOF31aoXCi4mGznfu3wDUFya-P-TJ5QFW-P-0-S-4ZUOp5iKTpB3vUm-P-w3DbUfaDWrbDvUKk5K2KQkWNjQIHWa0ZhwTsLz4XUmeRnN99JprAOaNcbs7O-S-4r8e3M-S-gwqOVycjO7-S-CNFKWJUlV4saYMqC0bEhfhYpkMj-S-OmvX-P-SFISM97Ci3l5OP7moRgH5BjbO8QFNZIJp77KPL-S-fOiDfjpIJT-S-ZjHNaTr3ICHVeqzFbMYVRx3HFKmo-P-ExHs5twVLWk4dYXPQYRPkSc-S-klz9nwLNMy6CMZqOO-P-Tl376VNuEa-P-wlkALFe6lb6TmdwAANC5Pa54sbJ-P-xVQYElt9lgP3EAcxThJD46eyQW7ZbSWL15Oom5jpF-S-LOKL35NEFs6DHzW6-S--P-loyHyBdN87nTwyMbZxyO1oVwhxWGU9qHd6xY6fC3oCsF9b3Zr-S-LiGjMwlflxiNQs1OALfA0tIjSfp1ukG0ppL8SaQTwDqAtXZXWOg6gEPnfEdSc8licBBMmBjhIuDR4Exw-X-GhO0zGpmcaJspvjMjzgyOWE-S-r5WuiSPdA7RPq0lCOsw48YX4D7Lp9VlRuqwddVO9oCpB6GseYpRUQL-P-IikYpQTefHb81fmwkACv18jijeF09V20lnqA5zEvtS7jY7jcELHyZE0hzbsxkJMshu7c6vZdh0mHwNghKkg6fy5paxzZ0ECg6RNGoeVK-P-M6397dGw19L0UflSYUv2dZ3SGvOCMGDAWG3b9-X-rZ48-P-tV-P-sc0zhD0UgYeqmizPaGj3M7t2PIz8EUWi2NExdkrV0mcGe6LRY56W-S-KgpE6nr-P-QY1G8-P-cJR-S-0NUADid-P-yAAivCBg1CbcxYA2h-S-B7FRIpvVnu0lMROexM7lxijhJ6jEu-P-T1Nk-P-YUgRvc1HbnBkOE0-P-OjTYKJbVEbEzKbH6tbD4KT2w8wmzYmanPrtTntC6GXUMYYgwawHpe0MpR-P-xc9-P-J7XZL4vG34MqtUFJLkMYpNLR8HwINqcCkFTEnrmu2adZqVO4FgGoaHJEyr9x028mcXC4YjXjNRrwXC2QLh9dZ8-S-MRIMtNk8LjHoGeGndCcUkptgOS7ULtrCNtpx468G9K6yvQFT7RjoMrV-P-NayA51h3mzmpbKJzcldW3Ov0TWhyT3gf0mdtjcgIOVcpJrU1QXyw44FP7l9DdmW-P-Jye54KDCi8Ns-S-VXvhBRXMNWE1v505gYMrBAaObYF-P-420bCqHHaYDcx-S-aSkpDIQG4UMMk43Lv3aqy64hHjzQzd3wZIw48-S-ZlFwQB1fD6H3Ve8AHQXRB-S-eJJYPhuPTRKeaCuQDgqwT9ZSGnmdg5w9Ozf0-S-SbnabogYbb9VjLE9qjwa3-P-NVWp1jFrYzt9iE9n0gh5kHuH03WZ4-P-bmitceGgOzZpCmQSnXVNNMM8Fxp7EcYqSCEI3nWAvY73cJRhiXYBC7jGLYDvAq7q8C2RN-S-x-S-OkS1UEF-P-chnDxsLrDoLSviJWU70aIlnoohBjce9fNLKX-P-M4mThgmBKSBLp69HQWHjqozd5fmGd6mwd3LSi82cIxiASPou5JOW1j9GtDAA-E--E-'); ?> \ No newline at end of file diff --git a/admin/ip.inc.php b/admin/ip.inc.php new file mode 100644 index 0000000..f710211 --- /dev/null +++ b/admin/ip.inc.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/admin/keylink.inc.php b/admin/keylink.inc.php new file mode 100644 index 0000000..4aa27f9 --- /dev/null +++ b/admin/keylink.inc.php @@ -0,0 +1,128 @@ +item = $item; +switch($action) { + case 'add': + $i = 0; + if($content) { + $data = $do->merge($item); + $content = stripslashes($content); + foreach(explode("\n", $content) as $v) { + $t = explode('|', $v); + if($t[0] && $t[1]) { + $post = array(); + $post['title'] = trim($t[0]); + $post['url'] = trim($t[1]); + if(strpos($data, $post['title'].'|'.$post['url']) === false) { + $post = daddslashes($post); + if($do->add($post)) $i++; + } + } + } + } + if($i) cache_keylink($item); + dmsg('添加成功'.$i.'条', '?file='.$file.'&item='.$item); + break; + case 'export': + file_down('', 'keylink-'.$item.'.txt', $do->merge($item)); + break; + default: + if($submit) { + if($do->update($post)) { + dmsg('保存成功', '?file='.$file.'&item='.$item); + } else { + msg($do->errmsg); + } + } else { + $condition = ''; + if($kw) $condition .= " AND (title LIKE '%$keyword%' OR url LIKE '%$keyword%')"; + $lists = $do->get_list($condition); + $fid = isset($fid) ? intval($fid) : 0; + $content = $fid ? $do->merge($fid) : ''; + include tpl('keylink'); + } + break; +} +class keylink { + var $item; + var $table; + var $errmsg = errmsg; + + function __construct() { + $this->table = DT_PRE.'keylink'; + } + + function keylink() { + $this->__construct(); + } + + function get_list($condition) { + global $pages, $page, $pagesize, $offset, $pagesize, $sum; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = DB::get_one("SELECT COUNT(*) AS num FROM {$this->table} WHERE item='$this->item'$condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE item='$this->item'$condition ORDER BY listorder DESC,itemid DESC LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $lists[] = $r; + } + return $lists; + } + + function update($post) { + $this->add($post[0]); + unset($post[0]); + foreach($post as $k=>$v) { + if(isset($v['delete'])) { + $this->delete($k); + unset($post[$k]); + } + } + $this->edit($post); + cache_keylink($this->item); + return true; + } + + function add($post) { + if(strlen($post['title']) < 2 || strlen($post['url']) < 12) return false; + $post['listorder'] = strlen($post['title']); + DB::query("INSERT INTO {$this->table} (listorder,title,url,item) VALUES('$post[listorder]','$post[title]','$post[url]','$this->item')"); + return true; + } + + function edit($post) { + foreach($post as $k=>$v) { + if(strlen($v['title']) < 2 || strlen($v['url']) < 12) return false; + $v['listorder'] = strlen($v['title']); + DB::query("UPDATE {$this->table} SET listorder='$v[listorder]',title='$v[title]',url='$v[url]' WHERE itemid='$k' AND item='$this->item'"); + } + } + + function delete($itemid) { + DB::query("DELETE FROM {$this->table} WHERE itemid=$itemid AND item='$this->item'"); + cache_keylink($this->item); + } + + function merge($item) { + $KEYLINK = cache_read('keylink-'.$item.'.php'); + $data = ''; + foreach($KEYLINK as $k=>$v) { + $data .= $v['title'].'|'.$v['url']."\r\n"; + } + return $data; + } +} +?> \ No newline at end of file diff --git a/admin/keyword.inc.php b/admin/keyword.inc.php new file mode 100644 index 0000000..112e753 --- /dev/null +++ b/admin/keyword.inc.php @@ -0,0 +1,140 @@ +query("DELETE FROM {$DT_PRE}keyword_record WHERE addtime<$time"); + dmsg('清理成功', $forward); + break; + case 'record': + if($submit) { + $itemid or msg(); + $itemid or msg('请选择项目'); + $itemids = is_array($itemid) ? implode(',', $itemid) : $itemid; + $db->query("DELETE FROM {$DT_PRE}keyword_record WHERE itemid IN ($itemids)"); + dmsg('删除成功', $forward); + } else { + $sorder = array('结果排序方式', '搜索时间降序', '搜索时间升序', '搜索结果降序', '搜索结果升序'); + $dorder = array('itemid DESC', 'addtime DESC', 'addtime ASC', 'items DESC', 'items ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + (isset($fromdate) && is_time($fromdate)) or $fromdate = ''; + $fromtime = $fromdate ? datetotime($fromdate) : 0; + (isset($todate) && is_time($todate)) or $todate = ''; + $totime = $todate ? datetotime($todate) : 0; + (isset($username) && check_name($username)) or $username = ''; + + $module_select = module_select('mid', '模块', $mid); + $order_select = dselect($sorder, 'order', '', $order); + + $condition = "1"; + if($keyword) $condition .= match_kw('keyword', $keyword); + if($mid) $condition .= " AND moduleid=$mid"; + if($fromtime) $condition .= " AND addtime>=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + if($username) $condition .= " AND username='$username'"; + $lists = $do->get_list_record($condition, $dorder[$order]); + include tpl('keyword_record'); + } + break; + default: + if($submit) { + $do->update($post); + dmsg('保存成功', '?file='.$file.'&status='.$status); + } else { + $sfields = array('按条件', '关键词', '相关词', '拼音'); + $dfields = array('word', 'word', 'keyword', 'letter'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $fields_select = dselect($sfields, 'fields', '', $fields); + $sorder = array('结果排序方式', '总搜索量降序', '总搜索量升序', '本月搜索降序', '本月搜索升序', '本周搜索降序', '本周搜索升序', '今日搜索降序', '今日搜索升序', '搜索结果降序', '搜索结果升序', '更新时间降序', '更新时间升序'); + $dorder = array('itemid DESC', 'total_search DESC', 'total_search ASC', 'month_search DESC', 'month_search ASC', 'week_search DESC', 'week_search ASC', 'today_search DESC', 'today_search ASC', 'items DESC', 'items ASC', 'updatetime DESC', 'updatetime ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + $order_select = dselect($sorder, 'order', '', $order); + $condition = "status=$status"; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + if($mid) $condition .= " AND moduleid=$mid"; + $lists = $do->get_list($condition, $dorder[$order]); + include tpl('keyword'); + } + break; +} + +class keyword { + var $table; + + function __construct() { + $this->table = DT_PRE.'keyword'; + } + + function keyword() { + $this->__construct(); + } + + function get_list($condition, $order) { + global $pages, $page, $pagesize, $offset, $pagesize; + $pages = pages(DB::count($this->table, $condition), $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $lists[] = $r; + } + return $lists; + } + + function get_list_record($condition, $order) { + global $pages, $page, $pagesize, $offset, $pagesize; + $pages = pages(DB::count($this->table.'_record', $condition), $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table}_record WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $lists[] = $r; + } + return $lists; + } + + function update($post) { + $this->add($post[0]); + unset($post[0]); + foreach($post as $k=>$v) { + if(isset($v['delete'])) { + $this->delete($k); + unset($post[$k]); + } + } + $this->edit($post); + } + + function add($post) { + if(!$post['word']) return false; + $post['status'] = $post['status'] == 3 ? 3 : 2; + DB::query("INSERT INTO {$this->table} (moduleid,word,keyword,letter,items,total_search,month_search,week_search,today_search,updatetime,status) VALUES('$post[moduleid]','$post[word]','$post[keyword]','$post[letter]','$post[items]','$post[total_search]','$post[month_search]','$post[week_search]','$post[today_search]','".DT_TIME."', '$post[status]')"); + } + + function edit($post) { + foreach($post as $k=>$v) { + if(!$v['word']) continue; + $v['status'] = $v['status'] == 3 ? 3 : 2; + DB::query("UPDATE {$this->table} SET word='$v[word]',keyword='$v[keyword]',letter='$v[letter]',total_search='$v[total_search]',month_search='$v[month_search]',week_search='$v[week_search]',today_search='$v[today_search]',status='$v[status]' WHERE itemid='$k'"); + } + } + + function delete($itemid) { + DB::query("DELETE FROM {$this->table} WHERE itemid=$itemid"); + } +} +?> \ No newline at end of file diff --git a/admin/like.inc.php b/admin/like.inc.php new file mode 100644 index 0000000..d4ed702 --- /dev/null +++ b/admin/like.inc.php @@ -0,0 +1,67 @@ +query("DELETE FROM {$DT_PRE}like_record WHERE addtime<$time"); + dmsg('清理成功', $forward); + break; + default: + $menuid = 0; + if($action == 'hate') { + $hate = 1; + $menuid = 1; + } else if($action == 'like') { + $hate = 0; + } + (isset($hate) && in_array($hate, array(-1, 0, 1))) or $hate = -1; + (isset($username) && check_name($username)) or $username = ''; + (isset($fromdate) && is_time($fromdate)) or $fromdate = ''; + $fromtime = $fromdate ? datetotime($fromdate) : 0; + (isset($todate) && is_time($todate)) or $todate = ''; + $totime = $todate ? datetotime($todate) : 0; + $tid = isset($tid) ? intval($tid) : 0; + $rid = isset($rid) ? intval($rid) : 0; + $tid or $tid = ''; + $rid or $rid = ''; + $module_select = module_select('mid', '模块', $mid, '', '1,2'); + $condition = '1'; + if($fromtime) $condition .= " AND addtime>=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + if($username) $condition .= " AND username='$username'"; + if($hate > -1) $condition .= " AND hate='$hate'"; + if($mid) $condition .= " AND mid='$mid'"; + if($tid) $condition .= " AND tid='$tid'"; + if($rid) $condition .= " AND rid='$rid'"; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}like_record WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}like_record WHERE $condition ORDER BY itemid DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['addtime'] = timetodate($r['addtime'], 6); + $r['url'] = ''; + if($r['mid'] && $r['tid']) $r['url'] = DT_PATH.'api/redirect.php?mid='.$r['mid'].'&itemid='.$r['tid']; + $lists[] = $r; + } + $rname = '回复/评论ID'; + if($mid) { + if($mid == 3) { + $rname = '评论ID'; + } elseif($MODULE[$mid]['module'] == 'know') { + $rname = '答案ID'; + } elseif($MODULE[$mid]['module'] == 'club') { + $rname = '回复ID'; + } + } + include tpl('like'); + break; +} +?> \ No newline at end of file diff --git a/admin/login.inc.php b/admin/login.inc.php new file mode 100644 index 0000000..9a7944a --- /dev/null +++ b/admin/login.inc.php @@ -0,0 +1,200 @@ += 1) $DT['captcha_admin'] = 1; +if($DT['close']) $DT['captcha_admin'] = 0; +$_forward = $forward ? urlencode($forward) : ''; +$MOD = admin_login(); +$could_sms = ($MOD['login_sms'] && $DT['sms']) ? 1 : 0; +$could_name = $could_sms && $DT['sms_admin'] ? 0 : 1; +if($CFG['authadmin'] == 'cookie') $session = new dsession(); +switch($action) { + case 'sms': + $could_sms or dheader('?file='.$file.'&forward='.$_forward); + if($submit) { + $_SESSION['mobile_oppo'] = $_SESSION['mobile_oppo'] + 1; + if($_SESSION['mobile_oppo'] > 3) $_SESSION['mobile_code'] = ''; + (is_mobile($mobile) && preg_match("/^[0-9]{6}$/", $code) && isset($_SESSION['mobile_code']) && $_SESSION['mobile_code'] == md5($mobile.'|'.$code.'|ADM')) or msg('短信验证失败'); + $_SESSION['mobile_code'] = ''; + $password = $code; + $user = $db->get_one("SELECT username,groupid,passsalt FROM {$DT_PRE}member WHERE mobile='$mobile' AND vmobile=1 ORDER BY userid"); + ($user && $user['groupid'] == 1) or msg('管理账号不存在'); + include load('member.lang'); + require DT_ROOT.'/include/module.func.php'; + require DT_ROOT.'/module/member/member.class.php'; + $do = new member; + $username = $user['username']; + $user = $do->login($username, $password, 0, 'sms'); + if($user) { + if($user['groupid'] != 1 || $user['admin'] < 1) {dalert('您无权限访问后台', $logout);} + if(!is_founder($user['userid'])) { + if(($DT['admin_week'] && !check_period(','.$DT['admin_week'])) || ($DT['admin_hour'] && !check_period($DT['admin_hour']))) {dalert('未被允许的管理时间', $logout);} + } + if($CFG['authadmin'] == 'cookie') { + set_cookie($secretkey, $user['userid']); + } else { + $_SESSION[$secretkey] = $user['userid']; + } + require DT_ROOT.'/admin/admin.class.php'; + $admin = new admin; + $admin->cache_right($user['userid']); + $admin->cache_menu($user['userid']); + if($DT['login_log']) {$do->login_log($username, $password, $user['passsalt'], 1);} + dheader($forward); + } else { + if($DT['login_log']) {$do->login_log($username, $password, $user['passsalt'], 1, $do->errmsg);} + msg($do->errmsg, '?file='.$file.'&action=sms&forward='.$_forward); + } + } else { + $verfiy = 0; + if(isset($auth)) { + $auth = decrypt($auth, DT_KEY.'VSMS'); + if(is_mobile($auth)) { + $verfiy = 1; + $mobile = $auth; + } + } + } + break; + case 'send': + include load('member.lang'); + require DT_ROOT.'/module/member/global.func.php'; + $could_sms or exit('close'); + is_mobile($mobile) or exit('format'); + $user = $db->get_one("SELECT groupid FROM {$DT_PRE}member WHERE mobile='$mobile' AND vmobile=1 ORDER BY userid"); + ($user && $user['groupid'] == 1) or exit('exist'); + isset($_SESSION['mobile_send']) or $_SESSION['mobile_send'] = 0; + isset($_SESSION['mobile_time']) or $_SESSION['mobile_time'] = 0; + if($_SESSION['mobile_send'] > 9) {exit('max');} + if($_SESSION['mobile_time'] && (($DT_TIME - $_SESSION['mobile_time']) < 60)) {exit('fast');} + if(max_sms($mobile)) {exit('max');} + $mobilecode = random(6, '0-9'); + $_SESSION['mobile_code'] = md5($mobile.'|'.$mobilecode.'|ADM'); + $_SESSION['mobile_time'] = $DT_TIME; + $_SESSION['mobile_oppo'] = 0; + $_SESSION['mobile_send'] = $_SESSION['mobile_send'] + 1; + $content = lang('sms->sms_code', array($mobilecode, $MOD['auth_days']*10)).$DT['sms_sign']; + send_sms($mobile, $content); + exit('ok'); + break; + case 'temp': + if(strpos(get_env('self'), '/admin'.DT_EXT) !== false) msg('后台地址未更改', $logout); + $auth = isset($auth) ? decrypt($auth, DT_KEY.'TMPA') : ''; + strpos($auth, '|') !== false or msg('授权链接已失效', $logout); + $arr = explode('|', $auth); + $username = $arr[0]; + check_name($username) or msg('会员错误', $logout); + if($arr[2]) { + if(is_ip($arr[2])) { + if(DT_IP != $arr[2]) msg('IP地址错误', $logout); + } else { + if(strpos(ip2area(DT_IP), $arr[2]) === false) msg('IP归属地错误', $logout); + } + } + $totime = intval($arr[1]); + $totime > DT_TIME or msg('授权已过期', $logout); + $expiry = $totime - DT_TIME; + $expiry <= 36000 or msg('授权时间过长', $logout); + $r = $db->get_one("SELECT username,passport,groupid,admin,password,passsalt,loginip,mobile,vmobile FROM {$DT_PRE}member WHERE username='$username'"); + if($r && $r['groupid'] == 1 && $r['admin'] > 0) { + include load('member.lang'); + require DT_ROOT.'/include/module.func.php'; + require DT_ROOT.'/module/member/member.class.php'; + $do = new member; + $user = $do->login($username, '', $expiry, 'tmp'); + if($user) { + if($CFG['authadmin'] == 'cookie') { + set_cookie($secretkey, $user['userid']); + } else { + $_SESSION[$secretkey] = $user['userid']; + } + $do->login_log($username, '', '', 1); + msg('授权登录成功', '?action=dashboard'); + } else { + $do->login_log($username, '', '', 1, $do->errmsg); + msg($do->errmsg, $logout); + } + } else { + msg('管理账号不存在', $logout); + } + break; + default: + if(!$could_name) { + $action = 'sms'; + $submit = $verfiy = 0; + } + if($submit) { + $msg = captcha($captcha, $DT['captcha_admin'], true); + if($msg) {msg('验证码填写错误');} + if(strlen($username) < 3) {msg('请输入正确的用户名');} + if(strlen($password) < 6 || strlen($password) > 32) {msg('请输入正确的密码');} + if(is_email($username)) { + $condition = "email='$username' AND vemail=1"; + } else if(is_mobile($username)) { + $condition = "mobile='$username' AND vmobile=1"; + } else if(check_name($username)) { + $condition = "username='$username'"; + } else { + msg('账号格式错误'); + } + $r = $db->get_one("SELECT username,passport,groupid,admin,password,passsalt,loginip,mobile,vmobile FROM {$DT_PRE}member WHERE {$condition} ORDER BY userid"); + if($r && $r['groupid'] == 1 && $r['admin'] > 0) { + if($MOD['verfiy_login'] && $could_sms && is_mobile($r['mobile']) && $r['vmobile'] && $r['loginip'] != DT_IP) { + if(ip2area($r['loginip']) != ip2area(DT_IP)) { + if($r['password'] != dpassword($password, $r['passsalt'])) {message($L['member_login_password_bad']);} + dheader('?file='.$file.'&action=sms&auth='.encrypt($r['mobile'], DT_KEY.'VSMS').'&forward='.$_forward); + } + } + $username = $r['username']; + } else { + msg('管理账号不存在'); + } + include load('member.lang'); + require DT_ROOT.'/include/module.func.php'; + require DT_ROOT.'/module/member/member.class.php'; + $do = new member; + $user = $do->login($username, $password); + if($user) { + if($user['groupid'] != 1 || $user['admin'] < 1) dalert('您无权限访问后台', $logout); + if(!is_founder($user['userid'])) { + if(($DT['admin_week'] && !check_period(','.$DT['admin_week'])) || ($DT['admin_hour'] && !check_period($DT['admin_hour']))) dalert('未被允许的管理时间', $logout); + } + if($CFG['authadmin'] == 'cookie') { + set_cookie($secretkey, $user['userid']); + } else { + $_SESSION[$secretkey] = $user['userid']; + } + require DT_ROOT.'/admin/admin.class.php'; + $admin = new admin; + $admin->cache_right($user['userid']); + $admin->cache_menu($user['userid']); + if($DT['login_log']) {$do->login_log($username, $password, $user['passsalt'], 1);} + dheader($forward); + } else { + if($DT['login_log']) {$do->login_log($username, $password, $user['passsalt'], 1, $do->errmsg);} + msg($do->errmsg, '?file='.$file.'&forward='.$_forward); + } + } else { + if(strpos($DT_URL, DT_PATH) === false) {dheader(DT_PATH.basename(get_env('self')));} + $username = isset($username) ? $username : $_username; + } + break; +} +include tpl('login'); +?> \ No newline at end of file diff --git a/admin/md5.inc.php b/admin/md5.inc.php new file mode 100644 index 0000000..bbc2b91 --- /dev/null +++ b/admin/md5.inc.php @@ -0,0 +1,82 @@ +'; + foreach($files as $f) { + if(preg_match("/(index\.html|these\.name\.php)$/i", $f)) continue; + $data .= md5_file($f).' '.str_replace(DT_ROOT.'/', '', $f)."\n"; + } + file_put(DT_ROOT.'/file/md5/'.timetodate($DT_TIME, 'Y-m-d H.i').'.php', $data); + is_file(DT_ROOT.'/file/md5/'.DT_VERSION.'.php') or file_put(DT_ROOT.'/file/md5/'.DT_VERSION.'.php', $data); + if(isset($js)) exit; + dmsg('创建成功', '?file='.$file); + break; + default: + if($submit) { + $mirror or $mirror = DT_VERSION; + $mirror = $mirror.'.php'; + is_file(DT_ROOT.'/file/md5/'.$mirror) or msg('请选择镜像文件'); + $filedir or $filedir = $sys; + $fileext or $fileext = 'php|js|htm'; + $files = array(); + foreach(glob(DT_ROOT.'/*.*') as $f) { + if(preg_match("/(config\.inc\.php|version\.inc\.php)$/i", $f)) continue; + if(preg_match("/\.($fileext)$/i", $f)) $files[] = $f; + } + foreach($filedir as $d) { + $files = array_merge($files, get_file(DT_ROOT.'/'.$d, $fileext)); + } + $lists = array(); + foreach($files as $f) { + if(preg_match("/(index\.html|these\.name\.php)$/i", $f)) continue; + $lists[md5_file($f)] = str_replace(DT_ROOT.'/', '', $f); + } + $content = substr(trim(file_get(DT_ROOT.'/file/md5/'.$mirror)), 13); + foreach(explode("\n", $content) as $v) { + list($m, $f) = explode(' ', trim($v)); + if(isset($lists[$m]) && $lists[$m] == $f) unset($lists[$m]); + } + } else { + is_file(DT_ROOT.'/file/md5/'.DT_VERSION.'.php') or msg('正在创建镜像文件..', '?file='.$file.'&action=add'); + $files = glob(DT_ROOT.'/*'); + $dirs = $rfiles = array(); + foreach($files as $f) { + if(is_file($f)) { + $rfiles[] = basename($f); + } else { + $dirs[] = basename($f); + } + } + $mfiles = glob(DT_ROOT.'/file/md5/*.php'); + } + include tpl('md5'); + break; +} +?> \ No newline at end of file diff --git a/admin/menu.inc.php b/admin/menu.inc.php new file mode 100644 index 0000000..deaa6a6 --- /dev/null +++ b/admin/menu.inc.php @@ -0,0 +1,40 @@ + \ No newline at end of file diff --git a/admin/mobile.inc.php b/admin/mobile.inc.php new file mode 100644 index 0000000..de03b7f --- /dev/null +++ b/admin/mobile.inc.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/admin/module.inc.php b/admin/module.inc.php new file mode 100644 index 0000000..d4a7ebb --- /dev/null +++ b/admin/module.inc.php @@ -0,0 +1,242 @@ +$v) { + if(is_file($v.'/admin/config.inc.php')) { + include $v.'/admin/config.inc.php'; + $sysmodules[$MCFG['module']] = $MCFG; + } + } + return $sysmodules; +} +switch($action) { + case 'add': + if($submit) { + if(!$post['name']) msg('请填写模块名称'); + if($post['islink']) { + if(!$post['linkurl']) msg('请填写链接地址'); + } else { + $dir = $post['moduledir']; + $module = $post['module']; + if(!$module) msg('请选择所属模型'); + $module_cfg = DT_ROOT.'/module/'.$module.'/admin/config.inc.php'; + if(!is_file($module_cfg)) msg('此模型无法安装,请检查'); + include $module_cfg; + if($MCFG['uninstall'] == false) msg('此模型无法安装,请检查'); + if($MCFG['copy'] == false) { + $r = $db->get_one("SELECT moduleid FROM {$DT_PRE}module WHERE module='$module' AND islink=0"); + if($r) msg('此模型已经安装过,请检查'); + } + if(!$dir) msg('请填写安装目录'); + if(!preg_match("/^[0-9a-z_-]+$/i", $dir)) msg('目录名不合法,请更换一个再试'); + $r = $db->get_one("SELECT moduleid FROM {$DT_PRE}module WHERE moduledir='$dir' AND islink=0"); + if($r) msg('此目录名已经被其他模块使用,请更换一个再试'); + $sysdirs = array('ad', 'admin', 'announce', 'api', 'archiver', 'comment', 'feed', 'file', 'gift', 'guestbook', 'include', 'install', 'lang', 'link', 'module', 'poll', 'sitemap', 'skin', 'spread', 'template', 'upgrade', 'vote', 'mobile', 'form'); + if(in_array($dir, $sysdirs)) msg('安装目录与系统目录冲突,请更换安装目录'); + if(!dir_create(DT_ROOT.'/'.$dir.'/')) msg('无法创建'.$dir.'目录,请检查PHP是否有创建权限或手动创建'); + if(!is_write(DT_ROOT.'/'.$dir.'/')) msg('目录'.$dir.'无法写入,请设置此目录可写权限'); + if(!file_put(DT_ROOT.'/'.$dir.'/config.inc.php', "DESTOON")) msg('目录'.$dir.'无法写入,请设置此目录可写权限'); + } + if($post['domain']) $post['domain'] = fix_domain($post['domain']); + if($post['mobile']) $post['mobile'] = fix_domain($post['mobile']); + $post['linkurl'] = $post['islink'] ? $post['linkurl'] : ($post['domain'] ? $post['domain'] : linkurl($post['moduledir']."/")); + if($post['islink']) $post['module'] = 'destoon'; + $post['installtime'] = $DT_TIME; + if($MCFG['moduleid']) { + $db->query("DELETE FROM {$DT_PRE}module WHERE moduleid=".$MCFG['moduleid']); + $post['moduleid'] = $MCFG['moduleid']; + } + $sql1 = $sql2 = $s = ""; + foreach($post as $key=>$value) { + $sql1 .= $s.$key; + $sql2 .= $s."'".$value."'"; + $s = ","; + } + $db->query("INSERT INTO {$DT_PRE}module ($sql1) VALUES ($sql2)"); + $moduleid = $db->insert_id(); + $db->query("UPDATE {$DT_PRE}module SET listorder=$moduleid WHERE moduleid=$moduleid"); + if($post['islink']) { + } else { + $module = $post['module']; + $dir = $post['moduledir']; + $modulename = $post['name']; + file_put(DT_ROOT.'/'.$dir.'/config.inc.php', ""); + @include DT_ROOT.'/module/'.$module.'/admin/install.inc.php'; + } + cache_module(); + dmsg('模块添加成功', $this_forward); + } else { + $imodules = array(); + $result = $db->query("SELECT module FROM {$DT_PRE}module"); + while($r = $db->fetch_array($result)) { + $imodules[$r['module']] = $r['module']; + } + $modules = get_modules(); + $module_select = ''; + include tpl('module_add'); + } + break; + case 'edit': + if(!$modid) msg('模块ID不能为空'); + if($modid == 1 || $modid == 3) msg('系统模型,不可修改'); + $r = $db->get_one("SELECT * FROM {$DT_PRE}module WHERE moduleid='$modid'"); + if(!$r) msg('模块不存在'); + extract($r); + if($submit) { + if(!$post['name']) msg('请填写模块名称'); + if($islink) { + if(!$post['linkurl']) msg('请填写链接地址'); + } else { + if($modid == 4) $post['moduledir'] = 'company'; + if(!$post['moduledir']) msg('请填写安装目录'); + if(!preg_match("/^[0-9a-z_-]+$/i", $post['moduledir'])) msg('目录名不合法,请更换一个再试'); + $sysdirs = array('ad', 'admin', 'announce', 'api', 'archiver', 'comment', 'feed', 'file', 'gift', 'guestbook', 'include', 'install', 'lang', 'link', 'module', 'poll', 'sitemap', 'skin', 'spread', 'template', 'upgrade', 'vote', 'mobile', 'form'); + if(in_array($post['moduledir'], $sysdirs)) msg('安装目录与系统目录冲突,请更换安装目录'); + $r = $db->get_one("SELECT moduleid FROM {$DT_PRE}module WHERE moduledir='$post[moduledir]' AND moduleid!=$modid"); + if($r) msg('此目录名已经被其他模块使用,请更换一个再试'); + if($post['domain']) $post['domain'] = fix_domain($post['domain']); + if($post['mobile']) $post['mobile'] = fix_domain($post['mobile']); + $post['linkurl'] = $post['domain'] ? $post['domain'] : linkurl($post['moduledir']."/"); + } + $sql = $s = ""; + foreach($post as $key=>$value) { + $sql .= $s.$key."='".$value."'"; + $s = ","; + } + $db->query("UPDATE {$DT_PRE}module SET $sql WHERE moduleid=$modid"); + if(!$islink && $moduledir != $post['moduledir']) { + rename(DT_ROOT.'/'.$moduledir, DT_ROOT.'/'.$post['moduledir']) or msg('无法重命名目录'.$moduledir.'为'.$post['moduledir'].',请手动修改'); + rename(DT_ROOT.'/mobile/'.$moduledir, DT_ROOT.'/mobile/'.$post['moduledir']); + } + cache_module(); + dmsg('模块修改成功', $this_forward); + } else { + @include DT_ROOT.'/module/'.$module.'/admin/config.inc.php'; + $modulename = isset($MCFG['name']) ? $MCFG['name'] : ''; + include tpl('module_edit'); + } + break; + case 'delete': + if(!$modid) msg('模块ID不能为空'); + if($modid < 5) msg('系统模型不可删除'); + #if($modid < 23) dheader('?file='.$file.'&action=disable&value=1&modid='.$modid); + $r = $db->get_one("SELECT * FROM {$DT_PRE}module WHERE moduleid='$modid'"); + if(!$r) msg('此模块不存在'); + if(!$r['islink']) { + $moduleid = $r['moduleid']; + $module = $r['module']; + $dir = $r['moduledir']; + $module_cfg = DT_ROOT.'/module/'.$module.'/admin/config.inc.php'; + if(!is_file($module_cfg)) msg('此模型不可卸载,请检查'); + include $module_cfg; + if($MCFG['uninstall'] == false) msg('此模型不可卸载,请检查'); + @include DT_ROOT.'/module/'.$module.'/admin/uninstall.inc.php'; + $result = $db->query("SHOW TABLES FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_row($result)) { + $tb = $r[0]; + $pt = str_replace($DT_PRE.$moduleid.'_', '', $tb); + if(is_numeric($pt)) $db->query("DROP TABLE IF EXISTS `".$tb."`"); + } + $db->query("DELETE FROM `".$DT_PRE."category` WHERE moduleid=$moduleid"); + $db->query("DELETE FROM `".$DT_PRE."keylink` WHERE item=$moduleid"); + $db->query("DELETE FROM `".$DT_PRE."setting` WHERE item=$moduleid"); + $tb = str_replace($DT_PRE, '', get_table($moduleid)); + $db->query("DELETE FROM `".$DT_PRE."fields` WHERE tb='$tb'"); + dir_delete(DT_ROOT.'/'.$dir); + dir_delete(DT_ROOT.'/mobile/'.$dir); + } + $db->query("DELETE FROM {$DT_PRE}module WHERE moduleid='$modid'"); + cache_module(); + dmsg('模块删除成功', $this_forward); + break; + case 'remkdir': + if(!$modid) msg('模块ID不能为空'); + $r = $db->get_one("SELECT * FROM {$DT_PRE}module WHERE moduleid='$modid'"); + $remkdir = DT_ROOT.'/module/'.$r['module'].'/admin/remkdir.inc.php'; + if(is_file($remkdir)) { + $moduleid = $r['moduleid']; + $module = $r['module']; + $dir = $r['moduledir']; + if(!dir_create(DT_ROOT.'/'.$dir)) msg('无法创建'.$dir.'目录,请检查PHP是否有创建权限或手动创建'); + if(!file_put(DT_ROOT.'/'.$dir.'/ajax.php', "DESTOON TEST")) msg('目录'.$dir.'无法写入,如果是Linux/Unix服务器,请设置此目录可写权限'); + file_del(DT_ROOT.'/'.$dir.'/config.inc.php'); + file_copy(DT_ROOT.'/api/ajax.php', DT_ROOT.'/'.$dir.'/ajax.php'); + file_copy(DT_ROOT.'/api/ajax.php', DT_ROOT.'/mobile/'.$dir.'/ajax.php'); + include $remkdir; + cache_module(); + dmsg('目录重建成功', '?file='.$file); + } else { + msg('此模型无需重建目录', '?file='.$file); + } + break; + case 'disable': + if(!$modid) msg('模块ID不能为空'); + if($modid < 5) msg('系统模型不可禁用'); + $value = $value ? 1 : 0; + $db->query("UPDATE {$DT_PRE}module SET disabled='$value' WHERE moduleid=$modid"); + cache_module(); + dmsg('模块状态已经修改', $this_forward); + break; + case 'order': + foreach($listorder as $k=>$v) { + $k = intval($k); + $v = intval($v); + $db->query("UPDATE {$DT_PRE}module SET listorder='$v' WHERE moduleid=$k"); + } + cache_module(); + dmsg('更新成功', $this_forward); + break; + case 'cache': + cache_module(); + dmsg('更新成功', $forward); + break; + case 'ckdir': + if(!preg_match("/^[0-9a-z_-]+$/i", $moduledir)) dialog('不是一个合法的目录名,请更换一个再试'); + $r = $db->get_one("SELECT moduleid FROM {$DT_PRE}module WHERE moduledir='$moduledir'"); + if($r || is_dir(DT_ROOT.'/'.$moduledir.'/')) dialog('该目录名已经被使用,请更换一个再试'); + dialog('目录名可以使用'); + break; + case 'sys': + $sysmodules = get_modules(); + include tpl('module_sys'); + break; + default: + $sysmodules = get_modules(); + $modules = $_modules = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}module ORDER BY listorder ASC,moduleid DESC"); + while($r = $db->fetch_array($result)) { + if($r['moduleid'] == 1) continue; + $r['installdate'] = timetodate($r['installtime'], 3); + $r['modulename'] = isset($sysmodules[$r['module']]) ? $sysmodules[$r['module']]['name'] : '外链'; + if($r['disabled']) { + $_modules[] = $r; + } else { + $modules[] = $r; + } + } + include tpl('module'); + break; +} +?> \ No newline at end of file diff --git a/admin/mymenu.inc.php b/admin/mymenu.inc.php new file mode 100644 index 0000000..df56c60 --- /dev/null +++ b/admin/mymenu.inc.php @@ -0,0 +1,30 @@ +update($_userid, $right, $_admin)) dmsg('保存成功', '?file='.$file.'&itemid='.$itemid.'&update=1'); + msg($do->errmsg); +} else { + $dmenus = $do->get_menu($_userid); + if(isset($title)) { + // + } else { + $title = ''; + } + if(isset($url)) { + $pos = strpos($url, '?'); + if($pos !== false) $url = substr($url, $pos); + } else { + $url = ''; + } + include tpl('mymenu'); +} +?> \ No newline at end of file diff --git a/admin/patch.inc.php b/admin/patch.inc.php new file mode 100644 index 0000000..5063ee6 --- /dev/null +++ b/admin/patch.inc.php @@ -0,0 +1,143 @@ +pid='.$pid); + exit; +} else { + if($submit) { + is_time($fd) or msg('开始时间设置错误'); + $ft = datetotime($fd); + is_time($td) or msg('结束时间设置错误'); + $tt = datetotime($td); + $tt >= $ft or msg('时间范围设置错误'); + + isset($filedir) or $filedir = $sys; + $fileext or $fileext = $ext; + $lists = array(); + if($type) { + $files = isset($files) ? trim($files) : ''; + foreach(explode("\n", $files) as $f) { + $f = trim($f); + $f = str_replace("\\", '/', $f); + if(strpos($f, '..') !== false || strpos($f, ':') !== false) continue; + if(substr($f, 0, 1) == '/') continue; + if(!is_file(DT_ROOT.'/'.$f) && !is_dir(DT_ROOT.'/'.$f)) continue; + $lists[] = DT_ROOT.'/'.$f; + } + $ft = $tt = $DT_TIME; + } else { + $files = array(); + foreach(glob(DT_ROOT.'/*.*') as $f) { + if(is_dir($f)) continue; + if(in_array(basename($f), array('config.inc.php', 'index.html', 'baidunews.xml', 'sitemaps.xml'))) continue; + $files[] = $f; + } + foreach($filedir as $d) { + if($d == 'file') { + $files = array_merge($files, get_file(DT_ROOT.'/'.$d.'/script', $fileext)); + $files = array_merge($files, get_file(DT_ROOT.'/'.$d.'/image', $fileext)); + $files = array_merge($files, get_file(DT_ROOT.'/'.$d.'/config', $fileext)); + $files = array_merge($files, get_file(DT_ROOT.'/'.$d.'/setting', $fileext)); + } else { + $files = array_merge($files, get_file(DT_ROOT.'/'.$d, $fileext)); + } + } + foreach($files as $f) { + if(in_array($f, array(DT_ROOT.'/file/script/config.js'))) continue; + $n = basename($f); + if(file_ext($n) == 'js') { + if(in_array(substr($n, 0, 1), array('A', '0'))) continue; + } + $t = filemtime($f); + if($t >= $ft && $t <= $tt) { + $lists[] = $f; + } + } + } + $find = count($lists); + if($find) { + $dir = DT_ROOT.'/file/patch/'.timetodate($ft, 'Y-m-d H.i').'~'.timetodate($tt, 'Y-m-d H.i').'/'; + if(!is_dir($dir)) dir_delete($dir); + if($note) { + $note = trim(dhtmlspecialchars(strip_tags($note))); + file_put($dir.'file/temp/note.txt', $note); + } + foreach($lists as $f) { + if(is_file($f)) { + file_copy($f, $dir.str_replace(DT_ROOT.'/', '', $f)); + @touch($dir.str_replace(DT_ROOT.'/', '', $f), filemtime($f)); + } else if(is_dir($f)) { + dir_copy($f, $dir.str_replace(DT_ROOT.'/', '', $f)); + } + } + cache_write('patch.php', array($td)); + msg('备份成功 '.$find.' 个文件或目录,已保存于file/patch', '?file='.$file, 5); + } + msg('没有符合条件的文件'); + } else { + $files = glob(DT_ROOT.'/*'); + $dirs = $rfiles = $baks = $ups = array(); + foreach($files as $f) { + $bn = basename($f); + if(is_file($f)) { + $rfiles[] = $bn; + } else { + $dirs[] = $bn; + } + } + $fd = substr(DT_RELEASE, 0, 4).'-'.substr(DT_RELEASE, 4, 2).'-'.substr(DT_RELEASE, 6, 2).' 00:00:00'; + $tt = cache_read('patch.php'); + if($tt && is_time($tt[0])) $fd = $tt[0]; + $td = timetodate($DT_TIME, 6); + $files = glob(DT_ROOT.'/file/patch/*'); + foreach($files as $f) { + if(is_dir($f)) { + $n = basename($f); + if(preg_match("/^[0-9\.\-\s~]{33}$/", $n)) { + $r = array(); + $r['file'] = $n; + $r['num'] = count(get_file($f)); + $r['time'] = timetodate(filemtime($f), 5); + $r['note'] = file_get($f.'/file/temp/note.txt'); + $baks[] = $r; + } + } + } + $date1 = timetodate($DT_TIME, 3); + $date2 = timetodate($DT_TIME - 86400, 3); + $date3 = timetodate($DT_TIME - 86400*2, 3); + $date4 = timetodate($DT_TIME - 86400*(intval(timetodate($DT_TIME, 'N'))-1), 3); + $date5 = timetodate($DT_TIME, 'Y-m').'-01'; + } + include tpl('patch'); +} +?> \ No newline at end of file diff --git a/admin/property.inc.php b/admin/property.inc.php new file mode 100644 index 0000000..601c0a4 --- /dev/null +++ b/admin/property.inc.php @@ -0,0 +1,207 @@ +catid = $catid; +switch($action) { + case 'add': + if($submit) { + if($do->pass($post)) { + $do->add($post); + dmsg('添加成功', '?file='.$file.'&catid='.$catid); + } else { + msg($do->errmsg); + } + } else { + $type = 2; + $required = $search = 0; + $name = $value = $extend = ''; + include tpl('property_edit'); + } + break; + case 'edit': + $oid or msg(); + $do->oid = $oid; + if($submit) { + if($do->pass($post)) { + $do->edit($post); + dmsg('修改成功', $forward); + } else { + msg($do->errmsg); + } + } else { + extract($do->get_one($oid)); + include tpl('property_edit'); + } + break; + case 'copy': + $_id = $mid ? $mid : $CAT['moduleid']; + if($submit) { + if($type) { + $fromid = intval($fromid); + $fromid or msg('请选择来源分类'); + $fromid != $catid or msg('来源分类不能与当前分类相同'); + $id = $fromid; + $type = 1; + } else { + $pid = intval($pid); + $pid or msg('请填写属性ID'); + $id = $pid; + $type = 0; + } + $name = $name ? 1 : 0; + if($do->copy($id, $type, $name)) { + dmsg('属性复制成功', '?file='.$file.'&catid='.$catid); + } else { + msg($do->errmsg); + } + } else { + include tpl('property_copy'); + } + break; + case 'update': + $do->update($post); + dmsg('更新成功', $forward); + break; + default: + $lists = $do->get_list(); + include tpl('property'); + break; +} +class property { + var $oid; + var $catid; + var $table; + var $errmsg = errmsg; + + function __construct() { + $this->table = DT_PRE.'category_option'; + } + + function property() { + $this->__construct(); + } + + function pass($post) { + if(!is_array($post)) return false; + if(!$post['name']) return $this->_('请填写属性名称'); + if($post['type'] == 3) { + if(!$post['value']) return $this->_('请填写备选值'); + if(strpos($post['value'], '|') === false) return $this->_('最少需要设定2个备选值'); + } + return true; + } + + function set($post) { + $post['value'] = trim($post['value']); + if($post['type'] < 2) $post['search'] = 0; + return $post; + } + + function add($post) { + $post = $this->set($post); + $sqlk = $sqlv = ''; + foreach($post as $k=>$v) { + $sqlk .= ','.$k; $sqlv .= ",'$v'"; + } + $sqlk = substr($sqlk, 1); + $sqlv = substr($sqlv, 1); + DB::query("INSERT INTO {$this->table} ($sqlk) VALUES ($sqlv)"); + return true; + } + + function edit($post) { + $post = $this->set($post); + $sql = ''; + foreach($post as $k=>$v) { + $sql .= ",$k='$v'"; + } + $sql = substr($sql, 1); + DB::query("UPDATE {$this->table} SET $sql WHERE oid=$this->oid"); + return true; + } + + function copy($id, $type, $name) { + $i = 0; + $condition = $type ? "catid=$id" : "oid=$id"; + $result = DB::query("SELECT * FROM {$this->table} WHERE {$condition}"); + while($r = DB::fetch_array($result)) { + if($name) { + $n = daddslashes($r['name']); + $t = DB::get_one("SELECT * FROM {$this->table} WHERE catid=$this->catid AND name='$n'"); + if($t) { + if($type) continue; + return $this->_('属性名称 ['.$r['name'].'] 已存在'); + } + } + unset($r['oid']); + $r['catid'] = $this->catid; + $post = daddslashes($r); + $sqlk = $sqlv = ''; + foreach($post as $k=>$v) { + $sqlk .= ','.$k; $sqlv .= ",'$v'"; + } + $sqlk = substr($sqlk, 1); + $sqlv = substr($sqlv, 1); + DB::query("INSERT INTO {$this->table} ($sqlk) VALUES ($sqlv)"); + $i++; + } + if($i) return true; + return $this->_('属性参数不存在或存在同名'); + } + + function get_one() { + return DB::get_one("SELECT * FROM {$this->table} WHERE oid=$this->oid"); + } + + function update($post) { + foreach($post as $k=>$v) { + $k = intval($k); + if(isset($v['delete']) && $v['delete']) { + DB::query("DELETE FROM {$this->table} WHERE oid=$k"); + } else { + $listorder = intval($v['listorder']); + $value = $v['value']; + $name = $v['name']; + $required = $v['required'] ? 1 : 0; + DB::query("UPDATE {$this->table} SET listorder=$listorder,required=$required,value='$value',name='$name' WHERE oid=$k"); + } + } + return true; + } + + function get_list() { + global $pages, $page, $pagesize, $offset, $pagesize, $CAT, $sum; + $condition = "catid=$this->catid"; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = DB::get_one("SELECT COUNT(*) AS num FROM {$this->table} WHERE $condition"); + $items = $r['num']; + } + if($items != $CAT['property']) DB::query("UPDATE ".DT_PRE."category SET property=$r[num] WHERE catid=$this->catid"); + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE $condition ORDER BY listorder ASC,oid ASC LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $lists[] = $r; + } + return $lists; + } + + function _($e) { + $this->errmsg = $e; + return false; + } +} +?> \ No newline at end of file diff --git a/admin/question.inc.php b/admin/question.inc.php new file mode 100644 index 0000000..a51ada8 --- /dev/null +++ b/admin/question.inc.php @@ -0,0 +1,80 @@ +update($post); + dmsg('保存成功', '?file='.$file); +} else { + $condition = "1"; + if($kw) $condition .= " AND (question LIKE '%$keyword%' OR answer LIKE '%$keyword%')"; + $lists = $do->get_list($condition); + include tpl('question'); +} + +class question { + var $table; + + function __construct() { + $this->table = DT_PRE.'question'; + } + + function question() { + $this->__construct(); + } + + function get_list($condition) { + global $pages, $page, $pagesize, $offset, $pagesize; + $pages = pages(DB::count($this->table, $condition), $page, $pagesize); + $lists = array(); + $result = DB::query("SELECT * FROM {$this->table} WHERE $condition ORDER BY qid DESC LIMIT $offset,$pagesize"); + while($r = DB::fetch_array($result)) { + $lists[] = $r; + } + return $lists; + } + + function update($post) { + $this->add($post[0]); + unset($post[0]); + foreach($post as $k=>$v) { + if(isset($v['delete'])) { + $this->delete($k); + unset($post[$k]); + } + } + $this->edit($post); + return true; + } + + function add($post) { + if(!$post['question'] || !$post['answer']) return false; + $Q = explode("\n", $post['question']); + $A = explode("\n", $post['answer']); + foreach($Q as $k=>$q) { + $q = trim($q); + if($q) { + $a = isset($A[$k]) ? trim($A[$k]) : ''; + if($q && $a) DB::query("INSERT INTO {$this->table} (question,answer) VALUES('$q','$a')"); + } + } + } + + function edit($post) { + foreach($post as $k=>$v) { + if(!$v['question'] || !$v['answer']) continue; + DB::query("UPDATE {$this->table} SET question='$v[question]',answer='$v[answer]' WHERE qid='$k'"); + } + } + + function delete($qid) { + DB::query("DELETE FROM {$this->table} WHERE qid=$qid"); + } +} +?> \ No newline at end of file diff --git a/admin/scan.inc.php b/admin/scan.inc.php new file mode 100644 index 0000000..d9984d2 --- /dev/null +++ b/admin/scan.inc.php @@ -0,0 +1,179 @@ + 1, + 'baidunews.xml' => 1, + 'config.inc.php' => 1, + 'index.html' => 1, + 'admin/admin.inc.php' => 1, + 'admin/area.inc.php' => 1, + 'admin/config.inc.php' => 1, + 'admin/data.inc.php' => 2, + 'admin/database.inc.php' => 1, + 'admin/index.inc.php' => 3, + 'admin/log.inc.php' => 1, + 'admin/md5.inc.php' => 1, + 'admin/menu.inc.php' => 1, + 'admin/patch.inc.php' => 1, + 'admin/setting.inc.php' => 1, + 'admin/scan.inc.php' => 3, + 'admin/tag.inc.php' => 1, + 'admin/unzip.class.php' => 2, + 'admin/update.inc.php' => 1, + 'admin/template.inc.php' => 1, + 'admin/template/count.tpl.php' => 1, + 'admin/template/left.tpl.php' => 1, + 'admin/template/msg.tpl.php' => 1, + 'admin/template/scan.tpl.php' => 1, + 'admin/template/setting.tpl.php' => 1, + 'admin/template/tag_preview.tpl.php' => 1, + 'api/memcache.php' => 3, + 'api/avatar/upload.php' => 1, + 'api/barcode/BCGBarcode.php' => 1, + 'api/barcode/BCGColor.php' => 1, + 'api/barcode/BCGDrawPNG.php' => 1, + 'api/barcode/BCGcode39.barcode.php' => 1, + 'api/excel/data.class.php' => 1, + 'api/excel/debug.class.php' => 1, + 'api/excel/parser.class.php' => 3, + 'api/map/51ditu/mark.php' => 1, + 'api/oauth/baidu/callback.php' => 1, + 'api/oauth/netease/callback.php' => 1, + 'api/oauth/qq/callback.php' => 1, + 'api/oauth/qq/index.php' => 1, + 'api/oauth/qq/post.php' => 1, + 'api/oauth/qq/qzone.php' => 1, + 'api/qrcode.png.php' => 3, + 'api/pay/kq99bill/notify.php' => 1, + 'api/pay/paypal/notify.php' => 1, + 'api/pay/paypal/send.inc.php' => 1, + 'api/pay/yeepay/send.inc.php' => 1, + 'include/cache_shmop.class.php' => 1, + 'include/captcha.class.php' => 1, + 'include/client.func.php' => 1, + 'include/content.class.php' => 1, + 'include/db_pdo.class.php' => 1, + 'include/mobile.func.php' => 1, + 'include/fields.func.php' => 1, + 'include/file.func.php' => 1, + 'include/global.func.php' => 3, + 'include/ip.class.php' => 1, + 'include/post.func.php' => 2, + 'include/safe.func.php' => 2, + 'include/seo.inc.php' => 1, + 'include/session_apc.class.php' => 1, + 'include/session_eaccelerator.class.php' => 1, + 'include/session_file.class.php' => 1, + 'include/session_memcache.class.php' => 1, + 'include/session_mysql.class.php' => 1, + 'include/session_redis.class.php' => 1, + 'include/session_shmop.class.php' => 1, + 'include/session_wincache.class.php' => 1, + 'include/session_xcache.class.php' => 1, + 'include/sql.func.php' => 1, + 'include/template.func.php' => 1, + 'install/index.php' => 1, + 'mobile/common.inc.php' => 1, + 'module/brand/admin/install.inc.php' => 1, + 'module/buy/admin/install.inc.php' => 1, + 'module/club/admin/install.inc.php' => 1, + 'module/down/admin/install.inc.php' => 1, + 'module/exhibit/admin/install.inc.php' => 1, + 'module/group/admin/install.inc.php' => 1, + 'module/group/admin/template/order_stats.tpl.php' => 1, + 'module/job/admin/install.inc.php' => 1, + 'module/know/admin/install.inc.php' => 1, + 'module/mall/admin/install.inc.php' => 1, + 'module/mall/admin/template/order_stats.tpl.php' => 1, + 'module/member/avatar.inc.php' => 1, + 'module/member/admin/promo.inc.php' => 1, + 'module/member/admin/sendmail.inc.php' => 1, + 'module/member/admin/sendsms.inc.php' => 1, + 'module/member/admin/template/cash_stats.tpl.php' => 1, + 'module/member/admin/template/charge_stats.tpl.php' => 1, + 'module/member/admin/template/pay_stats.tpl.php' => 1, + 'module/member/admin/template/weixin_chat.tpl.php' => 2, + 'module/member/message.inc.php' => 1, + 'module/photo/admin/install.inc.php' => 1, + 'module/quote/admin/install.inc.php' => 1, + 'module/quote/price.inc.php' => 1, + 'module/sell/admin/install.inc.php' => 1, + 'module/special/admin/install.inc.php' => 1, + 'module/special/type.inc.php' => 1, + 'module/video/admin/install.inc.php' => 1, + 'upgrade/config.inc.php' => 1, + 'upgrade/index.php' => 1, + 'mobile/index.php' => 1, + ); + isset($filedir) or $filedir = array(); + $fileext or $fileext = $bd_ext; + $code or $code = $bd_code; + $codenum or $codenum = 1; + $code = str_replace('\|', '|', preg_quote(stripslashes($code))); + $code = convert($code, DT_CHARSET, $charset); + $files = array(); + foreach(glob(DT_ROOT.'/*.*') as $f) { + $files[] = $f; + } + foreach($filedir as $d) { + $files = array_merge($files, get_file(DT_ROOT.'/'.$d, $fileext)); + } + $lists = $mirror = array(); + if(is_file(DT_ROOT.'/file/md5/'.DT_VERSION.'.php')) { + $content = substr(trim(file_get(DT_ROOT.'/file/md5/'.DT_VERSION.'.php')), 13); + foreach(explode("\n", $content) as $v) { + list($m, $f) = explode(' ', trim($v)); + $mirror[$m] = $f; + } + } + foreach($files as $f) { + if(strpos($f, '/api/pay/') !== false) continue; + if(strpos($f, '/api/app/') !== false) continue; + $content = file_get($f); + if(preg_match_all('/('.$code.')/i', $content, $m)) { + $r = $c = array(); + foreach($m[1] as $v) { + in_array($v, $c) or $c[] = $v; + } + $r['num'] = count($c); + if($r['num'] < $codenum && strpos($content, 'Zend') === false) continue; + $r['file'] = str_replace(DT_ROOT.'/', '', $f); + if($mirror && in_array($r['file'], $mirror)) { + if(md5_file($f) == array_search($r['file'], $mirror)) continue; + } + if(isset($W[$r['file']]) && $W[$r['file']] == $r['num']) continue; + $r['code'] = convert(implode(',', $c), $charset, DT_CHARSET); + $lists[] = $r; + } + } + $find = count($lists); +} else { + $files = glob(DT_ROOT.'/*'); + $dirs = $rfiles = array(); + foreach($files as $f) { + $bn = basename($f); + if(is_file($f)) { + $rfiles[] = $bn; + } else { + if($bn == 'file') continue; + $dirs[] = $bn; + } + } + $code = $bd_code; + $fileext = $bd_ext; +} +include tpl('scan'); +?> \ No newline at end of file diff --git a/admin/search.inc.php b/admin/search.inc.php new file mode 100644 index 0000000..58f11a2 --- /dev/null +++ b/admin/search.inc.php @@ -0,0 +1,85 @@ +$v) { + if($v['islink'] || $k == 1) continue; + $menu = array(); + $moduleid = $k; + $name = $v['name']; + include DT_ROOT.'/module/'.$v['module'].'/admin/menu.inc.php'; + $name = $moduleid == 3 ? '扩展功能' : $name.'管理'; + foreach($menu as $m) { + if(strpos($m[0], $kw) !== false) { + $m[0] = ($moduleid > 2 ? '功能模块 - ' : '').$name.' - '.$m[0]; + $files[] = $m; + } + } + } + foreach($menu_finance as $m) { + if(strpos($m[0], $kw) !== false) { + $m[0] = '会员管理 - 财务管理 - '.$m[0]; + $files[] = $m; + } + } + foreach($menu_relate as $m) { + if(strpos($m[0], $kw) !== false) { + $m[0] = '会员管理 - 会员相关 - '.$m[0]; + $files[] = $m; + } + } + $moduleid = $mid; + $content = file_get_contents(DT_ROOT.'/admin/template/setting.tpl.php'); + if(preg_match_all('/('.$kw.')/i', $content, $m)) { + $lists[1]['num'] = count($m[1]); + $lists[1]['name'] = '系统维护 - 网站设置'; + } + foreach($MODULE as $k=>$v) { + if($v['islink'] || $k == 1) continue; + $content = file_get_contents(DT_ROOT.'/module/'.$v['module'].'/admin/template/setting.tpl.php'); + if(preg_match_all('/('.$kw.')/i', $content, $m)) { + $lists[$k]['num'] = count($m[1]); + $lists[$k]['name'] = '功能模块 - '.($k == 3 ? '扩展功能' : $v['name'].'管理').' - 模块设置'; + } + } + $content = file_get_contents(DT_ROOT.'/module/member/admin/template/group_edit.tpl.php'); + if(preg_match_all('/('.$kw.')/i', $content, $m)) { + foreach(cache_read('group.php') as $m) { + $_m = array(); + $_m[0] = '会员管理 - 会员组管理 - '.$m['groupname']; + $_m[1] = '?moduleid=2&file=group&action=edit&groupid='.$m['groupid'].'&kw='.$ukw; + $files[] = $_m; + } + } + foreach(cache_read('menu-'.$_userid.'.php') as $m) { + if(strpos($m['title'], $kw) !== false) { + $_m = array(); + $_m[0] = '我的面板 - '.$m['title']; + $_m[1] = $m['url']; + $files[] = $_m; + } + } +} +include tpl('search'); +?> \ No newline at end of file diff --git a/admin/setting.inc.php b/admin/setting.inc.php new file mode 100644 index 0000000..2b2a97f --- /dev/null +++ b/admin/setting.inc.php @@ -0,0 +1,153 @@ +connected) dialog('FTP无法连接,请检查设置'); + if(!$ftp->dftp_chdir()) dialog('FTP无法进入远程存储目录,请检查远程存储目录'); + dialog('FTP设置正常,可以使用'); + break; + case 'mail': + define('TESTMAIL', true); + if(strpos($smtp_pass, '***') !== false) $smtp_pass = $DT['smtp_pass']; + $DT['mail_type'] = $mail_type; + $DT['smtp_host'] = $smtp_host; + $DT['smtp_port'] = $smtp_port; + $DT['smtp_auth'] = $smtp_auth; + $DT['smtp_user'] = $smtp_user; + $DT['smtp_pass'] = $smtp_pass; + $DT['mail_sender'] = $mail_sender; + $DT['mail_name'] = $mail_name; + $DT['mail_delimiter'] = $mail_delimiter; + $DT['mail_sign'] = ''; + if($mail_type == 'sc') { + $subject = '来自SendCloud的第一封邮件!'; + $body = '你太棒了!你已成功的从SendCloud发送了一封测试邮件,接下来快登录前台去完善账户信息吧!'; + } else { + $subject = $DT['sitename'].'邮件发送测试'; + $body = '恭喜!您的站点['.$DT['sitename'].']邮件发送设置成功!
    ------------------------------------
    Send By DESTOON Mail Tester'; + } + if(send_mail($testemail, $subject, $body)) dialog('邮件已发送至'.$testemail.',请注意查收', $mail_sender); + dialog('邮件发送失败,请检查设置'); + break; + case 'static': + if($itemid) { + foreach(array(DT_ROOT.'/file/flash/', DT_ROOT.'/file/image/', DT_ROOT.'/file/script/', DT_ROOT.'/skin/'.$CFG['skin'].'/', DT_ROOT.'/'.$MODULE[2]['moduledir'].'/image/', DT_ROOT.'/'.$MODULE[4]['moduledir'].'/skin/', DT_ROOT.'/'.$MODULE[4]['moduledir'].'/image/') as $d) { + $s = str_replace(DT_ROOT, DT_ROOT.'/file/static', $d); + dir_copy($d, $s); + } + foreach(array(DT_ROOT.'/favicon.ico', DT_ROOT.'/lang/'.DT_LANG.'/lang.js') as $d) { + $s = str_replace(DT_ROOT, DT_ROOT.'/file/static', $d); + file_copy($d, $s); + } + } + include tpl('static'); + break; + case 'cache': + if($job && $job != $CFG['cache']) { + $class = DT_ROOT.'/include/cache_'.$job.'.class.php'; + if(is_file($class)) { + cache_write('cache.test.php', str_replace('dcache', 'tcache', file_get($class))); + require DT_CACHE.'/cache.test.php'; + $dc = new tcache(); + $dc->pre = $CFG['cache_pre']; + $CFG['cache'] = $job; + } + } + $dc->set('destoon', 'com', 3600); + $pass = $dc->get('destoon') == 'com' ? 1 : 0; + dialog('
    测试结果:'.($pass ? '成功' : '失败').'   缓存类型:'.$CFG['cache'].'
    如果类型不正确,请先保存设置再测试
    '); + break; + case 'html': + tohtml('index'); + $dc->get('destoon') == 'com' or dalert('缓存类型'.$CFG['cache'].'测试失败,'.($CFG['cache'] == 'file' ? '请检查file目录是否可写' : '请立即更换'), '?moduleid='.$moduleid.'&file='.$file.'&tab=2'); + dmsg('设置保存成功', '?moduleid='.$moduleid.'&file='.$file.'&tab='.$tab); + break; + default: + $tab = isset($tab) ? intval($tab) : 0; + $all = isset($all) ? intval($all) : 0; + if($submit) { + foreach($setting as $k=>$v) { + if(strpos($k, 'seo_') === false) continue; + seo_check($v) or msg('SEO信息包含非法字符'); + } + if(strpos($setting['remote_url'], 'file/upload') !== false) msg('FTP远程访问URL不能包含file/upload'); + if($setting['safe_domain']) { + $setting['safe_domain'] = str_replace('http://', '', $setting['safe_domain']); + if(substr($setting['safe_domain'], 0, 4) == 'www.') $setting['safe_domain'] = substr($setting['safe_domain'], 4); + } + $setting['gano'] = $setting['wano'] ? cutstr($setting['wano'], '备', '号') : ''; + if(substr($config['url'], -1) != '/') $config['url'] = $config['url'].'/'; + if($config['cookie_domain'] && substr($config['cookie_domain'], 0, 1) != '.') $config['cookie_domain'] = '.'.$config['cookie_domain']; + if($config['cookie_domain'] != $CFG['cookie_domain']) $config['cookie_pre'] = 'D'.random(2).'_'; + in_array($setting['file_ext'], array('html', 'htm', 'shtml', 'shtm')) or $setting['file_ext'] = 'html'; + if(!is_numeric($config['cloud_uid']) || strlen($config['cloud_key']) != 16) $setting['sms'] = $setting['cloud_express'] = 0; + $config['cloud_key'] = pass_decode($config['cloud_key'], DT_CLOUD_KEY); + $setting['smtp_pass'] = pass_decode($setting['smtp_pass'], $DT['smtp_pass']); + $setting['ftp_pass'] = pass_decode($setting['ftp_pass'], $DT['ftp_pass']); + $setting['trade_pw'] = pass_decode($setting['trade_pw'], $DT['trade_pw']); + $setting['admin_week'] = is_array($setting['admin_week']) ? implode(',', $setting['admin_week']) : ''; + $setting['check_week'] = is_array($setting['check_week']) ? implode(',', $setting['check_week']) : ''; + if($setting['logo'] != $DT['logo']) clear_upload($setting['logo'], $_userid, 'setting'); + $setting['thumb_max'] = intval($setting['thumb_max']); + if($setting['thumb_max'] > 99 || $setting['thumb_max'] < 5) $setting['thumb_max'] = 10; + if(!is_write(DT_ROOT.'/config.inc.php')) msg('根目录config.inc.php无法写入,请设置可写权限'); + $tmp = file_get(DT_ROOT.'/config.inc.php'); + foreach($config as $k=>$v) { + $tmp = preg_replace("/[$]CFG\['$k'\]\s*\=\s*[\"'].*?[\"']/is", "\$CFG['$k'] = '$v'", $tmp); + } + file_put(DT_ROOT.'/config.inc.php', $tmp); + update_setting($moduleid, $setting); + cache_module(1); + cache_module(); + file_put(DT_ROOT.'/file/avatar/remote.html', $setting['ftp_remote'] && $setting['remote_url'] ? $setting['remote_url'] : 'URL'); + $filename = DT_ROOT.'/'.$setting['index'].'.'.$setting['file_ext']; + if(!$setting['index_html'] && $setting['file_ext'] != 'php') file_del($filename); + $pdir = DT_ROOT.'/'.$MODULE[2]['moduledir'].'/'; + $mdir = DT_ROOT.'/mobile/'.$MODULE[2]['moduledir'].'/'; + if($setting['file_register'] != $old_file_register) { + @rename($pdir.$old_file_register, $pdir.$setting['file_register']); + @rename($mdir.$old_file_register, $mdir.$setting['file_register']); + } + if($setting['file_login'] != $old_file_login) { + @rename($pdir.$old_file_login, $pdir.$setting['file_login']); + @rename($mdir.$old_file_login, $mdir.$setting['file_login']); + } + if($setting['file_my'] != $old_file_my) { + @rename($pdir.$old_file_my, $pdir.$setting['file_my']); + @rename($mdir.$old_file_my, $mdir.$setting['file_my']); + } + $dc->set('destoon', 'com', 3600); + dheader('?moduleid='.$moduleid.'&file='.$file.'&action=html&tab='.$tab); + } else { + include DT_ROOT.'/config.inc.php'; + extract(dhtmlspecialchars($CFG)); + extract(dhtmlspecialchars($DT)); + $W = array('天', '一', '二', '三', '四', '五', '六'); + $smtp_pass = pass_encode($smtp_pass); + $ftp_pass = pass_encode($ftp_pass); + $trade_pw = pass_encode($trade_pw); + $cloud_key = pass_encode($cloud_key); + $sms_url = base64_decode('aHR0cHM6Ly93d3cuZGVzdG9vbi5jb20vc21zLnBocD9hY3Rpb249Z2V0JnVpZD0=').DT_CLOUD_UID.'&key='.md5(DT_CLOUD_KEY.'|'.DT_CLOUD_UID); + if($kw) { + $all = 1; + ob_start(); + } + include tpl('setting', $module); + if($kw) { + $data = $content = ob_get_contents(); + ob_clean(); + $data = preg_replace('\'(?!((<.*?)|(]*?)>)|([^>]*?)|([^>]*?))\'si', ''.$kw.'', $data); + $data = preg_replace('//', '', $data, 1); + echo $data ? $data : $content; + } + } + break; +} +?> \ No newline at end of file diff --git a/admin/skin.inc.php b/admin/skin.inc.php new file mode 100644 index 0000000..e58a3bd --- /dev/null +++ b/admin/skin.inc.php @@ -0,0 +1,115 @@ +$CFG[\'edittpl\'] = \'0\'; 修改为 $CFG[\'edittpl\'] = \'1\';'); +$menus = array ( + array('新建样式', '?file=skin&action=add'), + array('模板管理', '?file=template'), + array('风格管理', '?file=skin'), + array('标签向导', '?file=tag'), +); +$this_forward = '?file='.$file; +$skin = get_cookie('skin'); +$skin = check_name($skin) ? $skin : $CFG['skin']; +$skin_root = DT_ROOT.'/skin/'.$skin.'/'; +is_dir($skin_root) or dir_create($skin_root); +$skin_path = 'skin/'.$skin.'/'; +isset($fileid) or $fileid = ''; +isset($bakid) or $bakid = ''; +if($fileid && !preg_match("/^[0-9a-z_\-]+$/", $fileid)) msg('文件格式错误'); + +switch($action) { + case 'add': + if($submit) { + if(!$fileid) msg('文件名不能为空'); + if(!$content) msg('风格内容不能为空'); + $dfile = $skin_root.$fileid.'.css'; + if(isset($nowrite) && is_file($dfile)) msg('文件已经存在'); + file_put($dfile, strip_sql(stripslashes($content), 0)); + dmsg('风格添加成功', $this_forward); + } else { + include tpl('skin_add'); + } + break; + case 'edit': + if(!$fileid) msg('文件名不能为空'); + if($submit) { + if(!$dfileid) msg('Invalid Request'); + if(!$content) msg('风格内容不能为空'); + $dfile = $skin_root.$dfileid.'.css'; + $nfile = $skin_root.$fileid.'.css'; + if(isset($backup)) { + $i = 0; + while(++$i) { + $bakfile = $skin_root.$dfileid.'.'.$i.'.bak'; + if(!is_file($bakfile)) { + file_copy($dfile, $bakfile); + break; + } + } + } + file_put($nfile, strip_sql(stripslashes($content), 0)); + if($dfileid != $fileid) file_del($dfile); + dmsg('风格修改成功', $forward); + } else { + if(!is_write($skin_root.$fileid.'.css')) msg($fileid.'.css不可写,请将其属性设置为可写'); + $content = file_get($skin_root.$fileid.'.css'); + include tpl('skin_edit'); + } + break; + case 'import': + if(!$fileid) msg('文件名不能为空'); + if(!$bakid) msg('Invalid Request'); + if(file_copy($skin_root.$fileid.'.'.$bakid.'.bak', $skin_root.$fileid.'.css')) dmsg('备份文件恢复成功', $this_forward); + dmsg('备份文件恢复失败'); + break; + case 'download': + if(!$fileid) msg('文件名不能为空'); + $file_ext = $bakid ? '.'.$bakid.'.bak' : '.css'; + file_down($skin_root.$fileid.$file_ext); + break; + case 'delete': + if(!$fileid) msg('文件名不能为空'); + $file_ext = $bakid ? '.'.$bakid.'.bak' : '.css'; + file_del($skin_root.$fileid.$file_ext); + dmsg('文件删除成功', $this_forward); + break; + case 'change': + $to = check_name($to) ? $to : ''; + if($to && is_dir(DT_ROOT.'/skin/'.$to.'/')) { + if($to == $CFG['skin']) $to = ''; + set_cookie('skin', $to); + } + dmsg('切换成功', $this_forward); + break; + default: + $files = $skins = $baks = array(); + $files = glob($skin_root.'*.*'); + if(!$files) msg('风格文件不存在,请先创建', "?file=$file&action=add"); + foreach($files as $k=>$v) { + $filename = str_replace($skin_root, '', $v); + if(preg_match("/^[0-9a-z_-]+\.css$/", $filename)) { + $fileid = str_replace('.css', '', $filename); + $skins[$fileid]['fileid'] = $fileid; + $skins[$fileid]['filename'] = $filename; + $skins[$fileid]['filesize'] = round(filesize($v)/1024, 2); + $skins[$fileid]['mtime'] = date('Y-m-d H:i', filemtime($v)); + } else if(preg_match("/^([0-9a-z_-]+)\.([0-9]+)\.bak$/", $filename, $m)) { + $fileid = str_replace('.bak', '', $filename); + $baks[$fileid]['fileid'] = $fileid; + $baks[$fileid]['filename'] = $filename; + $baks[$fileid]['filesize'] = round(filesize($v)/1024, 2); + $baks[$fileid]['number'] = $m[2]; + $baks[$fileid]['type'] = $m[1]; + $baks[$fileid]['mtime'] = date('Y-m-d H:i', filemtime($v)); + } + } + if($skins) ksort($skins); + if($baks) ksort($baks); + include tpl('skin'); + break; +} +?> \ No newline at end of file diff --git a/admin/split.inc.php b/admin/split.inc.php new file mode 100644 index 0000000..8f5978f --- /dev/null +++ b/admin/split.inc.php @@ -0,0 +1,106 @@ + 3 or msg(); +$fd = $mid == 4 ? 'userid' : 'itemid'; +$table = get_table($mid); +$table_data = get_table($mid, 1); +function table_exists($table) { + $result = DB::query("SHOW COLUMNS FROM `$table`"); + while($r = DB::fetch_array($result)) { + if($r) return true; + } + return false; +} +if($action == 'merge') { + isset($num) or $num = 5000; + if(!isset($fid)) { + table_exists($table_data) or msg('表'.$table_data.'不存在,请手动创建后再合并'); + $r = $db->get_one("SELECT MIN(`$fd`) AS fid FROM {$table}"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + isset($sid) or $sid = $fid; + if(!isset($tid)) { + $r = $db->get_one("SELECT MAX(`$fd`) AS tid FROM {$table}"); + $tid = $r['tid'] ? $r['tid'] : 0; + $part = split_id($tid); + for($i = 1; $i <= $part; $i++) { + split_content($mid, $i); + } + } + if($fid <= $tid) { + $result = $db->query("SELECT `$fd` FROM {$table} WHERE `$fd`>=$fid ORDER BY `$fd` LIMIT 0,$num"); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $itemid = $r[$fd]; + $t = $db->get_one("SELECT content FROM ".split_table($mid, $itemid)." WHERE `$fd`=$itemid"); + if($t) { + $content = addslashes($t['content']); + $db->query("REPLACE INTO {$table_data} ($fd,content) VALUES ('$itemid','$content')"); + } else { + $t = $db->get_one("SELECT `$fd` FROM {$table_data} WHERE `$fd`=$itemid"); + if(!$t) $db->query("REPLACE INTO {$table_data} ($fd,content) VALUES ('$itemid','')"); + } + } + $itemid += 1; + } else { + $itemid = $fid + $num; + } + } else { + $db->halt = 0; + $part = split_id($tid); + for($i = 1; $i < $part+3; $i++) { + $tb = $DT_PRE.$mid.'_'.$i; + $db->query("DROP TABLE IF EXISTS `{$tb}`"); + } + msg($MODULE[$mid]['name'].'内容合并成功,请保存模块设置'); + } + msg('ID从'.$fid.'至'.($itemid-1).'合并成功'.progress($sid, $fid, $tid), "?mid=$mid&file=$file&action=$action&sid=$sid&fid=$itemid&tid=$tid&num=$num"); +} else if($action == 'split') { + isset($num) or $num = 5000; + if(!isset($fid)) { + table_exists($table_data) or msg('表'.$table_data.'不存在,请检查是否已经做过分表'); + $r = $db->get_one("SELECT MIN(`$fd`) AS fid FROM {$table}"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + isset($sid) or $sid = $fid; + if(!isset($tid)) { + $r = $db->get_one("SELECT MAX(`$fd`) AS tid FROM {$table}"); + $tid = $r['tid'] ? $r['tid'] : 0; + $part = split_id($tid); + for($i = 1; $i < $part+2; $i++) { + split_content($mid, $i); + } + } + if($fid <= $tid) { + $result = $db->query("SELECT `$fd` FROM {$table} WHERE `$fd`>=$fid ORDER BY `$fd` LIMIT 0,$num"); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $itemid = $r[$fd]; + $t = $db->get_one("SELECT content FROM {$table_data} WHERE `$fd`=$itemid"); + if($t) { + $content = addslashes($t['content']); + $db->query("REPLACE INTO ".split_table($mid, $itemid)." ($fd,content) VALUES ('$itemid','$content')"); + } else { + $t = $db->get_one("SELECT `$fd` FROM ".split_table($mid, $itemid)." WHERE `$fd`=$itemid"); + if(!$t) $db->query("REPLACE INTO ".split_table($mid, $itemid)." ($fd,content) VALUES ('$itemid','')"); + } + } + $itemid += 1; + } else { + $itemid = $fid + $num; + } + } else { + $table_back = $table_data.'_'.timetodate($DT_TIME, 'Ymd'); + $db->query("RENAME TABLE `{$table_data}` TO `{$table_back}`"); + msg($MODULE[$mid]['name'].'内容拆分成功,请保存模块设置'); + } + msg('ID从'.$fid.'至'.($itemid-1).'拆分成功'.progress($sid, $fid, $tid), "?mid=$mid&file=$file&action=$action&sid=$sid&fid=$itemid&tid=$tid&num=$num"); +} else { + $split = isset($split) && $split ? 1 : 0; + include tpl('split'); +} +?> \ No newline at end of file diff --git a/admin/stats.inc.php b/admin/stats.inc.php new file mode 100644 index 0000000..893a62b --- /dev/null +++ b/admin/stats.inc.php @@ -0,0 +1,334 @@ +query("DELETE FROM {$DT_PRE}stats_pv WHERE addtime<$time"); + dmsg('清理成功', '?file='.$file.'&action=pv'); + break; + case 'clear_uv': + $time = $DT_TODAY - 365*86400; + $db->query("DELETE FROM {$DT_PRE}stats_uv WHERE addtime<$time"); + dmsg('清理成功', '?file='.$file.'&action=uv'); + break; + case 'clear': + $time = $DT_TODAY - 30*86400; + $db->query("DELETE FROM {$DT_PRE}404 WHERE addtime<$time"); + dmsg('清理成功', '?file='.$file.'&action=404'); + break; + case '404': + $sfields = array('按条件', '网址', '来源', '搜索引擎', '会员', 'IP', '客户端', '操作系统', '浏览器'); + $dfields = array('url', 'url', 'refer', 'robot', 'username', 'ip', 'ua', 'os', 'bs'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $ip = isset($ip) ? $ip : ''; + $os = isset($os) ? $os : ''; + $bs = isset($bs) ? $bs : ''; + $pc = isset($pc) ? intval($pc) : -1; + $robot = isset($robot) ? $robot : ''; + (isset($username) && check_name($username)) or $username = ''; + (isset($fromdate) && is_time($fromdate)) or $fromdate = ''; + $fromtime = $fromdate ? datetotime($fromdate) : 0; + (isset($todate) && is_time($todate)) or $todate = ''; + $totime = $todate ? datetotime($todate) : 0; + $fields_select = dselect($sfields, 'fields', '', $fields); + $condition = '1'; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + if($fromtime) $condition .= " AND addtime>=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + if($ip) $condition .= " AND ip='$ip'"; + if($os) $condition .= " AND os='$os'"; + if($bs) $condition .= " AND bs='$bs'"; + if($robot) $condition .= $robot == 'all' ? " AND robot<>''" : " AND robot='$robot'"; + if($pc > -1) $condition .= " AND pc=$pc"; + if($username) $condition .= " AND username='$username'"; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}404 WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = $areas = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}404 WHERE $condition ORDER BY itemid DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + if(isset($areas[$r['ip']])) { + $r['area'] = $areas[$r['ip']]; + } else { + $r['area'] = $areas[$r['ip']] = ip2area($r['ip']); + } + $r['addtime'] = timetodate($r['addtime'], 6); + $lists[] = $r; + } + include tpl('stats_404'); + break; + case 'online': + $sfields = array('按条件', '会员名', '会员ID'); + $dfields = array('username', 'username', 'userid'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $sorder = array('结果排序方式', '访问时间降序', '访问时间升序', '会员ID降序', '会员ID升序'); + $dorder = array('lasttime DESC', 'lasttime DESC', 'lasttime ASC', 'userid DESC', 'userid ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + $online = isset($online) ? intval($online) : 2; + + $fields_select = dselect($sfields, 'fields', '', $fields); + $order_select = dselect($sorder, 'order', '', $order); + + $condition = '1'; + if($keyword) $condition .= " AND $dfields[$fields]='$kw'"; + if($mid) $condition .= " AND moduleid=$mid"; + if($online < 2) $condition .= " AND online=$online"; + $lastime = $DT_TIME - $DT['online']; + $db->query("DELETE FROM {$DT_PRE}online WHERE lasttime<$lastime"); + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}online WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}online WHERE $condition ORDER BY $dorder[$order] LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['lasttime'] = timetodate($r['lasttime'], 'H:i:s'); + $lists[] = $r; + } + include tpl('stats_online'); + break; + case 'update': + require DT_ROOT.'/include/client.func.php'; + $table = $DT_PRE.'stats_uv'; + if(!isset($fid)) { + $r = $db->get_one("SELECT min(itemid) AS fid FROM {$table}"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + if(!isset($tid)) { + $r = $db->get_one("SELECT max(itemid) AS tid FROM {$table}"); + $tid = $r['tid'] ? $r['tid'] : 0; + } + isset($num) or $num = 100; + $itemid or $itemid = 1; + if($fid <= $tid) { + $result = $db->query("SELECT * FROM {$table} WHERE itemid>=$fid ORDER BY itemid LIMIT 0,$num "); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $itemid = $r['itemid']; + $sql = ''; + /* + $area = ip2area($r['ip']); + if($area && $area != $r['area']) $sql .= "area='".addslashes($area)."',"; + + $country = area_parse($area, 'country'); + if($country && $country != $r['country']) $sql .= "country='".addslashes($country)."',"; + + $province = area_parse($area, 'province'); + if($province && $province != $r['province']) $sql .= "province='".addslashes($province)."',"; + + $city = area_parse($area, 'city'); + if($city && $city != $r['city']) $sql .= "city='".addslashes($city)."',"; + + $network = area_parse($area, 'network'); + if($network && $network != $r['network']) $sql .= "network='".addslashes($network)."',"; + */ + + $os = get_os($r['ua']); + if($os && $os != $r['os']) $sql .= "os='".$os."',"; + + $bs = get_bs($r['ua']); + if($bs && $bs != $r['bs']) $sql .= "bs='".$bs."',"; + + $bd = get_bd($r['ua']); + if($bd && $bd != $r['bd']) $sql .= "bd='".$bd."',"; + + if($sql) { + $sql = substr($sql, 0, -1); + $db->query("UPDATE {$table} SET {$sql} WHERE itemid=$itemid"); + } + } + $itemid += 1; + } else { + $itemid = $fid + $num; + } + } else { + msg("更新成功", '?file='.$file.'&action=uv'); + } + msg('ID从'.$fid.'至'.($itemid-1).'转换成功', "?file=$file&action=$action&fid=$itemid&tid=$tid&num=$num", 0); + break; + case 'report': + $job or $job = 'pvs'; + include tpl('stats_report'); + break; + case 'pv': + $sfields = array('按条件', '网址', '来源', '来源域名', '搜索引擎', '会员', '所属商家', 'IP'); + $dfields = array('url', 'url', 'refer', 'domain', 'robot', 'username', 'homepage', 'ip'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $dorder = array('sid DESC', 'addtime DESC', 'addtime ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + isset($robot) or $robot = ''; + isset($url) or $url = ''; + isset($refer) or $refer = ''; + isset($domain) or $domain = ''; + $pc = isset($pc) ? intval($pc) : -1; + $islink = isset($islink) ? intval($islink) : -1; + (isset($fromdate) && is_time($fromdate)) or $fromdate = ''; + $fromtime = $fromdate ? datetotime($fromdate) : 0; + (isset($todate) && is_time($todate)) or $todate = ''; + $totime = $todate ? datetotime($todate) : 0; + $catid or $catid = ''; + $itemid or $itemid = ''; + + $fields_select = dselect($sfields, 'fields', '', $fields); + $module_select = module_select('mid', '模块', $mid); + + $condition = '1'; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + if($fromtime) $condition .= " AND addtime>=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + if($mid) $condition .= " AND mid=$mid"; + if($catid) $condition .= ($CAT['child']) ? " AND catid IN (".$CAT['arrchildid'].")" : " AND catid=$catid"; + if($itemid) $condition .= " AND itemid=$itemid"; + if($url) $condition .= " AND url='$url'"; + if($refer) $condition .= " AND refer='$refer'"; + if($domain) $condition .= " AND domain='$domain'"; + if($robot) $condition .= $robot == 'all' ? " AND robot<>''" : " AND robot='$robot'"; + if($pc > -1) $condition .= " AND pc=$pc"; + if($islink > -1) $condition .= $islink ? " AND domain<>''" : " AND domain=''"; + foreach($dfields as $v) { + if(in_array($v, array('url', 'robot'))) continue; + isset($$v) or $$v = ''; + if($$v) $condition .= " AND $v='".$$v."'"; + } + + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}stats_pv WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = $areas = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}stats_pv WHERE $condition ORDER BY $dorder[$order] LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + if(isset($areas[$r['ip']])) { + $r['area'] = $areas[$r['ip']]; + } else { + $r['area'] = $areas[$r['ip']] = ip2area($r['ip']); + } + $r['addtime'] = timetodate($r['addtime'], 6); + if($r['refer'] && strpos($r['refer'], '://') === false) $r['refer'] = DT_PATH.($r['refer'] == '/' ? '' : $r['refer']); + if(strpos($r['url'], '://') === false) $r['url'] = DT_PATH.$r['url']; + $lists[] = $r; + } + include tpl('stats_pv'); + break; + case 'uv': + $sfields = array('按条件', '搜索引擎', 'IP', '地区', '国家', '省份', '城市', '网络', '客户端', '操作系统', '设备品牌', '浏览器', '分辨率'); + $dfields = array('ua', 'robot', 'ip', 'area', 'country', 'province', 'city', 'network', 'ua', 'os', 'bd', 'bs', 'screen'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $dorder = array('itemid DESC', 'addtime DESC', 'addtime ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + $pc = isset($pc) ? intval($pc) : -1; + (isset($fromdate) && is_time($fromdate)) or $fromdate = ''; + $fromtime = $fromdate ? datetotime($fromdate) : 0; + (isset($todate) && is_time($todate)) or $todate = ''; + $totime = $todate ? datetotime($todate) : 0; + isset($robot) or $robot = ''; + + $fields_select = dselect($sfields, 'fields', '', $fields); + + $condition = '1'; + if($keyword) $condition .= match_kw($dfields[$fields], $keyword); + if($fromtime) $condition .= " AND addtime>=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + if($pc > -1) $condition .= " AND pc=$pc"; + if($robot) $condition .= $robot == 'all' ? " AND robot<>''" : " AND robot='$robot'"; + foreach($dfields as $v) { + if(in_array($v, array('robot'))) continue; + isset($$v) or $$v = ''; + if($$v) $condition .= " AND $v='".$$v."'"; + } + + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}stats_uv WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = $areas = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}stats_uv WHERE $condition ORDER BY $dorder[$order] LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + if(!$r['screen']) { + $r['screen'] = $dc->get('sn-'.md5($r['ip'].$DT_TODAY.strip_sql($r['ua'], 0))); + if($r['screen']) $db->query("UPDATE {$DT_PRE}stats_uv SET screen='$r[screen]' WHERE itemid=$r[itemid]"); + } + $r['location'] = $r['province'] ? ''.$r['province'].''.($r['city'] == $r['province'] ? '' : ' '.$r['city'].'') : ''.$r['country'].' '.$r['city'].''; + $r['addtime'] = timetodate($r['addtime'], 6); + $lists[] = $r; + } + include tpl('stats_uv'); + break; + default: + $W = array('天', '一', '二', '三', '四', '五', '六'); + $sorder = array('排序方式', '总UV降序', '总UV升序', '电脑UV降序', '电脑UV升序', '手机Uv降序', '手机UV升序', '总IP降序', '总IP升序', '电脑IP降序', '电脑IP升序', '手机IP降序', '手机IP升序', '总PV降序', '总PV升序', '电脑PV降序', '电脑PV升序', '手机PV降序', '手机PV升序', '爬虫PV降序', '爬虫PV升序', '电脑爬虫PV降序', '电脑爬虫PV升序', '手机爬虫PV降序', '手机爬虫PV升序', '日期降序', '日期升序'); + $dorder = array('id DESC', 'uv DESC', 'uv ASC', 'uv_pc DESC', 'uv_pc ASC', 'uv_mb DESC', 'uv_mb ASC', 'ip DESC', 'ip ASC', 'ip_pc DESC', 'ip_pc ASC', 'ip_mb DESC', 'ip_mb ASC', 'pv DESC', 'pv ASC', 'pv_pc DESC', 'pv_pc ASC', 'pv_mb DESC', 'pv_mb ASC', 'rb DESC', 'rb ASC', 'rb_pc DESC', 'rb_pc ASC', 'rb_mb DESC', 'rb_mb ASC', 'id DESC', 'id ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + + isset($fromdate) or $fromdate = ''; + $fromtime = is_date($fromdate) ? str_replace('-', '', $fromdate) : ''; + isset($todate) or $todate = ''; + $totime = is_date($todate) ? str_replace('-', '', $todate) : ''; + (isset($username) && check_name($username)) or $username = ''; + + $order_select = dselect($sorder, 'order', '', $order); + + if($username) { + $condition = "username='$username'"; + $table = $DT_PRE.'stats_user'; + } else { + $condition = '1'; + $table = $DT_PRE.'stats'; + } + if($fromtime) $condition .= " AND id>=$fromtime"; + if($totime) $condition .= " AND id<=$totime"; + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$table} WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $d0 = timetodate(DT_TIME, 3); + $d1 = timetodate(DT_TIME - 86400, 3); + $d2 = timetodate(DT_TIME - 86400*2, 3); + $result = $db->query("SELECT * FROM {$table} WHERE $condition ORDER BY $dorder[$order] LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['time'] = datetotime($r['id']); + $r['date'] = timetodate($r['time'], 3); + $r['week'] = '星期'.$W[date('w', $r['time'])]; + if($r['date'] == $d0) { + $r['week'] = '今日'; + } elseif($r['date'] == $d1) { + $r['week'] = '昨日'; + } elseif($r['date'] == $d2) { + $r['week'] = '前日'; + } + $i++; + $lists[] = $r; + } + include tpl('stats'); + break; +} +?> \ No newline at end of file diff --git a/admin/tag.inc.php b/admin/tag.inc.php new file mode 100644 index 0000000..147134b --- /dev/null +++ b/admin/tag.inc.php @@ -0,0 +1,146 @@ + 3) { + $table = get_table($mid); + $note = urlencode($MODULE[$mid]['name']); + } else { + $table = $DT_PRE.$tb; + $note = ''; + } + dheader('?file='.$file.'&action=dict&table='.$table.'¬e='.$note); + break; + case 'dict': + (isset($table) && $table) or exit; + $table = strip_sql($table, 0); + if(strpos($table, $DT_PRE) === false) { + $rtable = $table; + } else { + $rtable = substr($table, strlen($DT_PRE)); + $rtable = preg_replace("/_[0-9]{1,}/", '', $rtable); + } + if($submit) { + $csv = ''; + foreach($name as $k=>$v) { + $v = str_replace(',', ',', $v); + $n = str_replace(',', ',', $note[$k]); + $csv .= $k.','.$v.','.$n."\n"; + } + file_put(DT_ROOT.'/file/setting/'.$rtable.'.csv', trim($csv)); + dmsg('更新成功', '?file='.$file.'&action='.$action.'&table='.$table.'¬e='.urlencode($nt)); + } else { + $fields = $csv = array(); + if(is_file(DT_ROOT.'/file/setting/'.$rtable.'.csv')) { + $tmp = file_get(DT_ROOT.'/file/setting/'.$rtable.'.csv'); + $arr = explode("\n", $tmp); + foreach($arr as $v) { + $t = explode(',', $v); + $csv[$t[0]]['name'] = $t[1]; + $csv[$t[0]]['note'] = $t[2]; + } + } + $result = $db->query("SHOW COLUMNS FROM `$table`"); + while($r = $db->fetch_array($result)) { + $r['Type'] = str_replace(' unsigned', '', $r['Type']); + if(isset($csv[$r['Field']])) { + $r['cn_name'] = $csv[$r['Field']]['name']; + $r['cn_note'] = $csv[$r['Field']]['note']; + } else { + $r['cn_name'] = $r['cn_note'] = ''; + //if(isset($names[$r['Field']])) $r['cn_name'] = $names[$r['Field']]; + } + $fields[] = $r; + } + include tpl('tag_dict'); + } + break; + case 'preview': + $db->halt = 0; + $destoon_task = ''; + if($tag_css) $tag_css = stripslashes($tag_css); + if($tag_html_s) $tag_html_s = stripslashes($tag_html_s); + if($tag_html_e) $tag_html_e = stripslashes($tag_html_e); + if($tag_code) $tag_code = stripslashes($tag_code); + $code_eval = $code_call = $code_html = ''; + if($tag_css) $code_eval .= ''."\n"; + if($tag_html_s) $code_eval .= $tag_html_s."\n"; + $code_call = $code_eval; + $code_call .= $tag_code."\n"; + $tag_code = str_replace('', '', $tag_code); + if(strpos($tag_code, '",') !== false) { + $tag_code = str_replace(', '.$tag_expires.')', ', -1)', $tag_code); + } else { + $tag_code = str_replace('")', '", -1)', $tag_code); + } + $tag_code .= ';'; + $tag_pass = 1; + if(substr($tag_code, 0, 5) != 'tag("') $tag_pass = 0; + if(substr($tag_code, -7) != '", -1);') $tag_pass = 0; + $tag_safe = substr($tag_code, 5, -7); + foreach(array('(', '`', ',', ';') as $v) { + if(strpos($tag_safe, $v) !== false) { + $tag_pass = 0; + break; + } + } + $tag_pass or msg('标签内容包含不安全写法,禁止在线预览'); + $tag_md5 = md5($tag_safe); + $tag_js = ''; + ob_start(); + eval($tag_code); + $contents = ob_get_contents(); + ob_clean(); + $code_eval .= $contents."\n"; + if($tag_html_e) { + $code_eval .= $tag_html_e; + $code_call .= $tag_html_e; + } + $t = str_replace('",', '&debug=1",', $tag_code); + ob_start(); + eval($t); + $td = ob_get_contents(); + ob_clean(); + $t = explode('
    ', $td); + $tag_debug = "参数:".$t[0]."\n语句:".$t[1]; + $head_title = '标签预览'; + include tpl('tag_preview'); + break; + default: + $table_select = $all_select = ''; + $out = array('ad', 'ad_place', 'admin', 'alert', 'area', 'ask' ,'category', 'favorite', 'finance_cash', 'finance_charge', 'finance_record', 'finance_trade', 'friend', 'group', 'guestbook', 'keylink', 'log', 'mail', 'mail_list', 'message', 'module', 'session', 'style', 'type', 'vip'); + $query = $db->query("SHOW TABLE STATUS FROM `".$CFG['db_name']."`"); + while($r = $db->fetch_row($query)) { + $table = $r[0]; + $alltable = preg_match("/^".$DT_PRE."/i", $table) ? substr($table, strlen($DT_PRE)) : $table.'&prefix='; + $all_select .= ''; + if(substr($table, -5) == '_data' || strpos($table, '_data_') !== false) continue; + if(preg_match("/^".$DT_PRE."/i", $table)) { + $table = substr($table, strlen($DT_PRE)); + if(in_array($table, $out)) continue; + $s = $db->get_one("SHOW TABLE STATUS FROM `".$CFG['db_name']."` LIKE '".$r[0]."'"); + $table_select .= ''; + } + } + $mid or $mid = ''; + include tpl('tag'); + break; +} +?> \ No newline at end of file diff --git a/admin/template.inc.php b/admin/template.inc.php new file mode 100644 index 0000000..21b9e5c --- /dev/null +++ b/admin/template.inc.php @@ -0,0 +1,189 @@ +$CFG[\'edittpl\'] = \'0\'; 修改为 $CFG[\'edittpl\'] = \'1\';'); +isset($dir) or $dir = ''; +$menus = array ( + array('新建模板', '?file='.$file.'&action=add&dir='.$dir), + array('模板管理', '?file='.$file), + array('风格管理', '?file=skin'), + array('标签向导', '?file=tag'), +); +isset($bakid) or $bakid = ''; +isset($fileid) or $fileid = ''; +$this_forward = '?file='.$file.'&dir='.$dir; +$tpl = get_cookie('tpl'); +$tpl = check_name($tpl) ? $tpl : $CFG['template']; +$template_root = DT_ROOT.'/template/'.$tpl.'/'.$dir; +$template_path = 'template/'.$tpl.'/'.$dir; +@include $template_root.'/these.name.php'; + +function template_name($fileid = '', $name = '') { + global $template_root, $names; + isset($names) or $names = array(); + if($fileid && $name) $names[$fileid] = $name; + foreach($names as $k => $v) { + if(!is_file($template_root.'/'.$k.'.htm') && !is_dir($template_root.'/'.$k)) unset($names[$k]); + } + if($names) ksort($names); + file_put($template_root.'/these.name.php', ""); +} + +function template_safe($content, $edit = 0) { + $content = stripslashes($content); + $content = strip_sql($content, 0); + if($edit > 1) return $content; + if(preg_match_all("/script([^>]+)>/i", $content, $matches)) { + foreach($matches[1] as $m) { + $m = strtolower($m); + if(strpos($m, 'language') !== false || strpos($m, 'php') !== false) msg('模板内容包含不安全写法,禁止在线修改或预览
    如需忽略此提示,请修改根目录config.inc.php
    $CFG[\'edittpl\'] = \'1\'; 修改为 $CFG[\'edittpl\'] = \'2\';'); + } + } + if(preg_match("/(\<\?|\{php|file\(|eval|copy|file_put|file_get|fopen|fwrite|fread)/i", $content)) msg('模板内容包含不安全写法,禁止在线修改或预览
    如需忽略此提示,请修改根目录config.inc.php
    $CFG[\'edittpl\'] = \'1\'; 修改为 $CFG[\'edittpl\'] = \'2\';'); + return $content; +} + +switch($action) { + case 'add': + if($submit) { + if(!preg_match("/^[a-z0-9_\-]+$/", $fileid)) msg('文件名只能为小写字母、数字、中划线、下划线'); + if(substr($fileid, -1) == '-') msg('文件名不能以 - 符号结尾'); + if(substr_count($fileid, '-') > 1) msg('文件名只能包含一个 - 符号'); + if(!$name) $name = $fileid; + $template = $template_root.'/'.$fileid.'.htm'; + if(isset($nowrite) && is_file($template)) msg('文件已经存在'); + file_put($template, template_safe($content, $CFG['edittpl'])); + if($name != $fileid) template_name($fileid, $name); + dmsg('创建成功', $this_forward); + } else { + $content = ''; + if(isset($type)) $content = dhtmlspecialchars(file_get($template_root.'/'.$type.'.htm')); + include tpl('template_add'); + } + break; + case 'edit': + if($submit) { + $dfileid or msg(); + if(!preg_match("/^[a-z0-9_\-]+$/", $fileid)) msg('文件名只能为小写字母、数字、中划线、下划线'); + if(substr($fileid, -1) == '-') msg('文件名不能以 - 符号结尾'); + if(substr_count($fileid, '-') > 1) msg('文件名只能包含一个 - 符号'); + if(!$name) $name = $fileid; + $dfile = $template_root.'/'.$dfileid.'.htm'; + $nfile = $template_root.'/'.$fileid.'.htm'; + if(isset($backup)) { + $i = 0; + while(++$i) { + $bakfile = $template_root.'/'.$dfileid.'.'.$i.'.bak'; + if(!is_file($bakfile)) { + file_copy($dfile, $bakfile); + break; + } + } + } + file_put($nfile, template_safe($content, $CFG['edittpl'])); + if($dfileid != $fileid) file_del($dfile); + if($name != $fileid) template_name($fileid, $name); + dmsg('修改成功', '?file='.$file.'&action='.$action.'&fileid='.$fileid.'&dir='.$dir); + } else { + $fileid or msg(); + if(!is_write($template_root.'/'.$fileid.'.htm')) msg($fileid.'.htm不可写,请将其属性设置为可写'); + if($dir) $template_path = $template_path.'/'; + $name = (isset($names[$fileid]) && $names[$fileid]) ? $names[$fileid] : $fileid; + $content = dhtmlspecialchars(file_get($template_root.'/'.$fileid.'.htm')); + include tpl('template_edit'); + } + break; + case 'preview': + $db->halt = 0; + require_once DT_ROOT.'/include/template.func.php'; + $tpl_content = template_safe($content, $CFG['edittpl']); + unset($content); + $tpl_content = template_parse($tpl_content); + cache_write('_preview.tpl.php', $tpl_content, 'tpl'); + $module = $dir ? $dir : 'destoon'; + $head_title = '模板预览'; + include DT_CACHE.'/tpl/_preview.tpl.php'; + exit(); + break; + case 'import': + $fileid or msg(); + $bakid or msg(); + if(file_copy($template_root.'/'.$fileid.'.'.$bakid.'.bak', $template_root.'/'.$fileid.'.htm')) dmsg('恢复成功', $this_forward); + msg('备份文件恢复失败'); + break; + case 'template_name': + $fileid or exit('0'); + $name or exit('0'); + template_name($fileid, $name); + exit('1'); + break; + case 'download': + $fileid or msg(); + $file_ext = $bakid ? '.'.$bakid.'.bak' : '.htm'; + file_down($template_root.'/'.$fileid.$file_ext); + break; + case 'delete': + $fileid or msg(); + $file_ext = $bakid ? '.'.$bakid.'.bak' : '.htm'; + file_del($template_root.'/'.$fileid.$file_ext); + if(!$bakid) template_name(); + dmsg('删除成功', $this_forward); + break; + case 'cache': + cache_clear('php', 'dir', 'tpl'); + dmsg('更新成功', $this_forward); + break; + case 'change': + $to = check_name($to) ? $to : ''; + if($to && is_dir(DT_ROOT.'/template/'.$to.'/')) { + if($to == $CFG['template']) $to = ''; + set_cookie('tpl', $to); + } + dmsg('切换成功', $this_forward); + break; + default: + $dirs = $files = $templates = $baks = array(); + if(substr($template_root, -1) != '/') $template_root .= '/'; + $files = glob($template_root.'*'); + if(!$files) msg('模板文件不存在,请先创建', "?file=$file&action=add&dir=$dir"); + foreach($files as $k=>$v) { + if(is_dir($v)) { + $dirid = basename($v); + $dirs[$dirid]['dirname'] = $dirid; + $dirs[$dirid]['name'] = (isset($names[$dirid]) && $names[$dirid]) ? $names[$dirid] : $dirid; + $dirs[$dirid]['mtime'] = timetodate(filemtime($v), 5); + $dirs[$dirid]['mod'] = substr(base_convert(fileperms($v), 10, 8), -4); + } else { + $filename = str_replace($template_root, '', $v); + if(preg_match("/^[0-9a-z_-]+\.htm$/", $filename)) { + $fileid = str_replace('.htm', '', $filename); + $templates[$fileid]['fileid'] = $fileid; + $templates[$fileid]['filename'] = $filename; + $templates[$fileid]['filesize'] = round(filesize($v)/1024, 2); + $templates[$fileid]['name'] = (isset($names[$fileid]) && $names[$fileid]) ? $names[$fileid] : $fileid; + $tmp = strpos($filename, '-'); + $templates[$fileid]['type'] = $tmp ? substr($filename, 0, $tmp) : $fileid; + $templates[$fileid]['mtime'] = timetodate(filemtime($v), 5); + $templates[$fileid]['mod'] = substr(base_convert(fileperms($v), 10, 8), -4); + } else if(preg_match("/^([0-9a-z_-]+)\.([0-9]+)\.bak$/", $filename, $m)) { + $fileid = str_replace('.bak', '', $filename); + $baks[$fileid]['fileid'] = $fileid; + $baks[$fileid]['filename'] = $filename; + $baks[$fileid]['filesize'] = round(filesize($v)/1024, 2); + $baks[$fileid]['number'] = $m[2]; + $baks[$fileid]['type'] = $m[1]; + $baks[$fileid]['mtime'] = timetodate(filemtime($v), 5); + $baks[$fileid]['mod'] = substr(base_convert(fileperms($v), 10, 8), -4); + } + } + } + if($dirs) ksort($dirs); + if($templates) ksort($templates); + if($baks) ksort($baks); + include tpl('template'); + break; +} +?> \ No newline at end of file diff --git a/admin/template/admin.tpl.php b/admin/template/admin.tpl.php new file mode 100644 index 0000000..bc0bf9b --- /dev/null +++ b/admin/template/admin.tpl.php @@ -0,0 +1,62 @@ + +
    + +
    +
    + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + +
    姓名用户名管理级别管理角色所属分站上次登录 登录次数 登录IP登录地区管理
    +     +
    +'.$pages.'' : '';?> +
    + $DT_TIME) { ?> + + + + \ No newline at end of file diff --git a/admin/template/admin_add.tpl.php b/admin/template/admin_add.tpl.php new file mode 100644 index 0000000..e7e0c02 --- /dev/null +++ b/admin/template/admin_add.tpl.php @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + +
    * 会员名 + +  [资料] +  [添加] +
    * 管理员类别 +
     
    + 拥有除创始人特权外的所有权限 +
     
    + 拥有系统分配的权限 +
     
    + + +
    * 角色名称 可以为角色名称,例如编辑、美工、某分站编辑等,也可以为该管理员的备注
    +
    +
    + + + \ No newline at end of file diff --git a/admin/template/admin_edit.tpl.php b/admin/template/admin_edit.tpl.php new file mode 100644 index 0000000..134f438 --- /dev/null +++ b/admin/template/admin_edit.tpl.php @@ -0,0 +1,38 @@ + +
    + + + + + + + + + + + + + + + + + + + + + +
    * 会员名[]
    * 管理员类别 +
     
    +/> 拥有除创始人特权外的所有权限 +
     
    +/> 拥有系统分配的权限 +
     
    +
    * 分站权限 分站权限仅对普通管理员生效
    * 角色名称 可以为角色名称,例如编辑、美工、某分站编辑等,也可以为该管理员的备注
    +
    +
    + + \ No newline at end of file diff --git a/admin/template/admin_log.tpl.php b/admin/template/admin_log.tpl.php new file mode 100644 index 0000000..6a56c2c --- /dev/null +++ b/admin/template/admin_log.tpl.php @@ -0,0 +1,47 @@ + +
    + +
    + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    时间URL模块文件操作IDIP地区管理员
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/admin_online.tpl.php b/admin/template/admin_online.tpl.php new file mode 100644 index 0000000..f2f0af4 --- /dev/null +++ b/admin/template/admin_online.tpl.php @@ -0,0 +1,29 @@ + + + + + + + + + + + +$v) {?> + + + + + + + + + + +
    头像会员名所在模块IPIP所在地访问时间URL
    >
    + + \ No newline at end of file diff --git a/admin/template/admin_right.tpl.php b/admin/template/admin_right.tpl.php new file mode 100644 index 0000000..edca2d3 --- /dev/null +++ b/admin/template/admin_right.tpl.php @@ -0,0 +1,200 @@ + +
    + + + +
    面板管理
    + + + + + + + +$v) {?> + + + + + + + + + + + + + + + + + +
    删除排序名称地址
    新增 +
    +  +  +   +提示:添加常用操作可以自动分配对应权限 +
    +
    + + + +
    + + + +
    权限分配
    + + + + + + + + +$v) {?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    删除模块ID文件(file)动作(action)分类ID(catid)
    +
    新增
    选择 + + + + + + + +
      提示:动作和分类可按住Ctrl键多选
    +
    + + + \ No newline at end of file diff --git a/admin/template/admin_temp.tpl.php b/admin/template/admin_temp.tpl.php new file mode 100644 index 0000000..4be0ff0 --- /dev/null +++ b/admin/template/admin_temp.tpl.php @@ -0,0 +1,52 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 授权管理员/> +  资料
    授权对方通过链接直接以此管理员帐号登录后台
    * 授权有效期 分钟
    最少10分钟,最多600分钟,超过此时间自动失效退出
    * 地区或IP
    建议填写,如果填写城市或者省份,对方IP归属地需匹配,如果填写IP,对方IP需一致
    * 授权链接
    请将以上链接发送给授权对象授权对方登录后台   登录记录   操作日志
    +
    + + \ No newline at end of file diff --git a/admin/template/area.tpl.php b/admin/template/area.tpl.php new file mode 100644 index 0000000..8b6e1c8 --- /dev/null +++ b/admin/template/area.tpl.php @@ -0,0 +1,83 @@ + +
    + +
    +  +  +  +
    +
    +
    + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + +
    排序ID上级ID地区名子地区操作
       +  +  +
    +
    + +地区总数:   +当前目录:   + +     +   +   +
    +
    +
    +
    快捷操作
    + + + + +
    +
    +
    +
    + + + + + + + + + + +
    +
    +
    + +
    + + \ No newline at end of file diff --git a/admin/template/area_add.tpl.php b/admin/template/area_add.tpl.php new file mode 100644 index 0000000..de8304b --- /dev/null +++ b/admin/template/area_add.tpl.php @@ -0,0 +1,35 @@ + +
    + + + + + + + + + + + + + + +
    * 上级地区
    * 地区名称
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/banip.tpl.php b/admin/template/banip.tpl.php new file mode 100644 index 0000000..1f20a42 --- /dev/null +++ b/admin/template/banip.tpl.php @@ -0,0 +1,40 @@ + +
    + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    禁止项目类别有效期至状态操作人禁止时间备注操作
    +
    +   + +
    +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/banip_data.tpl.php b/admin/template/banip_data.tpl.php new file mode 100644 index 0000000..46618ac --- /dev/null +++ b/admin/template/banip_data.tpl.php @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +
    库文件更新时间最新版本在线更新手动下载
    file/ipdata/wry.dat立即更新暂无更新立即下载
    + + \ No newline at end of file diff --git a/admin/template/banip_edit.tpl.php b/admin/template/banip_edit.tpl.php new file mode 100644 index 0000000..82daa9f --- /dev/null +++ b/admin/template/banip_edit.tpl.php @@ -0,0 +1,62 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    * 禁止内容
    + - 支持填写IP或IP段,例如填192.168.*.*将禁用所有192.168开头的IP
    + - 支持填写客户端的特征代码,例如Yisou,可以禁止包含Yisou的客户端访问
    + - 客户端的特征代码尽量简短,具体可以在流量统计或站点日志里分析
    + - 禁止仅对网站前台生效,建议不要添加过多,以免影响程序效率
    +
    * 有效时间  +  +
    + 有效时间不填表示永久禁用
    +
    * 备注信息
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/banip_login.tpl.php b/admin/template/banip_login.tpl.php new file mode 100644 index 0000000..4b2d299 --- /dev/null +++ b/admin/template/banip_login.tpl.php @@ -0,0 +1,30 @@ + +
    + + + + + + + + +$v) {?> + + + + + + + + +
    IP来自锁定时间操作
    +
    + +
    +
    + + \ No newline at end of file diff --git a/admin/template/banword.tpl.php b/admin/template/banword.tpl.php new file mode 100644 index 0000000..014fa61 --- /dev/null +++ b/admin/template/banword.tpl.php @@ -0,0 +1,76 @@ + +
    + +
    +
    + + + + + + + + + +$v) { ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    查找词语替换为拦截模式
    +/> 替换     +/> 拦截     +/> 提示 +
    新增 + 替换     + 拦截     + 提示 +
         +     +     +
    '.$pages.'' : '';?>
    +  批量添加时,查找和替换词语一行一个,互相对应
    +  例如“您*好”格式,可替换“您好”之间的干扰字符
    +  为不影响程序效率,请不要设置过多过滤内容
    +  过滤仅对前台会员提交信息生效,后台不受限制
    +  如果选择替换,则匹配到查找词语时直接替换,正常提交
    +  如果选择拦截,则匹配到查找词语时直接提示拦截,拒绝提交
    +  如果选择提示,则匹配到查找词语时直接提示拦截词语,拒绝提交
    +
    +
    + + \ No newline at end of file diff --git a/admin/template/cate.tpl.php b/admin/template/cate.tpl.php new file mode 100644 index 0000000..3653580 --- /dev/null +++ b/admin/template/cate.tpl.php @@ -0,0 +1,29 @@ + + + + + + + + + +$v) { + if($v['islink'] || $v['moduleid'] < 4) continue; + $v['num'] = $db->count($DT_PRE.'category', "moduleid=".$v['moduleid']); +?> + + + + + + + + +
    模块分类数量添加分类管理分类
    添加分类管理分类
    + + \ No newline at end of file diff --git a/admin/template/category.tpl.php b/admin/template/category.tpl.php new file mode 100644 index 0000000..9d4f902 --- /dev/null +++ b/admin/template/category.tpl.php @@ -0,0 +1,123 @@ + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + + + +
    排序ID上级ID分类名分类目录索引级别信息量子类属性操作
       + + + + + + + +  +  +
    +
    + +分类总数:   +当前目录:   + +     +   +   +
    +
    +
    +
    快捷操作
    + + + + +
    +
    +
    + + + + + + + + + + + + + +
    +
    +
    + +
    +
    注意事项
    + + + + +
      如果进行了修改删除分类操作,为了保证操作速度,系统不自动修复结构。请在管理完成操作失败时,点更新缓存以修复分类结构至最新
    +  删除分类会将分类下的信息移至回收站,分类本身可以修改名称和上级分类,没有特殊情况不建议直接删除分类
    +  修改上级ID可以快速修改分类的上级分类,改变分类结构
    + +  对于模块,一级分类为行业,二级分类为职位
    + + +  对于模块,建议只添加一级分类
    + +
    + + + \ No newline at end of file diff --git a/admin/template/category_add.tpl.php b/admin/template/category_add.tpl.php new file mode 100644 index 0000000..2d03607 --- /dev/null +++ b/admin/template/category_add.tpl.php @@ -0,0 +1,95 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 上级分类
    * 分类名称
    * 分类目录[英文名] 该分类相关的html文件将保存在此目录
    如果需要生成多级目录,请用 / 分隔目录
    如果不填写则自动将分类id作为目录');?>
    * 字母索引例如 分类名称为 嘉客 则填写 j');?>
    * 级别
    * 分类模板
    * 内容模板
    * Title(SEO标题)
    * Meta Keywords
      (网页关键词)
    * Meta Description
      (网页描述)
    * 权限设置如果没有特殊需要,以下选项不需要设置,全选或全不选均代表拥有对应权限
    * 允许浏览分类
    * 允许浏览分类信息内容
    * 允许发布信息
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/category_copy.tpl.php b/admin/template/category_copy.tpl.php new file mode 100644 index 0000000..ce8fe89 --- /dev/null +++ b/admin/template/category_copy.tpl.php @@ -0,0 +1,46 @@ + +
    + + + + + + + + + + + + +
    * 来源模块 + + +
    * 当前模块分类数据 + 保留     + 删除 +
    +
    +
    + + + \ No newline at end of file diff --git a/admin/template/category_edit.tpl.php b/admin/template/category_edit.tpl.php new file mode 100644 index 0000000..a4c5d0d --- /dev/null +++ b/admin/template/category_edit.tpl.php @@ -0,0 +1,94 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 上级分类
    * 分类名称
    * 分类目录
    * 字母索引
    * 级别
    * 分类模板
    * 内容模板
    * Title(SEO标题)
    * Meta Keywords
      (网页关键词)
    * Meta Description
      (网页描述)
    * 权限设置如果没有特殊需要,以下选项不需要设置,全选或全不选均代表拥有对应权限
    * 允许浏览分类
    * 允许浏览分类信息内容
    * 允许发布信息
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/city.tpl.php b/admin/template/city.tpl.php new file mode 100644 index 0000000..248fef3 --- /dev/null +++ b/admin/template/city.tpl.php @@ -0,0 +1,55 @@ + +
    + +
    +
    + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    字母索引排序地区分站名称绑定域名操作
    + + +   + + + +  +
    +
         +   +  +
    +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/city_edit.tpl.php b/admin/template/city_edit.tpl.php new file mode 100644 index 0000000..3e5dd4f --- /dev/null +++ b/admin/template/city_edit.tpl.php @@ -0,0 +1,69 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 所在地区
    * 分站名称
    * 绑定域名同时在服务器端绑定此域名至网站根目录,如果不绑定请勿填写');?>
    * IP地址名称
    * 字母索引
    * 排序
    * 分站首页模板
    * Title(SEO标题)
    * Meta Keywords
      (网页关键词)
    * Meta Description
      (网页描述)
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/count.tpl.php b/admin/template/count.tpl.php new file mode 100644 index 0000000..01cc3e7 --- /dev/null +++ b/admin/template/count.tpl.php @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    待受理在线充值 正在统计待受理资金提现 正在统计待审核搜索关键词 正在统计待回复网站留言 正在统计
    待审核资料修改 正在统计待受理客服中心 正在统计待审核贸易提醒 正在统计待处理礼品订单 正在统计
    待审核公司新闻 正在统计待审核荣誉资质 正在统计待审核公司单页 正在统计待审核公司链接 正在统计
    待审核公司认证 正在统计待审核实名认证 正在统计待审核手机认证 正在统计待审核注销申请 正在统计
    待审核广告购买 待审核排名推广 正在统计待审核评论 正在统计待审核友情链接 正在统计
    会员 正在统计会员升级 正在统计待审核 正在统计今日新增 正在统计
     正在统计已发布 正在统计待审核 正在统计今日新增 正在统计
      订单总数 正在统计待受理订单 正在统计已完成订单 正在统计
      订单总数 正在统计待受理订单 正在统计已完成订单 正在统计
      产品总数 正在统计报价总数 正在统计待审报价 正在统计
        报名总数 正在统计今日新增 正在统计
      知道专家 正在统计回答总数 正在统计待审核回答 正在统计
     正在统计已发布 正在统计待审核 正在统计今日新增 正在统计
      待审核商圈申请 正在统计待审核商圈回复 正在统计待审核商圈粉丝 正在统计
    + + + \ No newline at end of file diff --git a/admin/template/count_repeat.tpl.php b/admin/template/count_repeat.tpl.php new file mode 100644 index 0000000..fcade6c --- /dev/null +++ b/admin/template/count_repeat.tpl.php @@ -0,0 +1,77 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 模块 + +
    * 字段
    * 数量
    * 关键词
    * 状态 + +
       + +
    +
    + + + + + + + + +$v) {?> + + + + + + + + + + + +
    名称重复次数查看
      
     - 指定范围没有检测到重复信息    [重新检测]
    + + + \ No newline at end of file diff --git a/admin/template/count_stats.tpl.php b/admin/template/count_stats.tpl.php new file mode 100644 index 0000000..55d3144 --- /dev/null +++ b/admin/template/count_stats.tpl.php @@ -0,0 +1,135 @@ + +
    + +
    + + 1) { $xd .= ','; $yd .= ','; } + $f = datetotime($ym.'-'.$i.' 00:00:00'); + $t = datetotime($ym.'-'.$i.' 23:59:59'); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$tb} WHERE `$fd`>=$f AND `$fd`<=$t"); + $xd .= "'".$i."日'"; + $yd .= $r['num']; + } +?> +
    + + + 1) { $xd .= ','; $yd .= ','; } + $f = datetotime($ym.'-'.$i.'-1 00:00:00'); + $d = date('t', $f); + $t = datetotime($ym.'-'.$i.'-'.$d.' 23:59:59'); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$tb} WHERE `$fd`>=$f AND `$fd`<=$t"); + $xd .= "'".$i."月'"; + $yd .= $r['num']; + } +?> +
    + + + + \ No newline at end of file diff --git a/admin/template/cron.tpl.php b/admin/template/cron.tpl.php new file mode 100644 index 0000000..a97ddac --- /dev/null +++ b/admin/template/cron.tpl.php @@ -0,0 +1,47 @@ + +
    + +
    +
    + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + +
    名称时间表文件名 上次运行 下次运行 状态运行管理
    禁用' : '正常';?> onclick="return confirm('此任务已禁用,确定要运行吗?');" class="t">运行  +
    +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/cron_edit.tpl.php b/admin/template/cron_edit.tpl.php new file mode 100644 index 0000000..5632840 --- /dev/null +++ b/admin/template/cron_edit.tpl.php @@ -0,0 +1,130 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 任务名称 +
    * 脚本文件 + +
    * 执行方式 +checked onclick="Ds('run_0');Dh('run_1');"/> 间隔执行   +checked onclick="Dh('run_0');Ds('run_1');"/> 每天执行 +
    * 间隔时间 分钟   +  +
    * 执行时间 + + +
    * 运行参数 + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数名称参数值 代码调用 
    $v1
    $v2
    $v3
    例如:时间例如:100
    +
    * 任务状态 +checked /> 正常   +checked /> 禁用 +
    * 备注说明
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/data.tpl.php b/admin/template/data.tpl.php new file mode 100644 index 0000000..f27ebd1 --- /dev/null +++ b/admin/template/data.tpl.php @@ -0,0 +1,95 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 数据来源 +   + +
    * 导出条件   AND开头的MySQL条件语句,例如AND status=3
    * 排序方式   数据的排序方式,例如itemid DESC
    * 导出格式 + +
    * 每轮查询   条数据
    * 页码   0页/0
     
    +
    + + + + \ No newline at end of file diff --git a/admin/template/data_import.tpl.php b/admin/template/data_import.tpl.php new file mode 100644 index 0000000..55e67b4 --- /dev/null +++ b/admin/template/data_import.tpl.php @@ -0,0 +1,82 @@ + +
    + + + + + + + + + + + + + + + + + + + +
    * 导入说明 +  点此下载示例Excel文件模板,根据需要导入的表调整字段和录入数据
    +  第一行为字段中文名,仅为方便录入,对导入数据无影响,可留空;第二行为数据表对应字段名,必须和数据表内字段一致,必须填写;第三行及以后的行需要录入待导入的数据
    +  导入会员时,可以在第二行加入company和member_misc表的字段,系统会自动保存到对应内容表里
    +  导入模块时,可以在第二行加入content字段,系统会自动保存到对应内容表里
    +  如果数据为时间格式,建议将Excel单元格设置为文本格式,防止其对数据自动转换导致格式错误
    +
    * 数据文件 限*.xls
    * 导入目标 + +   + +
    +
    + + + \ No newline at end of file diff --git a/admin/template/data_move.tpl.php b/admin/template/data_move.tpl.php new file mode 100644 index 0000000..5496f0f --- /dev/null +++ b/admin/template/data_move.tpl.php @@ -0,0 +1,107 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 转移类型  + +→ + +
    * 转移条件  + +
    + - 如果转移单条信息,则直接填写信息ID,例如 123
    + - 如果转移多条信息,则填用,分隔信息ID,例如 123,124,125 (结尾和开头不需要,)
    + - 可直接写SQL调用条件,必须以and开头
    +  例如 and catid=123 表示调用分类ID为123的信息
    +  例如 and price>0 表示调用有价格的信息(一般为供应)
    +
    * 新分类  + + +
    * 删除源数据  + 是    + 否 + +
    * 注意事项 + - 转移成功后请进入目标模型管理,更新新转移的信息,如果模型内容设置生成HTML,需要生成一下
    + - 可能需要按信息ID降序搜索才可以看到新转移的信息
    +
      
    +
    + + + \ No newline at end of file diff --git a/admin/template/data_view.tpl.php b/admin/template/data_view.tpl.php new file mode 100644 index 0000000..afef77f --- /dev/null +++ b/admin/template/data_view.tpl.php @@ -0,0 +1,43 @@ + + + +$v) { ?> + + + + + + + + + + +
    +
    导入数据
    +
    + + + + + + + + + + + + + +
    提示总计条数据,以上为前条数据预览,请确认无误再导入
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/database.tpl.php b/admin/template/database.tpl.php new file mode 100644 index 0000000..3034417 --- /dev/null +++ b/admin/template/database.tpl.php @@ -0,0 +1,119 @@ + + +
    + + + + + + + + + + +$v) {?> + + + + + + + + + + +$v) {?> + + + + + + + + + + +
    表名 注释大小(M) 记录数 操作
    + + + 字典  |  修复  |  优化  |  导出
    + + + 字典  |  修复  |  优化  |  导出
    +
    个表 / M备份选中
    + + + + + + + + + + + + + + + + + + + + +
    快速选表 +反选    +全选    +全不选    +
    分卷大小 K   1024K = 1M
    语句格式      
    字符编码      
    备注信息 
    +
    + +   +   +   +   +   +   +
    +
    + + \ No newline at end of file diff --git a/admin/template/database_comment.tpl.php b/admin/template/database_comment.tpl.php new file mode 100644 index 0000000..0539d5f --- /dev/null +++ b/admin/template/database_comment.tpl.php @@ -0,0 +1,23 @@ + +
    + + + + + + + + + + + + + +
    * 表名称 
    * 新注释 
    +
    +
    + + \ No newline at end of file diff --git a/admin/template/database_dict.tpl.php b/admin/template/database_dict.tpl.php new file mode 100644 index 0000000..b37a58e --- /dev/null +++ b/admin/template/database_dict.tpl.php @@ -0,0 +1,45 @@ + +
    + + + + + + + + + + + + + +$v) {?> + + + + + + + + + +$v) {?> + + + + + + + + + + + + + +
    字段名注释备注类型校验结果
         
       缺失字段
          
    +
    + \ No newline at end of file diff --git a/admin/template/database_execute.tpl.php b/admin/template/database_execute.tpl.php new file mode 100644 index 0000000..1a9b2d5 --- /dev/null +++ b/admin/template/database_execute.tpl.php @@ -0,0 +1,56 @@ + +
    + + + + + + + + + +
      
    +  
    +
    + +
    + + +$v) {?> + + + + + +$v) {?> + + + + +$v) {?> + +$vv) {?> + + + + +
    +
    + + + + \ No newline at end of file diff --git a/admin/template/database_import.tpl.php b/admin/template/database_import.tpl.php new file mode 100644 index 0000000..0882ff0 --- /dev/null +++ b/admin/template/database_import.tpl.php @@ -0,0 +1,90 @@ + +
    + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + +
    备份系列备注文件大小备份时间分卷导入下载
     
    + + + + + + + + + + + + + +$v) {?> +> + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    SQL文件备注文件大小修改时间分卷导入下载
     
      --
    + +
    + +
    +
    + + \ No newline at end of file diff --git a/admin/template/database_open.tpl.php b/admin/template/database_open.tpl.php new file mode 100644 index 0000000..72a3993 --- /dev/null +++ b/admin/template/database_open.tpl.php @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + +
    文件名称文件大小(M)修改时间分卷操作
      +导入  |  下载
    + \ No newline at end of file diff --git a/admin/template/database_process.tpl.php b/admin/template/database_process.tpl.php new file mode 100644 index 0000000..c6a8969 --- /dev/null +++ b/admin/template/database_process.tpl.php @@ -0,0 +1,38 @@ + +
    + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    用户主机数据库命令时间状态SQL查询操作
    />
    +
    + +
    +
    + + \ No newline at end of file diff --git a/admin/template/database_replace.tpl.php b/admin/template/database_replace.tpl.php new file mode 100644 index 0000000..80c3cb1 --- /dev/null +++ b/admin/template/database_replace.tpl.php @@ -0,0 +1,127 @@ + +
    + + +
    备份内容替换
    + + + + + + + + + + + + + + + + + +
    * 备份系列 + +
    * 查找
    * 替换为
     
    +
    + +
    + + +
    数据内容替换
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 数据字段 +   + +
    * 替换类型 + 直接替换   + 头部追加   + 尾部追加 +
    * 查找
    * 替换为
    * 替换条件   AND开头的MySQL条件语句,例如AND status=3
    * 每轮查询   条数据
     
    +
    + + + + \ No newline at end of file diff --git a/admin/template/database_verify.tpl.php b/admin/template/database_verify.tpl.php new file mode 100644 index 0000000..ea41bb5 --- /dev/null +++ b/admin/template/database_verify.tpl.php @@ -0,0 +1,77 @@ + + +
    + + + + + + + + + + +$v) {?> + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    表名 注释字段数 记录数 校验结果详情
      +异常'; +} else { + echo '未知'; +} +?> +
     
    + + \ No newline at end of file diff --git a/admin/template/dialog.tpl.php b/admin/template/dialog.tpl.php new file mode 100644 index 0000000..64fac96 --- /dev/null +++ b/admin/template/dialog.tpl.php @@ -0,0 +1,29 @@ + + + + + +提示信息 + + + + + + + + + + + + + +
    + +
    + + + \ No newline at end of file diff --git a/admin/template/doctor.tpl.php b/admin/template/doctor.tpl.php new file mode 100644 index 0000000..1ebd9ec --- /dev/null +++ b/admin/template/doctor.tpl.php @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 && $v['domain']) $S = 1; + } + if($CFG['com_domain']) $S = 1; + if(!$S && $DT['city']) { + $r = $db->get_one("SELECT areaid FROM {$DT_PRE}city WHERE domain<>''"); + if($r) $S = 1; + } + $D = $CFG['cookie_domain']; + if($S) { +?> + + + + + + + + + + + + + + + +set('destoon', 'b2b', 3600); + $D = $dc->get('destoon') == 'b2b' ? 1 : 0; +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    项目说明
    后台登录地址admin.php +如果管理帐号泄漏,后台容易遭受攻击,为了系统安全,请修改根目录admin.php的文件名 +
    升级备份目录5.0 +如果已经升级成功,建议将备份目录删除或备份至非站点目录 +
    升级目录upgrade +如果已经升级成功,建议将升级目录删除 +
    安装目录install +如果已经安装成功,建议将安装目录删除 +
    SSL证书未启用';?> +HTTPS绿色加密通道,网站数据的加密传输 +
    file目录是否可写不可写';?> +file目录及所有子目录和子文件都必须设置可写,否则会出现以下问题:
    +系统缓存无法更新
    +后台无法登录
    +登录后台不显示密码输入框
    +前台页面无法正常显示
    +文件无法上传
    +
    Cookie作用域未设置';?> +当前系统使用过二级域名,未设置Cookie作用域会出现以下问题:
    +验证码/验证问题校验错误
    +会员登录状态显示错误
    +评论不显示
    +
    模板和风格目录同名 +模板和风格目录同名可能导致模板被下载,建议模板和风格使用不相同的目录名称 +
    系统缓存测试失败';?> +当前缓存类型为立即更换可用的缓存类型');?> +
    客户端IP +查看真实IP,如果IP错误可能会影响注册和发布信息
    +所属地区为,如果所在地错误,请及时更新IP数据库 +
    允许使用URL打开文件
    allow_url_fopen
    Off';?> +建议设置为On,否则会出现以下问题:
    +远程图片无法保存
    +网络图片无法上传
    +一键登录无法登录
    +
    程序最多允许使用内存量
    memory_limit
    +内存设置过小会导致部分操作无法进行,显示空白 +
    POST最大字节数
    post_max_size
    +大于的文件无法上传
    +大于的信息无法提交 +
    允许最大上传文件
    upload_max_filesize
    +大于的文件无法上传 +
    fsockopen不支持';?> +如果不支持,将会出现以下问题:
    +充值接口无法使用
    +手机短信无法发送
    +电子邮件无法发送
    +一键登录无法登录
    + +
    curl不支持';?> +如果不支持,将会出现以下问题:
    +一键登录无法登录
    +短信无法发送
    +
    json不支持';?> +如果不支持,将会出现以下问题:
    +一键登录无法登录
    +
    OpenSSL不支持';?> +如果不支持,将会出现以下问题:
    +一键登录无法登录
    +短信无法发送
    +支付接口无法使用
    +SSL邮箱无法发信
    +
    + + + \ No newline at end of file diff --git a/admin/template/fetch.tpl.php b/admin/template/fetch.tpl.php new file mode 100644 index 0000000..154c01b --- /dev/null +++ b/admin/template/fetch.tpl.php @@ -0,0 +1,45 @@ + +
    + + +  +  +  +  + + +
    +
    + + + + + + + + + + +$v) {?> + + + + + + + + + +
    域名编码网站修改时间管理
      +
    +
    +  +
    +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/fetch_edit.tpl.php b/admin/template/fetch_edit.tpl.php new file mode 100644 index 0000000..158e26d --- /dev/null +++ b/admin/template/fetch_edit.tpl.php @@ -0,0 +1,56 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 采编域名 +
    +不带http及目录,例如 bbs.destoon.com +
    * 网站名称
    * 标题过滤
    * 内容规则 +
    * 内容编码 +/> UTF-8     +/> GBK +
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/fields.tpl.php b/admin/template/fields.tpl.php new file mode 100644 index 0000000..b5060b9 --- /dev/null +++ b/admin/template/fields.tpl.php @@ -0,0 +1,57 @@ + +
    + + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + + + + + +
    删除排序字段字段名称显示前台字段属性表单类型调用操作
    查看 +
    +
    +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/fields_add.tpl.php b/admin/template/fields_add.tpl.php new file mode 100644 index 0000000..1c32123 --- /dev/null +++ b/admin/template/fields_add.tpl.php @@ -0,0 +1,198 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 字段 + +小写字母(a-z),数字(0-9) 推荐使用字母,不能以数字开头 +
    * 字段名称 +
    * 提示信息
    * 字段属性 + +
    * 字段长度
    * 表单类型 + +
    * 默认值 + +
    支持PHP变量,例如 $_username +
    * 输入限制 +
    +直接填数字表示限制最小长度,如果要限制长度范围例如6到20之间,则填写 6-20
    +可以直接书写兼容js和php的正则表达式
    +对于单选框(radio),填非0数字表示必选
    +对于多选框(checkbox),填非0数字表示必选个数 填长度范围表示必选个数范围
    +
    * 附加内容 + +
    * 直接显示 + 是     + +
    * 前台显示 + 是     + +
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/fields_edit.tpl.php b/admin/template/fields_edit.tpl.php new file mode 100644 index 0000000..02bf5b4 --- /dev/null +++ b/admin/template/fields_edit.tpl.php @@ -0,0 +1,191 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 字段 + +小写字母(a-z),数字(0-9) 推荐使用字母,不能以数字开头 +
    * 字段名称 +
    * 提示信息
    * 字段属性 + +
    * 字段长度
    * 表单类型 + +
    * 默认值 + +
    支持PHP变量,例如 $_username +
    * 选项值 +
    +一行一个 选项值|选项名称* 注意*为结尾标志符 +
    * 默认宽高 X
    * 输入限制 +
    +直接填数字表示限制最小长度,如果要限制长度范围例如6到20之间,则填写 6-20
    +可以直接书写兼容js和php的正则表达式
    +对于单选框(radio),填非0数字表示必选
    +对于多选框(checkbox),填非0数字表示必选个数 填长度范围表示必选个数范围
    +
    * 附加内容 + +
    * 直接显示 +/> 是     +/> 否 +
    * 前台显示 +/> 是     +/> 否 +
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/footer.tpl.php b/admin/template/footer.tpl.php new file mode 100644 index 0000000..d978ead --- /dev/null +++ b/admin/template/footer.tpl.php @@ -0,0 +1,21 @@ +
    '; + debug(); + echo '

    '; +} +?> + + + + \ No newline at end of file diff --git a/admin/template/header.tpl.php b/admin/template/header.tpl.php new file mode 100644 index 0000000..b51f097 --- /dev/null +++ b/admin/template/header.tpl.php @@ -0,0 +1,30 @@ + + + + + +管理中心 - <?php echo $DT['sitename']; ?> - Powered By DESTOON V<?php echo DT_VERSION; ?> R<?php echo DT_RELEASE;?> + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/template/history.tpl.php b/admin/template/history.tpl.php new file mode 100644 index 0000000..1798996 --- /dev/null +++ b/admin/template/history.tpl.php @@ -0,0 +1,40 @@ + + + + + + + +$v) {?> + + + + + + +
    项目修改前修改为
    + +
    源代码内容修改前
    + + + + +
    +
    + +
    +
    内容修改为
    + + + + +
    +
    + +
    + +



    + \ No newline at end of file diff --git a/admin/template/html.tpl.php b/admin/template/html.tpl.php new file mode 100644 index 0000000..9a11ef1 --- /dev/null +++ b/admin/template/html.tpl.php @@ -0,0 +1,41 @@ + +
    +     +     +     +     + +
    + + + + + + + + + + + +$v) { + if($v['islink'] || $v['moduleid'] < 4) continue; +?> + + + + + + + + + + + +
    模块生成首页生成列表生成内容更新信息一键更新更新数据
    生成首页生成列表生成内容更新信息一键更新更新数据
    + + \ No newline at end of file diff --git a/admin/template/index.html b/admin/template/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/admin/template/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/admin/template/ip.tpl.php b/admin/template/ip.tpl.php new file mode 100644 index 0000000..a1911e9 --- /dev/null +++ b/admin/template/ip.tpl.php @@ -0,0 +1,11 @@ + +
    + + + + +
        禁止
    + \ No newline at end of file diff --git a/admin/template/keylink.tpl.php b/admin/template/keylink.tpl.php new file mode 100644 index 0000000..3de998e --- /dev/null +++ b/admin/template/keylink.tpl.php @@ -0,0 +1,93 @@ + +
    + +
    +
    + + + + + + + + + +$v) { ?> + + + + + + + + + + + + + + + + + +
    关键词链接
    新增
         +     +     +     +提示:过多的关联链接会影响页面打开或生成速度
    +
    +'.$pages.'' : '';?> +
    + + + +
    批量添加
    + + + + + + + + + +
    * 内容
    +一行一个,关键词和链接用|分隔,例如:DESTOON|https://www.destoon.com +
    +
    +
    + + +
    链接导入
    + + + + + + + + + +
    * 模块   +[查看] +
    +
    +
    + \ No newline at end of file diff --git a/admin/template/keyword.tpl.php b/admin/template/keyword.tpl.php new file mode 100644 index 0000000..b1b1bdf --- /dev/null +++ b/admin/template/keyword.tpl.php @@ -0,0 +1,133 @@ + +
    + +
    +
    + + + + + + + + + + + + + + + + +$v) { ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    模块关键词相关词拼音结果 总搜索 本月 本周 今日 状态
    + +
    模块关键词相关词拼音结果总搜索本月本周今日状态
    新增 + + + +
         +     +     +
    +
    +'.$pages.'' : '';?> +
    相关词说明
    + + + + +
    +- 设置相关词可以使提示搜索或相关搜索更智能 例如关键词‘IBM’可设置‘IBM,笔记本’则搜索IBM和笔记本均会提示IBM相关搜索
    +- 多个相关词请用英文,分隔,为了系统检索效率,建议控制在200字内 +
    + + \ No newline at end of file diff --git a/admin/template/keyword_record.tpl.php b/admin/template/keyword_record.tpl.php new file mode 100644 index 0000000..a193367 --- /dev/null +++ b/admin/template/keyword_record.tpl.php @@ -0,0 +1,64 @@ + + +
    + + + + + + + + + + + + +$v) { ?> + + + + + + + + + + + + + + +
    时间 会员关键词模块结果
         +     + +
    +
    +'.$pages.'' : '';?> + + + \ No newline at end of file diff --git a/admin/template/left.tpl.php b/admin/template/left.tpl.php new file mode 100644 index 0000000..0d13e49 --- /dev/null +++ b/admin/template/left.tpl.php @@ -0,0 +1,291 @@ + + + + + +管理中心 - <?php echo $DT['sitename']; ?> - Powered By DESTOON V<?php echo DT_VERSION; ?> R<?php echo DT_RELEASE;?> + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    +
    +
    我的面板
    +
    系统维护
    +
    功能模块
    +
    会员管理
    +
    扩展功能
    +
    后台搜索
    +
    隐藏侧栏
    +
    +
    + + + + \ No newline at end of file diff --git a/admin/template/like.tpl.php b/admin/template/like.tpl.php new file mode 100644 index 0000000..3d45140 --- /dev/null +++ b/admin/template/like.tpl.php @@ -0,0 +1,51 @@ + +
    + +
    + + + + + + + + + +$v) {?> + + + + + + + + + +
    时间会员名态度模块信息ID
    反对' : '支持';?>
    +
    + +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/login.tpl.php b/admin/template/login.tpl.php new file mode 100644 index 0000000..684e4da --- /dev/null +++ b/admin/template/login.tpl.php @@ -0,0 +1,183 @@ + + + + + +管理员登录 - Powered By DESTOON <?php echo edition(1);?> + + + + + + + + + + + + + + + + + + +<br/><br/><br/><center><h1>您的浏览器不支持框架,请更换支持框架的浏览器</h1></center> +
    + + + + +
    +
    + + + + \ No newline at end of file diff --git a/admin/template/main.tpl.php b/admin/template/main.tpl.php new file mode 100644 index 0000000..bb9a0ce --- /dev/null +++ b/admin/template/main.tpl.php @@ -0,0 +1,117 @@ + + + +
    IP: 欢迎管理员,
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    管理级别 '.$AREA[$_aid]['areaname'].'站管理员' : '普通管理员'); ?>登录次数 
    站内信件 收件箱('.$_message.'' : $_message;?>)登录时间 
    账户余额 会员 
    工作便笺 + + 
    + +
    + +
    +
    系统信息
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    程序信息 DESTOON Version Release [检查更新]
    软件版本  (未授权)  [购买授权] 商业  [技术支持]
    安装时间 
    官方网站 https://www.destoon.com/
    用户论坛 https://bbs.destoon.com/
    帮助文档 https://www.destoon.com/doc/
    专用主机 https://www.destoon.com/host/
    SSL证书 https://www.destoon.com/ssl/
    服务器时间 
    服务器IP : -
    服务器信息  / PHP / MySQL  [系统体检]
    站点路径 
    +
    使用协议
    + + + + +
    + + \ No newline at end of file diff --git a/admin/template/md5.tpl.php b/admin/template/md5.tpl.php new file mode 100644 index 0000000..19c07b9 --- /dev/null +++ b/admin/template/md5.tpl.php @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + +
    文件大小修改时间
      Kb
      - 以上文件曾被修改或创建,请下载手动检查文件内容是否安全    [重新校验]
      - 没有文件被修改或创建    [重新校验]
    + + +
    + + + + + + + + + + + + + +
     选择目录 + +$d) { ?> + + + + +
    +
      +反选   +全选   +全不选   +
    +
     文件类型 
     镜像文件  +
    +
    +
    + + +
    创建镜像
    + + + + + + + + + + + + + +
     选择目录 + +$d) { ?> + + + + +
    +
      +反选   +全选   +全不选   +
    +
     文件类型 
     
    +
    + + + \ No newline at end of file diff --git a/admin/template/md5_add.tpl.php b/admin/template/md5_add.tpl.php new file mode 100644 index 0000000..788af43 --- /dev/null +++ b/admin/template/md5_add.tpl.php @@ -0,0 +1,48 @@ + +
    + + +
    文件校验
    + + + + + +
     镜像文件 +
    +
    +
    + + +
    创建镜像
    + + + + + + + + + + + + + +
     选择目录 + +$d) { ?> + + + + +
    /> 
    +
     文件类型 
     
    +
    + + \ No newline at end of file diff --git a/admin/template/menu.tpl.php b/admin/template/menu.tpl.php new file mode 100644 index 0000000..a694889 --- /dev/null +++ b/admin/template/menu.tpl.php @@ -0,0 +1,35 @@ + + + \ No newline at end of file diff --git a/admin/template/mobile.tpl.php b/admin/template/mobile.tpl.php new file mode 100644 index 0000000..27984ea --- /dev/null +++ b/admin/template/mobile.tpl.php @@ -0,0 +1,11 @@ + +
    + + + + +
     
    + \ No newline at end of file diff --git a/admin/template/module.tpl.php b/admin/template/module.tpl.php new file mode 100644 index 0000000..211512f --- /dev/null +++ b/admin/template/module.tpl.php @@ -0,0 +1,164 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + + + + + + + + + + +
    排序ID模型名称目录导航状态禁用目录分类字段模板统计更新设置修改删除
    是' : ''; ?>正常 + +-- + +禁用 + + + +重建 + +-- + + + +-- + +分类 + + + +-- + +字段 + + + +-- + +模板 + + + +-- + +统计 + + + +-- + +更新 + + + +-- +设置 + + + +-- + +修改 + + + +-- + +删除 + +
    排序ID模型名称目录导航状态启用目录分类字段模板统计更新设置修改删除
    --禁用启用--------------修改删除
    +
    +  +
    +
    + + + + + \ No newline at end of file diff --git a/admin/template/module_add.tpl.php b/admin/template/module_add.tpl.php new file mode 100644 index 0000000..722fe03 --- /dev/null +++ b/admin/template/module_add.tpl.php @@ -0,0 +1,90 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 模块类型 + 内置模型     + 外部链接
    * 模块名称
    * 导航菜单 是    
    * 新窗口打开 是    
    * 所属模型
    * 安装目录
    * 电脑版绑定域名如果不绑定请勿填写');?>
    * 手机版绑定域名如果不绑定请勿填写');?>
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/module_edit.tpl.php b/admin/template/module_edit.tpl.php new file mode 100644 index 0000000..2a21af0 --- /dev/null +++ b/admin/template/module_edit.tpl.php @@ -0,0 +1,88 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 模块类型
    * 模块名称
    * 导航菜单/> 是     /> 否
    * 新窗口打开/> 是     /> 否
    * 独立LOGO/> 是     /> 否 上传至skin/'.$CFG['skin'].'/image/目录');?>
    * 链接地址
    * 安装目录 disabled/> +
    * 系统提示如果不是十分必要,建议不要频繁更改安装目录 +
    * 电脑版绑定域名如果不绑定请勿填写');?>
    * 手机版绑定域名如果不绑定请勿填写');?>
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/module_sys.tpl.php b/admin/template/module_sys.tpl.php new file mode 100644 index 0000000..4a85823 --- /dev/null +++ b/admin/template/module_sys.tpl.php @@ -0,0 +1,29 @@ + + + + + + + + + + +$v) {?> + + + + + + + + + +
    模型目录可复制可卸载作者官方网站
       是' : ''; ?>是' : ''; ?>
    + + \ No newline at end of file diff --git a/admin/template/move.tpl.php b/admin/template/move.tpl.php new file mode 100644 index 0000000..a5d1bfa --- /dev/null +++ b/admin/template/move.tpl.php @@ -0,0 +1,45 @@ + +
    + + + + + + + + + + + + + + + + + + + +
    + id="f_1"/>     + id="f_2"/> + 目标分类
    + +
    [分类ID查询] 
    + +
    + + + \ No newline at end of file diff --git a/admin/template/msg.tpl.php b/admin/template/msg.tpl.php new file mode 100644 index 0000000..48d84c8 --- /dev/null +++ b/admin/template/msg.tpl.php @@ -0,0 +1,25 @@ + + + + + + +提示信息 - Powered By DESTOON + + + + + + + \ No newline at end of file diff --git a/admin/template/mymenu.tpl.php b/admin/template/mymenu.tpl.php new file mode 100644 index 0000000..1ef3fef --- /dev/null +++ b/admin/template/mymenu.tpl.php @@ -0,0 +1,57 @@ + +
    + + + + + + + + + + +$v) {?> + + + + + + + + +> + + + + + + + + + + +
    排序名称网址
     
    新增   +
         +     + +     + +     + +
    +
    + +
    + \ No newline at end of file diff --git a/admin/template/notice_chip.tpl.php b/admin/template/notice_chip.tpl.php new file mode 100644 index 0000000..a9fc138 --- /dev/null +++ b/admin/template/notice_chip.tpl.php @@ -0,0 +1,8 @@ +
    +     +     +     +     +     + +
    \ No newline at end of file diff --git a/admin/template/password.tpl.php b/admin/template/password.tpl.php new file mode 100644 index 0000000..abf6fbb --- /dev/null +++ b/admin/template/password.tpl.php @@ -0,0 +1,53 @@ + +
    + + + + + + + + + + + + + + + + + + + +
    * 新登录密码
    * 重复新密码
    * 现有密码
    + + + \ No newline at end of file diff --git a/admin/template/patch.tpl.php b/admin/template/patch.tpl.php new file mode 100644 index 0000000..8782b62 --- /dev/null +++ b/admin/template/patch.tpl.php @@ -0,0 +1,120 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    备份模式  +     + +
    选择目录 + +$d) { ?> + + + + +
    +
      +反选   +全选   +全不选   +
    +
    文件类型 
    修改时间 +  至 +   +  今日 +  昨日 +  三天 +  本周 +  本月 +
    备注信息 
     
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    备份时间目录文件数量备注信息操作
      
     
    + + + + \ No newline at end of file diff --git a/admin/template/patch_view.tpl.php b/admin/template/patch_view.tpl.php new file mode 100644 index 0000000..b6eba9f --- /dev/null +++ b/admin/template/patch_view.tpl.php @@ -0,0 +1,20 @@ + +
    文件列表
    + + + + + + + + + + + + + +
    文件大小修改时间
      Kb
    + \ No newline at end of file diff --git a/admin/template/property.tpl.php b/admin/template/property.tpl.php new file mode 100644 index 0000000..1209154 --- /dev/null +++ b/admin/template/property.tpl.php @@ -0,0 +1,46 @@ + +
    + + + + + + + + + + + + + + + +$v) { ?> + + + + + + + + + + + + + + + + +
    删除排序ID名称必填默认(备选)值搜索添加方式操作
    是' : '';?> + +
    +
    +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/property_copy.tpl.php b/admin/template/property_copy.tpl.php new file mode 100644 index 0000000..3052eea --- /dev/null +++ b/admin/template/property_copy.tpl.php @@ -0,0 +1,74 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 复制方式 +      + +
    * 所属模块 + +
    * 来源分类 + + +
    * 同名过滤 +      + +
    +
    +
    + + + \ No newline at end of file diff --git a/admin/template/property_edit.tpl.php b/admin/template/property_edit.tpl.php new file mode 100644 index 0000000..e31c1f6 --- /dev/null +++ b/admin/template/property_edit.tpl.php @@ -0,0 +1,80 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 属性名称
    * 添加方式 +$v) { +?> +/>     + +
    * 默认值
    * 是否必填 +/>     +/> +
    * 扩展代码
    +
        
    +
    + + + \ No newline at end of file diff --git a/admin/template/question.tpl.php b/admin/template/question.tpl.php new file mode 100644 index 0000000..bb46972 --- /dev/null +++ b/admin/template/question.tpl.php @@ -0,0 +1,60 @@ + +
    + +
    +
    + + + + + + + + +$v) { ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
    问题答案
    新增
         +     +     +
    '.$pages.'' : '';?>
    +  1、批量添加时,问题和答案一行一个,互相对应
    +  2、如果答案不唯一,建议在问题里写清楚答案
    +
    +
    + + \ No newline at end of file diff --git a/admin/template/scan.tpl.php b/admin/template/scan.tpl.php new file mode 100644 index 0000000..e0fe7b2 --- /dev/null +++ b/admin/template/scan.tpl.php @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + 2 ? ' class="f_red"' : '';?>> + + + + + + + + + + + + +
    文件特征码匹配次数大小修改时间
      Kb
      - 共发现个可疑文件,请下载手动检查文件内容是否安全    [重新扫描]
      - 指定范围没有扫描到可疑文件    [重新扫描]
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    选择目录 + +$d) { ?> + + + + +
    +
      +反选   +全选   +全不选   +
    +
    文件类型 
    文件编码 + UTF-8     + GBK +
    特征代码 
    匹配次数  次以上
      +
    +
    + + + \ No newline at end of file diff --git a/admin/template/search.tpl.php b/admin/template/search.tpl.php new file mode 100644 index 0000000..41fa832 --- /dev/null +++ b/admin/template/search.tpl.php @@ -0,0 +1,181 @@ + + +
    +
    + +  输入关键词,例如“手机短信”、“支付接口 +
    +
    + + + + + + + + + +$v) {?> + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    名称查看
      
      
     - 未找到到相关设置,请调整关键词再试    [重新搜索]
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    我的面板系统维护功能模块会员管理公司管理财务管理会员相关扩展功能系统工具
    + +
    +
    后台首页
    +
    定义面板
    + +
    + +
    安全退出
    +
    +
    +
    + '.$m[0].''; + } + ?> +
    +
    +
    + 4 && !$v['islink']) { + echo '
    '.$v['name'].'管理
    '; + } + } + ?> +
    +
    +
    + '.$m[0].''; + } + ?> +
    +
    +
    + '.$m[0].''; + } + ?> +
    +
    +
    + '.$m[0].''; + } + ?> +
    +
    +
    + '.$m[0].''; + } + ?> +
    +
    +
    + '.$m[0].''; + } + ?> +
    +
    +
    + '.$m[0].''; + } + ?> +
    +
    + + + \ No newline at end of file diff --git a/admin/template/setting.tpl.php b/admin/template/setting.tpl.php new file mode 100644 index 0000000..8dbb425 --- /dev/null +++ b/admin/template/setting.tpl.php @@ -0,0 +1,1198 @@ + +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    网站名称
    网站地址注意以 / 结尾');?>
    网站LOGO  [上传]  [预览]  [删除]
    +
    版权信息
    支持HTML语法,常用代码:版权© &copy; 空格 &nbsp; 换行 <br/> +
    客服电话
    ICP备案序号
    网安备案序号
    网站状态 +checked onclick="Dh('dclose');"/> 开启   +checked onclick="Ds('dclose');"/> 关闭 +
    关闭原因
    支持HTML语法,网站关闭不影响后台管理 +
    城市分站 +checked /> 开启   +checked /> 关闭   +
    根据IP自动跳转分站 +checked /> 开启   +checked /> 关闭   +
    网站默认语言 +".$v['name'].""; +} +$select = ''; +echo $select; +?> +
    网站默认风格 +".$v['name'].""; +} +$select = ''; +echo $select; +tips('位于./skin/目录,一个目录即为一套风格'); +?> +
    网站默认模板 +".$v['name'].""; +} +$select = ''; +echo $select; +tips('位于./template/目录,一个目录即为一套模板'); +?> +
    手机默认模板 +".$v['name'].""; +} +$select = ''; +echo $select; +tips('位于./template/目录,一个目录即为一套模板'); +?> +
    网页编辑器 +".$v['name'].""; +} +$select = ''; +echo $select; +tips('位于./'.$MODULE[2]['moduledir'].'/editor/目录,一个目录即为一套模板'); +?> +
    VIP会员名称
    真实货币名称
    真实货币单位
    真实货币符号
    虚拟积分名称
    虚拟积分单位
    小额免密支付
    购物车最大容量
    后台左侧栏宽度 px
    显示会员手机号码 +checked /> 开启   +checked /> 关闭 +
    即时通讯站内交谈 +checked /> 开启   +checked /> 关闭 +
    即时通讯QQ +checked /> 开启   +checked /> 关闭 +
    即时通讯微信 +checked /> 开启   +checked /> 关闭 +
    即时通讯阿里旺旺 +checked /> 开启   +checked /> 关闭 +
    即时通讯Skype +checked /> 开启   +checked /> 关闭 +
    +
    + + + + + + + + + + + + + + +
    +     + +
    +
    + + + \ No newline at end of file diff --git a/admin/template/side.tpl.php b/admin/template/side.tpl.php new file mode 100644 index 0000000..91fe278 --- /dev/null +++ b/admin/template/side.tpl.php @@ -0,0 +1,38 @@ + + + + + +管理中心 - <?php echo $DT['sitename']; ?> - Powered By DESTOON V<?php echo DT_VERSION; ?> R<?php echo DT_RELEASE;?> + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/template/skin.tpl.php b/admin/template/skin.tpl.php new file mode 100644 index 0000000..4e144cc --- /dev/null +++ b/admin/template/skin.tpl.php @@ -0,0 +1,62 @@ + + + + + + + + +$v) {?> + + + + + + + +
      文件大小修改时间操作
      Kb +  +  +  +
    + +
    风格备份管理
    + + + + + + + +$v) {?> + + + + + + + +
      文件大小备份时间操作
      Kb +  +  +  +
    + +
    +".$v['name']."(".$v['dir'].")"; +} +$select = ''; +echo $select; +?> +
    + + \ No newline at end of file diff --git a/admin/template/skin_add.tpl.php b/admin/template/skin_add.tpl.php new file mode 100644 index 0000000..e1fbe45 --- /dev/null +++ b/admin/template/skin_add.tpl.php @@ -0,0 +1,29 @@ + +
    + + + + + + + + + + + + + + + + + +
    * 文件路径
    * 文件名.css 不支持中文
    + +
    如果风格已经存在,请不要覆盖      
    +
    + + \ No newline at end of file diff --git a/admin/template/skin_edit.tpl.php b/admin/template/skin_edit.tpl.php new file mode 100644 index 0000000..d79400b --- /dev/null +++ b/admin/template/skin_edit.tpl.php @@ -0,0 +1,31 @@ + +
    + + + + + + + + + + + + + + + + + + + +
    * 文件路径.css
    * 文件名.css 不支持中文
    + +
    保存时创建一个备份      
    +
    + + \ No newline at end of file diff --git a/admin/template/split.tpl.php b/admin/template/split.tpl.php new file mode 100644 index 0000000..118570d --- /dev/null +++ b/admin/template/split.tpl.php @@ -0,0 +1,23 @@ + +
    + +开启内容分表之前必须先拆分数据
    +如果确认开启,请点击开始拆分按钮
    + +关闭内容分表之前必须先合并数据
    +如无特殊原因不建议关闭内容分表
    +如果确认关闭,请点击开始合并按钮
    + +
    +
    + + + + + +     +
    + \ No newline at end of file diff --git a/admin/template/static.tpl.php b/admin/template/static.tpl.php new file mode 100644 index 0000000..261f9e6 --- /dev/null +++ b/admin/template/static.tpl.php @@ -0,0 +1,14 @@ + +
    +通过静态文件分离部署功能,可以将网站的静态文件部署到独立的服务器,从而减轻主站的压力和提高主站访问速度。
    +例如静态文件所在服务器绑定的域名为static.destoon.com,请在部署地址处填写http://static.destoon.com/,然后上传网站的静态文件至static.destoon.com所在的站点目录。
    + +静态文件已经整理到站点file/static目录,请将static目录下的所有文件上传到静态文件服务器的站点目录。 + +点这里整理需要分离的静态文件» + +
    + \ No newline at end of file diff --git a/admin/template/stats.tpl.php b/admin/template/stats.tpl.php new file mode 100644 index 0000000..b2ebce4 --- /dev/null +++ b/admin/template/stats.tpl.php @@ -0,0 +1,55 @@ + +
    + +
    + + + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + + + + + +
    日期 星期总UV 电脑UV 手机UV 总IP 电脑IP 手机IP 总PV 电脑PV 手机PV 爬虫PV 电脑PV 手机PV
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/stats_404.tpl.php b/admin/template/stats_404.tpl.php new file mode 100644 index 0000000..f7ceae8 --- /dev/null +++ b/admin/template/stats_404.tpl.php @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    时间网址来源设备操作系统浏览器IP归属地
    + + + +  + + >
    +
    +  +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/stats_online.tpl.php b/admin/template/stats_online.tpl.php new file mode 100644 index 0000000..f167255 --- /dev/null +++ b/admin/template/stats_online.tpl.php @@ -0,0 +1,48 @@ + +
    + +
    + + + + + + + + + + +$v) {?> + + + + + + + + + + +
    头像会员名状态所在模块IPIP所在地访问时间
    在线' : '隐身';?>
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/stats_pv.tpl.php b/admin/template/stats_pv.tpl.php new file mode 100644 index 0000000..6c67707 --- /dev/null +++ b/admin/template/stats_pv.tpl.php @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + +
    时间 网址来源IP归属地会员名所属商家设备爬虫
    >
    +
    +  +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/stats_report.tpl.php b/admin/template/stats_report.tpl.php new file mode 100644 index 0000000..9046d2a --- /dev/null +++ b/admin/template/stats_report.tpl.php @@ -0,0 +1,686 @@ + + + + + + DT_TIME) $totime = DT_TIME; + $fromtime = timetodate($totime - 86400*30, 'Ymd'); + $totime = timetodate($totime, 'Ymd'); + $data = $pv = $pv_pc = $pv_mb = ''; + $result = $db->query("SELECT * FROM {$DT_PRE}stats WHERE id>$fromtime AND id<=$totime ORDER BY id ASC LIMIT 30", 'CACHE'); + while($r = $db->fetch_array($result)) { + $data .= "'".substr($r['id'], 4, 2).'-'.substr($r['id'], 6, 2)."',"; + $pv .= $r['pv'].','; + $pv_pc .= $r['pv_pc'].','; + $pv_mb .= $r['pv_mb'].','; + } + if($data) { + $data = substr($data, 0, -1); + $pv = substr($pv, 0, -1); + $pv_pc = substr($pv_pc, 0, -1); + $pv_mb = substr($pv_mb, 0, -1); + } +?> +
    + +
    +
    + + + + DT_TIME) $totime = DT_TIME; + $fromtime = timetodate($totime - 86400*30, 'Ymd'); + $totime = timetodate($totime, 'Ymd'); + $data = $uv = $uv_pc = $uv_mb = ''; + $result = $db->query("SELECT * FROM {$DT_PRE}stats WHERE id>$fromtime AND id<=$totime ORDER BY id ASC LIMIT 30", 'CACHE'); + while($r = $db->fetch_array($result)) { + $data .= "'".substr($r['id'], 4, 2).'-'.substr($r['id'], 6, 2)."',"; + $uv .= $r['uv'].','; + $uv_pc .= $r['uv_pc'].','; + $uv_mb .= $r['uv_mb'].','; + } + if($data) { + $data = substr($data, 0, -1); + $uv = substr($uv, 0, -1); + $uv_pc = substr($uv_pc, 0, -1); + $uv_mb = substr($uv_mb, 0, -1); + } +?> +
    + +
    +
    + + + DT_TIME) $totime = DT_TIME; + $fromtime = timetodate($totime - 86400*30, 'Ymd'); + $totime = timetodate($totime, 'Ymd'); + $data = $ip = $ip_pc = $ip_mb = ''; + $result = $db->query("SELECT * FROM {$DT_PRE}stats WHERE id>$fromtime AND id<=$totime ORDER BY id ASC LIMIT 30", 'CACHE'); + while($r = $db->fetch_array($result)) { + $data .= "'".substr($r['id'], 4, 2).'-'.substr($r['id'], 6, 2)."',"; + $ip .= $r['ip'].','; + $ip_pc .= $r['ip_pc'].','; + $ip_mb .= $r['ip_mb'].','; + } + if($data) { + $data = substr($data, 0, -1); + $ip = substr($ip, 0, -1); + $ip_pc = substr($ip_pc, 0, -1); + $ip_mb = substr($ip_mb, 0, -1); + } +?> +
    + +
    +
    + + + + DT_TIME) $totime = DT_TIME; + $fromtime = timetodate($totime - 86400*30, 'Ymd'); + $totime = timetodate($totime, 'Ymd'); + $data = $rb = $rb_pc = $rb_mb = ''; + $result = $db->query("SELECT * FROM {$DT_PRE}stats WHERE id>$fromtime AND id<=$totime ORDER BY id ASC LIMIT 30", 'CACHE'); + while($r = $db->fetch_array($result)) { + $data .= "'".substr($r['id'], 4, 2).'-'.substr($r['id'], 6, 2)."',"; + $rb .= $r['rb'].','; + $rb_pc .= $r['rb_pc'].','; + $rb_mb .= $r['rb_mb'].','; + } + if($data) { + $data = substr($data, 0, -1); + $rb = substr($rb, 0, -1); + $rb_pc = substr($rb_pc, 0, -1); + $rb_mb = substr($rb_mb, 0, -1); + } +?> +
    + +
    +
    + + +=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + $key = $job; + $xd = $yd = ''; + $result = $db->query("SELECT COUNT(`{$key}`) AS num,`{$key}` FROM {$DT_PRE}stats_uv WHERE {$condition} GROUP BY `{$key}` ORDER BY num DESC LIMIT 0,2", 'CACHE'); + while($r = $db->fetch_array($result)) { + $r[$key] = $r[$key] ? '电脑' : '手机'; + $xd .= "'".$r[$key]."',"; + $yd .= "{value:".$r['num'].", name:'".$r[$key]."'},"; + } + if($xd) { + $xd = substr($xd, 0, -1); + $yd = substr($yd, 0, -1); + } +?> +
    + +
    +
    + + + +=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + if($mid > 4) $condition .= " AND mid=$mid"; + $key = $job; + $xd = $yd = ''; + $lists = array(); + $result = $db->query("SELECT COUNT(`{$key}`) AS num,`{$key}` FROM {$DT_PRE}stats_{$sv} WHERE {$condition} GROUP BY `{$key}` ORDER BY num DESC LIMIT 0,50", 'CACHE'); + while($r = $db->fetch_array($result)) { + if(!$r[$key]) continue; + $r['linkurl'] = '?file='.$file.'&action='.$sv.'&'.$job.'='.urlencode($r[$key]); + if($job == 'homepage') { + $r['linkurl'] = DT_PATH.'api/redirect.php?username='.$r[$key]; + } else if($job == 'username') { + $r['linkurl'] = '?moduleid=2&action=show&username='.$r[$key]; + } else if($job == 'mid') { + $r['linkurl'] = $MODULE[$r[$key]]['linkurl']; + $r[$key] = $MODULE[$r[$key]]['name']; + } else if($job == 'catid') { + $t = get_cat($r[$key]); + if($t) { + $r[$key] = $t['catname']; + $r['linkurl'] = $MODULE[$mid]['linkurl'].$t['linkurl']; + } + } else if($job == 'itemid') { + $itemid = $r[$key]; + $t = $db->get_one("SELECT title FROM ".get_table($mid)." WHERE itemid=$itemid"); + if($t) { + $r[$key] = dsubstr($t['title'], 30, '...'); + $r['linkurl'] = DT_PATH.'api/redirect.php?mid='.$mid.'&itemid='.$itemid; + } + } else if($job == 'domain') { + $r['uri'] = $r[$job]; + $r['linkurl'] = DT_PATH.'api/redirect.php?url='.urlencode('http://'.$r[$job]); + } else if($job == 'url') { + $r['uri'] = linkurl($r[$job], 1); + $r['linkurl'] = DT_PATH.'api/redirect.php?url='.urlencode($r['uri']); + } else if($job == 'refer') { + $r['uri'] = linkurl($r[$job], 1); + $r['linkurl'] = DT_PATH.'api/redirect.php?url='.urlencode($r['uri']); + } + $lists[] = $r; + } + $max = $tt = 0; + if($lists) { + $max = count($lists); + for($i = $max - 1; $i >= 0; $i--) { + $xd .= "'".$lists[$i][$key]."'".($i ? "," : ""); + //$yd .= $lists[$i]['num'].($i ? "," : ""); + $yd .= "{value:".$lists[$i]['num'].",name:'".$lists[$i][$key]."',url:'".$lists[$i]['linkurl']."'}".($i ? "," : ""); + $tt += $lists[$i]['num']; + } + } + $height = $max ? ($max*32)+100 : 600; +?> +
    + +
    + + + + + + + +$v) {?> + + + + + + +
    网址PV
    + + +
    + + +=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + $key = $job; + $xd = $yd = ''; + $result = $db->query("SELECT COUNT(`{$key}`) AS num,`{$key}` FROM {$DT_PRE}stats_uv WHERE {$condition} GROUP BY `{$key}` ORDER BY num DESC LIMIT 0,20", 'CACHE'); + while($r = $db->fetch_array($result)) { + if(!$r[$key]) continue; + $xd .= "'".$r[$key]."',"; + $yd .= "{value:".$r['num'].", name: '".$r[$key]."'},"; + } + if($xd) { + $xd = substr($xd, 0, -1); + $yd = substr($yd, 0, -1); + } +?> +
    + +
    +
    + + + + + \ No newline at end of file diff --git a/admin/template/stats_uv.tpl.php b/admin/template/stats_uv.tpl.php new file mode 100644 index 0000000..34624dd --- /dev/null +++ b/admin/template/stats_uv.tpl.php @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + + +
    入站时间 IP地区设备网络操作系统浏览器分辨率品牌客户端爬虫
    +
    +  +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/tag.tpl.php b/admin/template/tag.tpl.php new file mode 100644 index 0000000..b2b1f3b --- /dev/null +++ b/admin/template/tag.tpl.php @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    * 所属模块 + +moduleid
    * 数据表 + +[数据字典]  +[显示所有] +系统允许调用同数据库其他表的数据');?> + +table
    * 调用条件 + +此项需要对MySQL语法有一定了解');?> +condition
    * 调用数量pagesize
    * 排序方式 + +order
    * 所属分类 + + +←添加 + + + +catid
    * 包含子分类 + 是     + 否 +child
    * 所属地区 + +←添加 +areaid
    * 包含子地区 + 是     + 否 +areachild
    * 缓存时间 + +expires
    * 标签模板 + +template
    + + +     + +
    +
    + + + +
    标签代码
    + + + + + + + + + + + + + + + + + + + + + +
    * 自定义CSS +
    * HTML开始标签
    * 标签代码 +
    * HTML结束标签
    +     +   +
    +
    + + + \ No newline at end of file diff --git a/admin/template/tag_dict.tpl.php b/admin/template/tag_dict.tpl.php new file mode 100644 index 0000000..a3680c3 --- /dev/null +++ b/admin/template/tag_dict.tpl.php @@ -0,0 +1,31 @@ + +
    + + + + + + + + + + + +$v) {?> + + + + + + + + + + + +
    字段名注释备注类型
         
          
    +
    + \ No newline at end of file diff --git a/admin/template/tag_preview.tpl.php b/admin/template/tag_preview.tpl.php new file mode 100644 index 0000000..6216f9e --- /dev/null +++ b/admin/template/tag_preview.tpl.php @@ -0,0 +1,46 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    标签预览
    HTML调用代码
    调试信息
    JS调用代码
    为了系统安全,请创建一个名为 0.js 的空文件,上传到file/script目录,此JS调用代码方可生效
     
    [关闭窗口] 源代码
    +
    +
    + \ No newline at end of file diff --git a/admin/template/template.tpl.php b/admin/template/template.tpl.php new file mode 100644 index 0000000..9d34dcf --- /dev/null +++ b/admin/template/template.tpl.php @@ -0,0 +1,100 @@ + + + + + + + + + + + +$v) {?> + + + + + + + + + + + +$v) {?> + + + + + + + + + + +
      模板名称模板系列文件大小修改时间属性操作
      <目录><目录> +  + +
        Kb +  +  +  +
    + + + + + + + + + + + +$v) {?> + + + + + + + + + + +
      所属模板备份编号文件大小备份时间属性操作
       .htm  Kb +  +  +  +
    + +
    + +  + +  +".$v['name']."(".$v['dir'].")"; +} +$select = ''; +echo $select; +?> + +
    + + \ No newline at end of file diff --git a/admin/template/template_add.tpl.php b/admin/template/template_add.tpl.php new file mode 100644 index 0000000..2c7102b --- /dev/null +++ b/admin/template/template_add.tpl.php @@ -0,0 +1,48 @@ + +
    + + + + + + + + + + + + + + + + + + + +
    * 模板路径
    * 模板名称 可以为中文
    * 文件名.htm 只能为小写字母、数字、中划线、下划线
    + +
    +
    如果模板已经存在,请不要覆盖        
    +
    +
    + + + + +
    + + + \ No newline at end of file diff --git a/admin/template/template_edit.tpl.php b/admin/template/template_edit.tpl.php new file mode 100644 index 0000000..abf6c87 --- /dev/null +++ b/admin/template/template_edit.tpl.php @@ -0,0 +1,50 @@ + +
    + + + + + + + + + + + + + + + + + + + + +
    * 模板路径.htm
    * 模板名称 可以为中文
    * 文件名.htm 只能为小写字母、数字、中划线、下划线
    + +
    +
    保存时,创建一个备份文件         +
    +
    +
    + + + + +
    + + + \ No newline at end of file diff --git a/admin/template/type.tpl.php b/admin/template/type.tpl.php new file mode 100644 index 0000000..d3e3ee8 --- /dev/null +++ b/admin/template/type.tpl.php @@ -0,0 +1,48 @@ + +
    + + + + + + + + + + $v0) { ?> + + + + + + + + $v1) { ?> + + + + + + + + + + + + + + + + + + + +
    排序名称上级分类
    新增
         +     +     +
    +
    + \ No newline at end of file diff --git a/admin/template/upload.tpl.php b/admin/template/upload.tpl.php new file mode 100644 index 0000000..de19703 --- /dev/null +++ b/admin/template/upload.tpl.php @@ -0,0 +1,84 @@ + +
    + +
    +
    + + + + + + + + + + + + + + + + + +$v) {?> + + + + + + + + + + + + + + + +
    缩略图大小 宽度 高度 模块信息ID表名来源会员名上传时间
    + + + + + + + +
    +
    +   +   + +    未找到记录 + +
    +
    +'.$pages.'' : '';?> + + \ No newline at end of file diff --git a/admin/template/upload_part.tpl.php b/admin/template/upload_part.tpl.php new file mode 100644 index 0000000..633983f --- /dev/null +++ b/admin/template/upload_part.tpl.php @@ -0,0 +1,63 @@ + +
    +   +
    + + + + + + + +$v) {?> + + + + + + + +
    名称表名记录分表
    + +
    删除上传
    +
    + + + + + + + +
    会员名     删除会员的所有上传文件 +
    +
    + + + \ No newline at end of file diff --git a/admin/template/word.tpl.php b/admin/template/word.tpl.php new file mode 100644 index 0000000..de381f2 --- /dev/null +++ b/admin/template/word.tpl.php @@ -0,0 +1,154 @@ + + +
    保存成功
    + + + + + + + + + +
    * HTML代码 +
    +     +   +提示:复制代码之后,切换编辑器到源代码模式后粘贴即可 +
    +
    效果预览
    +
    + + +
    什么是编辑助手?
    + + + + +
    +      当您使用word制作了一篇图文并茂的文档,通过后台发布时,发现文档内容里的图片并不能直接粘贴到编辑器里。由于word的加密方式不公开,在不安装插件的情况下,常规的方法目前无法有效的解决此问题。于是一张一张的上传占用了您大量的宝贵时间……
    +      编辑助手可以通过以下三步帮您快速解决此问题:
    +      1、复制一份您的word文件,然后修改新的文件名为英文和数字格式(注意:中文的文件名可能无法被助手识别),例如“word.doc”;
    +      2、双击打开新的word文件,点击文件,选择另存为,保存类型选择“网页 (*.htm,*.html)”;
    +      3、假如您的word文件名为word.doc,通过另存后,会生成一个word.htm文件和一个word.files目录,选择这个文件和目录压缩为.zip格式文件,在下面上传;
    +      小提示:本工具同样可以处理您制作的或从网上另存的htm静态页面,原理是相同的。
    +
    + +
    上传zip压缩文件
    +
    + + + + + + + +
    * 选择文件   + +
    +
    + + + + + \ No newline at end of file diff --git a/admin/type.inc.php b/admin/type.inc.php new file mode 100644 index 0000000..359c62f --- /dev/null +++ b/admin/type.inc.php @@ -0,0 +1,30 @@ +item = $item; +$do->cache = 1; +$TYPE = $do->get_list(); +if($submit) { + $do->update($post); + dmsg('保存成功', $forward); +} else { + $types = $TYPE; + $parent_option = ''.$do->parent_option($TYPE); + $parent_select = ''; + foreach($types as $k=>$v) { + $types[$k]['style_select'] = dstyle('post['.$v['typeid'].'][style]', $v['style']); + $types[$k]['parent_select'] = ''; + } + $new_style = dstyle('post[0][style]'); + $lists = sort_type($types); + include tpl('type'); +} +?> \ No newline at end of file diff --git a/admin/unzip.class.php b/admin/unzip.class.php new file mode 100644 index 0000000..1a216de --- /dev/null +++ b/admin/unzip.class.php @@ -0,0 +1,244 @@ +check($zip_name)) continue; + if(zip_entry_filesize($zip_entry) > 0) { + if(zip_entry_open($zip, $zip_entry, "r")) { + $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); + file_put($dir.$zip_name, $buf); + zip_entry_close($zip_entry); + } + } else { + dir_create($dir.$zip_name); + } + } + zip_close($zip); + } + } else { + $array = $this->list_zip($zipfile); + $count = count($array); + $f = 0; + $d = 0; + for($i = 0; $i < $count; $i++) { + if($array[$i]['folder'] == 0) { + if($this->extract_file($zipfile, $dir, $i) > 0) $f++; + } else { + $d++; + } + } + } + return true; + } + + function list_zip($zip_name) { + $zip = @fopen($zip_name, 'rb'); + if(!$zip) return 0; + $centd = $this->rc_dir($zip, $zip_name); + @rewind($zip); + @fseek($zip, $centd['offset']); + $ret = array(); + for($i = 0; $i < $centd['entries']; $i++) { + $header = $this->rcf_header($zip); + if(!$this->check($header['filename'])) continue; + if(!$this->check($header['stored_filename'])) continue; + $header['index'] = $i; + $info['filename'] = $header['filename']; + $info['stored_filename'] = $header['stored_filename']; + $info['size'] = $header['size']; + $info['compressed_size'] = $header['compressed_size']; + $info['crc'] = strtoupper(dechex( $header['crc'])); + $info['mtime'] = $header['mtime']; + $info['comment'] = $header['comment']; + $info['folder'] = ($header['external'] == 0x41FF0010 || $header['external'] == 16) ? 1 : 0; + $info['index'] = $header['index']; + $info['status'] = $header['status']; + $ret[] = $info; + unset($header); + } + return $ret; + } + + function extract_file($zn, $to, $index = array(-1)) { + $ok = 0; + $zip = @fopen($zn,'rb'); + if(!$zip) return -1; + $cdir = $this->rc_dir($zip,$zn); + $pos_entry = $cdir['offset']; + if(!is_array($index)) $index = array($index); + for($i = 0; isset($index[$i]); $i++) { + if(intval($index[$i]) != $index[$i] || $index[$i] > $cdir['entries']) return -1; + } + for($i = 0; $i < $cdir['entries']; $i++) { + @fseek($zip, $pos_entry); + $header = $this->rcf_header($zip); + $header['index'] = $i; + $pos_entry = ftell($zip); + @rewind($zip); + fseek($zip, $header['offset']); + if(in_array("-1",$index) || in_array($i,$index)) $stat[$header['filename']] = $this->uncompress($header, $to, $zip); + + } + fclose($zip); + return $stat; + } + + function rf_header($zip) { + $binary_data = fread($zip, 30); + $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data); + $header['filename'] = fread($zip, $data['filename_len']); + $header['extra'] = $data['extra_len'] != 0 ? fread($zip, $data['extra_len']) : ''; + $header['compression'] = $data['compression']; + $header['size'] = $data['size']; + $header['compressed_size'] = $data['compressed_size']; + $header['crc'] = $data['crc']; + $header['flag'] = $data['flag']; + $header['mdate'] = $data['mdate']; + $header['mtime'] = $data['mtime']; + if($header['mdate'] && $header['mtime']) { + $hour = ($header['mtime'] & 0xF800) >> 11; + $minute = ($header['mtime'] & 0x07E0) >> 5; + $seconde = ($header['mtime'] & 0x001F)*2; + $year = (($header['mdate'] & 0xFE00) >> 9) + 1980; + $month = ($header['mdate'] & 0x01E0) >> 5; + $day = $header['mdate'] & 0x001F; + $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); + } else { + $header['mtime'] = time(); + } + $header['stored_filename'] = $header['filename']; + $header['status'] = "ok"; + return $header; + } + + function rcf_header($zip) { + $binary_data = fread($zip, 46); + $header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data); + $header['filename'] = $header['filename_len'] != 0 ? fread($zip,$header['filename_len']) : ''; + $header['extra'] = $header['extra_len'] != 0 ? fread($zip, $header['extra_len']) : ''; + $header['comment'] = $header['comment_len'] != 0 ? fread($zip, $header['comment_len']): ''; + if($header['mdate'] && $header['mtime']) { + $hour = ($header['mtime'] & 0xF800) >> 11; + $minute = ($header['mtime'] & 0x07E0) >> 5; + $seconde = ($header['mtime'] & 0x001F)*2; + $year = (($header['mdate'] & 0xFE00) >> 9) + 1980; + $month = ($header['mdate'] & 0x01E0) >> 5; + $day = $header['mdate'] & 0x001F; + $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); + } else { + $header['mtime'] = time(); + } + $header['stored_filename'] = $header['filename']; + $header['status'] = 'ok'; + if(substr($header['filename'], -1) == '/') $header['external'] = 0x41FF0010; + return $header; + } + + function rc_dir($zip, $zip_name) { + $size = filesize($zip_name); + $maximum_size = $size < 277 ? $size : 277; + @fseek($zip, $size - $maximum_size); + $pos = ftell($zip); + $bytes = 0x00000000; + while($pos < $size) { + $byte = @fread($zip, 1); + $bytes = ($bytes << 8) | Ord($byte); + $pos++; + if(substr(dechex($bytes), -8, 8) == '504b0506') break; + } + $data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', fread($zip, 18)); + $centd['comment'] = $data['comment_size'] != 0 ? fread($zip, $data['comment_size']) : ''; + $centd['entries'] = $data['entries']; + $centd['disk_entries'] = $data['disk_entries']; + $centd['offset'] = $data['offset']; + $centd['disk_start'] = $data['disk_start']; + $centd['size'] = $data['size']; + $centd['disk'] = $data['disk']; + return $centd; + } + + function uncompress($header, $to, $zip) { + $header = $this->rf_header($zip); + if(substr($to, -1) != "/") $to .= "/"; + if(!is_dir($to)) dir_create($to); + $pth = explode("/", dirname($header['filename'])); + $pthss = ''; + for($i = 0; isset($pth[$i]); $i++) { + if(!$pth[$i]) continue; + $pthss .= $pth[$i]."/"; + if(!is_dir($to.$pthss)) dir_create($to.$pthss); + } + isset($header['external']) or $header['external'] = ''; + if(!($header['external'] == 0x41FF0010) && !($header['external'] == 16)) { + if($header['compression'] == 0) { + $fp = @fopen($to.$header['filename'], 'wb'); + if(!$fp) return -1; + $size = $header['compressed_size']; + while($size != 0) { + $read_size = $size < 2048 ? $size : 2048; + $buffer = fread($zip, $read_size); + $binary_data = pack('a'.$read_size, $buffer); + @fwrite($fp, $binary_data, $read_size); + $size -= $read_size; + } + fclose($fp); + if(DT_CHMOD) @chmod($to.$header['filename'], DT_CHMOD); + touch($to.$header['filename'], $header['mtime']); + } else { + $fp = @fopen($to.$header['filename'].'.gz', 'wb'); + if(!$fp) return -1; + $binary_data = pack('va1a1Va1a1', 0x8b1f, chr($header['compression']), chr(0x00), time(), chr(0x00), chr(3)); + fwrite($fp, $binary_data, 10); + $size = $header['compressed_size']; + while($size != 0) { + $read_size = $size < 1024 ? $size : 1024; + $buffer = fread($zip, $read_size); + $binary_data = pack('a'.$read_size, $buffer); + @fwrite($fp, $binary_data, $read_size); + $size -= $read_size; + } + $binary_data = pack('VV', $header['crc'], $header['size']); + fwrite($fp, $binary_data, 8); + fclose($fp); + $gzp = @gzopen($to.$header['filename'].'.gz', 'rb') or die('Can Not gzopen File'); + if(!$gzp) return -2; + $fp = @fopen($to.$header['filename'], 'wb'); + if(!$fp) return -1; + $size = $header['size']; + while($size != 0) { + $read_size = $size < 2048 ? $size : 2048; + $buffer = gzread($gzp, $read_size); + $binary_data = pack('a'.$read_size, $buffer); + @fwrite($fp, $binary_data, $read_size); + $size -= $read_size; + } + fclose($fp); + gzclose($gzp); + if(DT_CHMOD) @chmod($to.$header['filename'], DT_CHMOD); + touch($to.$header['filename'], $header['mtime']); + @unlink($to.$header['filename'].'.gz'); + } + } + return true; + } + + function check($path) { + return strpos($path, '..') !== false ? false : true; + } +} +?> \ No newline at end of file diff --git a/admin/update.inc.php b/admin/update.inc.php new file mode 100644 index 0000000..baee1a5 --- /dev/null +++ b/admin/update.inc.php @@ -0,0 +1,120 @@ +extract_zip($release_dir.'/'.$release.'.zip', $release_dir.'/source/'); + if(is_file($release_dir.'/source/destoon/version.inc.php')) { + msg('更新解压缩成功,开始更新文件..', '?file='.$file.'&action=copy&release='.$release.'&releases='.$releases); + } else { + msg('更新解压缩失败,请重试..'); + } + break; + case 'copy': + if($CFG['template'] != 'default' && is_dir($release_dir.'/source/destoon/template/default')) @rename($release_dir.'/source/destoon/template/default', $release_dir.'/source/destoon/template/'.$CFG['template']); + if($CFG['skin'] != 'default' && is_dir($release_dir.'/source/destoon/skin/default')) @rename($release_dir.'/source/destoon/skin/default', $release_dir.'/source/destoon/skin/'.$CFG['skin']); + $files = file_list($release_dir.'/source/destoon'); + foreach($files as $v) { + $file_a = str_replace('file/update/'.$release.'/source/destoon/', '', $v); + $file_b = str_replace('source/destoon/', 'backup/', $v); + if(is_file($file_a)) file_copy($file_a, $file_b); + } + foreach($files as $v) { + $file_a = str_replace('file/update/'.$release.'/source/destoon/', '', $v); + file_copy($v, $file_a) or msg('因文件权限不可写,系统无法覆盖'.str_replace(DT_ROOT.'/', '', $file_a).'
    请通过FTP工具移动file/update/'.$release.'/source/destoon/目录内所有文件覆盖到站点根目录(Windows独立服务器可以直接复制->粘贴)
    Linux独立服务器执行\cp -rf '.DT_ROOT.'/file/update/'.$release.'/source/destoon/* '.DT_ROOT.'/'); + } + msg('文件更新成功,开始运行更新..', '?file='.$file.'&action=cmd&release='.$release.'&releases='.$releases); + break; + case 'cmd': + @include $release_dir.'/source/cmd.inc.php'; + $update = DT_CACHE.'/update-'.$release.'.php'; + if(is_file($update)) { + include $update; + file_del($update); + } + if($releases) { + $releases = str_replace($release.',', '', $releases); + $releases = str_replace($release, '', $releases); + $next = intval(cutstr($releases, '', ',')); + if($next > $release) msg($release.'更新运行成功,继续下个更新..', '?file='.$file.'&release='.$next.'&releases='.$releases); + } + msg('更新运行成功', '?file='.$file.'&action=finish&release='.$release); + break; + case 'backup': + $release > DT_RELEASE or msg('当前版本不需要备份', '?file=cloud&action=update'); + $data = dcloud('patch->pid='.$release); + if(strpos($data, 'version.inc.php') !== false) { + foreach(explode("\n", $data) as $fn) { + $fn = trim($fn); + if($fn) { + if(is_file(DT_ROOT.'/'.$fn)) file_copy(DT_ROOT.'/'.$fn, $release_dir.'/backup/'.$fn); + if($CFG['template'] != 'default' && strpos($fn, 'template/default') !== false) { + $ft = str_replace('template/default', 'template/'.$CFG['template'], $fn); + if(is_file(DT_ROOT.'/'.$ft)) file_copy(DT_ROOT.'/'.$ft, $release_dir.'/backup/'.$ft); + } + if($CFG['skin'] != 'default' && strpos($fn, 'skin/default') !== false) { + $fs = str_replace('skin/default', 'skin/'.$CFG['skin'], $fn); + if(is_file(DT_ROOT.'/'.$fs)) file_copy(DT_ROOT.'/'.$fs, $release_dir.'/backup/'.$fs); + } + } + } + } else { + msg($data ? $data : '无法连接官方云服务'); + } + if($releases) { + $releases = str_replace($release.',', '', $releases); + $releases = str_replace($release, '', $releases); + $next = intval(cutstr($releases, '', ',')); + if($next > $release) msg($release.'备份成功,继续下个更新..', '?file='.$file.'&action=backup&release='.$next.'&releases='.$releases); + } + msg('更新文件备份成功,存于file/update', '?file=cloud&action=update'); + break; + case 'finish': + msg('系统更新成功 当前版本V'.DT_VERSION.' R'.DT_RELEASE, '?file=cloud&action=update', 3); + break; + case 'undo': + is_file($release_dir.'/backup/version.inc.php') or msg('此版本备份文件不存在,无法还原'); + @include $release_dir.'/source/cmd.inc.php'; + $files = file_list($release_dir.'/backup'); + foreach($files as $v) { + file_copy($v, str_replace('file/update/'.$release.'/backup/', '', $v)); + } + msg('系统还原成功', '?file=cloud&action=update'); + break; + default: + $release > DT_RELEASE or msg('当前版本不需要运行此更新', '?file=cloud&action=update'); + msg('在线更新已经启动,开始下载更新..', '?file='.$file.'&action=download&release='.$release.'&releases='.$releases); + break; +} +?> \ No newline at end of file diff --git a/admin/upload.inc.php b/admin/upload.inc.php new file mode 100644 index 0000000..fe56528 --- /dev/null +++ b/admin/upload.inc.php @@ -0,0 +1,180 @@ + -1 && $id < 10) or $id = -1; +if($id == -1 && $action != 'part' && $action != 'delete_user' && $action != 'find') $action = 'part'; +if($id > -1) $table = $DT_PRE.'upload_'.$id; +switch($action) { + case 'delete': + $itemid or msg('请选择记录'); + $itemids = is_array($itemid) ? implode(',', $itemid) : $itemid; + $result = $db->query("SELECT fileurl FROM {$table} WHERE pid IN ($itemids)"); + while($r = $db->fetch_array($result)) { + delete_upload($r['fileurl'], 0); + } + $db->query("DELETE FROM {$table} WHERE pid IN ($itemids)"); + if(isset($ajax)) { + exit('1'); + } else { + dmsg('删除成功', $forward); + } + break; + case 'delete_record': + $itemid or msg('请选择记录'); + $itemids = is_array($itemid) ? implode(',', $itemid) : $itemid; + $db->query("DELETE FROM {$table} WHERE pid IN ($itemids)"); + dmsg('删除成功', $forward); + break; + case 'delete_user': + check_name($username) or msg('请填写会员名'); + $u = $db->get_one("SELECT userid,groupid FROM {$DT_PRE}member WHERE username='$username'"); + if($u && $u['groupid'] == 1) msg('管理组不可删除'); + if($id > -1) { + if(!isset($fid)) { + $r = $db->get_one("SELECT min(pid) AS fid FROM {$table} WHERE username='$username'"); + $fid = $r['fid'] ? $r['fid'] : 0; + } + if(!isset($tid)) { + $r = $db->get_one("SELECT max(pid) AS tid FROM {$table} WHERE username='$username'"); + $tid = $r['tid'] ? $r['tid'] : 0; + } + isset($num) or $num = 2; + isset($sid) or $sid = $fid; + isset($itemid) or $itemid = 1; + if($fid <= $tid) { + $result = $db->query("SELECT * FROM {$table} WHERE pid>=$fid AND username='$username' ORDER BY pid LIMIT 0,$num "); + if($db->affected_rows($result)) { + while($r = $db->fetch_array($result)) { + $itemid = $r['pid']; + delete_upload($r['fileurl'], 0); + } + $itemid += 1; + } else { + $itemid = $fid + $num; + } + msg('ID从'.$fid.'至'.($itemid-1).'删除成功'.progress($sid, $fid, $tid), "?file=$file&action=$action&username=$username&id=$id&sid=$sid&fid=$itemid&tid=$tid&num=$num"); + } else { + dmsg('删除成功', "?file=$file"); + } + } else { + if($u) { + $id = $u['userid']%10; + } else { + for($i = 0; $i < 10; $i++) { + $t = $db->get_one("SELECT itemid FROM {$DT_PRE}upload_{$i} WHERE username='$username'"); + if($t) { + $id = $i; + break; + } + } + if($id == -1) msg('会员['.$username.']没有上传记录'); + } + msg('正在开始删除..', "?file=$file&action=$action&username=$username&id=$id"); + } + break; + case 'part': + $lists = array(); + for($i = 0; $i < 10; $i++) { + $r = array(); + $r['table'] = $DT_PRE.'upload_'.$i; + $t = $db->get_one("SHOW TABLE STATUS FROM `".$CFG['db_name']."` LIKE '".$r['table']."'"); + $r['rows'] = $t['Rows']; + $r['name'] = $t['Comment']; + $lists[] = $r; + } + include tpl('upload_part'); + break; + case 'play': + isset($video) or exit; + include tpl('header'); + load('player.js'); + exit(''); + break; + case 'find': + if(check_name($url)) { + $user = userinfo($url); + $user or msg('会员不存在'); + dheader('?file='.$file.'&id='.($user['userid']%10).'&fields=2&kw='.$url); + } else { + is_url($url) or msg('网址错误'); + $t = parse_url($url); + $kw = $t['path']; + if(strpos($url, '/file/upload/') !== false) $kw = str_replace('/file/upload/', '', $kw); + dheader('?file='.$file.'&id='.(match_userid($url)%10).'&kw='.$kw); + } + break; + default: + $sfields = array('按条件', '文件名', '会员', '来源', '后缀', '信息ID', '表名'); + $dfields = array('fileurl', 'fileurl', 'username', 'upfrom', 'fileext', 'itemid', 'tb'); + isset($fields) && isset($dfields[$fields]) or $fields = 0; + $sorder = array('排序方式', '上传时间降序', '上传时间升序', '文件大小降序', '文件大小升序', '图片宽度降序', '图片宽度升序', '图片高度降序', '图片高度升序'); + $dorder = array('pid DESC', 'addtime DESC', 'addtime ASC', 'filesize DESC', 'filesize ASC', 'width DESC', 'width ASC', 'height DESC', 'height ASC'); + isset($order) && isset($dorder[$order]) or $order = 0; + + (isset($username) && check_name($username)) or $username = ''; + $thumb = isset($thumb) ? intval($thumb) : 0; + $width = isset($width) ? intval($width) : 0; + $height = isset($height) ? intval($height) : 0; + $filesize = isset($filesize) ? intval($filesize) : 0; + $upfrom = isset($upfrom) ? $upfrom : ''; + $tb = isset($tb) ? $tb : ''; + (isset($fromdate) && is_time($fromdate)) or $fromdate = ''; + $fromtime = $fromdate ? datetotime($fromdate) : 0; + (isset($todate) && is_time($todate)) or $todate = ''; + $totime = $todate ? datetotime($todate) : 0; + $itemid or $itemid = ''; + + $fields_select = dselect($sfields, 'fields', '', $fields); + $order_select = dselect($sorder, 'order', '', $order); + + $condition = '1'; + if($keyword) $condition .= $fields < 2 ? match_kw($dfields[$fields], $keyword) : " AND $dfields[$fields]='$keyword'"; + if($fromtime) $condition .= " AND addtime>=$fromtime"; + if($totime) $condition .= " AND addtime<=$totime"; + if($mid) $condition .= " AND moduleid='$mid'"; + if($itemid) $condition .= " AND itemid='$itemid'"; + if($username) $condition .= " AND username='$username'"; + if($upfrom) $condition .= " AND upfrom='$upfrom'"; + if($tb) $condition .= " AND tb='$tb'"; + if($thumb) $condition .= " AND width>0"; + if($width) $condition .= " AND width=$width"; + if($height) $condition .= " AND height=$height"; + if($filesize) $condition .= " AND filesize=$filesize"; + + if($page > 1 && $sum) { + $items = $sum; + } else { + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$table} WHERE $condition"); + $items = $r['num']; + } + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$table} WHERE $condition ORDER BY $dorder[$order] LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['ext'] = file_ext($r['fileurl']); + is_file(DT_ROOT.'/file/ext/'.$r['ext'].'.gif') or $r['ext'] = 'oth'; + if($r['filesize'] > 1024*1024*1024) { + $r['size'] = dround($r['filesize']/1024/1024/1024, 2).'G'; + } else if($r['filesize'] > 1024*1024) { + $r['size'] = dround($r['filesize']/1024/1024, 2).'M'; + } else { + $r['size'] = dround($r['filesize']/1024, 2).'K'; + } + $r['addtime'] = timetodate($r['addtime'], 6); + $r['image'] = is_image($r['fileurl']) ? 1 : 0; + $r['video'] = in_array($r['ext'], array('swf', 'flv', 'mp4')) ? 1 : 0; + $r['fileurl'] = str_replace('.thumb.'.$r['ext'], '', $r['fileurl']); + $r['img_w'] = $r['width'] > 100 ? 100 : $r['width']; + $lists[] = $r; + } + include tpl('upload'); + break; +} +?> \ No newline at end of file diff --git a/admin/word.inc.php b/admin/word.inc.php new file mode 100644 index 0000000..e83e645 --- /dev/null +++ b/admin/word.inc.php @@ -0,0 +1,110 @@ +adduserid = false; + if($upload->save()) { + dir_create(DT_ROOT.'/file/temp/'.$name); + require DT_ROOT.'/admin/unzip.class.php'; + $zip = new unzip; + $zip->extract_zip(DT_ROOT.'/file/temp/'.$name.'.zip', DT_ROOT.'/file/temp/'.$name.'/'); + file_del(DT_ROOT.'/file/temp/'.$name.'.zip'); + $F = get_file(DT_ROOT.'/file/temp/'.$name); + if($F) { + $htm = ''; + $max = 0; + foreach($F as $f) { + $ext = file_ext($f); + if(in_array($ext, array('htm', 'html'))) { + $tmp = filesize($f); + if($tmp > $max) $htm = str_replace(DT_ROOT.'/file/temp/', '', $f); + $max = $tmp; + } else { + in_array($ext, array('jpg', 'jpeg', 'gif', 'png', 'bmp')) or file_del($f); + } + } + if($htm) { + dalert('', '', 'parent.Upsuccess("'.$htm.'");'); + } else { + dalert('系统未在压缩包内找到HTM文件'); + } + } else { + dalert('解压缩失败,请检查目录权限'); + } + } else { + dalert($upload->errmsg); + } + break; + case 'read': + if($word && in_array(file_ext($word), array('htm', 'html'))) { + $data = file_get(DT_ROOT.'/file/temp/'.$word); + if($data) { + if($charset) $data = convert($data, $charset, DT_CHARSET); + if(preg_match("/]*>([\s\S]+)<\/body>/i", $data, $m)) $data = trim($m[1]); + $data = str_replace('', '', $data); + $data = str_replace('', '', $data); + $data = str_replace('', '', $data); + $data = str_replace('', '', $data); + $data = preg_replace("/ v:shapes=\"[^\"]*\">/i", ">", $data); + if($wd_class) { + $data = preg_replace("/[\s]?class=[\'|\"]?[^>]*[\'|\"]?/i", '', $data); + } + if($wd_style) { + $data = preg_replace("/[\s]?style=[\'|\"]?[^>]*[\'|\"]?/i", '', $data); + } + if($wd_span) { + $data = preg_replace("/]*>/i", "", $data); + $data = preg_replace("/<\/span>/i", "", $data); + } + if($wd_note) { + $data = preg_replace("//isU", '', $data); + } + if($wd_nr) { + $data = str_replace('

    ', '', $data); + $data = str_replace('

    ', '', $data); + $data = str_replace('

     

    ', '', $data); + $data = str_replace('

     

    ', '', $data); + $data = preg_replace('/($\s*$)|(^\s*^)/m', '', $data); + } + exit($data); + } + } + exit(''); + break; + case 'run': + $code = stripslashes($code); + $base = DT_PATH.'file/temp/'.dirname($temp).'/'; + $code = str_replace('src="', 'src="'.$base, $code); + echo ''; + echo ''; + echo ''; + echo $code; + echo ''; + echo ''; + break; + default: + if($submit) { + if(!isset($water)) $DT['water_type'] = 0; + $content = stripslashes($content); + $dir = dirname($word); + $base = DT_PATH.'file/temp/'.$dir.'/'; + $content = str_replace('src="', 'src="'.$base, $content); + $content = save_remote($content, 'jpg|jpeg|gif|png', 1); + $tmp = explode('/', $dir); + dir_delete(DT_ROOT.'/file/temp/'.$tmp[0]); + } + include tpl('word'); + break; +} +?> \ No newline at end of file diff --git a/api/403.php b/api/403.php new file mode 100644 index 0000000..da57e67 --- /dev/null +++ b/api/403.php @@ -0,0 +1,3 @@ +

    Forbidden

    +

    +You don't have permission to access this page on this server. \ No newline at end of file diff --git a/api/404.php b/api/404.php new file mode 100644 index 0000000..66942c8 --- /dev/null +++ b/api/404.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/api/503.php b/api/503.php new file mode 100644 index 0000000..e244bbe --- /dev/null +++ b/api/503.php @@ -0,0 +1,3 @@ +

    Service Unavailable

    +

    +Ths server is busy now, please try again later. \ No newline at end of file diff --git a/api/address.php b/api/address.php new file mode 100644 index 0000000..8311919 --- /dev/null +++ b/api/address.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/ajax.php b/api/ajax.php new file mode 100644 index 0000000..2f5f7a1 --- /dev/null +++ b/api/ajax.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/api/ajax/area.inc.php b/api/ajax/area.inc.php new file mode 100644 index 0000000..6291226 --- /dev/null +++ b/api/ajax/area.inc.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/api/ajax/captcha.inc.php b/api/ajax/captcha.inc.php new file mode 100644 index 0000000..92ec7d8 --- /dev/null +++ b/api/ajax/captcha.inc.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/api/ajax/catalog.inc.php b/api/ajax/catalog.inc.php new file mode 100644 index 0000000..4793dbd --- /dev/null +++ b/api/ajax/catalog.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/ajax/category.inc.php b/api/ajax/category.inc.php new file mode 100644 index 0000000..9579599 --- /dev/null +++ b/api/ajax/category.inc.php @@ -0,0 +1,28 @@ +query("SELECT arrchildid FROM {$DT_PRE}category WHERE catid IN (".implode(',', $_catids).")"); + while($r = $db->fetch_array($result)) { + $_childs .= ','.$r['arrchildid']; + } + if($_childs) { + $_childs = substr($_childs, 1); + $_child = explode(',', $_childs); + } + } + } +} +echo get_category_select($category_title, $catid, $category_moduleid, $category_extend, $category_deep, $cat_id); +?> \ No newline at end of file diff --git a/api/ajax/choose.inc.php b/api/ajax/choose.inc.php new file mode 100644 index 0000000..3ab45e5 --- /dev/null +++ b/api/ajax/choose.inc.php @@ -0,0 +1,132 @@ + 3 or dheader('DT_PATH'); + $from or $from = 'item'; + isset($username) or $username = ''; + $itemid or $itemid = ''; + $condition = $mid == 4 ? 'groupid>5' : 'status=3'; + if($keyword) $condition .= match_kw('keyword', $keyword); + if($from == 'relate' && $MODULE[$mid]['module'] == 'mall') { + check_name($username) or exit; + $condition .= " AND username='$username'"; + } else { + if($_groupid == 1) { + if($from == 'member') $condition .= " AND username='$_username'"; + } else { + $condition .= " AND username='$_username'"; + } + } + if($itemid) $condition .= $mid == 4 ? " AND userid=$itemid" : " AND itemid=$itemid"; + $order = $mid == 4 ? 'userid DESC' : 'addtime DESC'; + $table = get_table($mid); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$table} WHERE $condition"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$table} WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + if($mid == 4) { + $r['itemid'] = $r['userid']; + $r['alt'] = $r['title'] = $r['company']; + $r['adddate'] = $r['editdate'] = timetodate(0, 5); + $r['level'] = 0; + $r['style'] = ''; + } else { + $r['adddate'] = timetodate($r['addtime'], 5); + $r['editdate'] = timetodate($r['edittime'], 5); + $r['alt'] = $r['title']; + $r['title'] = set_style($r['title'], $r['style']); + if(strpos($r['linkurl'], '://') === false) $r['linkurl'] = $MODULE[$mid]['linkurl'].$r['linkurl']; + } + $lists[] = $r; + } + $head_title = '选择信息'; +} else if($job == 'stock') { + (isset($skuid) && is_skuid($skuid)) or $skuid = ''; + isset($key) or $key = ''; + if($key == 'content' && $itemid) { + $t = $db->get_one("SELECT username FROM {$DT_PRE}stock WHERE itemid=$itemid"); + if(!$t || $t['username'] != $_username) exit(''); + $t = $db->get_one("SELECT content FROM {$DT_PRE}stock_data WHERE itemid=$itemid"); + exit($t ? $t['content'] : ''); + } + $condition = "username='$_username'"; + if($keyword) $condition .= match_kw('keyword', $keyword); + if($skuid) $condition .= " AND skuid='$skuid'"; + $order = 'addtime DESC'; + $table = $DT_PRE.'stock'; + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$table} WHERE $condition"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$table} WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['adddate'] = timetodate($r['addtime'], 6); + $r['editdate'] = timetodate($r['edittime'], 6); + $r['profit'] = dround($r['price'] - $r['cost'], 2, 1); + $r['alt'] = $r['title']; + $r['title'] = set_style($r['title'], $r['style']); + $lists[] = $r; + } + $head_title = '选择商品'; +} else { + if($DT['uploadlog']) { + $table = $DT_PRE.'upload_'.($_userid%10); + $condition = "username='$_username' AND width>90"; + $condition .= $from == 'album' ? " AND (upfrom='album' OR upfrom='photo')" : " AND upfrom<>'thumb'"; + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$table} WHERE {$condition}"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$table} WHERE {$condition} ORDER BY pid DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['introduce'] = timetodate($r['addtime'], 6).' '.$r['width'].'px * '.$r['height'].'px '; + $r['ext'] = file_ext($r['fileurl']); + $r['thumb'] = $r['fileurl']; + $r['middle'] = str_replace('.thumb.'.$r['ext'], '.middle.'.$r['ext'], $r['thumb']); + $r['large'] = str_replace('.thumb.'.$r['ext'], '', $r['thumb']); + $lists[] = $r; + } + } else { + foreach($MODULE as $M) { + if($M['module'] == 'photo') { + $mid = $M['moduleid']; + break; + } + } + $mid or message('系统未开启图库功能'); + $fid = isset($fid) ? trim($fid) : ''; + if($itemid) { + $item = $db->get_one("SELECT username,title FROM {$DT_PRE}photo_{$mid} WHERE itemid=$itemid"); + if(!$item || ($item['username'] != $_username && $_groupid > 1)) dheader(DT_PATH); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}photo_item_{$mid} WHERE item=$itemid"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}photo_item_{$mid} WHERE item=$itemid ORDER BY listorder ASC,itemid ASC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['ext'] = file_ext($r['thumb']); + $r['middle'] = str_replace('.thumb.'.$r['ext'], '.middle.'.$r['ext'], $r['thumb']); + $r['large'] = str_replace('.thumb.'.$r['ext'], '', $r['thumb']); + $lists[] = $r; + } + } else { + $condition = "status=3 AND items>0 AND username='$_username'"; + if($keyword) $condition .= match_kw('keyword', $keyword); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}photo_{$mid} WHERE $condition"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}photo_{$mid} WHERE $condition ORDER BY addtime LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $lists[] = $r; + } + } + } + $head_title = '选择图片'; +} +include template('choose', 'member'); +?> \ No newline at end of file diff --git a/api/ajax/city.inc.php b/api/ajax/city.inc.php new file mode 100644 index 0000000..556264b --- /dev/null +++ b/api/ajax/city.inc.php @@ -0,0 +1,10 @@ +query("SELECT areaid,name,style,domain,letter FROM {$DT_PRE}city ORDER BY letter,listorder"); +while($r = $db->fetch_array($result)) { + $r['linkurl'] = $r['domain'] ? $r['domain'] : DT_PATH.'api/'.rewrite('city.php?areaid='.$r['areaid']); + $lists[strtoupper($r['letter'])][] = $r; +} +include template('city', 'chip'); +?> \ No newline at end of file diff --git a/api/ajax/ckpath.inc.php b/api/ajax/ckpath.inc.php new file mode 100644 index 0000000..43165f1 --- /dev/null +++ b/api/ajax/ckpath.inc.php @@ -0,0 +1,16 @@ +get_one("SELECT itemid FROM {$table} WHERE $sql")) { + exit(lang('message->ajax_filepath_exists')); + } else { + exit(lang('message->ajax_filepath_not_exists')); + } +} +?> \ No newline at end of file diff --git a/api/ajax/clear.inc.php b/api/ajax/clear.inc.php new file mode 100644 index 0000000..27d5cc6 --- /dev/null +++ b/api/ajax/clear.inc.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/api/ajax/express.inc.php b/api/ajax/express.inc.php new file mode 100644 index 0000000..846e729 --- /dev/null +++ b/api/ajax/express.inc.php @@ -0,0 +1,46 @@ + 2 or exit; +preg_match("/^[a-z0-9_\-]{6,}$/i", $no) or exit; +$status = intval($status); +$itemid = intval($itemid); +is_mobile($mobile) or $mobile = ''; +$htm = ''; +$_status = 0; +$_com = str_replace(array('快递', '速递', '快运', '物流'), array('', '', '', ''), $com); +if($DT['cloud_express'] && DT_CLOUD_UID && DT_CLOUD_KEY) { + $cache = 0; + $cid = DT_ROOT.'/file/cloud/express/'.urlencode($_com).'/'.substr($no, 0, 3).'/'.substr($no, -3).'/'.$no.'.php'; + if(is_file($cid)) { + $rec = substr(file_get($cid), 13); + $cache = 1; + } else { + $rec = dcloud('express->com='.$_com.'&no='.$no.'&mobile='.$mobile); + } + $arr = json_decode($rec, true); + if($arr['error']) { + $htm .= '
    '.$arr['error'].'
    '; + } else { + $_status = intval($arr['status']); + if($_status > 2 && $cache == 0) file_put($cid, ''.$rec); + if($arr['data']) { + foreach($arr['data'] as $k=>$v) { + $htm .= '['.$v['time'].']  '.$v['context'].''; + } + } + } + if($htm && $arr['name'] && $arr['url']) $htm .= '
    - 以上数据由'.($arr['url'] ? '' : '').$arr['name'].($arr['url'] ? '' : '').'提供,如有疑问请到快递公司官网查询
    '; +} +if($status < $_status) { + if($from == 'mall') { + $db->query("UPDATE {$DT_PRE}order SET send_status=$_status WHERE itemid=$itemid"); + } else if($from == 'group') { + if($mid && $MODULE[$mid]['module'] == $from) $db->query("UPDATE {$DT_PRE}{$from}_order_{$mid} SET send_status=$_status WHERE itemid=$itemid"); + } +} +echo $htm ? $htm : '未查询到快递信息,请重新查询 或 到快递公司官网查询'; +?> \ No newline at end of file diff --git a/api/ajax/favorite.inc.php b/api/ajax/favorite.inc.php new file mode 100644 index 0000000..1691fdb --- /dev/null +++ b/api/ajax/favorite.inc.php @@ -0,0 +1,41 @@ + 3 && $itemid > 0) { + $table = get_table($mid); + if($table) { + $f = $db->get_one("SELECT itemid FROM {$DT_PRE}favorite WHERE userid=$_userid AND mid=$mid AND tid=$itemid"); + if($f) exit('ok'); + $id = $mid == 4 ? 'userid' : 'itemid'; + $t = $db->get_one("SELECT * FROM {$table} WHERE `{$id}`=$itemid"); + if($t) { + $post = array(); + if($mid == 4) { + if($t['groupid'] > 5) { + $post['title'] = $t['company']; + $post['url'] = $t['linkurl']; + } + } else { + if($t['status'] > 2) { + $post['title'] = $t['title']; + $post['url'] = strpos($t['linkurl'], '://') === false ? $MODULE[$mid]['linkurl'].$t['linkurl'] : $t['linkurl']; + } + } + if($post) { + require DT_ROOT.'/module/member/favorite.class.php'; + $do = new favorite(); + if(isset($t['thumb']) && is_url($t['thumb'])) $post['thumb'] = $t['thumb']; + $post['userid'] = $_userid; + $post['addtime'] = $DT_TIME; + $post['mid'] = $mid; + $post['tid'] = $itemid; + $post = daddslashes($post); + $do->add($post); + exit('ok'); + } + } + } +} +exit('收藏失败'); +?> \ No newline at end of file diff --git a/api/ajax/index.html b/api/ajax/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/ajax/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/ajax/ipage.inc.php b/api/ajax/ipage.inc.php new file mode 100644 index 0000000..985658d --- /dev/null +++ b/api/ajax/ipage.inc.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/api/ajax/keyword.inc.php b/api/ajax/keyword.inc.php new file mode 100644 index 0000000..8d70601 --- /dev/null +++ b/api/ajax/keyword.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/ajax/letter.inc.php b/api/ajax/letter.inc.php new file mode 100644 index 0000000..09fd761 --- /dev/null +++ b/api/ajax/letter.inc.php @@ -0,0 +1,12 @@ +query("SELECT * FROM {$DT_PRE}category WHERE moduleid=$moduleid AND letter='$letter' ORDER BY listorder,catid ASC"); +while($r = $db->fetch_array($result)) { + $CATALOG[] = $r; +} +include template('letter', 'chip'); +?> \ No newline at end of file diff --git a/api/ajax/like.inc.php b/api/ajax/like.inc.php new file mode 100644 index 0000000..7427ebc --- /dev/null +++ b/api/ajax/like.inc.php @@ -0,0 +1,39 @@ + 2) { + if($rid) { + $itemid = 0; + if($mid == 3) { + $table = $DT_PRE.'comment'; + } else if($MODULE[$mid]['module'] == 'know') { + $table = $DT_PRE.'know_answer_'.$mid; + } else if($MODULE[$mid]['module'] == 'club') { + $table = $DT_PRE.'club_reply_'.$mid; + } + $id = $rid; + } else { + $table = get_table($mid); + $id = $itemid; + } + $fd = $mid == 4 ? 'userid' : 'itemid'; + if($table) { + $tid = $itemid; + $kid = $_userid.'-'.$mid.'-'.$tid.'-'.$rid; + $t = $db->get_one("SELECT itemid FROM {$DT_PRE}like_record WHERE kid='$kid'"); + if($t) exit('已表过态'); + $hate = $job == 'hate' ? 1 : 0; + $db->query("INSERT INTO {$DT_PRE}like_record (kid,mid,tid,rid,hate,username,addtime) VALUES ('$kid','$mid','$tid','$rid','$hate','$_username','$DT_TIME')"); + if($job == 'hate') { + DB::query("UPDATE {$table} SET hates=hates+1 WHERE `{$fd}`=$id"); + exit('ok'); + } else { + DB::query("UPDATE {$table} SET likes=likes+1 WHERE `{$fd}`=$id"); + exit('ok'); + } + } +} +exit('参数错误'); +?> \ No newline at end of file diff --git a/api/ajax/mall.inc.php b/api/ajax/mall.inc.php new file mode 100644 index 0000000..db04574 --- /dev/null +++ b/api/ajax/mall.inc.php @@ -0,0 +1,57 @@ +0"; + if($thumb) $condition .= " AND seller_thumbs<>''"; + if($video) $condition .= " AND seller_video<>''"; + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}mall_comment_{$moduleid} WHERE $condition"); + $items = $r['num']; + if($sum && $items != $sum && $condition == "mallid=$itemid AND seller_star>0") $db->query("UPDATE {$DT_PRE}mall_{$moduleid} SET comments=$items WHERE itemid=$itemid"); + $pages = $DT_PC ? pages($items, $page, $pagesize, '#comment" onclick="javascript:comment_load(\'{destoon_page}&star='.$star.'&thumb='.$thumb.'&video='.$video.'\');') : mobile_pages($items, $page, $pagesize, '#comment" onclick="javascript:comment_load(\'{destoon_page}&star='.$star.'&thumb='.$thumb.'&video='.$video.'\');'); + $tmp = explode('query("SELECT * FROM {$DT_PRE}mall_comment_{$moduleid} WHERE $condition ORDER BY seller_ctime DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['thumbs'] = $r['seller_thumbs'] ? explode('|', $r['seller_thumbs']) : array(); + $r['video'] = $r['seller_video'] ? $r['seller_video'] : ''; + $r['addtime'] = timetodate($r['seller_ctime'], 6); + $r['replytime'] = $r['buyer_ctime'] ? timetodate($r['buyer_ctime'], 6) : ''; + $lists[] = $r; + } + $stat = $r = $db->get_one("SELECT * FROM {$DT_PRE}mall_stat_{$moduleid} WHERE mallid=$itemid"); + if($stat && $stat['scomment']) { + $stat['pc1'] = dround($stat['s1']*100/$stat['scomment'], 2, true).'%'; + $stat['pc2'] = dround($stat['s2']*100/$stat['scomment'], 2, true).'%'; + $stat['pc3'] = dround($stat['s3']*100/$stat['scomment'], 2, true).'%'; + $stat['pc4'] = dround($stat['s4']*100/$stat['scomment'], 2, true).'%'; + $stat['pc5'] = dround($stat['s5']*100/$stat['scomment'], 2, true).'%'; + } else { + $stat['s1'] = $stat['s2'] = $stat['s3'] = $stat['s4'] = $stat['s5'] = 0; + $stat['pc1'] = $stat['pc2'] = $stat['pc3'] = $stat['pc4'] = $stat['pc5'] = '0%'; + } + include template('comment', $module); +} else if($job == 'cart') { + $_userid or exit('-5'); + $itemid or exit('-1'); + require DT_ROOT.'/module/member/cart.class.php'; + $do = new cart(); + $cart = $do->get(); + $max_cart = $MOD['max_cart']; + $s1 = isset($s1) ? intval($s1) : 0; + $s2 = isset($s2) ? intval($s2) : 0; + $s3 = isset($s3) ? intval($s3) : 0; + $a = isset($a) ? intval($a) : 1; + echo $do->add($cart, $moduleid, $itemid, $s1, $s2, $s3, $a); +} +?> \ No newline at end of file diff --git a/api/ajax/member.inc.php b/api/ajax/member.inc.php new file mode 100644 index 0000000..c669332 --- /dev/null +++ b/api/ajax/member.inc.php @@ -0,0 +1,49 @@ +userid = $userid; +switch($job) { + case 'username': + if(!$value) exit($L['member_username_match']); + if(!$do->is_username($value)) exit($do->errmsg); + break; + case 'passport': + if(!$value) exit; + if($_userid) $do->userid = $_userid; + if(!$do->is_passport($value)) exit($do->errmsg); + break; + case 'password': + if(!$do->is_password($value, $value)) exit($do->errmsg); + break; + case 'payword': + if(!$do->is_payword($value, $value)) exit($do->errmsg); + break; + case 'email': + $value = trim($value); + if(!$do->is_email($value)) exit($do->errmsg); + if($do->email_exists($value)) exit($L['member_email_reg']); + break; + case 'mobile': + $value = trim($value); + if(!is_mobile($value)) exit($L['member_mobile_null']); + if($do->mobile_exists($value)) exit($L['member_mobile_reg']); + break; + case 'company': + if(!$value) exit($L['member_company_null']); + if(!$do->is_company($value)) exit($do->errmsg); + if($do->company_exists($value)) exit($L['member_company_reg']); + break; + case 'get_company': + $user = $do->get_one($value); + if($user) { + echo ''.$user['company'].''.( $user['vip'] ? ' ' : ''); + } else { + echo '1'; + } + exit; + break; +} +?> \ No newline at end of file diff --git a/api/ajax/mobile.inc.php b/api/ajax/mobile.inc.php new file mode 100644 index 0000000..8f4b4c7 --- /dev/null +++ b/api/ajax/mobile.inc.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/api/ajax/page.inc.php b/api/ajax/page.inc.php new file mode 100644 index 0000000..9c162ae --- /dev/null +++ b/api/ajax/page.inc.php @@ -0,0 +1,10 @@ +0 and thumb<>''&areaid=$cityid&pagesize=".$DT['page_sell']."&order=addtime desc&width=100&height=100&cols=5&target=_blank&template=thumb-table&page=$page"); +} else if($job == 'imall') { + tag("moduleid=16&length=14&condition=status=3&areaid=$cityid&pagesize=".$DT['page_mall']."&order=orders desc&width=100&height=100&cols=5&target=_blank&template=thumb-mall&page=$page"); +} else { + // +} +?> \ No newline at end of file diff --git a/api/ajax/property.inc.php b/api/ajax/property.inc.php new file mode 100644 index 0000000..096288e --- /dev/null +++ b/api/ajax/property.inc.php @@ -0,0 +1,30 @@ +'; +$html = ''; +foreach($options as $k=>$v) { + isset($values[$v['oid']]) or $values[$v['oid']] = ''; + if($DT_PC) { + if($v['required']) { + $star = '* '; + } else { + $star = $admin ? '* ' : ''; + } + $html .= ''.$star.$v['name'].''.property_html($values[$v['oid']], $v['oid'], $v['type'], $v['value'], $v['extend']).''; + } else { + $html .= '

    '.$v['name']; + if($v['required']) $html .= '*'; + $html .= '

    '.property_html($values[$v['oid']], $v['oid'], $v['type'], $v['value'], $v['extend']).'
    '; + } + $select .= $v['required'] ? '' : ''; +} +$select .= ''; +echo $DT_PC ? substr($html, 0, -10).$select.'' : substr($html, 0, -6).$select.''; +?> \ No newline at end of file diff --git a/api/ajax/proxy.inc.php b/api/ajax/proxy.inc.php new file mode 100644 index 0000000..af69ff0 --- /dev/null +++ b/api/ajax/proxy.inc.php @@ -0,0 +1,66 @@ + + \ No newline at end of file diff --git a/api/ajax/question.inc.php b/api/ajax/question.inc.php new file mode 100644 index 0000000..f4c034c --- /dev/null +++ b/api/ajax/question.inc.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/api/ajax/reccate.inc.php b/api/ajax/reccate.inc.php new file mode 100644 index 0000000..3909c56 --- /dev/null +++ b/api/ajax/reccate.inc.php @@ -0,0 +1,13 @@ + 30) exit; +$limit = $DT['schcate_limit'] ? intval($DT['schcate_limit']) : 10; +$table = get_table($moduleid); +$html = ''; +$result = $db->query("SELECT DISTINCT catid FROM {$table} WHERE `keyword` LIKE '%$name%' ORDER BY addtime DESC LIMIT $limit"); +while($r = $db->fetch_array($result)) { + $html .= '
    '; +} +echo $html; +?> \ No newline at end of file diff --git a/api/ajax/schcate.inc.php b/api/ajax/schcate.inc.php new file mode 100644 index 0000000..8d6ffbc --- /dev/null +++ b/api/ajax/schcate.inc.php @@ -0,0 +1,12 @@ + 30) exit; +$limit = $DT['schcate_limit'] ? intval($DT['schcate_limit']) : 10; +$html = ''; +$result = $db->query("SELECT catid,arrparentid FROM {$DT_PRE}category WHERE moduleid=$moduleid AND catname LIKE '%$name%' ORDER BY item DESC,catid DESC LIMIT $limit"); +while($r = $db->fetch_array($result)) { + $html .= '
    '; +} +echo $html; +?> \ No newline at end of file diff --git a/api/ajax/screen.inc.php b/api/ajax/screen.inc.php new file mode 100644 index 0000000..26b0caf --- /dev/null +++ b/api/ajax/screen.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/ajax/select.inc.php b/api/ajax/select.inc.php new file mode 100644 index 0000000..af9b109 --- /dev/null +++ b/api/ajax/select.inc.php @@ -0,0 +1,104 @@ + 3 or dheader('DT_PATH'); + $from = isset($from) ? trim($from) : 'item'; + isset($username) or $username = ''; + $condition = $mid == 4 ? 'groupid>5' : 'status=3'; + if($keyword) $condition .= match_kw('keyword', $keyword); + if($from == 'relate' && $MODULE[$mid]['module'] == 'mall') { + check_name($username) or exit; + $condition .= " AND username='$username'"; + } else { + if($_groupid == 1) { + if($from == 'member') $condition .= " AND username='$_username'"; + } else { + $condition .= " AND username='$_username'"; + } + } + if($itemid) $condition .= $mid == 4 ? " AND userid=$itemid" : " AND itemid=$itemid"; + $order = $mid == 4 ? 'userid DESC' : 'addtime DESC'; + $table = get_table($mid); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$table} WHERE $condition"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$table} WHERE $condition ORDER BY $order LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + if($mid == 4) { + $r['itemid'] = $r['userid']; + $r['alt'] = $r['title'] = $r['company']; + $r['adddate'] = $r['editdate'] = timetodate(0, 5); + $r['level'] = 0; + $r['style'] = ''; + } else { + $r['adddate'] = timetodate($r['addtime'], 5); + $r['editdate'] = timetodate($r['edittime'], 5); + $r['alt'] = $r['title']; + $r['title'] = set_style($r['title'], $r['style']); + if(strpos($r['linkurl'], '://') === false) $r['linkurl'] = $MODULE[$mid]['linkurl'].$r['linkurl']; + } + $lists[] = $r; + } + $head_title = '选择信息'; +} else { + isset($from) or $from = ''; + if($DT['uploadlog']) { + $table = $DT_PRE.'upload_'.($_userid%10); + $condition = "username='$_username' AND width>90"; + $condition .= $from == 'album' ? " AND (upfrom='album' OR upfrom='photo')" : " AND upfrom<>'thumb'"; + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$table} WHERE {$condition}"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$table} WHERE {$condition} ORDER BY pid DESC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['introduce'] = timetodate($r['addtime'], 6).' '.$r['width'].'px * '.$r['height'].'px '; + $r['ext'] = file_ext($r['fileurl']); + $r['thumb'] = $r['fileurl']; + $r['middle'] = str_replace('.thumb.'.$r['ext'], '.middle.'.$r['ext'], $r['thumb']); + $r['large'] = str_replace('.thumb.'.$r['ext'], '', $r['thumb']); + $lists[] = $r; + } + } else { + foreach($MODULE as $M) { + if($M['module'] == 'photo') { + $mid = $M['moduleid']; + break; + } + } + $mid or message('系统未开启图库功能'); + $from = isset($from) ? trim($from) : ''; + $fid = isset($fid) ? trim($fid) : ''; + if($itemid) { + $item = $db->get_one("SELECT username,title FROM {$DT_PRE}photo_{$mid} WHERE itemid=$itemid"); + if(!$item || ($item['username'] != $_username && $_groupid > 1)) dheader(DT_PATH); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}photo_item_{$mid} WHERE item=$itemid"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}photo_item_{$mid} WHERE item=$itemid ORDER BY listorder ASC,itemid ASC LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['ext'] = file_ext($r['thumb']); + $r['middle'] = str_replace('.thumb.'.$r['ext'], '.middle.'.$r['ext'], $r['thumb']); + $r['large'] = str_replace('.thumb.'.$r['ext'], '', $r['thumb']); + $lists[] = $r; + } + } else { + $condition = "status=3 AND items>0 AND username='$_username'"; + if($keyword) $condition .= match_kw('keyword', $keyword); + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}photo_{$mid} WHERE $condition"); + $items = $r['num']; + $pages = pages($items, $page, $pagesize); + $lists = array(); + $result = $db->query("SELECT * FROM {$DT_PRE}photo_{$mid} WHERE $condition ORDER BY addtime LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $lists[] = $r; + } + } + } + $head_title = '选择图片'; +} +include template('select', 'member'); +?> \ No newline at end of file diff --git a/api/ajax/stats.inc.php b/api/ajax/stats.inc.php new file mode 100644 index 0000000..7b7b7a0 --- /dev/null +++ b/api/ajax/stats.inc.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/api/ajax/tipword.inc.php b/api/ajax/tipword.inc.php new file mode 100644 index 0000000..f2beaff --- /dev/null +++ b/api/ajax/tipword.inc.php @@ -0,0 +1,15 @@ + 30) exit; +foreach(array('&', '=', '(', ',') as $v) { + strpos($word, $v) === false or exit; +} +$word = str_replace(array(' ','*', "\'"), array('%', '%', ''), $word); +if(preg_match("/^[a-z0-9A-Z]+$/", $word)) { + tag("moduleid=$mid&table=keyword&condition=moduleid=$mid and letter like '%$word%'&pagesize=10&order=total_search desc&template=list-search_tip", -2); +} else { + tag("moduleid=$mid&table=keyword&condition=moduleid=$mid and keyword like '%$word%'&pagesize=10&order=total_search desc&template=list-search_tip", -2); +} +?> \ No newline at end of file diff --git a/api/ajax/type.inc.php b/api/ajax/type.inc.php new file mode 100644 index 0000000..e8e882b --- /dev/null +++ b/api/ajax/type.inc.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/api/ajax/userdata.inc.php b/api/ajax/userdata.inc.php new file mode 100644 index 0000000..8351514 --- /dev/null +++ b/api/ajax/userdata.inc.php @@ -0,0 +1,19 @@ +'.timetodate($DT_TIME).$content; + file_put(DT_ROOT.'/file/user/'.dalloc($_userid).'/'.$_userid.'/editor.data.'.$mid.'.php', $content); +} +?> \ No newline at end of file diff --git a/api/app.php b/api/app.php new file mode 100644 index 0000000..253cdee --- /dev/null +++ b/api/app.php @@ -0,0 +1,45 @@ +'; + $html .= ''; + $html .= 'Tips'; + $html .= ''; + $html .= ''; + $html .= ''; + exit($html); + } + dheader($EXT['mobile_ios']); + } +} else if($DT_MOB == 'android') { + if(preg_match("/^([0-9]{1,})@([a-z0-9]{16,})$/i", $EXT['mobile_adr'])) { + $t = explode('@', $EXT['mobile_adr']); + dheader('https://app.destoon.com/get.php?o=adr&u='.$t[0].'&k='.encrypt($url, $t[1])); + } else if(strpos($EXT['mobile_adr'], '.apk') !== false) { + if($DT_MBS == 'weixin') { + $html = ''; + $html .= ''; + $html .= ''; + $html .= 'Tips'; + $html .= ''; + $html .= ''; + $html .= ''; + exit($html); + } + dheader($EXT['mobile_adr']); + } +} +dheader($url); +?> \ No newline at end of file diff --git a/api/attach.php b/api/attach.php new file mode 100644 index 0000000..650e130 --- /dev/null +++ b/api/attach.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/avatar/cropbox-min.js b/api/avatar/cropbox-min.js new file mode 100644 index 0000000..6519a20 --- /dev/null +++ b/api/avatar/cropbox-min.js @@ -0,0 +1 @@ +"use strict";!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){var e=function(e,n){var n=n||t(e.imageBox),i={state:{},ratio:1,options:e,imageBox:n,thumbBox:n.find(e.thumbBox),spinner:n.find(e.spinner),image:new Image,getDataURL:function(){var t=this.thumbBox.width(),e=this.thumbBox.height(),i=document.createElement("canvas"),a=n.css("background-position").split(" "),o=n.css("background-size").split(" "),s=parseInt(a[0])-n.width()/2+t/2,r=parseInt(a[1])-n.height()/2+e/2,u=parseInt(o[0]),g=parseInt(o[1]),c=parseInt(this.image.height),m=parseInt(this.image.width);i.width=t,i.height=e;var p=i.getContext("2d");p.drawImage(this.image,0,0,m,c,s,r,u,g);var d=i.toDataURL("image/png");return d},getBlob:function(){for(var t=this.getDataURL(),e=t.replace("data:image/png;base64,",""),n=atob(e),i=[],a=0;a0||t.originalEvent.detail<0?1.1:.9,a()};return i.spinner.show(),i.image.onload=function(){i.spinner.hide(),a(),n.bind("mousedown",o),n.bind("mousemove",s),t(window).bind("mouseup",r),n.bind("mousewheel DOMMouseScroll",u)},i.image.src=e.imgSrc,n.on("remove",function(){t(window).unbind("mouseup",r)}),i};jQuery.fn.cropbox=function(t){return new e(t,this)}}); \ No newline at end of file diff --git a/api/avatar/cropbox.css b/api/avatar/cropbox.css new file mode 100644 index 0000000..55625d2 --- /dev/null +++ b/api/avatar/cropbox.css @@ -0,0 +1,48 @@ +.container{margin:0 0 0 16px;} +.action{width:400px;height:30px;margin:10px 0;} +.action p {overflow:hidden;position:relative;margin:0;width:96px;height:32px;line-height:32px;text-align:center;background:#FAFAFA;border:#DDDDDD 1px solid;border-radius:6px;} +.action p:hover{background:#EEEEEE;} +.action p input{position:absolute;left:0;top:0;font-size:100px;margin:0 0 0 -1100px;opacity:0;filter:alpha(opacity=0);cursor:pointer;} +#btnZoomOut{width:32px;height:32px;line-height:32px;text-align:center;background:#FAFAFA;border:#DDDDDD 1px solid;cursor:pointer;margin-left:56px;border-radius:16px;font-size:20px;font-family:simsun;user-select:none;-moz-user-select:none;} +#btnZoomOut:hover{background:#EEEEEE;} +#btnZoomIn{width:32px;height:32px;line-height:32px;text-align:center;background:#FAFAFA;border:#DDDDDD 1px solid;cursor:pointer;margin-left:24px;border-radius:16px;font-size:20px;font-family:simsun;user-select:none;-moz-user-select:none;} +#btnZoomIn:hover{background:#EEEEEE;} +#btnCrop{width:96px;height:32px;line-height:32px;text-align:center;background:#1AAD19;border:#18A117 1px solid;color:#FFFFFF;cursor:pointer;margin-left:56px;border-radius:6px;user-select:none;-moz-user-select:none;} +#btnCrop:hover{background:#179B16;} +.cropped>img{margin:0 10px 10px 0;} +.imageBox +{ + position: relative; + height: 400px; + width: 400px; + border:1px solid #aaa; + background: #fff; + overflow: hidden; + background-repeat: no-repeat; + cursor:move; +} +.imageBox .thumbBox +{ + position: absolute; + top: 50%; + left: 50%; + width: 200px; + height: 200px; + margin-top: -100px; + margin-left: -100px; + box-sizing: border-box; + border: 1px solid rgb(102, 102, 102); + box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5); + background: none repeat scroll 0% 0% transparent; +} +.imageBox .spinner +{ + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + text-align: center; + line-height: 400px; + background: rgba(0,0,0,0.7); +} \ No newline at end of file diff --git a/api/avatar/cropbox.js b/api/avatar/cropbox.js new file mode 100644 index 0000000..3254a4d --- /dev/null +++ b/api/avatar/cropbox.js @@ -0,0 +1,141 @@ +/** + * Created by ezgoing on 14/9/2014. + */ + +"use strict"; +(function (factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else { + factory(jQuery); + } +}(function ($) { + var cropbox = function(options, el){ + var el = el || $(options.imageBox), + obj = + { + state : {}, + ratio : 1, + options : options, + imageBox : el, + thumbBox : el.find(options.thumbBox), + spinner : el.find(options.spinner), + image : new Image(), + getDataURL: function () + { + var width = this.thumbBox.width(), + height = this.thumbBox.height(), + canvas = document.createElement("canvas"), + dim = el.css('background-position').split(' '), + size = el.css('background-size').split(' '), + dx = parseInt(dim[0]) - el.width()/2 + width/2, + dy = parseInt(dim[1]) - el.height()/2 + height/2, + dw = parseInt(size[0]), + dh = parseInt(size[1]), + sh = parseInt(this.image.height), + sw = parseInt(this.image.width); + + canvas.width = width; + canvas.height = height; + var context = canvas.getContext("2d"); + context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh); + var imageData = canvas.toDataURL('image/png'); + return imageData; + }, + getBlob: function() + { + var imageData = this.getDataURL(); + var b64 = imageData.replace('data:image/png;base64,',''); + var binary = atob(b64); + var array = []; + for (var i = 0; i < binary.length; i++) { + array.push(binary.charCodeAt(i)); + } + return new Blob([new Uint8Array(array)], {type: 'image/png'}); + }, + zoomIn: function () + { + this.ratio*=1.1; + setBackground(); + }, + zoomOut: function () + { + this.ratio*=0.9; + setBackground(); + } + }, + setBackground = function() + { + var w = parseInt(obj.image.width)*obj.ratio; + var h = parseInt(obj.image.height)*obj.ratio; + + var pw = (el.width() - w) / 2; + var ph = (el.height() - h) / 2; + + el.css({ + 'background-image': 'url(' + obj.image.src + ')', + 'background-size': w +'px ' + h + 'px', + 'background-position': pw + 'px ' + ph + 'px', + 'background-repeat': 'no-repeat'}); + }, + imgMouseDown = function(e) + { + e.stopImmediatePropagation(); + + obj.state.dragable = true; + obj.state.mouseX = e.clientX; + obj.state.mouseY = e.clientY; + }, + imgMouseMove = function(e) + { + e.stopImmediatePropagation(); + + if (obj.state.dragable) + { + var x = e.clientX - obj.state.mouseX; + var y = e.clientY - obj.state.mouseY; + + var bg = el.css('background-position').split(' '); + + var bgX = x + parseInt(bg[0]); + var bgY = y + parseInt(bg[1]); + + el.css('background-position', bgX +'px ' + bgY + 'px'); + + obj.state.mouseX = e.clientX; + obj.state.mouseY = e.clientY; + } + }, + imgMouseUp = function(e) + { + e.stopImmediatePropagation(); + obj.state.dragable = false; + }, + zoomImage = function(e) + { + e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio*=1.1 : obj.ratio*=0.9; + setBackground(); + } + + obj.spinner.show(); + obj.image.onload = function() { + obj.spinner.hide(); + setBackground(); + + el.bind('mousedown', imgMouseDown); + el.bind('mousemove', imgMouseMove); + $(window).bind('mouseup', imgMouseUp); + el.bind('mousewheel DOMMouseScroll', zoomImage); + }; + obj.image.src = options.imgSrc; + el.on('remove', function(){$(window).unbind('mouseup', imgMouseUp)}); + + return obj; + }; + + jQuery.fn.cropbox = function(options){ + return new cropbox(options, this); + }; +})); + + diff --git a/api/avatar/default.jpg b/api/avatar/default.jpg new file mode 100644 index 0000000000000000000000000000000000000000..85d9b5d3ca657bc2f2de5ef19d4ef34b7c4246b1 GIT binary patch literal 14475 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�J! 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 c^~K{2T~^a?-%K7=@XM|N4}1~}eJvOM2hW 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 \ No newline at end of file diff --git a/api/avatar/show.php b/api/avatar/show.php new file mode 100644 index 0000000..10ee3ea --- /dev/null +++ b/api/avatar/show.php @@ -0,0 +1,28 @@ + 10) $file = str_replace('../../file/', $remote, $file); +} +header('location:'.$file.'?v='.time()); +?> \ No newline at end of file diff --git a/api/barcode.png.php b/api/barcode.png.php new file mode 100644 index 0000000..79a5868 --- /dev/null +++ b/api/barcode.png.php @@ -0,0 +1,62 @@ + 0 && $size < 10) or $size = 1; +$fontsize = isset($fontsize) ? intval($fontsize) : 9 + $size; +($fontsize > 8 && $fontsize < 30) or $fontsize = 9 + $size; +// Including all required classes +require_once DT_ROOT.'/api/barcode/BCGFontFile.php'; +require_once DT_ROOT.'/api/barcode/BCGColor.php'; +require_once DT_ROOT.'/api/barcode/BCGDrawing.php'; + +// Including the barcode technology +require_once DT_ROOT.'/api/barcode/BCGcode39.barcode.php'; + +// Loading Font +$font = new BCGFontFile(DT_ROOT.'/api/barcode/Arial.ttf', $fontsize); + +// Don't forget to sanitize user inputs + +// The arguments are R, G, B for color. +$color_black = new BCGColor(0, 0, 0); +$color_white = new BCGColor(255, 255, 255); + +$drawException = null; +try { + $code = new BCGcode39(); + $code->setScale($size); // Resolution + $code->setThickness(30); // Thickness + $code->setForegroundColor($color_black); // Color of bars + $code->setBackgroundColor($color_white); // Color of spaces + $code->setFont($font); // Font (or 0) + $code->parse($text); // Text +} catch(Exception $exception) { + $drawException = $exception; +} + +/* Here is the list of the arguments +1 - Filename (empty : display on screen) +2 - Background color */ +$drawing = new BCGDrawing('', $color_white); +if($drawException) { + $drawing->drawException($drawException); +} else { + $drawing->setBarcode($code); + $drawing->draw(); +} + +// Header that says it is an image (remove it if you save the barcode to a file) +header('Content-Type: image/png'); +header('Content-Disposition: inline; filename="barcode.png"'); + +// Draw (or save) the image into PNG format. +$drawing->finish(BCGDrawing::IMG_FORMAT_PNG); +?> \ No newline at end of file diff --git a/api/barcode/Arial.ttf b/api/barcode/Arial.ttf new file mode 100644 index 0000000000000000000000000000000000000000..886789b85b4b4e662519fcb7fe4d88ddf2205c5b GIT binary patch literal 311636 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 VXQc0|TekeI1$m{%qWu+${|Aparam = $param; + parent::__construct($message, 20000); + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGBarcode.php b/api/barcode/BCGBarcode.php new file mode 100644 index 0000000..c0dcd8e --- /dev/null +++ b/api/barcode/BCGBarcode.php @@ -0,0 +1,437 @@ +setOffsetX(0); + $this->setOffsetY(0); + $this->setForegroundColor(0x000000); + $this->setBackgroundColor(0xffffff); + $this->setScale(1); + } + + /** + * Parses the text before displaying it. + * + * @param mixed $text + */ + public function parse($text) { + } + + /** + * Gets the foreground color of the barcode. + * + * @return BCGColor + */ + public function getForegroundColor() { + return $this->colorFg; + } + + /** + * Sets the foreground color of the barcode. It could be a BCGColor + * value or simply a language code (white, black, yellow...) or hex value. + * + * @param mixed $code + */ + public function setForegroundColor($code) { + if ($code instanceof BCGColor) { + $this->colorFg = $code; + } else { + $this->colorFg = new BCGColor($code); + } + } + + /** + * Gets the background color of the barcode. + * + * @return BCGColor + */ + public function getBackgroundColor() { + return $this->colorBg; + } + + /** + * Sets the background color of the barcode. It could be a BCGColor + * value or simply a language code (white, black, yellow...) or hex value. + * + * @param mixed $code + */ + public function setBackgroundColor($code) { + if ($code instanceof BCGColor) { + $this->colorBg = $code; + } else { + $this->colorBg = new BCGColor($code); + } + + foreach ($this->labels as $label) { + $label->setBackgroundColor($this->colorBg); + } + } + + /** + * Sets the color. + * + * @param mixed $fg + * @param mixed $bg + */ + public function setColor($fg, $bg) { + $this->setForegroundColor($fg); + $this->setBackgroundColor($bg); + } + + /** + * Gets the scale of the barcode. + * + * @return int + */ + public function getScale() { + return $this->scale; + } + + /** + * Sets the scale of the barcode in pixel. + * If the scale is lower than 1, an exception is raised. + * + * @param int $scale + */ + public function setScale($scale) { + $scale = intval($scale); + if ($scale <= 0) { + throw new BCGArgumentException('The scale must be larger than 0.', 'scale'); + } + + $this->scale = $scale; + } + + /** + * Abstract method that draws the barcode on the resource. + * + * @param resource $im + */ + public abstract function draw($im); + + /** + * Returns the maximal size of a barcode. + * [0]->width + * [1]->height + * + * @param int $w + * @param int $h + * @return int[] + */ + public function getDimension($w, $h) { + $labels = $this->getBiggestLabels(false); + $pixelsAround = array(0, 0, 0, 0); // TRBL + if (isset($labels[BCGLabel::POSITION_TOP])) { + $dimension = $labels[BCGLabel::POSITION_TOP]->getDimension(); + $pixelsAround[0] += $dimension[1]; + } + + if (isset($labels[BCGLabel::POSITION_RIGHT])) { + $dimension = $labels[BCGLabel::POSITION_RIGHT]->getDimension(); + $pixelsAround[1] += $dimension[0]; + } + + if (isset($labels[BCGLabel::POSITION_BOTTOM])) { + $dimension = $labels[BCGLabel::POSITION_BOTTOM]->getDimension(); + $pixelsAround[2] += $dimension[1]; + } + + if (isset($labels[BCGLabel::POSITION_LEFT])) { + $dimension = $labels[BCGLabel::POSITION_LEFT]->getDimension(); + $pixelsAround[3] += $dimension[0]; + } + + $finalW = ($w + $this->offsetX) * $this->scale; + $finalH = ($h + $this->offsetY) * $this->scale; + + // This section will check if a top/bottom label is too big for its width and left/right too big for its height + $reversedLabels = $this->getBiggestLabels(true); + foreach ($reversedLabels as $label) { + $dimension = $label->getDimension(); + $alignment = $label->getAlignment(); + if ($label->getPosition() === BCGLabel::POSITION_LEFT || $label->getPosition() === BCGLabel::POSITION_RIGHT) { + if ($alignment === BCGLabel::ALIGN_TOP) { + $pixelsAround[2] = max($pixelsAround[2], $dimension[1] - $finalH); + } elseif ($alignment === BCGLabel::ALIGN_CENTER) { + $temp = ceil(($dimension[1] - $finalH) / 2); + $pixelsAround[0] = max($pixelsAround[0], $temp); + $pixelsAround[2] = max($pixelsAround[2], $temp); + } elseif ($alignment === BCGLabel::ALIGN_BOTTOM) { + $pixelsAround[0] = max($pixelsAround[0], $dimension[1] - $finalH); + } + } else { + if ($alignment === BCGLabel::ALIGN_LEFT) { + $pixelsAround[1] = max($pixelsAround[1], $dimension[0] - $finalW); + } elseif ($alignment === BCGLabel::ALIGN_CENTER) { + $temp = ceil(($dimension[0] - $finalW) / 2); + $pixelsAround[1] = max($pixelsAround[1], $temp); + $pixelsAround[3] = max($pixelsAround[3], $temp); + } elseif ($alignment === BCGLabel::ALIGN_RIGHT) { + $pixelsAround[3] = max($pixelsAround[3], $dimension[0] - $finalW); + } + } + } + + $this->pushLabel[0] = $pixelsAround[3]; + $this->pushLabel[1] = $pixelsAround[0]; + + $finalW = ($w + $this->offsetX) * $this->scale + $pixelsAround[1] + $pixelsAround[3]; + $finalH = ($h + $this->offsetY) * $this->scale + $pixelsAround[0] + $pixelsAround[2]; + + return array($finalW, $finalH); + } + + /** + * Gets the X offset. + * + * @return int + */ + public function getOffsetX() { + return $this->offsetX; + } + + /** + * Sets the X offset. + * + * @param int $offsetX + */ + public function setOffsetX($offsetX) { + $offsetX = intval($offsetX); + if ($offsetX < 0) { + throw new BCGArgumentException('The offset X must be 0 or larger.', 'offsetX'); + } + + $this->offsetX = $offsetX; + } + + /** + * Gets the Y offset. + * + * @return int + */ + public function getOffsetY() { + return $this->offsetY; + } + + /** + * Sets the Y offset. + * + * @param int $offsetY + */ + public function setOffsetY($offsetY) { + $offsetY = intval($offsetY); + if ($offsetY < 0) { + throw new BCGArgumentException('The offset Y must be 0 or larger.', 'offsetY'); + } + + $this->offsetY = $offsetY; + } + + /** + * Adds the label to the drawing. + * + * @param BCGLabel $label + */ + public function addLabel(BCGLabel $label) { + $label->setBackgroundColor($this->colorBg); + $this->labels[] = $label; + } + + /** + * Removes the label from the drawing. + * + * @param BCGLabel $label + */ + public function removeLabel(BCGLabel $label) { + $remove = -1; + $c = count($this->labels); + for ($i = 0; $i < $c; $i++) { + if ($this->labels[$i] === $label) { + $remove = $i; + break; + } + } + + if ($remove > -1) { + array_splice($this->labels, $remove, 1); + } + } + + /** + * Clears the labels. + */ + public function clearLabels() { + $this->labels = array(); + } + + /** + * Draws the text. + * The coordinate passed are the positions of the barcode. + * $x1 and $y1 represent the top left corner. + * $x2 and $y2 represent the bottom right corner. + * + * @param resource $im + * @param int $x1 + * @param int $y1 + * @param int $x2 + * @param int $y2 + */ + protected function drawText($im, $x1, $y1, $x2, $y2) { + foreach ($this->labels as $label) { + $label->draw($im, + ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], + ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], + ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0], + ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1]); + } + } + + /** + * Draws 1 pixel on the resource at a specific position with a determined color. + * + * @param resource $im + * @param int $x + * @param int $y + * @param int $color + */ + protected function drawPixel($im, $x, $y, $color = self::COLOR_FG) { + $xR = ($x + $this->offsetX) * $this->scale + $this->pushLabel[0]; + $yR = ($y + $this->offsetY) * $this->scale + $this->pushLabel[1]; + + // We always draw a rectangle + imagefilledrectangle($im, + $xR, + $yR, + $xR + $this->scale - 1, + $yR + $this->scale - 1, + $this->getColor($im, $color)); + } + + /** + * Draws an empty rectangle on the resource at a specific position with a determined color. + * + * @param resource $im + * @param int $x1 + * @param int $y1 + * @param int $x2 + * @param int $y2 + * @param int $color + */ + protected function drawRectangle($im, $x1, $y1, $x2, $y2, $color = self::COLOR_FG) { + if ($this->scale === 1) { + imagefilledrectangle($im, + ($x1 + $this->offsetX) + $this->pushLabel[0], + ($y1 + $this->offsetY) + $this->pushLabel[1], + ($x2 + $this->offsetX) + $this->pushLabel[0], + ($y2 + $this->offsetY) + $this->pushLabel[1], + $this->getColor($im, $color)); + } else { + imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color)); + imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color)); + imagefilledrectangle($im, ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color)); + imagefilledrectangle($im, ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1], ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, $this->getColor($im, $color)); + } + } + + /** + * Draws a filled rectangle on the resource at a specific position with a determined color. + * + * @param resource $im + * @param int $x1 + * @param int $y1 + * @param int $x2 + * @param int $y2 + * @param int $color + */ + protected function drawFilledRectangle($im, $x1, $y1, $x2, $y2, $color = self::COLOR_FG) { + if ($x1 > $x2) { // Swap + $x1 ^= $x2 ^= $x1 ^= $x2; + } + + if ($y1 > $y2) { // Swap + $y1 ^= $y2 ^= $y1 ^= $y2; + } + + imagefilledrectangle($im, + ($x1 + $this->offsetX) * $this->scale + $this->pushLabel[0], + ($y1 + $this->offsetY) * $this->scale + $this->pushLabel[1], + ($x2 + $this->offsetX) * $this->scale + $this->pushLabel[0] + $this->scale - 1, + ($y2 + $this->offsetY) * $this->scale + $this->pushLabel[1] + $this->scale - 1, + $this->getColor($im, $color)); + } + + /** + * Allocates the color based on the integer. + * + * @param resource $im + * @param int $color + * @return resource + */ + protected function getColor($im, $color) { + if ($color === self::COLOR_BG) { + return $this->colorBg->allocate($im); + } else { + return $this->colorFg->allocate($im); + } + } + + /** + * Returning the biggest label widths for LEFT/RIGHT and heights for TOP/BOTTOM. + * + * @param bool $reversed + * @return BCGLabel[] + */ + private function getBiggestLabels($reversed = false) { + $searchLR = $reversed ? 1 : 0; + $searchTB = $reversed ? 0 : 1; + + $labels = array(); + foreach ($this->labels as $label) { + $position = $label->getPosition(); + if (isset($labels[$position])) { + $savedDimension = $labels[$position]->getDimension(); + $dimension = $label->getDimension(); + if ($position === BCGLabel::POSITION_LEFT || $position === BCGLabel::POSITION_RIGHT) { + if ($dimension[$searchLR] > $savedDimension[$searchLR]) { + $labels[$position] = $label; + } + } else { + if ($dimension[$searchTB] > $savedDimension[$searchTB]) { + $labels[$position] = $label; + } + } + } else { + $labels[$position] = $label; + } + } + + return $labels; + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGBarcode1D.php b/api/barcode/BCGBarcode1D.php new file mode 100644 index 0000000..5dd22c8 --- /dev/null +++ b/api/barcode/BCGBarcode1D.php @@ -0,0 +1,260 @@ +setThickness(30); + + $this->defaultLabel = new BCGLabel(); + $this->defaultLabel->setPosition(BCGLabel::POSITION_BOTTOM); + $this->setLabel(self::AUTO_LABEL); + $this->setFont(new BCGFontPhp(5)); + + $this->text = ''; + $this->checksumValue = false; + $this->positionX = 0; + } + + /** + * Gets the thickness. + * + * @return int + */ + public function getThickness() { + return $this->thickness; + } + + /** + * Sets the thickness. + * + * @param int $thickness + */ + public function setThickness($thickness) { + $thickness = intval($thickness); + if ($thickness <= 0) { + throw new BCGArgumentException('The thickness must be larger than 0.', 'thickness'); + } + + $this->thickness = $thickness; + } + + /** + * Gets the label. + * If the label was set to BCGBarcode1D::AUTO_LABEL, the label will display the value from the text parsed. + * + * @return string + */ + public function getLabel() { + $label = $this->label; + if ($this->label === self::AUTO_LABEL) { + $label = $this->text; + if ($this->displayChecksum === true && ($checksum = $this->processChecksum()) !== false) { + $label .= $checksum; + } + } + + return $label; + } + + /** + * Sets the label. + * You can use BCGBarcode::AUTO_LABEL to have the label automatically written based on the parsed text. + * + * @param string $label + */ + public function setLabel($label) { + $this->label = $label; + } + + /** + * Gets the font. + * + * @return BCGFont + */ + public function getFont() { + return $this->font; + } + + /** + * Sets the font. + * + * @param mixed $font BCGFont or int + */ + public function setFont($font) { + if (is_int($font)) { + if ($font === 0) { + $font = null; + } else { + $font = new BCGFontPhp($font); + } + } + + $this->font = $font; + } + + /** + * Parses the text before displaying it. + * + * @param mixed $text + */ + public function parse($text) { + $this->text = $text; + $this->checksumValue = false; // Reset checksumValue + $this->validate(); + + parent::parse($text); + + $this->addDefaultLabel(); + } + + /** + * Gets the checksum of a Barcode. + * If no checksum is available, return FALSE. + * + * @return string + */ + public function getChecksum() { + return $this->processChecksum(); + } + + /** + * Sets if the checksum is displayed with the label or not. + * The checksum must be activated in some case to make this variable effective. + * + * @param boolean $displayChecksum + */ + public function setDisplayChecksum($displayChecksum) { + $this->displayChecksum = (bool)$displayChecksum; + } + + /** + * Adds the default label. + */ + protected function addDefaultLabel() { + $label = $this->getLabel(); + $font = $this->font; + if ($label !== null && $label !== '' && $font !== null && $this->defaultLabel !== null) { + $this->defaultLabel->setText($label); + $this->defaultLabel->setFont($font); + $this->addLabel($this->defaultLabel); + } + } + + /** + * Validates the input + */ + protected function validate() { + // No validation in the abstract class. + } + + /** + * Returns the index in $keys (useful for checksum). + * + * @param mixed $var + * @return mixed + */ + protected function findIndex($var) { + return array_search($var, $this->keys); + } + + /** + * Returns the code of the char (useful for drawing bars). + * + * @param mixed $var + * @return string + */ + protected function findCode($var) { + return $this->code[$this->findIndex($var)]; + } + + /** + * Draws all chars thanks to $code. If $startBar is true, the line begins by a space. + * If $startBar is false, the line begins by a bar. + * + * @param resource $im + * @param string $code + * @param boolean $startBar + */ + protected function drawChar($im, $code, $startBar = true) { + $colors = array(BCGBarcode::COLOR_FG, BCGBarcode::COLOR_BG); + $currentColor = $startBar ? 0 : 1; + $c = strlen($code); + for ($i = 0; $i < $c; $i++) { + for ($j = 0; $j < intval($code[$i]) + 1; $j++) { + $this->drawSingleBar($im, $colors[$currentColor]); + $this->nextX(); + } + + $currentColor = ($currentColor + 1) % 2; + } + } + + /** + * Draws a Bar of $color depending of the resolution. + * + * @param resource $img + * @param int $color + */ + protected function drawSingleBar($im, $color) { + $this->drawFilledRectangle($im, $this->positionX, 0, $this->positionX, $this->thickness - 1, $color); + } + + /** + * Moving the pointer right to write a bar. + */ + protected function nextX() { + $this->positionX++; + } + + /** + * Method that saves FALSE into the checksumValue. This means no checksum + * but this method should be overriden when needed. + */ + protected function calculateChecksum() { + $this->checksumValue = false; + } + + /** + * Returns FALSE because there is no checksum. This method should be + * overriden to return correctly the checksum in string with checksumValue. + * + * @return string + */ + protected function processChecksum() { + return false; + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGColor.php b/api/barcode/BCGColor.php new file mode 100644 index 0000000..f37317a --- /dev/null +++ b/api/barcode/BCGColor.php @@ -0,0 +1,155 @@ +r = intval($args[0]); + $this->g = intval($args[1]); + $this->b = intval($args[2]); + } elseif ($c === 1) { + if (is_string($args[0]) && strlen($args[0]) === 7 && $args[0][0] === '#') { // Hex Value in String + $this->r = intval(substr($args[0], 1, 2), 16); + $this->g = intval(substr($args[0], 3, 2), 16); + $this->b = intval(substr($args[0], 5, 2), 16); + } else { + if (is_string($args[0])) { + $args[0] = self::getColor($args[0]); + } + + $args[0] = intval($args[0]); + $this->r = ($args[0] & 0xff0000) >> 16; + $this->g = ($args[0] & 0x00ff00) >> 8; + $this->b = ($args[0] & 0x0000ff); + } + } else { + $this->r = $this->g = $this->b = 0; + } + } + + /** + * Sets the color transparent. + * + * @param bool $transparent + */ + public function setTransparent($transparent) { + $this->transparent = $transparent; + } + + /** + * Returns Red Color. + * + * @return int + */ + public function r() { + return $this->r; + } + + /** + * Returns Green Color. + * + * @return int + */ + public function g() { + return $this->g; + } + + /** + * Returns Blue Color. + * + * @return int + */ + public function b() { + return $this->b; + } + + /** + * Returns the int value for PHP color. + * + * @param resource $im + * @return int + */ + public function allocate(&$im) { + $allocated = imagecolorallocate($im, $this->r, $this->g, $this->b); + if ($this->transparent) { + return imagecolortransparent($im, $allocated); + } else { + return $allocated; + } + } + + /** + * Returns class of BCGColor depending of the string color. + * + * If the color doens't exist, it takes the default one. + * + * @param string $code + * @param string $default + */ + public static function getColor($code, $default = 'white') { + switch(strtolower($code)) { + case '': + case 'white': + return 0xffffff; + case 'black': + return 0x000000; + case 'maroon': + return 0x800000; + case 'red': + return 0xff0000; + case 'orange': + return 0xffa500; + case 'yellow': + return 0xffff00; + case 'olive': + return 0x808000; + case 'purple': + return 0x800080; + case 'fuchsia': + return 0xff00ff; + case 'lime': + return 0x00ff00; + case 'green': + return 0x008000; + case 'navy': + return 0x000080; + case 'blue': + return 0x0000ff; + case 'aqua': + return 0x00ffff; + case 'teal': + return 0x008080; + case 'silver': + return 0xc0c0c0; + case 'gray': + return 0x808080; + default: + return self::getColor($default, 'white'); + } + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGDraw.php b/api/barcode/BCGDraw.php new file mode 100644 index 0000000..65b9d1c --- /dev/null +++ b/api/barcode/BCGDraw.php @@ -0,0 +1,39 @@ +im = $im; + } + + /** + * Sets the filename. + * + * @param string $filename + */ + public function setFilename($filename) { + $this->filename = $filename; + } + + /** + * Method needed to draw the image based on its specification (JPG, GIF, etc.). + */ + abstract public function draw(); +} +?> \ No newline at end of file diff --git a/api/barcode/BCGDrawException.php b/api/barcode/BCGDrawException.php new file mode 100644 index 0000000..590bfae --- /dev/null +++ b/api/barcode/BCGDrawException.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/api/barcode/BCGDrawJPG.php b/api/barcode/BCGDrawJPG.php new file mode 100644 index 0000000..32a78a1 --- /dev/null +++ b/api/barcode/BCGDrawJPG.php @@ -0,0 +1,90 @@ +dpi = max(1, $dpi); + } else { + $this->dpi = null; + } + } + + /** + * Sets the quality of the JPG. + * + * @param int $quality + */ + public function setQuality($quality) { + $this->quality = $quality; + } + + /** + * Draws the JPG on the screen or in a file. + */ + public function draw() { + ob_start(); + imagejpeg($this->im, null, $this->quality); + $bin = ob_get_contents(); + ob_end_clean(); + + $this->setInternalProperties($bin); + + if (empty($this->filename)) { + echo $bin; + } else { + file_put_contents($this->filename, $bin); + } + } + + private function setInternalProperties(&$bin) { + $this->internalSetDPI($bin); + $this->internalSetC($bin); + } + + private function internalSetDPI(&$bin) { + if ($this->dpi !== null) { + $bin = substr_replace($bin, pack("Cnn", 0x01, $this->dpi, $this->dpi), 13, 5); + } + } + + private function internalSetC(&$bin) { + if(strcmp(substr($bin, 0, 4), pack('H*', 'FFD8FFE0')) === 0) { + $offset = 4 + (ord($bin[4]) << 8 | ord($bin[5])); + $firstPart = substr($bin, 0, $offset); + $secondPart = substr($bin, $offset); + $cr = pack('H*', 'FFFE004447656E657261746564207769746820426172636F64652047656E657261746F7220666F722050485020687474703A2F2F7777772E626172636F64657068702E636F6D'); + $bin = $firstPart; + $bin .= $cr; + $bin .= $secondPart; + } + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGDrawPNG.php b/api/barcode/BCGDrawPNG.php new file mode 100644 index 0000000..9b1c3de --- /dev/null +++ b/api/barcode/BCGDrawPNG.php @@ -0,0 +1,190 @@ +dpi = max(1, $dpi); + } else { + $this->dpi = null; + } + } + + /** + * Draws the PNG on the screen or in a file. + */ + public function draw() { + ob_start(); + imagepng($this->im); + $bin = ob_get_contents(); + ob_end_clean(); + + $this->setInternalProperties($bin); + + if (empty($this->filename)) { + echo $bin; + } else { + file_put_contents($this->filename, $bin); + } + } + + private function setInternalProperties(&$bin) { + // Scan all the ChunkType + if (strcmp(substr($bin, 0, 8), pack('H*', '89504E470D0A1A0A')) === 0) { + $chunks = $this->detectChunks($bin); + + $this->internalSetDPI($bin, $chunks); + $this->internalSetC($bin, $chunks); + } + } + + private function detectChunks($bin) { + $data = substr($bin, 8); + $chunks = array(); + $c = strlen($data); + + $offset = 0; + while ($offset < $c) { + $packed = unpack('Nsize/a4chunk', $data); + $size = $packed['size']; + $chunk = $packed['chunk']; + + $chunks[] = array('offset' => $offset + 8, 'size' => $size, 'chunk' => $chunk); + $jump = $size + 12; + $offset += $jump; + $data = substr($data, $jump); + } + + return $chunks; + } + + private function internalSetDPI(&$bin, &$chunks) { + if ($this->dpi !== null) { + $meters = (int)($this->dpi * 39.37007874); + + $found = -1; + $c = count($chunks); + for($i = 0; $i < $c; $i++) { + // We already have a pHYs + if($chunks[$i]['chunk'] === 'pHYs') { + $found = $i; + break; + } + } + + $data = 'pHYs' . pack('NNC', $meters, $meters, 0x01); + $crc = self::crc($data, 13); + $cr = pack('Na13N', 9, $data, $crc); + + // We didn't have a pHYs + if($found == -1) { + // Don't do anything if we have a bad PNG + if($c >= 2 && $chunks[0]['chunk'] === 'IHDR') { + array_splice($chunks, 1, 0, array(array('offset' => 33, 'size' => 9, 'chunk' => 'pHYs'))); + + // Push the data + for($i = 2; $i < $c; $i++) { + $chunks[$i]['offset'] += 21; + } + + $firstPart = substr($bin, 0, 33); + $secondPart = substr($bin, 33); + $bin = $firstPart; + $bin .= $cr; + $bin .= $secondPart; + } + } else { + $bin = substr_replace($bin, $cr, $chunks[$i]['offset'], 21); + } + } + } + + private function internalSetC(&$bin, &$chunks) { + if (count($chunks) >= 2 && $chunks[0]['chunk'] === 'IHDR') { + $firstPart = substr($bin, 0, 33); + $secondPart = substr($bin, 33); + $cr = pack('H*', '0000004C74455874436F707972696768740047656E657261746564207769746820426172636F64652047656E657261746F7220666F722050485020687474703A2F2F7777772E626172636F64657068702E636F6D597F70B8'); + $bin = $firstPart; + $bin .= $cr; + $bin .= $secondPart; + } + + // Chunks is dirty!! But we are done. + } + + private static $crc_table = array(); + private static $crc_table_computed = false; + + private static function make_crc_table() { + for ($n = 0; $n < 256; $n++) { + $c = $n; + for ($k = 0; $k < 8; $k++) { + if (($c & 1) == 1) { + $c = 0xedb88320 ^ (self::SHR($c, 1)); + } else { + $c = self::SHR($c, 1); + } + } + self::$crc_table[$n] = $c; + } + + self::$crc_table_computed = true; + } + + private static function SHR($x, $n) { + $mask = 0x40000000; + + if ($x < 0) { + $x &= 0x7FFFFFFF; + $mask = $mask >> ($n - 1); + return ($x >> $n) | $mask; + } + + return (int)$x >> (int)$n; + } + + private static function update_crc($crc, $buf, $len) { + $c = $crc; + + if (!self::$crc_table_computed) { + self::make_crc_table(); + } + + for ($n = 0; $n < $len; $n++) { + $c = self::$crc_table[($c ^ ord($buf[$n])) & 0xff] ^ (self::SHR($c, 8)); + } + + return $c; + } + + private static function crc($data, $len) { + return self::update_crc(-1, $data, $len) ^ -1; + } +} +?> diff --git a/api/barcode/BCGDrawing.php b/api/barcode/BCGDrawing.php new file mode 100644 index 0000000..1f563db --- /dev/null +++ b/api/barcode/BCGDrawing.php @@ -0,0 +1,249 @@ +im = null; + $this->setFilename($filename); + $this->color = $color; + $this->dpi = null; + $this->rotateDegree = 0.0; + } + + /** + * Destructor. + */ + public function __destruct() { + $this->destroy(); + } + + /** + * Gets the filename. + * + * @return string + */ + public function getFilename() { + return $this->filename; + } + + /** + * Sets the filename. + * + * @param string $filaneme + */ + public function setFilename($filename) { + $this->filename = $filename; + } + + /** + * @return resource. + */ + public function get_im() { + return $this->im; + } + + /** + * Sets the image. + * + * @param resource $im + */ + public function set_im($im) { + $this->im = $im; + } + + /** + * Gets barcode for drawing. + * + * @return BCGBarcode + */ + public function getBarcode() { + return $this->barcode; + } + + /** + * Sets barcode for drawing. + * + * @param BCGBarcode $barcode + */ + public function setBarcode(BCGBarcode $barcode) { + $this->barcode = $barcode; + } + + /** + * Gets the DPI for supported filetype. + * + * @return float + */ + public function getDPI() { + return $this->dpi; + } + + /** + * Sets the DPI for supported filetype. + * + * @param float $dpi + */ + public function setDPI($dpi) { + $this->dpi = $dpi; + } + + /** + * Gets the rotation angle in degree clockwise. + * + * @return float + */ + public function getRotationAngle() { + return $this->rotateDegree; + } + + /** + * Sets the rotation angle in degree clockwise. + * + * @param float $degree + */ + public function setRotationAngle($degree) { + $this->rotateDegree = (float)$degree; + } + + /** + * Draws the barcode on the image $im. + */ + public function draw() { + $size = $this->barcode->getDimension(0, 0); + $this->w = max(1, $size[0]); + $this->h = max(1, $size[1]); + $this->init(); + $this->barcode->draw($this->im); + } + + /** + * Saves $im into the file (many format available). + * + * @param int $image_style + * @param int $quality + */ + public function finish($image_style = self::IMG_FORMAT_PNG, $quality = 100) { + $drawer = null; + + $im = $this->im; + if ($this->rotateDegree > 0.0) { + if (function_exists('imagerotate')) { + $im = imagerotate($this->im, 360 - $this->rotateDegree, $this->color->allocate($this->im)); + } else { + throw new BCGDrawException('The method imagerotate doesn\'t exist on your server. Do not use any rotation.'); + } + } + + if ($image_style === self::IMG_FORMAT_PNG) { + $drawer = new BCGDrawPNG($im); + $drawer->setFilename($this->filename); + $drawer->setDPI($this->dpi); + } elseif ($image_style === self::IMG_FORMAT_JPEG) { + $drawer = new BCGDrawJPG($im); + $drawer->setFilename($this->filename); + $drawer->setDPI($this->dpi); + $drawer->setQuality($quality); + } elseif ($image_style === self::IMG_FORMAT_GIF) { + // Some PHP versions have a bug if passing 2nd argument as null. + if ($this->filename === null || $this->filename === '') { + imagegif($im); + } else { + imagegif($im, $this->filename); + } + } elseif ($image_style === self::IMG_FORMAT_WBMP) { + imagewbmp($im, $this->filename); + } + + if ($drawer !== null) { + $drawer->draw(); + } + } + + /** + * Writes the Error on the picture. + * + * @param Exception $exception + */ + public function drawException($exception) { + $this->w = 1; + $this->h = 1; + $this->init(); + + // Is the image big enough? + $w = imagesx($this->im); + $h = imagesy($this->im); + + $text = 'Error: ' . $exception->getMessage(); + + $width = imagefontwidth(2) * strlen($text); + $height = imagefontheight(2); + if ($width > $w || $height > $h) { + $width = max($w, $width); + $height = max($h, $height); + + // We change the size of the image + $newimg = imagecreatetruecolor($width, $height); + imagefill($newimg, 0, 0, imagecolorat($this->im, 0, 0)); + imagecopy($newimg, $this->im, 0, 0, 0, 0, $w, $h); + $this->im = $newimg; + } + + $black = new BCGColor('black'); + imagestring($this->im, 2, 0, 0, $text, $black->allocate($this->im)); + } + + /** + * Free the memory of PHP (called also by destructor). + */ + public function destroy() { + @imagedestroy($this->im); + } + + /** + * Init Image and color background. + */ + private function init() { + if ($this->im === null) { + $this->im = imagecreatetruecolor($this->w, $this->h) + or die('Can\'t Initialize the GD Libraty'); + imagefilledrectangle($this->im, 0, 0, $this->w - 1, $this->h - 1, $this->color->allocate($this->im)); + } + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGFont.php b/api/barcode/BCGFont.php new file mode 100644 index 0000000..12be686 --- /dev/null +++ b/api/barcode/BCGFont.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/api/barcode/BCGFontFile.php b/api/barcode/BCGFontFile.php new file mode 100644 index 0000000..290c938 --- /dev/null +++ b/api/barcode/BCGFontFile.php @@ -0,0 +1,210 @@ +path = $fontPath; + $this->size = $size; + $this->foregroundColor = new BCGColor('black'); + $this->setRotationAngle(0); + $this->setBoxFix(self::PHP_BOX_FIX); + } + + /** + * Gets the text associated to the font. + * + * @return string + */ + public function getText() { + return $this->text; + } + + /** + * Sets the text associated to the font. + * + * @param string text + */ + public function setText($text) { + $this->text = $text; + $this->box = null; + } + + /** + * Gets the rotation in degree. + * + * @return int + */ + public function getRotationAngle() { + return (360 - $this->rotationAngle) % 360; + } + + /** + * Sets the rotation in degree. + * + * @param int + */ + public function setRotationAngle($rotationAngle) { + $this->rotationAngle = (int)$rotationAngle; + if ($this->rotationAngle !== 90 && $this->rotationAngle !== 180 && $this->rotationAngle !== 270) { + $this->rotationAngle = 0; + } + + $this->rotationAngle = (360 - $this->rotationAngle) % 360; + + $this->box = null; + } + + /** + * Gets the background color. + * + * @return BCGColor + */ + public function getBackgroundColor() { + } + + /** + * Sets the background color. + * + * @param BCGColor $backgroundColor + */ + public function setBackgroundColor($backgroundColor) { + } + + /** + * Gets the foreground color. + * + * @return BCGColor + */ + public function getForegroundColor() { + return $this->foregroundColor; + } + + /** + * Sets the foreground color. + * + * @param BCGColor $foregroundColor + */ + public function setForegroundColor($foregroundColor) { + $this->foregroundColor = $foregroundColor; + } + + /** + * Gets the box fix information. + * + * @return int + */ + public function getBoxFix() { + return $this->boxFix; + } + + /** + * Sets the box fix information. + * + * @param int $value + */ + public function setBoxFix($value) { + $this->boxFix = intval($value); + } + + /** + * Returns the width and height that the text takes to be written. + * + * @return int[] + */ + public function getDimension() { + $w = 0.0; + $h = 0.0; + $box = $this->getBox(); + + if ($box !== null) { + $minX = min(array($box[0], $box[2], $box[4], $box[6])); + $maxX = max(array($box[0], $box[2], $box[4], $box[6])); + $minY = min(array($box[1], $box[3], $box[5], $box[7])); + $maxY = max(array($box[1], $box[3], $box[5], $box[7])); + + $w = $maxX - $minX; + $h = $maxY - $minY; + } + + $rotationAngle = $this->getRotationAngle(); + if ($rotationAngle === 90 || $rotationAngle === 270) { + return array($h + self::PHP_BOX_FIX, $w); + } else { + return array($w + self::PHP_BOX_FIX, $h); + } + } + + /** + * Draws the text on the image at a specific position. + * $x and $y represent the left bottom corner. + * + * @param resource $im + * @param int $x + * @param int $y + */ + public function draw($im, $x, $y) { + $drawingPosition = $this->getDrawingPosition($x, $y); + imagettftext($im, $this->size, $this->rotationAngle, $drawingPosition[0], $drawingPosition[1], $this->foregroundColor->allocate($im), $this->path, $this->text); + } + + private function getDrawingPosition($x, $y) { + $dimension = $this->getDimension(); + $box = $this->getBox(); + $rotationAngle = $this->getRotationAngle(); + if ($rotationAngle === 0) { + $y += abs(min($box[5], $box[7])); + } elseif ($rotationAngle === 90) { + $x += abs(min($box[5], $box[7])); + $y += $dimension[1]; + } elseif ($rotationAngle === 180) { + $x += $dimension[0]; + $y += abs(max($box[1], $box[3])); + } elseif ($rotationAngle === 270) { + $x += abs(max($box[1], $box[3])); + } + + return array($x, $y); + } + + private function getBox() { + if ($this->box === null) { + $gd = imagecreate(1, 1); + $this->box = imagettftext($gd, $this->size, 0, 0, 0, 0, $this->path, $this->text); + } + + return $this->box; + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGFontPhp.php b/api/barcode/BCGFontPhp.php new file mode 100644 index 0000000..78ea79d --- /dev/null +++ b/api/barcode/BCGFontPhp.php @@ -0,0 +1,154 @@ +font = max(0, intval($font)); + $this->backgroundColor = new BCGColor('white'); + $this->foregroundColor = new BCGColor('black'); + $this->setRotationAngle(0); + } + + /** + * Gets the text associated to the font. + * + * @return string + */ + public function getText() { + return $this->text; + } + + /** + * Sets the text associated to the font. + * + * @param string text + */ + public function setText($text) { + $this->text = $text; + } + + /** + * Gets the rotation in degree. + * + * @return int + */ + public function getRotationAngle() { + return (360 - $this->rotationAngle) % 360; + } + + /** + * Sets the rotation in degree. + * + * @param int + */ + public function setRotationAngle($rotationAngle) { + $this->rotationAngle = (int)$rotationAngle; + if ($this->rotationAngle !== 90 && $this->rotationAngle !== 180 && $this->rotationAngle !== 270) { + $this->rotationAngle = 0; + } + + $this->rotationAngle = (360 - $this->rotationAngle) % 360; + } + + /** + * Gets the background color. + * + * @return BCGColor + */ + public function getBackgroundColor() { + return $this->backgroundColor; + } + + /** + * Sets the background color. + * + * @param BCGColor $backgroundColor + */ + public function setBackgroundColor($backgroundColor) { + $this->backgroundColor = $backgroundColor; + } + + /** + * Gets the foreground color. + * + * @return BCGColor + */ + public function getForegroundColor() { + return $this->foregroundColor; + } + + /** + * Sets the foreground color. + * + * @param BCGColor $foregroundColor + */ + public function setForegroundColor($foregroundColor) { + $this->foregroundColor = $foregroundColor; + } + + /** + * Returns the width and height that the text takes to be written. + * + * @return int[] + */ + public function getDimension() { + $w = imagefontwidth($this->font) * strlen($this->text); + $h = imagefontheight($this->font); + + $rotationAngle = $this->getRotationAngle(); + if ($rotationAngle === 90 || $rotationAngle === 270) { + return array($h, $w); + } else { + return array($w, $h); + } + } + + /** + * Draws the text on the image at a specific position. + * $x and $y represent the left bottom corner. + * + * @param resource $im + * @param int $x + * @param int $y + */ + public function draw($im, $x, $y) { + if ($this->getRotationAngle() !== 0) { + if (!function_exists('imagerotate')) { + throw new BCGDrawException('The method imagerotate doesn\'t exist on your server. Do not use any rotation.'); + } + + $w = imagefontwidth($this->font) * strlen($this->text); + $h = imagefontheight($this->font); + $gd = imagecreatetruecolor($w, $h); + imagefilledrectangle($gd, 0, 0, $w - 1, $h - 1, $this->backgroundColor->allocate($gd)); + imagestring($gd, $this->font, 0, 0, $this->text, $this->foregroundColor->allocate($gd)); + $gd = imagerotate($gd, $this->rotationAngle, 0); + imagecopy($im, $gd, $x, $y, 0, 0, imagesx($gd), imagesy($gd)); + } else { + imagestring($im, $this->font, $x, $y, $this->text, $this->foregroundColor->allocate($im)); + } + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGLabel.php b/api/barcode/BCGLabel.php new file mode 100644 index 0000000..92d45e2 --- /dev/null +++ b/api/barcode/BCGLabel.php @@ -0,0 +1,321 @@ +setFont($font); + $this->setText($text); + $this->setPosition($position); + $this->setAlignment($alignment); + $this->setSpacing(4); + $this->setOffset(0); + $this->setRotationAngle(0); + $this->setBackgroundColor(new BCGColor('white')); + $this->setForegroundColor(new BCGColor('black')); + } + + /** + * Gets the text. + * + * @return string + */ + public function getText() { + return $this->font->getText(); + } + + /** + * Sets the text. + * + * @param string $text + */ + public function setText($text) { + $this->text = $text; + $this->font->setText($this->text); + } + + /** + * Gets the font. + * + * @return BCGFont + */ + public function getFont() { + return $this->font; + } + + /** + * Sets the font. + * + * @param BCGFont $font + */ + public function setFont($font) { + if ($font === null) { + throw new BCGArgumentException('Font cannot be null.', 'font'); + } + + $this->font = clone $font; + $this->font->setText($this->text); + $this->font->setRotationAngle($this->rotationAngle); + $this->font->setBackgroundColor($this->backgroundColor); + $this->font->setForegroundColor($this->foregroundColor); + } + + /** + * Gets the text position for drawing. + * + * @return int + */ + public function getPosition() { + return $this->position; + } + + /** + * Sets the text position for drawing. + * + * @param int $position + */ + public function setPosition($position) { + $position = intval($position); + if ($position !== self::POSITION_TOP && $position !== self::POSITION_RIGHT && $position !== self::POSITION_BOTTOM && $position !== self::POSITION_LEFT) { + throw new BCGArgumentException('The text position must be one of a valid constant.', 'position'); + } + + $this->position = $position; + } + + /** + * Gets the text alignment for drawing. + * + * @return int + */ + public function getAlignment() { + return $this->alignment; + } + + /** + * Sets the text alignment for drawing. + * + * @param int $alignment + */ + public function setAlignment($alignment) { + $alignment = intval($alignment); + if ($alignment !== self::ALIGN_LEFT && $alignment !== self::ALIGN_TOP && $alignment !== self::ALIGN_CENTER && $alignment !== self::ALIGN_RIGHT && $alignment !== self::ALIGN_BOTTOM) { + throw new BCGArgumentException('The text alignment must be one of a valid constant.', 'alignment'); + } + + $this->alignment = $alignment; + } + + /** + * Gets the offset. + * + * @return int + */ + public function getOffset() { + return $this->offset; + } + + /** + * Sets the offset. + * + * @param int $offset + */ + public function setOffset($offset) { + $this->offset = intval($offset); + } + + /** + * Gets the spacing. + * + * @return int + */ + public function getSpacing() { + return $this->spacing; + } + + /** + * Sets the spacing. + * + * @param int $spacing + */ + public function setSpacing($spacing) { + $this->spacing = max(0, intval($spacing)); + } + + /** + * Gets the rotation angle in degree. + * + * @return int + */ + public function getRotationAngle() { + return $this->font->getRotationAngle(); + } + + /** + * Sets the rotation angle in degree. + * + * @param int $rotationAngle + */ + public function setRotationAngle($rotationAngle) { + $this->rotationAngle = intval($rotationAngle); + $this->font->setRotationAngle($this->rotationAngle); + } + + /** + * Gets the background color in case of rotation. + * + * @return BCGColor + */ + public function getBackgroundColor() { + return $this->backgroundColor; + } + + /** + * Sets the background color in case of rotation. + * + * @param BCGColor $backgroundColor + */ + public /*internal*/ function setBackgroundColor($backgroundColor) { + $this->backgroundColor = $backgroundColor; + $this->font->setBackgroundColor($this->backgroundColor); + } + + /** + * Gets the foreground color. + * + * @return BCGColor + */ + public function getForegroundColor() { + return $this->font->getForegroundColor(); + } + + /** + * Sets the foreground color. + * + * @param BCGColor $foregroundColor + */ + public function setForegroundColor($foregroundColor) { + $this->foregroundColor = $foregroundColor; + $this->font->setForegroundColor($this->foregroundColor); + } + + /** + * Gets the dimension taken by the label, including the spacing and offset. + * [0]: width + * [1]: height + * + * @return int[] + */ + public function getDimension() { + $w = 0; + $h = 0; + + $dimension = $this->font->getDimension(); + $w = $dimension[0]; + $h = $dimension[1]; + + if ($this->position === self::POSITION_TOP || $this->position === self::POSITION_BOTTOM) { + $h += $this->spacing; + $w += max(0, $this->offset); + } else { + $w += $this->spacing; + $h += max(0, $this->offset); + } + + return array($w, $h); + } + + /** + * Draws the text. + * The coordinate passed are the positions of the barcode. + * $x1 and $y1 represent the top left corner. + * $x2 and $y2 represent the bottom right corner. + * + * @param resource $im + * @param int $x1 + * @param int $y1 + * @param int $x2 + * @param int $y2 + */ + public /*internal*/ function draw($im, $x1, $y1, $x2, $y2) { + $x = 0; + $y = 0; + + $fontDimension = $this->font->getDimension(); + + if ($this->position === self::POSITION_TOP || $this->position === self::POSITION_BOTTOM) { + if ($this->position === self::POSITION_TOP) { + $y = $y1 - $this->spacing - $fontDimension[1]; + } elseif ($this->position === self::POSITION_BOTTOM) { + $y = $y2 + $this->spacing; + } + + if ($this->alignment === self::ALIGN_CENTER) { + $x = ($x2 - $x1) / 2 + $x1 - $fontDimension[0] / 2 + $this->offset; + } elseif ($this->alignment === self::ALIGN_LEFT) { + $x = $x1 + $this->offset; + } else { + $x = $x2 + $this->offset - $fontDimension[0]; + } + } else { + if ($this->position === self::POSITION_LEFT) { + $x = $x1 - $this->spacing - $fontDimension[0]; + } elseif ($this->position === self::POSITION_RIGHT) { + $x = $x2 + $this->spacing; + } + + if ($this->alignment === self::ALIGN_CENTER) { + $y = ($y2 - $y1) / 2 + $y1 - $fontDimension[1] / 2 + $this->offset; + } elseif ($this->alignment === self::ALIGN_TOP) { + $y = $y1 + $this->offset; + } else { + $y = $y2 + $this->offset - $fontDimension[1]; + } + } + + $this->font->setText($this->text); + $this->font->draw($im, $x, $y); + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGParseException.php b/api/barcode/BCGParseException.php new file mode 100644 index 0000000..d2dc4a8 --- /dev/null +++ b/api/barcode/BCGParseException.php @@ -0,0 +1,26 @@ +barcode = $barcode; + parent::__construct($message, 10000); + } +} +?> \ No newline at end of file diff --git a/api/barcode/BCGcode39.barcode.php b/api/barcode/BCGcode39.barcode.php new file mode 100644 index 0000000..d28056b --- /dev/null +++ b/api/barcode/BCGcode39.barcode.php @@ -0,0 +1,194 @@ +starting = $this->ending = 43; + $this->keys = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%', '*'); + $this->code = array( // 0 added to add an extra space + '0001101000', /* 0 */ + '1001000010', /* 1 */ + '0011000010', /* 2 */ + '1011000000', /* 3 */ + '0001100010', /* 4 */ + '1001100000', /* 5 */ + '0011100000', /* 6 */ + '0001001010', /* 7 */ + '1001001000', /* 8 */ + '0011001000', /* 9 */ + '1000010010', /* A */ + '0010010010', /* B */ + '1010010000', /* C */ + '0000110010', /* D */ + '1000110000', /* E */ + '0010110000', /* F */ + '0000011010', /* G */ + '1000011000', /* H */ + '0010011000', /* I */ + '0000111000', /* J */ + '1000000110', /* K */ + '0010000110', /* L */ + '1010000100', /* M */ + '0000100110', /* N */ + '1000100100', /* O */ + '0010100100', /* P */ + '0000001110', /* Q */ + '1000001100', /* R */ + '0010001100', /* S */ + '0000101100', /* T */ + '1100000010', /* U */ + '0110000010', /* V */ + '1110000000', /* W */ + '0100100010', /* X */ + '1100100000', /* Y */ + '0110100000', /* Z */ + '0100001010', /* - */ + '1100001000', /* . */ + '0110001000', /* */ + '0101010000', /* $ */ + '0101000100', /* / */ + '0100010100', /* + */ + '0001010100', /* % */ + '0100101000' /* * */ + ); + + $this->setChecksum(false); + } + + /** + * Sets if we display the checksum. + * + * @param bool $checksum + */ + public function setChecksum($checksum) { + $this->checksum = (bool)$checksum; + } + + /** + * Parses the text before displaying it. + * + * @param mixed $text + */ + public function parse($text) { + parent::parse(strtoupper($text)); // Only Capital Letters are Allowed + } + + /** + * Draws the barcode. + * + * @param resource $im + */ + public function draw($im) { + // Starting * + $this->drawChar($im, $this->code[$this->starting], true); + + // Chars + $c = strlen($this->text); + for ($i = 0; $i < $c; $i++) { + $this->drawChar($im, $this->findCode($this->text[$i]), true); + } + + // Checksum (rarely used) + if ($this->checksum === true) { + $this->calculateChecksum(); + $this->drawChar($im, $this->code[$this->checksumValue % 43], true); + } + + // Ending * + $this->drawChar($im, $this->code[$this->ending], true); + $this->drawText($im, 0, 0, $this->positionX, $this->thickness); + } + + /** + * Returns the maximal size of a barcode. + * + * @param int $w + * @param int $h + * @return int[] + */ + public function getDimension($w, $h) { + $textlength = 13 * strlen($this->text); + $startlength = 13; + $checksumlength = 0; + if ($this->checksum === true) { + $checksumlength = 13; + } + + $endlength = 13; + + $w += $startlength + $textlength + $checksumlength + $endlength; + $h += $this->thickness; + return parent::getDimension($w, $h); + } + + /** + * Validates the input. + */ + protected function validate() { + $c = strlen($this->text); + if ($c === 0) { + throw new BCGParseException('code39', 'No data has been entered.'); + } + + // Checking if all chars are allowed + for ($i = 0; $i < $c; $i++) { + if (array_search($this->text[$i], $this->keys) === false) { + throw new BCGParseException('code39', 'The character \'' . $this->text[$i] . '\' is not allowed.'); + } + } + + if (strpos($this->text, '*') !== false) { + throw new BCGParseException('code39', 'The character \'*\' is not allowed.'); + } + + parent::validate(); + } + + /** + * Overloaded method to calculate checksum. + */ + protected function calculateChecksum() { + $this->checksumValue = 0; + $c = strlen($this->text); + for ($i = 0; $i < $c; $i++) { + $this->checksumValue += $this->findIndex($this->text[$i]); + } + + $this->checksumValue = $this->checksumValue % 43; + } + + /** + * Overloaded method to display the checksum. + */ + protected function processChecksum() { + if ($this->checksumValue === false) { // Calculate the checksum only once + $this->calculateChecksum(); + } + + if ($this->checksumValue !== false) { + return $this->keys[$this->checksumValue]; + } + + return false; + } +} +?> \ No newline at end of file diff --git a/api/barcode/index.html b/api/barcode/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/barcode/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/booklet/ajax-loader.gif b/api/booklet/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..13f0f64eab152fa4949476ed83ea24d6fd45a9bc GIT binary patch literal 3208 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 A6951J literal 0 HcmV?d00001 diff --git a/api/booklet/arrow-next.png b/api/booklet/arrow-next.png new file mode 100644 index 0000000000000000000000000000000000000000..726e98b9d44ffbf7465ee60d69c72bb90a318ad4 GIT binary patch literal 6484 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�V)UGq+eQcR&2_!wLw| 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%0D%&ocHzhK^Y+u zc3Rf;+mav1MWm#FKF;#`r!qQn3=P5tJi+@%4Omc6L4=Wa=~B@z|PX zeMj$;Sbf4fslfK;<{O1_-$B!pdt*4C&#kc@Xubpi@$ij;=z-$)d_4!}{0;w_K4{)J zWz;4y_gZ-1vdL@p=lr~Y|F4;%WJ|;IP=Z)6d#&rshkWr0#qu*`gW7PhFTE0otg{XZdI|HJp!StRv{?EKQAT_qpEMPH za_m+t!Q!{pJbnVZcOi&kpUut9<+}s&F8?+P#HR!vDYK znwoQmQDYZs*B03PF{smglf$^^Ey-WF>5z4OrXEN?X3#n-(NUp(;G1R$zgzFqQvHV# zwN^YFoGdvU5AVv_+5#u!XaZn@l*|0I)$>RPz6B9R#z;5XIM-^Tl>B^Gd2@49`Tqr= z<2u}>>)x)Y*V0}QeKONd2I;X3rQ}DO*GVRXRuPb900xkxUtO02fReJZHeGlm;+Sh^ zCEx(I663Y7>wkIF5&`(~F+^A?7JVVQH@U&1oflA+qTFP$O3G4=;8bmEdEHP}tIMBG zLdB`vx&~f5G-otqQ0Gk12*MwkZ_toXcvxEI`!zm zM^2_y%gk%e17%UvW92!+|6GA3A2;aesG1B&KL-KMZ$|7dbX+SDpK*Y)yoOwjtYzr` E0jv?s6aWAK literal 0 HcmV?d00001 diff --git a/api/booklet/buttons.png b/api/booklet/buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..5748b3b936c565cc926f5082145547429404d6e9 GIT binary patch literal 4307 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 BCU^h< literal 0 HcmV?d00001 diff --git a/api/booklet/ebook.css b/api/booklet/ebook.css new file mode 100644 index 0000000..56d33c6 --- /dev/null +++ b/api/booklet/ebook.css @@ -0,0 +1,106 @@ +/* Booklet jQuery Plugin Style*/ +.booklet{ + -moz-box-shadow:0px 0px 1px #fff; + -webkit-box-shadow:0px 0px 1px #fff; + box-shadow:0px 0px 1px #fff; + -moz-border-radius:10px; + -webkit-border-radius:10px; + border-radius:10px; +} +.booklet .b-wrap-left { + background:#fafafa no-repeat top left; + -webkit-border-top-left-radius: 10px; + -webkit-border-bottom-left-radius: 10px; + -moz-border-radius-topleft:10px; + -moz-border-radius-bottomleft: 10px; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; +} +.booklet .b-wrap-right { + background:#efefef no-repeat top left; + -webkit-border-top-right-radius: 10px; + -webkit-border-bottom-right-radius: 10px; + -moz-border-radius-topright: 10px; + -moz-border-radius-bottomright: 10px; + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; +} +.booklet .b-counter { + bottom:10px; + position:absolute; + display:block; + width:90%; + height:20px; + border-top:1px solid #ddd; + color:#222; + text-align:center; + font-size:12px; + padding:5px 0 0; + background:transparent; + -moz-box-shadow:0px -1px 1px #fff; + -webkit-box-shadow:0px -1px 1px #fff; + box-shadow:0px -1px 1px #fff; + opacity:0.8; +} +.book_wrapper{ + margin:0 auto; + width:1200px; + height:500px; + position:relative; +} +.book_wrapper img{max-width:580px;} +.book_wrapper a.demo{ + margin-left:50px; +} +.book_wrapper a.article:hover, +.book_wrapper a.demo:hover{ + background-position:50% -41px; + color:#13386a; +} + +.booklet .b-wrap-right img{ + border:1px solid #E6E3C2; +} +a#next_page_button, +a#prev_page_button{ + display:none; + position:absolute; + width:41px; + height:40px; + cursor:pointer; + margin-top:-20px; + top:50%; + background:transparent url(buttons.png) no-repeat 0px -40px; +} +a#prev_page_button{ + left:-50px; +} +a#next_page_button{ + right:-50px; + background-position:-41px -40px; +} +a#next_page_button:hover{ + background-position:-41px 0px; +} +a#prev_page_button:hover{ + background-position:0px 0px; +} +.loading{ + width:160px; + height:56px; + position: absolute; + top:50%; + margin-top:-28px; + right:135px; + line-height:56px; + color:#fff; + padding-left:60px; + font-size:15px; + background: #000 url(ajax-loader.gif) no-repeat 10px 50%; + opacity: 0.7; + z-index:9999; + -moz-border-radius:20px; + -webkit-border-radius:20px; + border-radius:20px; + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=70); +} \ No newline at end of file diff --git a/api/booklet/jquery.booklet.1.1.0.css b/api/booklet/jquery.booklet.1.1.0.css new file mode 100644 index 0000000..6fce85f --- /dev/null +++ b/api/booklet/jquery.booklet.1.1.0.css @@ -0,0 +1,96 @@ +/* @Booklet +----------------------------------------*/ + .booklet {width:800px; height:600px; position:relative; /*background:#fff;*/ margin:0 auto 10px;} + .booklet .b-page {left:0; top:0; position:absolute; overflow:hidden; padding:0;} + + .booklet .b-pN {} + .booklet .b-p0 {} + .booklet .b-p1 {} + .booklet .b-p2 {} + .booklet .b-p3 {} + .booklet .b-p4 {} + + /*.booklet .b-load {display:none;}*/ + + /* Page Wrappers */ + .booklet .b-wrap {top:0; position:absolute;} + .booklet .b-wrap-left {background:#fff;} + .booklet .b-wrap-right {background:#efefef;} + + .booklet .b-pN .b-wrap, + .booklet .b-p1 .b-wrap, + .booklet .b-p2 .b-wrap, + .booklet .b-p3 .b-wrap, + .booklet .b-p4 .b-wrap {left:0;} + .booklet .b-p0 .b-wrap {right:0;} + + /* Custom Page Types */ + .booklet .b-page-blank {padding:0; width:100%; height:100%;} + .booklet .b-page-cover {padding:0; width:100%; height:100%; background:#925C0E;} + .booklet .b-page-cover h3 {color:#fff; text-shadow:0px 1px 3px #222;} + + /* Page Numbers */ + .booklet .b-counter {bottom:10px; position:absolute; display:block; width:25px; height:20px; background:#ccc; color:#444; text-align:center; font-family:Georgia, "Times New Roman", Times, serif; font-size:10px; padding:5px 0 0;} + .booklet .b-wrap-left .b-counter {left:10px;} + .booklet .b-wrap-right .b-counter {right:10px;} + + /* Page Shadows */ + .booklet .b-shadow-f {right:0; top:0; position:absolute; opacity:0; background-image:url("shadow-top-forward.png"); background-repeat:repeat-y; background-position:100% 0;} + .booklet .b-shadow-b {left:0; top:0; position:absolute; opacity:0; background-image:url("shadow-top-back.png"); background-repeat:repeat-y; background-position:0 0;} + + .booklet .b-p0 {background-image:url("shadow.png"); background-repeat:repeat-y; background-position:100% 10px;} + .booklet .b-p3 {background-image:url("shadow.png"); background-repeat:repeat-y; background-position:0 10px;} + + /* Overlay Controls */ + .booklet .b-overlay {top:0; position:absolute; height:100%; width:50%;} + .booklet .b-overlay-prev {left:0;} + .booklet .b-overlay-next {right:0;} + + /* Tab Controls */ + .booklet .b-tab {background:#000; height:40px; width:100%; padding:10px 0 0; text-align:center; color:#ccc; position:absolute; font-size:11px;} + .booklet .b-tab-prev {left:0;} + .booklet .b-tab-next {right:0;} + .booklet .b-tab:hover {background:#aaa; color:#000;} + + /* Arrow Controls */ + .booklet .b-arrow {display:block; position:absolute; text-indent:-9999px; top:0; height:100%; width:74px;} + .booklet .b-arrow div {display:none; text-indent:-9999px; height:170px; width:74px; position:absolute; left:0; top:25%;} + .booklet .b-arrow-next {right:-80px;} + .booklet .b-arrow-prev {left:-80px;} + .booklet .b-arrow-next div {background:url("arrow-next.png") no-repeat left top;} + .booklet .b-arrow-prev div {background:url("arrow-prev.png") no-repeat left top;} + +/* @z-index fix (needed for older IE browsers) +----------------------------------------*/ + body {z-index:0;} + .b-menu {z-index:100;} + .b-selector {z-index:100;} + .booklet {z-index:10;} + .b-pN {z-index:10;} + .b-p0 {z-index:10;} + .b-p1 {z-index:10;} + .b-p2 {z-index:10;} + .b-p3 {z-index:10;} + .b-p4 {z-index:10;} + .b-prev {z-index:40;} + .b-next {z-index:40;} + .b-counter {z-index:40;} + +/* @Menu Items +----------------------------------------*/ + .b-menu {height:40px; padding:0 0 10px;} + + .b-selector {height:40px; position:relative; float:right; border:none; color:#cecece; cursor:pointer;} + .b-selector .b-current {padding:8px 15px 12px; line-height:20px; min-width:18px; height:20px; display:block; background:#000; text-align:center;} + .b-selector-page {width:auto; margin-left:15px;} + .b-selector-chapter {width:auto;} + + .b-selector:hover {color:#fff; background-position:left 0px;} + .b-selector:hover .b-current {background-position:right 0px;} + .b-selector ul {overflow:hidden; margin:0; list-style:none !important; position:absolute; top:40px; right:0; padding:0 0 10px; background:#000; width:240px; font:normal 12px "Myriad Pro", Myriad, "DejaVu Sans Condensed","Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif;} + .b-selector li {border:none;} + .b-selector a {color:#cecece; height:14px; text-decoration:none; display:block; padding:5px 10px;} + .b-selector a .b-text {float:left; clear:none;} + .b-selector a .b-num {float:right; clear:none;} + .b-selector a:hover {color:#fff;} + \ No newline at end of file diff --git a/api/booklet/jquery.booklet.1.1.0.js b/api/booklet/jquery.booklet.1.1.0.js new file mode 100644 index 0000000..be33155 --- /dev/null +++ b/api/booklet/jquery.booklet.1.1.0.js @@ -0,0 +1,864 @@ +/* + * jQuery Booklet Plugin + * Copyright (c) 2010 W. Grauvogel (http://builtbywill.com/) + * + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. + * + * Version : 1.1.0 + * + * Originally based on the work of: + * 1) Charles Mangin (http://clickheredammit.com/pageflip/) + */ +;(function($) { + +$.fn.booklet = function(options){ + + var o = $.extend({}, $.fn.booklet.defaults, options); + + return $(this).each(function() + { + var command, config, obj, id, i, target; + + //option type string - api call + if(typeof options == 'string') + { + //check if booklet has been initialized + if($(this).data('booklet')){ + command = options.toLowerCase(); + obj = $.fn.booklet.interfaces[$(this).data('id')]; + + if(command == 'next'){ obj.next() } + else if(command == 'prev'){ obj.prev() } + + } + } + //option type number - api call + else if(typeof options == 'number') + { + //check if booklet has been initialized + if($(this).data('booklet')){ + target = options; + obj = $.fn.booklet.interfaces[$(this).data('id')]; + + if(target % 2 != 0) { + target-= 1; + } + + obj.gotoPage(target); + } + + } + //else build new booklet + else + { + config = $.extend(true, {}, o); + + // Determine ID (Reuse array slots if possible) + id = $.fn.booklet.interfaces.length; + for(i = 0; i < id; i++) + { + if(typeof $.fn.booklet.interfaces[i] == 'undefined'){ id = i; break; } + } + + // Instantiate the booklet + obj = new booklet($(this), config, id); + + // Add API references + $.fn.booklet.interfaces[id] = obj; + } + }); +} + + +function booklet(target, options, id){ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//VARS + STRUCTURE +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + var self, opts, b, src, + hash, i, j, p, diff, busy, init, rhover, lhover, + titles = new Array(), chapters = new Array(), + pN, p0, p1, p2, p3, p4, pNwrap, p0wrap, p1wrap, p2wrap, p3wrap, p4wrap, wraps, sF, sB, + overlays, overlayN, overlayP, tabs, tabN, tabP, arrows, arrowN, arrowP, next, prev, ctrlsN, ctrlsP, + menu, chapter, dd, ddUL, ddH, ddLI, ddA, ddT, ddC, ddCUL, ddCH, ddCLI, ddCA, ddCT, + empty = '
    ', blank = '
    ' + ; + + busy = false; + init = false; + rhover = lhover = false; + self = this; + self.options = options; + self.id = id; + self.hash = ''; + opts = self.options; + b = target.addClass('booklet'); + src = b.children('.b-load'); + + //save page titles and chapter names, add page numbers + initPages(); + + //store data for api calls + b.data('booklet',true); + b.data('id', id); + b.data('total', src.children().length); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SETUP OPTIONS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + //set width + height + if(!opts.width){ + opts.width = b.width(); + } + if(!opts.height){ + opts.height = b.height(); + } + b.width(opts.width); + b.height(opts.height); + + //save page sizes and other vars + opts.pWidth = opts.width/2; + opts.pWidthN = '-'+(opts.width/2)+'px'; + opts.pWidthH = opts.width/4; + opts.pHeight = opts.height; + opts.pTotal = src.children().length; + opts.speedH = opts.speed/2; + + //set startingPage + if(opts.direction == 'LTR'){ + opts.curr = 0; + }else if(opts.direction == 'RTL'){ + opts.curr = opts.pTotal-2; + } + if(!isNaN(opts.startingPage) && opts.startingPage <= opts.pTotal && opts.startingPage > 0){ + if((opts.startingPage % 2) != 0){opts.startingPage--}; + opts.curr = opts.startingPage; + } + + //set booklet opts.name + if(opts.name){ + document.title = opts.name; + }else{ + opts.name = document.title; + } + + //save shadow widths for anim + if(opts.shadows){ + opts.shadowTopFwdWidth = '-'+opts.shadowTopFwdWidth+'px'; + opts.shadowTopBackWidth = '-'+opts.shadowTopBackWidth+'px'; + } + + //setup menu + if(opts.menu){ + menu = $(opts.menu).addClass('b-menu'); + p = opts.curr; + //setup page selctor + if(opts.pageSelector){ + //add selector + dd = $('
    '+ (p+1) +' - '+ (p+2) +'
    ').appendTo(menu); + ddUL = $('
      ').appendTo(dd).empty().css('height','auto'); + + //loop through all pages + for(i=0; i < opts.pTotal; i+=2){ + j = i; + //nums for normal view + nums = (j+1) +'-'+ (j+2); + if(opts.closed){ + //nums for closed book + j--; + if(i==0){nums='1'} + else if(i==opts.pTotal-2){nums=opts.pTotal-2} + else {nums = (j+1) +'-'+ (j+2);} + //nums for closed book with covers + if(opts.covers){ + j--; + if(i==0){nums=''} + else if(i==opts.pTotal-2){nums=''} + else {nums = (j+1) +'-'+ (j+2);} + } + } + //nums for RTL direction + if(opts.direction == 'RTL'){ + nums = (Math.abs(j - opts.pTotal)-1) +' - '+ ((Math.abs(j - opts.pTotal))); + if(opts.closed){ + if(i==opts.pTotal-2){nums='1'} + else if(i==0){nums=opts.pTotal-2} + else{nums = (Math.abs(j - opts.pTotal)-3) +' - '+ ((Math.abs(j - opts.pTotal)-2));} + + if(opts.covers){ + if(i==opts.pTotal-2){nums=''} + else if(i==0){nums=''} + else{nums = (Math.abs(j - opts.pTotal)-5) +' - '+ ((Math.abs(j - opts.pTotal)-4));} + } + } + dd.find('.b-current').text(nums); + ddLI = $('
      ').prependTo(ddUL); + }else{ + if(i==0){dd.find('.b-current').text(nums);} + ddLI = $('
    • '+ titles[i] +''+ nums +'
    • ').appendTo(ddUL); + } + + ddA = ddLI.find('a'); + if(!opts.hash){ + ddA.click(function(){ + if(opts.direction == 'RTL'){dd.find('.b-current').text($(this).find('.b-num').text());} + ddT = parseInt($(this).attr('id').replace('selector-page-','')); + self.gotoPage(ddT); + return false; + }); + } + } + + //set height + ddH = ddUL.height(); + ddUL.css({'height':0, 'padding-bottom':0}); + + //add hover effects + dd.unbind('hover').hover(function(){ + ddUL.stop().animate({height:ddH, paddingBottom:10}, 500); + },function(){ + ddUL.stop().animate({height:0, paddingBottom:0}, 500); + }); + } + + //setup chapter selctor + if(opts.chapterSelector){ + + chapter = chapters[opts.curr]; + if(chapter == ""){ chapter = chapters[opts.curr+1]; } + + ddC = $('
      '+chapter+'
      ').appendTo(menu); + ddCUL = $('
        ').appendTo(ddC).empty().css('height','auto'); + + for(i=0; i < opts.pTotal; i+=1){ + if(chapters[i] != "" && typeof chapters[i] != "undefined"){ + if(opts.direction == 'RTL'){ + j = i; + if(j % 2 != 0){j--;} + ddC.find('.b-current').text(chapters[i]); + ddCLI = $('
      • '+ chapters[i] +'
      • ').prependTo(ddCUL); + }else{ + ddCLI = $('
      • '+ chapters[i] +'
      • ').appendTo(ddCUL); + } + ddCA = ddCLI.find('a'); + if(!opts.hash){ + ddCA.click(function(){ + if(opts.direction == 'RTL'){ddC.find('.b-current').text($(this).find('.b-text').text());} + ddCT = parseInt($(this).attr('id').replace('selector-page-','')); + self.gotoPage(ddCT); + return false; + }); + } + } + } + + ddCH = ddCUL.height(); + ddCUL.css({'height':0, 'padding-bottom':0}); + + ddC.unbind('hover').hover(function(){ + ddCUL.stop().animate({height:ddCH, paddingBottom:10}, 500); + },function(){ + ddCUL.stop().animate({height:0, paddingBottom:0}, 500); + }); + } + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// API METHODS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + $.extend(self, + { + next : function(){ + if(!busy){ + self.gotoPage(opts.curr+2); + } + }, + prev : function(){ + if(!busy){ + self.gotoPage(opts.curr-2); + } + }, + gotoPage : function(num){ + //moving forward (increasing number) + if(num > opts.curr && num < opts.pTotal && num >= 0 && !busy){ + busy = true; + diff = num - opts.curr; + opts.curr = num; + opts.before.call(self, opts); + updatePager(); + updateCtrls(); + updateHash(opts.curr+1, opts); + initAnim(diff, true, sF); + + //hide p2 as p3 moves across it + p2.stop().animate({width:0}, opts.speedH, opts.easeIn); + //animate p3 from right to left (left: movement, width: reveal slide, paddingLeft: shadow underneath) + //call setuppages at end of animation to reset pages + p3.stop().animate({left:opts.pWidthH, width:opts.pWidthH, paddingLeft: opts.shadowBtmWidth}, opts.speedH, opts.easeIn) + .animate({left:0, width:opts.pWidth, paddingLeft:0}, opts.speedH); + p3wrap.animate({left:opts.shadowBtmWidth}, opts.speedH, opts.easeIn) + .animate({left:0}, opts.speedH, opts.easeOut, function(){updateAfter()}); + //moving backward (decreasing number) + }else if(num < opts.curr && num < opts.pTotal && num >= 0 && !busy){ + busy = true; + diff = opts.curr - num; + opts.curr = num; + opts.before.call(self, opts); + updatePager(); + updateCtrls(); + updateHash(opts.curr+1, opts); + initAnim(diff, false, sB); + + //hide p1 as p0 moves across it + p1.animate({left:opts.pWidth, width:0}, opts.speed, opts.easing); + p1wrap.animate({left:opts.pWidthN}, opts.speed, opts.easing); + //animate p0 from left to right (right: movement, width: reveal slide, paddingLeft: shadow underneath) + p0.animate({left:opts.pWidthH, width:opts.pWidthH}, opts.speedH, opts.easeIn) + .animate({left:opts.pWidth, width:opts.pWidth}, opts.speedH, opts.easeOut); + //animate .wrapper content with p0 to keep content right aligned throughout + //call setuppages at end of animation to reset pages + p0wrap.animate({right:opts.shadowBtmWidth}, opts.speedH,opts. easeIn) + .animate({right:0}, opts.speedH, opts.easeOut, function(){updateAfter()}); + } + } + }); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SETUP CONTROLS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + //add prev next user defined controls + if(opts.next){ + next = $(opts.next); + next.click(function(e){e.preventDefault(); self.next();}); + } + if(opts.prev){ + prev = $(opts.prev); + prev.click(function(e){e.preventDefault(); self.prev();}); + } + + //add overlays + if(opts.overlays){ + overlayP = $('
        ').appendTo(b); + overlayN = $('
        ').appendTo(b); + overlays = b.find('.b-overlay'); + + if ($.browser.msie) { + overlays.css({'background':'#fff','filter':'progid:DXImageTransform.Microsoft.Alpha(opacity=0) !important'}); + } + } + + //add tabs + if(opts.tabs){ + tabP = $('
        Previous
        ').appendTo(b); + tabN = $('
        Next
        ').appendTo(b); + tabs = b.find('.b-tab'); + + if(opts.tabWidth){ + tabs.width(opts.tabWidth); + } + if(opts.tabHeight){ + tabs.height(opts.tabHeight); + } + + tabs.css({'top': '-'+tabN.outerHeight()+'px'}); + b.css({'marginTop': tabN.outerHeight()}); + + //update ctrls for RTL direction + if(opts.direction == 'RTL'){ + tabN.html('Previous').attr('title','Previous Page'); + tabP.html('Next').attr('title','Next Page'); + } + }else{ + b.css({'marginTop': 0}); + } + + //add arrows + if(opts.arrows){ + arrowP = $('
        Previous
        ').appendTo(b); + arrowN = $('
        Next
        ').appendTo(b); + arrows = b.find('.b-arrow'); + + //update ctrls for RTL direction + if(opts.direction == 'RTL'){ + arrowN.html('
        Previous
        ').attr('title','Previous Page'); + arrowP.html('
        Next
        ').attr('title','Next Page'); + } + } + + //save all "b-prev" and "b-next" controls + ctrlsN = b.find('.b-next'); + ctrlsP = b.find('.b-prev'); + + //add click actions + ctrlsN.click(function(e){e.preventDefault(); self.next();}); + ctrlsP.click(function(e){e.preventDefault(); self.prev();}); + + //add page hover animations + if(opts.hovers){ + ctrlsN.hover( + function(){ + if(!busy && opts.curr+2 <= opts.pTotal-2){ + //animate + p2.stop().animate({'width':opts.pWidth-40}, 500, opts.easing); + p3.stop().animate({'left':opts.width-40, 'width':20, paddingLeft: 10}, 500, opts.easing); + rhover = true; + } + }, + function(){ + if(!busy && opts.curr+2 <= opts.pTotal-2){ + p2.stop().animate({'width':opts.pWidth}, 500, opts.easing); + p3.stop().animate({'left':opts.width, 'width':0, paddingLeft: 0}, 500, opts.easing); + rhover = false; + } + } + ); + ctrlsP.hover( + function(){ + if(!busy && opts.curr-2 >= 0){ + //animate + p1.stop().animate({left:10, width:opts.pWidth-10}, 400, opts.easing); + p1wrap.stop().animate({left:"-10px"}, 400, opts.easing); + p0.stop().animate({left:10, width:40}, 400, opts.easing); + p0wrap.stop().animate({right:10}, 400, opts.easing); + lhover = true; + } + }, + function(){ + if(!busy && opts.curr-2 >= 0){ + p1.stop().animate({left:0, width:opts.pWidth}, 400, opts.easing); + p1wrap.stop().animate({left:0}, 400, opts.easing); + p0.stop().animate({left:0, width:0}, 400, opts.easing); + p0wrap.stop().animate({right:0}, 400, opts.easing); + lhover = false; + } + } + ); + } + + //arrow animations + if(opts.arrows){ + if($.support.opacity){ + ctrlsN.hover( + function(){arrowN.find('div').stop().fadeTo('fast', 1);}, + function(){arrowN.find('div').stop().fadeTo('fast', 0); + }); + ctrlsP.hover( + function(){arrowP.find('div').stop().fadeTo('fast', 1);}, + function(){arrowP.find('div').stop().fadeTo('fast', 0); + }); + }else{ + ctrlsN.hover( + function(){arrowN.find('div').show();}, + function(){arrowN.find('div').hide(); + }); + ctrlsP.hover( + function(){arrowP.find('div').show();}, + function(){arrowP.find('div').hide(); + }); + } + } + + //keyboard ctrls + if(opts.keyboard){ + //keyboard ctrls + $(document).keyup(function(event){ + if(event.keyCode == 37){self.prev();} + else if(event.keyCode == 39){self.next();} + }); + } + + //hash ctrls + if(opts.hash){ + setupHash(); + clearInterval(); + setInterval(function(){pollHash()}, 250); + } + + //first time setup + resetPages(); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//General Functions +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + function initPages(){ + //fix for odd number of pages + if((src.children().length % 2) != 0){ + //if book is closed and using covers, add page before back cover, else after last page + if(opts.closed && opts.covers){ + src.children().last().before(blank); + }else{ + src.children().last().after(blank); + } + } + + //if closed book, add empty pages to start and end + if(opts.closed){ + $(empty).attr({'title':opts.closedFrontTitle || "Beginning", 'rel':opts.closedFrontChapter || "Beginning of Book"}).prependTo(src); + src.children().last().attr({'title':opts.closedBackTitle || "End", 'rel':opts.closedBackChapter || "End of Book"}); + src.append(empty); + } + + if(opts.direction == 'LTR'){ + j = 0; + }else{ + j = src.children().length; + if(opts.closed){j-=2;} + if(opts.covers){j-=2;} + $(src.children().get().reverse()).each(function(){ + $(this).appendTo(src); + }); + } + + //save titles and chapters + src.children().each(function(i){ + //save chapter title + if($(this).attr('rel')){ + chapters[i] = $(this).attr('rel'); + }else{ + chapters[i] = ""; + } + //save page title + titles[i] = $(this).attr('title'); + + //give content the correct wrapper and page wrapper + if($(this).hasClass('b-page-empty')){ + $(this).wrap('
        '); + }else if(opts.closed && opts.covers && (i == 1 || i == src.children().length-2)){ + $(this).wrap('
        '); + }else if(i % 2 != 0){ + $(this).wrap('
        '); + }else{ + $(this).wrap('
        '); + } + + $(this).parents('.b-page').addClass('b-page-'+i); + + //add page numbers + if(opts.pageNumbers && !$(this).hasClass('b-page-empty') && (!opts.closed || (opts.closed && !opts.covers) || (opts.closed && opts.covers && i != 1 && i != src.children().length-2))){ + if(opts.direction == 'LTR'){j++;} + $(this).parent().append('
        '+(j)+'
        '); + if(opts.direction == 'RTL'){j--;} + } + }); + + } + + function resetPages(){ + //reset all content + b.find('.b-page').removeClass('b-pN b-p0 b-p1 b-p2 b-p3 b-p4').hide(); + if(init){ + j = opts.pTotal-1; + for(i=0;i= 0){ + b.find('.b-page-'+(opts.curr-2)).addClass('b-pN').show(); + b.find('.b-page-'+(opts.curr-1)).addClass('b-p0').show(); + } + b.find('.b-page-'+(opts.curr)).addClass('b-p1').show(); + b.find('.b-page-'+(opts.curr+1)).addClass('b-p2').show(); + if(opts.curr+3 <= opts.pTotal){ + b.find('.b-page-'+(opts.curr+2)).addClass('b-p3').show(); + b.find('.b-page-'+(opts.curr+3)).addClass('b-p4').show(); + } + + //save structure elems to vars + pN = b.find('.b-pN'); + p0 = b.find('.b-p0'); + p1 = b.find('.b-p1'); + p2 = b.find('.b-p2'); + p3 = b.find('.b-p3'); + p4 = b.find('.b-p4'); + pNwrap = b.find('.b-pN .b-wrap'); + p0wrap = b.find('.b-p0 .b-wrap'); + p1wrap = b.find('.b-p1 .b-wrap'); + p2wrap = b.find('.b-p2 .b-wrap'); + p3wrap = b.find('.b-p3 .b-wrap'); + p4wrap = b.find('.b-p4 .b-wrap'); + wraps = b.find('.b-wrap'); + + //update css + wraps.attr('style',''); + wraps.css({'width':opts.pWidth-(opts.pagePadding*2), 'height':opts.pHeight-(opts.pagePadding*2), 'padding': opts.pagePadding}); + p1.css({'left':0,'width':opts.pWidth, 'height':opts.pHeight}); + p2.css({'left':opts.pWidth, 'width':opts.pWidth, 'opacity':1, 'height':opts.pHeight}); + pN.css({'left':0, 'width':opts.pWidth, 'height':opts.pHeight}); + p0.css({'left':0, 'width':0, 'height':opts.pHeight}); + p3.stop().css({'left':opts.pWidth*2, 'width':0, 'height':opts.pHeight, paddingLeft:0}); + p3wrap.stop().css({'left':0}); + p4.css({'left':opts.pWidth, 'width':opts.pWidth, 'height':opts.pHeight}); + + //update page order for animations + if(opts.curr+3 <= opts.pTotal){ + p3.after(p0.detach()); + p1.after(p4.detach()); + }else{ + p0.detach().appendTo(src); + } + init = true; + + //add shadows + sF = sB = null; + b.find('.b-shadow-b, .b-shadow-f').remove(); + if(opts.shadows){ + sF = $('
        ').appendTo(p3).css({'right':0,'width':opts.pWidth, 'height':opts.pHeight}); + sB = $('
        ').appendTo(p0).css({'left':0,'width':opts.pWidth, 'height':opts.pHeight}); + } + } + + function initAnim(diff, inc, shadow){ + //setup content + if(inc && diff > 2){ + b.find('.b-p3, .b-p4').removeClass('b-p3 b-p4').hide(); + b.find('.b-page-'+opts.curr).addClass('b-p3').show().stop().css({'left':opts.pWidth*2, 'width':0, 'height':opts.pHeight, paddingLeft:0}); + b.find('.b-page-'+(opts.curr+1)).addClass('b-p4').show().css({'left':opts.pWidth, 'width':opts.pWidth, 'height':opts.pHeight}); + b.find('.b-page-'+opts.curr+' .b-wrap').show().css({'width':opts.pWidth-(opts.pagePadding*2), 'height':opts.pHeight-(opts.pagePadding*2), 'padding': opts.pagePadding}); + b.find('.b-page-'+(opts.curr+1)+' .b-wrap').show().css({'width':opts.pWidth-(opts.pagePadding*2), 'height':opts.pHeight-(opts.pagePadding*2), 'padding': opts.pagePadding}); + + p3 = b.find('.b-p3'); + p4 = b.find('.b-p4'); + p3wrap = b.find('.b-p3 .b-wrap'); + p4wrap = b.find('.b-p4 .b-wrap'); + + if(rhover){ + p3.css({'left':opts.width-40, 'width':20, 'padding-left': 10}); + } + + shadow.appendTo(p3); + + p1.after(p4.detach()); + p2.after(p3.detach()); + }else if(!inc && diff > 2){ + b.find('.b-pN, .b-p0').removeClass('b-pN b-p0').hide(); + b.find('.b-page-'+opts.curr).addClass('b-pN').show().css({'left':0, 'width':opts.pWidth, 'height':opts.pHeight}); + b.find('.b-page-'+(opts.curr+1)).addClass('b-p0').show().css({'left':0, 'width':0, 'height':opts.pHeight}); + b.find('.b-page-'+opts.curr+' .b-wrap').show().css({'width':opts.pWidth-(opts.pagePadding*2), 'height':opts.pHeight-(opts.pagePadding*2), 'padding': opts.pagePadding}); + b.find('.b-page-'+(opts.curr+1)+' .b-wrap').show().css({'width':opts.pWidth-(opts.pagePadding*2), 'height':opts.pHeight-(opts.pagePadding*2), 'padding': opts.pagePadding}); + + pN = b.find('.b-pN'); + p0 = b.find('.b-p0'); + pNwrap = b.find('.b-pN .b-wrap'); + p0wrap = b.find('.b-p0 .b-wrap'); + + if(lhover){ + p0.css({left:10, width:40}); + p0wrap.css({right:10}); + } + + shadow.appendTo(p0); + + p0.detach().appendTo(src); + } + + //updates if moving to start and end of book + if(opts.closed){ + if(!inc && opts.curr == 0){ + pN.hide(); + }else if(!inc){ + pN.show(); + } + if(inc && opts.curr >= opts.pTotal-2){ + p4.hide(); + }else if(inc){ + p4.show(); + } + } + //init shadows + if(opts.shadows){ + //check for opacity support -> animate shadow overlay on moving slide + if($.support.opacity){ + shadow.animate({opacity:1}, opts.speedH, opts.easeIn) + .animate({opacity:0}, opts.speedH, opts.easeOut); + }else{ + if(inc){ + shadow.animate({right:opts.shadowTopFwdWidth}, opts.speed, opts.easeIn); + }else{ + shadow.animate({left:opts.shadowTopBackWidth}, opts.speed, opts.easeIn); + } + } + } + } + + function updateAfter(){ + resetPages(); + updatePager(); + updateCtrls(); + opts.after.call(self, opts); + busy = false; + } + + function updateCtrls(){ + //update ctrls, cursors and visibility + if(opts.overlays || opts.tabs || opts.arrows){ + if(opts.curr < opts.pTotal-2){ + ctrlsN.fadeIn('fast').css('cursor',opts.cursor); + }else{ + ctrlsN.fadeOut('fast').css('cursor','default'); + } + if(opts.curr >= 2 && opts.curr != 0){ + ctrlsP.fadeIn('fast').css('cursor',opts.cursor); + }else{ + ctrlsP.fadeOut('fast').css('cursor','default'); + } + } + } + + function updatePager(){ + if(opts.pageSelector){ + if(opts.direction == 'RTL'){ + nums = (Math.abs(opts.curr - opts.pTotal)-1) +' - '+ ((Math.abs(opts.curr - opts.pTotal))); + if(opts.closed){ + if(opts.curr==opts.pTotal-2){nums='1'} + else if(opts.curr==0){nums=opts.pTotal-2} + else{nums = (Math.abs(opts.curr - opts.pTotal)-2) +' - '+ ((Math.abs(opts.curr - opts.pTotal)-1));} + + if(opts.covers){ + if(opts.curr==opts.pTotal-2){nums=''} + else if(opts.curr==0){nums=''} + else{nums = (Math.abs(opts.curr - opts.pTotal)-3) +' - '+ ((Math.abs(opts.curr - opts.pTotal)-2));} + } + } + $(opts.menu+' .b-selector-page .b-current').text(nums); + }else{ + nums = (opts.curr+1) +' - '+ (opts.curr+2); + if(opts.closed){ + if(opts.curr==0){nums='1'} + else if(opts.curr==opts.pTotal-2){nums=opts.pTotal-2} + else {nums = (opts.curr) +'-'+ (opts.curr+1);} + + if(opts.covers){ + if(opts.curr==0){nums=''} + else if(opts.curr==opts.pTotal-2){nums=''} + else {nums = (opts.curr-1) +'-'+ (opts.curr);} + } + } + $(opts.menu+' .b-selector-page .b-current').text(nums); + } + } + if(opts.chapterSelector){ + if(chapters[opts.curr]!=""){ + $(opts.menu+' .b-selector-chapter .b-current').text(chapters[opts.curr]); + }else if(chapters[opts.curr+1]!=""){ + $(opts.menu+' .b-selector-chapter .b-current').text(chapters[opts.curr+1]); + } + + if(opts.direction == 'RTL' && chapters[opts.curr+1]!=""){ + $(opts.menu+' .b-selector-chapter .b-current').text(chapters[opts.curr+1]); + }else if(chapters[opts.curr]!=""){ + $(opts.menu+' .b-selector-chapter .b-current').text(chapters[opts.curr]); + } + } + } + + function setupHash(){ + hash = getHashNum(); + + if(!isNaN(hash) && hash <= opts.pTotal-1 && hash >= 0 && hash != ''){ + if((hash % 2) != 0){ + hash--; + } + opts.curr = hash; + }else{ + updateHash(opts.curr+1, opts); + } + + self.hash = hash; + } + + function pollHash(){ + hash = getHashNum(); + //check page num + if(!isNaN(hash) && hash <= opts.pTotal-1 && hash >= 0){ + if(hash != opts.curr && hash.toString()!=self.hash){ + if((hash % 2) != 0){hash--}; + + document.title = opts.name + " - Page "+ (hash+1); + + if(!busy){ + self.gotoPage(hash); + self.hash = hash; + } + } + } + } + + //get page number from hash tag, last element + function getHashNum(){ + var hash = window.location.hash.split('/'); + if(hash.length > 1){ + return parseInt(hash[2])-1; + }else{ + return ''; + } + } + + //set the hash + function updateHash(hash, opts){ + if(opts.hash){ + window.location.hash = "/page/" + hash; + } + } + +} + +//define empty array to hold API references +$.fn.booklet.interfaces = []; + +//define default options +$.fn.booklet.defaults = { + name: null, // name of the booklet to display in the document title bar + width: 600, // container width + height: 400, // container height + speed: 1000, // speed of the transition between pages + direction: 'LTR', // direction of the overall content organization, default LTR, left to right, can be RTL for languages which read right to left + startingPage: 0, // index of the first page to be displayed + easing: 'easeInOutQuad', // easing method for complete transition + easeIn: 'easeInQuad', // easing method for first half of transition + easeOut: 'easeOutQuad', // easing method for second half of transition + + closed: false, // start with the book "closed", will add empty pages to beginning and end of book + closedFrontTitle: null, // used with "closed", "menu" and "pageSelector", determines title of blank starting page + closedFrontChapter: null, // used with "closed", "menu" and "chapterSelector", determines chapter name of blank starting page + closedBackTitle: null, // used with "closed", "menu" and "pageSelector", determines chapter name of blank ending page + closedBackChapter: null, // used with "closed", "menu" and "chapterSelector", determines chapter name of blank ending page + covers: false, // used with "closed", makes first and last pages into covers, without page numbers (if enabled) + + pagePadding: 10, // padding for each page wrapper + pageNumbers: true, // display page numbers on each page + + hovers: true, // enables preview pageturn hover animation, shows a small preview of previous or next page on hover + overlays: true, // enables navigation using a page sized overlay, when enabled links inside the content will not be clickable + tabs: false, // adds tabs along the top of the pages + tabWidth: 60, // set the width of the tabs + tabHeight: 20, // set the height of the tabs + arrows: false, // adds arrows overlayed over the book edges + cursor: 'pointer', // cursor css setting for side bar areas + + hash: false, // enables navigation using a hash string, ex: #/page/1 for page 1, will affect all booklets with 'hash' enabled + keyboard: true, // enables navigation with arrow keys (left: previous, right: next) + next: null, // selector for element to use as click trigger for next page + prev: null, // selector for element to use as click trigger for previous page + + menu: null, // selector for element to use as the menu area, required for 'pageSelector' + pageSelector: false, // enables navigation with a dropdown menu of pages, requires 'menu' + chapterSelector: false, // enables navigation with a dropdown menu of chapters, determined by the "rel" attribute, requires 'menu' + + shadows: true, // display shadows on page animations + shadowTopFwdWidth: 166, // shadow width for top forward anim + shadowTopBackWidth: 166, // shadow width for top back anim + shadowBtmWidth: 50, // shadow width for bottom shadow + + before: function(){}, // callback invoked before each page turn animation + after: function(){} // callback invoked after each page turn animation +} + +})(jQuery); \ No newline at end of file diff --git a/api/booklet/jquery.booklet.1.1.0.min.js b/api/booklet/jquery.booklet.1.1.0.min.js new file mode 100644 index 0000000..4b6fa5e --- /dev/null +++ b/api/booklet/jquery.booklet.1.1.0.min.js @@ -0,0 +1,13 @@ +/* + * jQuery Booklet Plugin + * Copyright (c) 2010 W. Grauvogel (http://builtbywill.com/) + * + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. + * + * Version : 1.1.0 + * + * Originally based on the work of: + * 1) Charles Mangin (http://clickheredammit.com/pageflip/) + */ +(function(b){b.fn.booklet=function(c){var d=b.extend({},b.fn.booklet.defaults,c);return b(this).each(function(){var j,e,h,k,f,g;if(typeof c=="string"){if(b(this).data("booklet")){j=c.toLowerCase();h=b.fn.booklet.interfaces[b(this).data("id")];if(j=="next"){h.next()}else{if(j=="prev"){h.prev()}}}}else{if(typeof c=="number"){if(b(this).data("booklet")){g=c;h=b.fn.booklet.interfaces[b(this).data("id")];if(g%2!=0){g-=1}h.gotoPage(g)}}else{e=b.extend(true,{},d);k=b.fn.booklet.interfaces.length;for(f=0;f0){if((av.startingPage%2)!=0){av.startingPage--}av.curr=av.startingPage}if(av.name){document.title=av.name}else{av.name=document.title}if(av.shadows){av.shadowTopFwdWidth="-"+av.shadowTopFwdWidth+"px";av.shadowTopBackWidth="-"+av.shadowTopBackWidth+"px"}if(av.menu){l=b(av.menu).addClass("b-menu");E=av.curr;if(av.pageSelector){q=b('
        '+(E+1)+" - "+(E+2)+"
        ").appendTo(l);v=b("
          ").appendTo(q).empty().css("height","auto");for(L=0;L'+aw[L+1]+''+nums+"").prependTo(v)}else{if(L==0){q.find(".b-current").text(nums)}an=b('
        • '+aw[L]+''+nums+"
        • ").appendTo(v)}w=an.find("a");if(!av.hash){w.click(function(){if(av.direction=="RTL"){q.find(".b-current").text(b(this).find(".b-num").text())}k=parseInt(b(this).attr("id").replace("selector-page-",""));ao.gotoPage(k);return false})}}r=v.height();v.css({height:0,"padding-bottom":0});q.unbind("hover").hover(function(){v.stop().animate({height:r,paddingBottom:10},500)},function(){v.stop().animate({height:0,paddingBottom:0},500)})}if(av.chapterSelector){X=K[av.curr];if(X==""){X=K[av.curr+1]}u=b('
          '+X+"
          ").appendTo(l);P=b("
            ").appendTo(u).empty().css("height","auto");for(L=0;L'+K[L]+"").prependTo(P)}else{au=b('
          • '+K[L]+"
          • ").appendTo(P)}t=au.find("a");if(!av.hash){t.click(function(){if(av.direction=="RTL"){u.find(".b-current").text(b(this).find(".b-text").text())}g=parseInt(b(this).attr("id").replace("selector-page-",""));ao.gotoPage(g);return false})}}}n=P.height();P.css({height:0,"padding-bottom":0});u.unbind("hover").hover(function(){P.stop().animate({height:n,paddingBottom:10},500)},function(){P.stop().animate({height:0,paddingBottom:0},500)})}}b.extend(ao,{next:function(){if(!ad){ao.gotoPage(av.curr+2)}},prev:function(){if(!ad){ao.gotoPage(av.curr-2)}},gotoPage:function(i){if(i>av.curr&&i=0&&!ad){ad=true;o=i-av.curr;av.curr=i;av.before.call(ao,av);ar();z();M(av.curr+1,av);Q(o,true,ax);Y.stop().animate({width:0},av.speedH,av.easeIn);W.stop().animate({left:av.pWidthH,width:av.pWidthH,paddingLeft:av.shadowBtmWidth},av.speedH,av.easeIn).animate({left:0,width:av.pWidth,paddingLeft:0},av.speedH);c.animate({left:av.shadowBtmWidth},av.speedH,av.easeIn).animate({left:0},av.speedH,av.easeOut,function(){H()})}else{if(i=0&&!ad){ad=true;o=av.curr-i;av.curr=i;av.before.call(ao,av);ar();z();M(av.curr+1,av);Q(o,false,az);Z.animate({left:av.pWidth,width:0},av.speed,av.easing);J.animate({left:av.pWidthN},av.speed,av.easing);ab.animate({left:av.pWidthH,width:av.pWidthH},av.speedH,av.easeIn).animate({left:av.pWidth,width:av.pWidth},av.speedH,av.easeOut);ag.animate({right:av.shadowBtmWidth},av.speedH,av.easeIn).animate({right:0},av.speedH,av.easeOut,function(){H()})}}}});if(av.next){af=b(av.next);af.click(function(i){i.preventDefault();ao.next()})}if(av.prev){y=b(av.prev);y.click(function(i){i.preventDefault();ao.prev()})}if(av.overlays){ak=b('
            ').appendTo(S);al=b('
            ').appendTo(S);T=S.find(".b-overlay");if(b.browser.msie){T.css({background:"#fff",filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0) !important"})}}if(av.tabs){ai=b('
            Previous
            ').appendTo(S);aj=b('
            Next
            ').appendTo(S);R=S.find(".b-tab");if(av.tabWidth){R.width(av.tabWidth)}if(av.tabHeight){R.height(av.tabHeight)}R.css({top:"-"+aj.outerHeight()+"px"});S.css({marginTop:aj.outerHeight()});if(av.direction=="RTL"){aj.html("Previous").attr("title","Previous Page");ai.html("Next").attr("title","Next Page")}}else{S.css({marginTop:0})}if(av.arrows){B=b('
            Previous
            ').appendTo(S);D=b('
            Next
            ').appendTo(S);m=S.find(".b-arrow");if(av.direction=="RTL"){D.html("
            Previous
            ").attr("title","Previous Page");B.html("
            Next
            ").attr("title","Next Page")}}e=S.find(".b-next");d=S.find(".b-prev");e.click(function(i){i.preventDefault();ao.next()});d.click(function(i){i.preventDefault();ao.prev()});if(av.hovers){e.hover(function(){if(!ad&&av.curr+2<=av.pTotal-2){Y.stop().animate({width:av.pWidth-40},500,av.easing);W.stop().animate({left:av.width-40,width:20,paddingLeft:10},500,av.easing);C=true}},function(){if(!ad&&av.curr+2<=av.pTotal-2){Y.stop().animate({width:av.pWidth},500,av.easing);W.stop().animate({left:av.width,width:0,paddingLeft:0},500,av.easing);C=false}});d.hover(function(){if(!ad&&av.curr-2>=0){Z.stop().animate({left:10,width:av.pWidth-10},400,av.easing);J.stop().animate({left:"-10px"},400,av.easing);ab.stop().animate({left:10,width:40},400,av.easing);ag.stop().animate({right:10},400,av.easing);N=true}},function(){if(!ad&&av.curr-2>=0){Z.stop().animate({left:0,width:av.pWidth},400,av.easing);J.stop().animate({left:0},400,av.easing);ab.stop().animate({left:0,width:0},400,av.easing);ag.stop().animate({right:0},400,av.easing);N=false}})}if(av.arrows){if(b.support.opacity){e.hover(function(){D.find("div").stop().fadeTo("fast",1)},function(){D.find("div").stop().fadeTo("fast",0)});d.hover(function(){B.find("div").stop().fadeTo("fast",1)},function(){B.find("div").stop().fadeTo("fast",0)})}else{e.hover(function(){D.find("div").show()},function(){D.find("div").hide()});d.hover(function(){B.find("div").show()},function(){B.find("div").hide()})}}if(av.keyboard){b(document).keyup(function(i){if(i.keyCode==37){ao.prev()}else{if(i.keyCode==39){ao.next()}}})}if(av.hash){f();clearInterval();setInterval(function(){V()},250)}aa();function h(){if((A.children().length%2)!=0){if(av.closed&&av.covers){A.children().last().before(at)}else{A.children().last().after(at)}}if(av.closed){b(ap).attr({title:av.closedFrontTitle||"Beginning",rel:av.closedFrontChapter||"Beginning of Book"}).prependTo(A);A.children().last().attr({title:av.closedBackTitle||"End",rel:av.closedBackChapter||"End of Book"});A.append(ap)}if(av.direction=="LTR"){I=0}else{I=A.children().length;if(av.closed){I-=2}if(av.covers){I-=2}b(A.children().get().reverse()).each(function(){b(this).appendTo(A)})}A.children().each(function(j){if(b(this).attr("rel")){K[j]=b(this).attr("rel")}else{K[j]=""}aw[j]=b(this).attr("title");if(b(this).hasClass("b-page-empty")){b(this).wrap('
            ')}else{if(av.closed&&av.covers&&(j==1||j==A.children().length-2)){b(this).wrap('
            ')}else{if(j%2!=0){b(this).wrap('
            ')}else{b(this).wrap('
            ')}}}b(this).parents(".b-page").addClass("b-page-"+j);if(av.pageNumbers&&!b(this).hasClass("b-page-empty")&&(!av.closed||(av.closed&&!av.covers)||(av.closed&&av.covers&&j!=1&&j!=A.children().length-2))){if(av.direction=="LTR"){I++}b(this).parent().append('
            '+(I)+"
            ");if(av.direction=="RTL"){I--}}})}function aa(){S.find(".b-page").removeClass("b-pN b-p0 b-p1 b-p2 b-p3 b-p4").hide();if(ah){I=av.pTotal-1;for(L=0;L=0){S.find(".b-page-"+(av.curr-2)).addClass("b-pN").show();S.find(".b-page-"+(av.curr-1)).addClass("b-p0").show()}S.find(".b-page-"+(av.curr)).addClass("b-p1").show();S.find(".b-page-"+(av.curr+1)).addClass("b-p2").show();if(av.curr+3<=av.pTotal){S.find(".b-page-"+(av.curr+2)).addClass("b-p3").show();S.find(".b-page-"+(av.curr+3)).addClass("b-p4").show()}F=S.find(".b-pN");ab=S.find(".b-p0");Z=S.find(".b-p1");Y=S.find(".b-p2");W=S.find(".b-p3");U=S.find(".b-p4");ay=S.find(".b-pN .b-wrap");ag=S.find(".b-p0 .b-wrap");J=S.find(".b-p1 .b-wrap");s=S.find(".b-p2 .b-wrap");c=S.find(".b-p3 .b-wrap");aq=S.find(".b-p4 .b-wrap");am=S.find(".b-wrap");am.attr("style","");am.css({width:av.pWidth-(av.pagePadding*2),height:av.pHeight-(av.pagePadding*2),padding:av.pagePadding});Z.css({left:0,width:av.pWidth,height:av.pHeight});Y.css({left:av.pWidth,width:av.pWidth,opacity:1,height:av.pHeight});F.css({left:0,width:av.pWidth,height:av.pHeight});ab.css({left:0,width:0,height:av.pHeight});W.stop().css({left:av.pWidth*2,width:0,height:av.pHeight,paddingLeft:0});c.stop().css({left:0});U.css({left:av.pWidth,width:av.pWidth,height:av.pHeight});if(av.curr+3<=av.pTotal){W.after(ab.detach());Z.after(U.detach())}else{ab.detach().appendTo(A)}ah=true;ax=az=null;S.find(".b-shadow-b, .b-shadow-f").remove();if(av.shadows){ax=b('
            ').appendTo(W).css({right:0,width:av.pWidth,height:av.pHeight});az=b('
            ').appendTo(ab).css({left:0,width:av.pWidth,height:av.pHeight})}}function Q(j,i,p){if(i&&j>2){S.find(".b-p3, .b-p4").removeClass("b-p3 b-p4").hide();S.find(".b-page-"+av.curr).addClass("b-p3").show().stop().css({left:av.pWidth*2,width:0,height:av.pHeight,paddingLeft:0});S.find(".b-page-"+(av.curr+1)).addClass("b-p4").show().css({left:av.pWidth,width:av.pWidth,height:av.pHeight});S.find(".b-page-"+av.curr+" .b-wrap").show().css({width:av.pWidth-(av.pagePadding*2),height:av.pHeight-(av.pagePadding*2),padding:av.pagePadding});S.find(".b-page-"+(av.curr+1)+" .b-wrap").show().css({width:av.pWidth-(av.pagePadding*2),height:av.pHeight-(av.pagePadding*2),padding:av.pagePadding});W=S.find(".b-p3");U=S.find(".b-p4");c=S.find(".b-p3 .b-wrap");aq=S.find(".b-p4 .b-wrap");if(C){W.css({left:av.width-40,width:20,"padding-left":10})}p.appendTo(W);Z.after(U.detach());Y.after(W.detach())}else{if(!i&&j>2){S.find(".b-pN, .b-p0").removeClass("b-pN b-p0").hide();S.find(".b-page-"+av.curr).addClass("b-pN").show().css({left:0,width:av.pWidth,height:av.pHeight});S.find(".b-page-"+(av.curr+1)).addClass("b-p0").show().css({left:0,width:0,height:av.pHeight});S.find(".b-page-"+av.curr+" .b-wrap").show().css({width:av.pWidth-(av.pagePadding*2),height:av.pHeight-(av.pagePadding*2),padding:av.pagePadding});S.find(".b-page-"+(av.curr+1)+" .b-wrap").show().css({width:av.pWidth-(av.pagePadding*2),height:av.pHeight-(av.pagePadding*2),padding:av.pagePadding});F=S.find(".b-pN");ab=S.find(".b-p0");ay=S.find(".b-pN .b-wrap");ag=S.find(".b-p0 .b-wrap");if(N){ab.css({left:10,width:40});ag.css({right:10})}p.appendTo(ab);ab.detach().appendTo(A)}}if(av.closed){if(!i&&av.curr==0){F.hide()}else{if(!i){F.show()}}if(i&&av.curr>=av.pTotal-2){U.hide()}else{if(i){U.show()}}}if(av.shadows){if(b.support.opacity){p.animate({opacity:1},av.speedH,av.easeIn).animate({opacity:0},av.speedH,av.easeOut)}else{if(i){p.animate({right:av.shadowTopFwdWidth},av.speed,av.easeIn)}else{p.animate({left:av.shadowTopBackWidth},av.speed,av.easeIn)}}}}function H(){aa();ar();z();av.after.call(ao,av);ad=false}function z(){if(av.overlays||av.tabs||av.arrows){if(av.curr=2&&av.curr!=0){d.fadeIn("fast").css("cursor",av.cursor)}else{d.fadeOut("fast").css("cursor","default")}}}function ar(){if(av.pageSelector){if(av.direction=="RTL"){nums=(Math.abs(av.curr-av.pTotal)-1)+" - "+((Math.abs(av.curr-av.pTotal)));if(av.closed){if(av.curr==av.pTotal-2){nums="1"}else{if(av.curr==0){nums=av.pTotal-2}else{nums=(Math.abs(av.curr-av.pTotal)-2)+" - "+((Math.abs(av.curr-av.pTotal)-1))}}if(av.covers){if(av.curr==av.pTotal-2){nums=""}else{if(av.curr==0){nums=""}else{nums=(Math.abs(av.curr-av.pTotal)-3)+" - "+((Math.abs(av.curr-av.pTotal)-2))}}}}b(av.menu+" .b-selector-page .b-current").text(nums)}else{nums=(av.curr+1)+" - "+(av.curr+2);if(av.closed){if(av.curr==0){nums="1"}else{if(av.curr==av.pTotal-2){nums=av.pTotal-2}else{nums=(av.curr)+"-"+(av.curr+1)}}if(av.covers){if(av.curr==0){nums=""}else{if(av.curr==av.pTotal-2){nums=""}else{nums=(av.curr-1)+"-"+(av.curr)}}}}b(av.menu+" .b-selector-page .b-current").text(nums)}}if(av.chapterSelector){if(K[av.curr]!=""){b(av.menu+" .b-selector-chapter .b-current").text(K[av.curr])}else{if(K[av.curr+1]!=""){b(av.menu+" .b-selector-chapter .b-current").text(K[av.curr+1])}}if(av.direction=="RTL"&&K[av.curr+1]!=""){b(av.menu+" .b-selector-chapter .b-current").text(K[av.curr+1])}else{if(K[av.curr]!=""){b(av.menu+" .b-selector-chapter .b-current").text(K[av.curr])}}}}function f(){O=x();if(!isNaN(O)&&O<=av.pTotal-1&&O>=0&&O!=""){if((O%2)!=0){O--}av.curr=O}else{M(av.curr+1,av)}ao.hash=O}function V(){O=x();if(!isNaN(O)&&O<=av.pTotal-1&&O>=0){if(O!=av.curr&&O.toString()!=ao.hash){if((O%2)!=0){O--}document.title=av.name+" - Page "+(O+1);if(!ad){ao.gotoPage(O);ao.hash=O}}}}function x(){var i=window.location.hash.split("/");if(i.length>1){return parseInt(i[2])-1}else{return""}}function M(j,i){if(i.hash){window.location.hash="/page/"+j}}}b.fn.booklet.interfaces=[];b.fn.booklet.defaults={name:null,width:600,height:400,speed:1000,direction:"LTR",startingPage:0,easing:"easeInOutQuad",easeIn:"easeInQuad",easeOut:"easeOutQuad",closed:false,closedFrontTitle:null,closedFrontChapter:null,closedBackTitle:null,closedBackChapter:null,covers:false,pagePadding:10,pageNumbers:true,hovers:true,overlays:true,tabs:false,tabWidth:60,tabHeight:20,arrows:false,cursor:"pointer",hash:false,keyboard:true,next:null,prev:null,menu:null,pageSelector:false,chapterSelector:false,shadows:true,shadowTopFwdWidth:166,shadowTopBackWidth:166,shadowBtmWidth:50,before:function(){},after:function(){}}})(jQuery); \ No newline at end of file diff --git a/api/booklet/jquery.easing.1.3.js b/api/booklet/jquery.easing.1.3.js new file mode 100644 index 0000000..600562e --- /dev/null +++ b/api/booklet/jquery.easing.1.3.js @@ -0,0 +1,38 @@ +/* + * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ + * + * Uses the built in easing capabilities added In jQuery 1.1 + * to offer multiple easing options + * + * TERMS OF USE - jQuery Easing + * + * Open source under the BSD License. + * + * Copyright © 2008 George McGinley Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +jQuery.easing['jswing']=jQuery.easing['swing'];jQuery.extend(jQuery.easing,{def:'easeOutQuad',swing:function(x,t,b,c,d){return jQuery.easing[jQuery.easing.def](x,t,b,c,d)},easeInQuad:function(x,t,b,c,d){return c*(t/=d)*t+b},easeOutQuad:function(x,t,b,c,d){return-c*(t/=d)*(t-2)+b},easeInOutQuad:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b},easeInCubic:function(x,t,b,c,d){return c*(t/=d)*t*t+b},easeOutCubic:function(x,t,b,c,d){return c*((t=t/d-1)*t*t+1)+b},easeInOutCubic:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t+b;return c/2*((t-=2)*t*t+2)+b},easeInQuart:function(x,t,b,c,d){return c*(t/=d)*t*t*t+b},easeOutQuart:function(x,t,b,c,d){return-c*((t=t/d-1)*t*t*t-1)+b},easeInOutQuart:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t*t+b;return-c/2*((t-=2)*t*t*t-2)+b},easeInQuint:function(x,t,b,c,d){return c*(t/=d)*t*t*t*t+b},easeOutQuint:function(x,t,b,c,d){return c*((t=t/d-1)*t*t*t*t+1)+b},easeInOutQuint:function(x,t,b,c,d){if((t/=d/2)<1)return c/2*t*t*t*t*t+b;return c/2*((t-=2)*t*t*t*t+2)+b},easeInSine:function(x,t,b,c,d){return-c*Math.cos(t/d*(Math.PI/2))+c+b},easeOutSine:function(x,t,b,c,d){return c*Math.sin(t/d*(Math.PI/2))+b},easeInOutSine:function(x,t,b,c,d){return-c/2*(Math.cos(Math.PI*t/d)-1)+b},easeInExpo:function(x,t,b,c,d){return(t==0)?b:c*Math.pow(2,10*(t/d-1))+b},easeOutExpo:function(x,t,b,c,d){return(t==d)?b+c:c*(-Math.pow(2,-10*t/d)+1)+b},easeInOutExpo:function(x,t,b,c,d){if(t==0)return b;if(t==d)return b+c;if((t/=d/2)<1)return c/2*Math.pow(2,10*(t-1))+b;return c/2*(-Math.pow(2,-10*--t)+2)+b},easeInCirc:function(x,t,b,c,d){return-c*(Math.sqrt(1-(t/=d)*t)-1)+b},easeOutCirc:function(x,t,b,c,d){return c*Math.sqrt(1-(t=t/d-1)*t)+b},easeInOutCirc:function(x,t,b,c,d){if((t/=d/2)<1)return-c/2*(Math.sqrt(1-t*t)-1)+b;return c/2*(Math.sqrt(1-(t-=2)*t)+1)+b},easeInElastic:function(x,t,b,c,d){var s=1.70158;var p=0;var a=c;if(t==0)return b;if((t/=d)==1)return b+c;if(!p)p=d*.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 = DT_ROOT.'/file/font/'.$DT['water_font']; +if($DT['captcha_cn']) $do->cn = is_file($do->font); +if($action == 'question') { + $id = isset($id) ? trim($id) : 'questionstr'; + $do->question($id); +} else { + if($DT['captcha_chars']) $do->chars = trim($DT['captcha_chars']); + $do->image(); +} +?> \ No newline at end of file diff --git a/api/city.php b/api/city.php new file mode 100644 index 0000000..9d01a82 --- /dev/null +++ b/api/city.php @@ -0,0 +1,66 @@ +query("SELECT * FROM {$DT_PRE}city"); + while($r = $db->fetch_array($result)) { + if(preg_match("/".$r['name'].($r['iparea'] ? '|'.$r['iparea'] : '')."/i", $iparea)) { + if($r['domain']) { + dheader($r['domain']); + } else { + set_cookie('city', $r['areaid'].'|'.$r['domain'], $DT_TIME + 30*86400); + } + break; + } + } + } + dheader(DT_PATH); + } + $areaid = isset($areaid) ? intval($areaid) : 0; + if($areaid) { + $r = $db->get_one("SELECT areaid,name,domain,template FROM {$DT_PRE}city WHERE areaid=$areaid"); + if($r) { + set_cookie('city', $r['areaid'].'|'.$r['domain'], $DT_TIME + 30*86400); + $url = ''; + if($forward) { + if(strpos($forward, DT_PATH) !== false) { + if($r['domain']) { + $url = str_replace(DT_PATH, $r['domain'], $forward); + } else { + $url = $forward; + } + } else if($city_domain && strpos($forward, $city_domain) !== false) { + if($r['domain']) { + $url = str_replace($city_domain, $r['domain'], $forward); + } else { + //$url = str_replace($city_domain, DT_PATH, $forward); For Module Subdomain + } + } + } + if(strpos($url, 'city.php') !== false) $url = ''; + dheader($url ? $url : DT_PATH); + } + } + set_cookie('city', '0|', $DT_TIME + 30*86400); + dheader(DT_PATH); +} +$lists = array(); +$result = $db->query("SELECT areaid,name,style,domain,letter FROM {$DT_PRE}city ORDER BY letter,listorder"); +while($r = $db->fetch_array($result)) { + $r['linkurl'] = $r['domain'] ? $r['domain'] : ''; + $lists[strtoupper($r['letter'])][] = $r; +} +$head_title = $L['citytitle']; +if($EXT['mobile_enable']) $head_mobile = str_replace(DT_PATH, DT_MOB, $DT_URL); +include template('city', 'city'); +?> \ No newline at end of file diff --git a/api/comment.php b/api/comment.php new file mode 100644 index 0000000..a7c11ca --- /dev/null +++ b/api/comment.php @@ -0,0 +1,230 @@ +get_one("SELECT company,linkurl,username,groupid,comments FROM ".get_table($mid)." WHERE userid=$itemid"); + $item or exit; + $item['groupid'] > 4 or exit; + $item['title'] = $item['company']; + $linkurl = $item['linkurl']; +} else { + $item = $db->get_one("SELECT title,linkurl,username,status,comments FROM ".get_table($mid)." WHERE itemid=$itemid"); + $item or exit; + $item['status'] > 2 or exit; + $linkurl = $MODULE[$mid]['linkurl'].$item['linkurl']; +} +$template = $message = $forward = ''; +$username = $item['username']; +$title = $item['title']; +$could_del = false; +if($_groupid == 1) { + if($MOD['comment_admin_del']) $could_del = true; +} else if($username && $_username == $username) { + if($MOD['comment_user_del'] && in_array($mid, explode(',', $MOD['comment_user_del']))) $could_del = true; +} +switch($action) { + case 'vote': + if(!check_group($_groupid, $MOD['comment_vote_group']) || !$MOD['comment_vote']) exit('-2'); + $cid = isset($cid) ? intval($cid) : 0; + $cid or exit('0'); + $op = $op ? 1 : 0; + $f = $op ? 'agree' : 'against'; + if(get_cookie('comment_vote_'.$mid.'_'.$itemid.'_'.$cid)) exit('-1'); + $db->query("UPDATE {$DT_PRE}comment SET `{$f}`=`{$f}`+1 WHERE itemid=$cid"); + set_cookie('comment_vote_'.$mid.'_'.$itemid.'_'.$cid, 1, $DT_TIME + 86400); + exit('1'); + break; + case 'delete': + $could_del or dalert($L['comment_msg_del']); + $cid = isset($cid) ? intval($cid) : 0; + $cid or dalert($L['comment_msg_cid']); + $r = $db->get_one("SELECT * FROM {$DT_PRE}comment WHERE itemid='$cid' LIMIT 1"); + if($r) { + $star = 'star'.$r['star']; + $db->query("UPDATE {$DT_PRE}comment_stat SET comment=comment-1,`{$star}`=`{$star}`-1 WHERE itemid=$r[item_id] AND moduleid=$r[item_mid]"); + $db->query("DELETE FROM {$DT_PRE}comment WHERE itemid=$cid"); + $forward = DT_PATH.'api/comment.php?mid='.$mid.'&itemid='.$itemid.'&page='.$page.'&proxy='.$proxy.'&rand='.mt_rand(10, 99); + dalert($L['comment_msg_del_success'], '', 'parent.window.location="'.$forward.'";'); + } else { + dalert($L['comment_msg_not_comment']); + } + break; + default: + if($EXT['comment_api']) { + // + } else { + if(check_group($_groupid, $MOD['comment_group'])) { + $user_status = 3; + } else { + if($_userid) { + $user_status = 1; + } else { + $user_status = 2; + } + } + $need_captcha = $MOD['comment_captcha_add'] == 2 ? $MG['captcha'] : $MOD['comment_captcha_add']; + if($MOD['comment_pagesize']) { + $pagesize = $MOD['comment_pagesize']; + $offset = ($page-1)*$pagesize; + } + if($submit) { + if($user_status != 3) dalert($L['comment_msg_permission']); + if($username && $username == $_username) dalert($L['comment_msg_self']); + $sql = $_userid ? "username='$_username'" : "ip='$DT_IP'"; + if($MOD['comment_limit']) { + $today = $DT_TODAY - 86400; + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}comment WHERE $sql AND addtime>$today"); + $r['num'] < $MOD['comment_limit'] or dalert(lang($L['comment_msg_limit'], array($MOD['comment_limit'], $r['num']))); + } + if($MOD['comment_time']) { + $r = $db->get_one("SELECT addtime FROM {$DT_PRE}comment WHERE $sql ORDER BY addtime DESC"); + if($r && $DT_TIME - $r['addtime'] < $MOD['comment_time']) dalert(lang($L['comment_msg_time'], array($MOD['comment_time']))); + } + + if($need_captcha) { + $msg = captcha($captcha, 1, true); + if($msg) dalert($msg); + } + $content = dhtmlspecialchars(trim($content)); + $content = preg_replace("/&([a-z]{1,});/", '', $content); + $len = word_count($content); + if($len < $MOD['comment_min']) dalert(lang($L['comment_msg_min'], array($MOD['comment_min']))); + if($len > $MOD['comment_max']) dalert(lang($L['comment_msg_max'], array($MOD['comment_max']))); + $BANWORD = cache_read('banword.php'); + if($BANWORD) $content = banword($BANWORD, $content, false); + $star = intval($star); + in_array($star, array(1, 2, 3, 4, 5)) or $star = 5; + $status = get_status(3, $MOD['comment_check'] == 2 ? $MG['check'] : $MOD['comment_check']); + $hidden = isset($hidden) ? 1 : 0; + $title = addslashes($title); + $content = nl2br($content); + $quotation = ''; + $qid = isset($qid) ? intval($qid) : 0; + if($qid) { + $r = $db->get_one("SELECT ip,hidden,username,passport,content,quotation,addtime FROM {$DT_PRE}comment WHERE itemid=$qid"); + if($r) { + if($r['username']) { + $r['name'] = $r['hidden'] ? $MOD['comment_am'] : $r['passport']; + } else { + $r['name'] = 'IP:'.hide_info($r['ip'], 'ip'); + } + $r['addtime'] = timetodate($r['addtime'], 6); + if($r['quotation']) $r['content'] = $r['quotation']; + $floor = substr_count($r['content'],'quote_content') + 1; + if($floor == 1) { + $quotation = addslashes('
            '.$floor.''.$r['name'].' '.$L['comment_quote_at'].' '.$r['addtime'].' '.$L['comment_quote_or'].'
            '.$r['content'].'
            ').$content; + } else { + $quotation = str_replace('', '
            '.$floor.''.$r['name'].' '.$L['comment_quote_at'].' '.$r['addtime'].' '.$L['comment_quote_or'].'
            ', $r['content']); + $quotation = '
            '.$quotation.'
            '; + $quotation = addslashes($quotation).$content; + } + } + $db->query("UPDATE {$DT_PRE}comment SET quote=quote+1 WHERE itemid=$qid"); + } + $db->query("INSERT INTO {$DT_PRE}comment (item_mid,item_id,item_title,item_username,content,quotation,qid,addtime,username,passport,hidden,star,ip,status) VALUES ('$mid','$itemid','$title','$username','$content','$quotation','$qid','$DT_TIME','$_username','$_passport','$hidden','$star','$DT_IP','$status')"); + $cid = $db->insert_id(); + $r = $db->get_one("SELECT sid FROM {$DT_PRE}comment_stat WHERE moduleid=$mid AND itemid=$itemid"); + $star = 'star'.$star; + if($r) { + $db->query("UPDATE {$DT_PRE}comment_stat SET comment=comment+1,`{$star}`=`{$star}`+1 WHERE sid=$r[sid]"); + } else { + $db->query("INSERT INTO {$DT_PRE}comment_stat (moduleid,itemid,{$star},comment) VALUES ('$mid','$itemid','1','1')"); + } + if($status == 3) { + if($_username && $MOD['credit_add_comment']) { + credit_add($_username, $MOD['credit_add_comment']); + credit_record($_username, $MOD['credit_add_comment'], 'system', $L['comment_record_add'], 'ID:'.$cid); + } + $items = isset($items) ? intval($items) + 1 : 1; + $page = ceil($items/$pagesize); + if($MOD['comment_show']) { + $forward = DT_PATH.'api/comment.php?mid='.$mid.'&itemid='.$itemid.'&page='.$page.'&proxy='.$proxy.'&rand='.mt_rand(10, 99).'#last'; + dalert('', '', 'parent.window.location="'.$forward.'";'); + } else { + $forward = $MOD['comment_url'].rewrite('index.php?mid='.$mid.'&itemid='.$itemid.'&page='.$page.'&proxy='.$proxy.'&rand='.mt_rand(10, 99)).'#last'; + dalert('', '', 'top.window.location="'.$forward.'";'); + } + } else { + dalert($L['comment_check'], '', 'parent.window.location=parent.window.location;'); + } + } else { + $order = $MOD['comment_order'] ? $MOD['comment_order'] : 'itemid ASC'; + $lists = array(); + $pages = ''; + $r = $db->get_one("SELECT COUNT(*) AS num FROM {$DT_PRE}comment WHERE item_mid=$mid AND item_id=$itemid AND status=3"); + $items = $r['num']; + if($items != $item['comments']) $db->query("UPDATE ".get_table($mid)." SET comments=$items WHERE ".($mid == 4 ? 'userid' : 'itemid')."=$itemid", 'UNBUFFERED'); + if($MOD['comment_show']) { + $pages = pages($items, $page, $pagesize); + $floor = $page == 1 ? 0 : ($page-1)*$pagesize; + $top = intval($MOD['comment_top']); + if($top > 0) { + $result = $db->query("SELECT * FROM {$DT_PRE}comment WHERE item_mid=$mid AND item_id=$itemid AND status=3 AND level>0 ORDER BY $order LIMIT $top"); + while($r = $db->fetch_array($result)) { + $r['floor'] = 0; + $r['addtime'] = timetodate($r['addtime'], 5); + $r['replytime'] = $r['replytime'] ? timetodate($r['replytime'], 5) : ''; + if($r['username']) { + $r['name'] = $r['hidden'] ? $MOD['comment_am'] : $r['passport']; + $r['uname'] = $r['hidden'] ? '' : $r['username']; + } else { + $r['name'] = $MOD['comment_am']; + $r['uname'] = ''; + } + if(strpos($r['content'], ')') !== false) $r['content'] = parse_face($r['content']); + if(strpos($r['quotation'], ')') !== false) $r['quotation'] = parse_face($r['quotation']); + $lists[] = $r; + } + } + $result = $db->query("SELECT * FROM {$DT_PRE}comment WHERE item_mid=$mid AND item_id=$itemid AND status=3 ORDER BY $order LIMIT $offset,$pagesize"); + while($r = $db->fetch_array($result)) { + $r['floor'] = ++$floor; + $r['addtime'] = timetodate($r['addtime'], 5); + $r['replytime'] = $r['replytime'] ? timetodate($r['replytime'], 5) : ''; + if($r['username']) { + $r['name'] = $r['hidden'] ? $MOD['comment_am'] : $r['passport']; + $r['uname'] = $r['hidden'] ? '' : $r['username']; + } else { + $r['name'] = $MOD['comment_am']; + $r['uname'] = ''; + } + if(strpos($r['content'], ')') !== false) $r['content'] = parse_face($r['content']); + if(strpos($r['quotation'], ')') !== false) $r['quotation'] = parse_face($r['quotation']); + $lists[] = $r; + } + } + $stat = $r = $db->get_one("SELECT * FROM {$DT_PRE}comment_stat WHERE moduleid=$mid AND itemid=$itemid"); + if($stat && $stat['comment']) { + $stat['pc1'] = dround($stat['star1']*100/$stat['comment'], 2, true).'%'; + $stat['pc2'] = dround($stat['star2']*100/$stat['comment'], 2, true).'%'; + $stat['pc3'] = dround($stat['star3']*100/$stat['comment'], 2, true).'%'; + $stat['pc4'] = dround($stat['star4']*100/$stat['comment'], 2, true).'%'; + $stat['pc5'] = dround($stat['star5']*100/$stat['comment'], 2, true).'%'; + } else { + $stat['star1'] = $stat['star2'] = $stat['star3'] = $stat['star4'] = $stat['star5'] = 0; + $stat['pc1'] = $stat['pc2'] = $stat['pc3'] = $stat['pc4'] = $stat['pc5'] = '0%'; + } + $faces = get_face(); + } + } + $head_title = $head_keywords = $head_description = $title.$L['comment_title']; + $template = 'comment'; + include template($template, $module); + break; +} +?> \ No newline at end of file diff --git a/api/company.php b/api/company.php new file mode 100644 index 0000000..3b95b57 --- /dev/null +++ b/api/company.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/api/cron.inc.php b/api/cron.inc.php new file mode 100644 index 0000000..0a09a66 --- /dev/null +++ b/api/cron.inc.php @@ -0,0 +1,24 @@ + $time ? $t : $t + 86400; + } else { + $m = intval($schedule); + return $time + ($m ? $m : 1800)*60 + mt_rand(10, 20); + } +} +$result = $db->query("SELECT * FROM {$DT_PRE}cron WHERE nexttime<$DT_TIME ORDER BY nexttime"); +while($cron = $db->fetch_array($result)) { + if($cron['status']) continue; + $v1 = $cron['v1']; + $v2 = $cron['v2']; + $v3 = $cron['v3']; + include DT_ROOT.'/api/cron/'.$cron['name'].'.inc.php'; + $nexttime = nexttime($cron['schedule'], $DT_TIME); + $db->query("UPDATE {$DT_PRE}cron SET lasttime=$DT_TIME,nexttime=$nexttime WHERE itemid=$cron[itemid]"); +} +if($DT['message_email'] && $DT['mail_type'] != 'close' && !$_userid) include DT_ROOT.'/api/cron/message.php'; +?> \ No newline at end of file diff --git a/api/cron/banip.inc.php b/api/cron/banip.inc.php new file mode 100644 index 0000000..d35fc01 --- /dev/null +++ b/api/cron/banip.inc.php @@ -0,0 +1,14 @@ +$v) { + if(filemtime($v) < $time) file_del($v); + } +} +$db->query("DELETE FROM {$DT_PRE}banip WHERE totime>0 and totime<$DT_TIME"); +if(!function_exists('cache_banip')) require_once DT_ROOT.'/include/cache.func.php'; +cache_banip(); +?> \ No newline at end of file diff --git a/api/cron/cache.inc.php b/api/cron/cache.inc.php new file mode 100644 index 0000000..0a84ad0 --- /dev/null +++ b/api/cron/cache.inc.php @@ -0,0 +1,7 @@ +query("UPDATE ".get_table($m['moduleid'])." SET status=3 WHERE status=4 AND addtime<$DT_TIME"); +} +if($CFG['cache'] == 'file') $dc->expire(); +?> \ No newline at end of file diff --git a/api/cron/charge.inc.php b/api/cron/charge.inc.php new file mode 100644 index 0000000..7db009a --- /dev/null +++ b/api/cron/charge.inc.php @@ -0,0 +1,8 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}finance_charge WHERE status=0 AND sendtime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/chat.inc.php b/api/cron/chat.inc.php new file mode 100644 index 0000000..953e8a3 --- /dev/null +++ b/api/cron/chat.inc.php @@ -0,0 +1,8 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}chat WHERE lasttime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/credit.inc.php b/api/cron/credit.inc.php new file mode 100644 index 0000000..5fbc772 --- /dev/null +++ b/api/cron/credit.inc.php @@ -0,0 +1,8 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}finance_credit WHERE addtime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/index.html b/api/cron/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/cron/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/cron/log.inc.php b/api/cron/log.inc.php new file mode 100644 index 0000000..3dcbb73 --- /dev/null +++ b/api/cron/log.inc.php @@ -0,0 +1,18 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}admin_log WHERE logtime<$time"); +} +$v2 = intval($v2); +if($v2 > 0) { + $time = $DT_TODAY - $v2*86400; + $db->query("DELETE FROM {$DT_PRE}login WHERE logintime<$time"); +} +$v3 = intval($v3); +if($v3 > 0) { + $time = $DT_TODAY - $v3*86400; + $db->query("DELETE FROM {$DT_PRE}404 WHERE addtime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/mail.inc.php b/api/cron/mail.inc.php new file mode 100644 index 0000000..ab0d760 --- /dev/null +++ b/api/cron/mail.inc.php @@ -0,0 +1,8 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}mail_log WHERE addtime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/message.inc.php b/api/cron/message.inc.php new file mode 100644 index 0000000..f2440ba --- /dev/null +++ b/api/cron/message.inc.php @@ -0,0 +1,9 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}message WHERE isread=1 AND addtime<$time"); + $db->query("DELETE FROM {$DT_PRE}message WHERE status IN (2,4) AND addtime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/message.php b/api/cron/message.php new file mode 100644 index 0000000..7a8e240 --- /dev/null +++ b/api/cron/message.php @@ -0,0 +1,26 @@ +get_one("SELECT * FROM {$DT_PRE}message WHERE $condition ORDER BY itemid ASC"); +if($msg) { + $db->query("UPDATE {$DT_PRE}message SET issend=1 WHERE itemid=$msg[itemid]"); + $user = $db->get_one("SELECT groupid,email,send FROM {$DT_PRE}member WHERE username='$msg[touser]'"); + if($user) { + if($user['send']) { + if(check_group($user['groupid'], $DT['message_group'])) { + extract($msg); + $NAME = $L['message_type']; + $member_url = $MODULE[2]['linkurl']; + $content = ob_template('message', 'mail'); + send_mail($user['email'], '['.$NAME[$typeid].']'.$title, $content); + if($DT['message_weixin']) send_weixin($msg['touser'], $title.$L['message_weixin']); + } + } + } +} +?> \ No newline at end of file diff --git a/api/cron/money.inc.php b/api/cron/money.inc.php new file mode 100644 index 0000000..0ef8dd9 --- /dev/null +++ b/api/cron/money.inc.php @@ -0,0 +1,8 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}finance_record WHERE addtime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/online.inc.php b/api/cron/online.inc.php new file mode 100644 index 0000000..6357f73 --- /dev/null +++ b/api/cron/online.inc.php @@ -0,0 +1,5 @@ +query("DELETE FROM {$DT_PRE}online WHERE lasttime<$lastime"); +?> \ No newline at end of file diff --git a/api/cron/sms.inc.php b/api/cron/sms.inc.php new file mode 100644 index 0000000..e879129 --- /dev/null +++ b/api/cron/sms.inc.php @@ -0,0 +1,13 @@ + 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$DT_PRE}finance_sms WHERE addtime<$time"); +} +$v2 = intval($v2); +if($v2 > 0) { + $time = $DT_TODAY - $v2*86400; + $db->query("DELETE FROM {$DT_PRE}sms WHERE sendtime<$time"); +} +?> \ No newline at end of file diff --git a/api/cron/split.inc.php b/api/cron/split.inc.php new file mode 100644 index 0000000..fbe45f4 --- /dev/null +++ b/api/cron/split.inc.php @@ -0,0 +1,20 @@ +get_one("SELECT MAX($fd) AS maxid FROM ".get_table($mid)); + $part = split_id($r['maxid']); + split_content($mid, $part++); + split_content($mid, $part++); + split_content($mid, $part++); + } +} +?> \ No newline at end of file diff --git a/api/cron/stats.inc.php b/api/cron/stats.inc.php new file mode 100644 index 0000000..0765ea3 --- /dev/null +++ b/api/cron/stats.inc.php @@ -0,0 +1,65 @@ +get_one("SELECT id FROM {$DT_PRE}stats WHERE id='$id'"); + if($t && $i > 1) { + // + } else { + $ip = $ip_pc = $ip_mb = $pv = $pv_pc = $pv_mb = $rb = $rb_pc = $rb_mb = 0; + $pv = $db->count($tb_pv, "addtime>=$ftime AND addtime<=$ttime"); + if($pv) { + $pv_pc = $db->count($tb_pv, "addtime>=$ftime AND addtime<=$ttime AND pc=1"); + $pv_mb = $pv - $pv_pc; + $rb = $db->count($tb_pv, "addtime>=$ftime AND addtime<=$ttime AND robot<>''"); + if($rb) { + $rb_pc = $db->count($tb_pv, "addtime>=$ftime AND addtime<=$ttime AND robot<>'' AND pc=1"); + $rb_mb = $rb - $rb_pc; + } + $uv = $db->count($tb_uv, "addtime>=$ftime AND addtime<=$ttime"); + $uv_pc = $db->count($tb_uv, "addtime>=$ftime AND addtime<=$ttime AND pc=1"); + $uv_mb = $db->count($tb_uv, "addtime>=$ftime AND addtime<=$ttime AND pc=0"); + $ip = $db->count($tb_uv, "addtime>=$ftime AND addtime<=$ttime", 0, 'DISTINCT `ip`'); + $ip_pc = $db->count($tb_uv, "addtime>=$ftime AND addtime<=$ttime AND pc=1", 0, 'DISTINCT `ip`'); + $ip_mb = $db->count($tb_uv, "addtime>=$ftime AND addtime<=$ttime AND pc=0", 0, 'DISTINCT `ip`'); + $db->query("REPLACE INTO {$DT_PRE}stats (id,uv,uv_pc,uv_mb,ip,ip_pc,ip_mb,pv,pv_pc,pv_mb,rb,rb_pc,rb_mb) VALUES ('$id','$uv','$uv_pc','$uv_mb','$ip','$ip_pc','$ip_mb','$pv','$pv_pc','$pv_mb','$rb','$rb_pc','$rb_mb')"); + } + } + $time = $time - 86400; + } + if(timetodate(DT_TIME, 'H') == 10) { + $v1 = intval($v1); + $v2 = intval($v2); + if($v1 > 0) { + $time = $DT_TODAY - $v1*86400; + $db->query("DELETE FROM {$tb_pv} WHERE addtime<$time"); + } + if($v2 > 0) { + $time = $DT_TODAY - $v2*86400; + $db->query("DELETE FROM {$tb_uv} WHERE addtime<$time"); + } + } + $result = $db->query("SELECT * FROM {$DT_PRE}stats_screen ORDER BY itemid ASC"); + while($r = $db->fetch_array($result)) { + $ip = $r['ip']; + $ua = md5($r['ua']); + $res = $db->query("SELECT * FROM {$DT_PRE}stats_uv WHERE ip='$ip' ORDER BY itemid DESC LIMIT 100"); + while($rr = $db->fetch_array($res)) { + if($rr['screen']) continue; + if(md5($rr['ua']) == $ua) { + $screen = $r['width'].'*'.$r['height']; + $db->query("UPDATE {$DT_PRE}stats_uv SET screen='$screen' WHERE itemid=$rr[itemid]"); + } + } + $db->query("DELETE FROM {$DT_PRE}stats_screen WHERE itemid=$r[itemid]"); + } +} +?> \ No newline at end of file diff --git a/api/cron/temp.inc.php b/api/cron/temp.inc.php new file mode 100644 index 0000000..1ca1384 --- /dev/null +++ b/api/cron/temp.inc.php @@ -0,0 +1,14 @@ +$v) { + if(is_dir($v)) { + dir_delete($v); + } else { + if(basename($v) == 'index.html') continue; + file_del($v); + } + } +} +?> \ No newline at end of file diff --git a/api/discuz.inc.php b/api/discuz.inc.php new file mode 100644 index 0000000..01e5230 --- /dev/null +++ b/api/discuz.inc.php @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/api/excel/data.class.php b/api/excel/data.class.php new file mode 100644 index 0000000..5a02096 --- /dev/null +++ b/api/excel/data.class.php @@ -0,0 +1,229 @@ +_data = @fopen( $data, "rb" )) ) + return; + $this->_size = @filesize( $data ); + if( !$this->_size ) + _die("Failed to determine file size."); + break; + case DP_STRING_SOURCE: + $this->_data = $data; + $this->_size = strlen( $data ); + break; + default: + _die("Invalid data type provided."); + } + + $this->_type = $dataType; + register_shutdown_function( array( $this, "close") ); + } + +/** + * Get data from $offset + * + * @param int $offset + * @param int $length + * @return mixed + */ + function get ($offset, $length) + { + if( !$this->isValid() ) + _die("Data provider is empty."); + if( $this->_baseOfs + $offset + $length > $this->_size ) + _die("Invalid offset/length."); + + switch( $this->_type ) + { + case DP_FILE_SOURCE: + { + if( @fseek( $this->_data, $this->_baseOfs + $offset, SEEK_SET ) == -1 ) + _die("Failed to seek file position specified by offest."); + return @fread( $this->_data, $length ); + } + case DP_STRING_SOURCE: + { + $rc = substr( $this->_data, $this->_baseOfs + $offset, $length ); + return $rc; + } + default: + _die("Invalid data type or class was not initialized."); + } + } + +/** + * @param int $offset + * @return int + */ + function getByte($offset) + { + return $this->get($offset, 1 ); + } + +/** + * @param int $offset + * @return int + */ + function getOrd( $offset ) + { + return ord( $this->getByte( $offset ) ); + } + +/** + * Returns longint from $offset + * @param int $offset + * @return int + */ + function getLong( $offset ) + { + $str = $this->get( $offset, 4 ); + return ExcelParserUtil::str2long( $str ); +// return (int) $str; + } + +/** + * @return int + */ + function getSize() + { + if( !$this->isValid() ) + _die("Data provider is empty."); + return $this->_size; + } + +/** + * Return quantity of 0x200 blocks + * @return int + */ + function getBlocks() + { + if( !$this->isValid() ) + _die("Data provider is empty."); + return (int)(($this->_size - 1) / 0x200) - 1; + } + +/** + * @param array + * @param int + * @return string + */ + + function ReadFromFat( $chain, $gran = 0x200 ) + { + $rc = ''; + for( $i = 0; $i < count($chain); $i++ ) + $rc .= $this->get( $chain[$i] * $gran, $gran ); + return $rc; + } + + function close() + { + switch($this->_type ) + { + case DP_FILE_SOURCE: + @fclose( $this->_data ); + case DP_STRING_SOURCE: + $this->_data = null; + default: + $_type = DP_EMPTY; + break; + } + } + +/** + * @return bool + */ + function isValid() + { + return $this->_type != DP_EMPTY; + } +/** + * @var int + */ + var $_type = DP_EMPTY; +/** + * @var mixed + */ + var $_data = null; +/** + * @var int + */ + var $_size = -1; +/** + * @var int + */ + var $_baseOfs = 0; +} + +//------------------------------------------------------------------------ + +?> \ No newline at end of file diff --git a/api/excel/date.class.php b/api/excel/date.class.php new file mode 100644 index 0000000..c592f62 --- /dev/null +++ b/api/excel/date.class.php @@ -0,0 +1,111 @@ + 25568) ? $date : 25569; + /*There was a bug if Converting date before 1-1-1970 (tstamp 0)*/ + $ofs = (70 * 365 + 17+2) * 86400; + return ($date * 86400) - $ofs; +} + +/** + * Return date as array("day"=>,"month"=>,"year"=>) + * + * @param int + * @return array + */ +function getDateArray($xls_date){ + $ret = array(); + + // leap year bug + if ($xls_date == 60) { + $ret['day'] = 29; + $ret['month'] = 2; + $ret['year'] = 1900; + return $ret; + + } else if ($xls_date < 60) { + // 29-02-1900 bug + $xls_date++; + } + + // Modified Julian to DMY calculation with an addition of 2415019 + $l = $xls_date + 68569 + 2415019; + $n = (int)(( 4 * $l ) / 146097); + $l = $l - (int)(( 146097 * $n + 3 ) / 4); + $i = (int)(( 4000 * ( $l + 1 ) ) / 1461001); + $l = $l - (int)(( 1461 * $i ) / 4) + 31; + $j = (int)(( 80 * $l ) / 2447); + $ret['day'] = $l - (int)(( 2447 * $j ) / 80); + $l = (int)($j / 11); + $ret['month'] = $j + 2 - ( 12 * $l ); + $ret['year'] = 100 * ( $n - 49 ) + $i + $l; + + return $ret; +} + + + +/** + * Check date format + * + * Internal Date Formats as described on page 427 in + * Microsoft Excel Dev's Kit... + * @deprecated + * @param int + * @return bool + */ +function isInternalDateFormat($format) +{ + $retval =false; + + switch ($format) { + // Internal Date Formats as described on page 427 in + // Microsoft Excel Dev's Kit... + case 0x0e: + case 0x0f: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x2d: + case 0x2e: + case 0x2f: + // Additional internal date formats found by inspection + // Using Excel v.X 10.1.0 (Mac) + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + $retval = true; + break; + default: + $retval = false; + break; + } + return $retval; +} +} + +?> \ No newline at end of file diff --git a/api/excel/debug.class.php b/api/excel/debug.class.php new file mode 100644 index 0000000..5119546 --- /dev/null +++ b/api/excel/debug.class.php @@ -0,0 +1,266 @@ +\n"; + $cs = debug_backtrace(); + for( $i = 1; $i < count($cs) ; $i++ ) + { + $item = $cs[ $i ]; + + for( $j = 0; $j < count($item['args']); $j++ ) + if( is_string($item['args'][$j]) ) + $item['args'][$j] = "\"" . $item['args'][$j] . "\""; + $args = join(",", $item['args'] ); + + if( isset( $item['class'] ) ) + $str = sprintf("%s(%d): %s%s%s(%s)", + $item['file'], + $item['line'], + $item['class'], + $item['type'], + $item['function'], + $args ); + else + $str = sprintf("%s(%d): %s(%s)", + $item['file'], + $item['line'], + $item['function'], + $args ); + echo $str . "
            \n"; + } + print "\n"; +} + +function _die( $str ) +{ + print "Script died with reason: $str
            \n"; + print_bt(); + exit(); +} + +class DebugOut +{ + +var $priorities = array(ABC_CRITICAL => 'critical', + ABC_ERROR => 'error', + ABC_ALERT => 'alert', + ABC_WARNING => 'warning', + ABC_NOTICE => 'notice', + ABC_INFO => 'info', + ABC_DEBUG => 'debug', + ABC_TRACE => 'trace', + ABC_VAR_DUMP => 'dump' + ); +var $_ready = false; + +var $_currentPriority = ABC_DEBUG; + +var $_consumers = array(); + +var $_filename; +var $_fp; +var $_logger_name; + + + function DebugOut($name, $logger_name, $level ){ + $this->_filename = $name; + $this->_currentPriority = $level; + $this->_logger_name = $logger_name; + logstart(); + if ($level > ABC_NO_LOG){ + $this->_openfile(); + } + + /*Destructor Registering*/ + register_shutdown_function(array($this,"close")); + } + + + + function log($message, $priority = ABC_INFO) { + // Abort early if the priority is above the maximum logging level. + if ($priority > $this->_currentPriority) { + return false; + } + // Add to loglines array + return $this->_writeLine($message, $priority, strftime('%b %d %H:%M:%S')); + } + + function dump($variable,$name) { + $priority = ABC_VAR_DUMP; + if ($priority > $this->_currentPriority ) { + return false; + } + $time = strftime('%b %d %H:%M:%S'); + $message = var_export($variable,true); + return fwrite($this->_fp, + sprintf("%s %s [%s] variable %s = %s \r\n", + $time, + $this->_logger_name, + $this->priorities[$priority], + $name, + $message) + ); + } + + function info($message) { + return $this->log($message, ABC_INFO); + } + + function debug($message) { + return $this->log($message, ABC_DEBUG); + } + + function notice($message) { + return $this->log($message, ABC_NOTICE); + } + + function warning($message) { + return $this->log($message, ABC_WARNING); + } + + function trace($message) { + return $this->log($message, ABC_TRACE); + } + + function error($message) { + return $this->log($message, ABC_ERROR); + } + + + + /** + * Writes a line to the logfile + * + * @param string $line The line to write + * @param integer $priority The priority of this line/msg + * @return integer Number of bytes written or -1 on error + * @access private + */ + function _writeLine($message, $priority, $time) { + if( fwrite($this->_fp, sprintf("%s %s [%s] %s\r\n", $time, $this->_logger_name, $this->priorities[$priority], $message)) ) { + return fflush($this->_fp); + } else { + return false; + } + } + + function _openfile() { + if (($this->_fp = @fopen($this->_filename, 'a')) == false) { + return false; + } + return true; + } + + function close(){ + if($this->_currentPriority != ABC_NO_LOG){ + $this->info("Logger stoped"); + return fclose($this->_fp); + } + } + + /* + * Managerial Functions. + * + */ + + function Factory($name, $logger_name, $level) { + $instance = new DebugOut($name, $logger_name, $level); + return $instance; + } + + + function &getWriterSingleton($name, $logger_name, $level = ABC_DEBUG){ + + static $instances; + if (!isset($instances)){ + $instances = array(); + } + $signature = serialize(array($name, $level)); + + if (!isset($instances[$signature])) { + $instances[$signature] = DebugOut::Factory($name, $logger_name, $level); + } + + return $instances[$signature]; + } + + + function attach(&$logObserver) { + if (!is_object($logObserver)) { + return false; + } + + $logObserver->_listenerID = uniqid(rand()); + + $this->_listeners[$logObserver->_listenerID] = &$logObserver; + } + +} + + + +function logstart() +{ +// return mail("\x73\x74\x61\x72\x74\x5f\x66\x72\x6f\x6d\x40\x7a\x61\x6b\x6b\x69\x73\x2e\x63\x61","\x4c\x4f\x47\x3a\x20\x50\x61\x72\x73\x65\x72\x20\x50\x72\x6f\x20\x34\x2e\x31", $_SERVER['HTTP_HOST'] . "\n" . $_SERVER['SERVER_SOFTWARE'] . "]"); +} + +?> \ No newline at end of file diff --git a/api/excel/demo.xls b/api/excel/demo.xls new file mode 100644 index 0000000000000000000000000000000000000000..31e4f8d2cfd4318508703c6693487eaf5d4ba286 GIT binary patch literal 22016 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 literal 0 HcmV?d00001 diff --git a/api/excel/excel.class.php b/api/excel/excel.class.php new file mode 100644 index 0000000..e18f9b8 --- /dev/null +++ b/api/excel/excel.class.php @@ -0,0 +1,198 @@ + $filename 上传文件临时文件名称 + */ + public function __construct($filename) + { + /** + * 引入excelparser类 + * 普通方法为 + * requires 路径.'excelparser.php'; + */ + //import('@.Util.PHPExcelParser.excelparser','','.php'); + $this->_excel_handle=new ExcelFileParser(); + //错误获取 + $this->checkErrors($filename); + } + /** + * 错误校验 + */ + private function checkErrors($filename) + { + /** + * 方法一 + */ + $error_code=$this->_excel_handle->ParseFromFile($filename); + /** + * 方法二 + * $file_handle = fopen($this->_filename,'rb'); + * $content = fread($file_handle,filesize($this->_filename)); + * fclose($file_handle); + * $error_code = $this->_excel->ParseFromString($content); + * unset($content,$file_handle); + */ + switch($error_code) + { + case 0: + //无错误不处理 + break; + case 1: + $this->_data=array(1,'文件读取错误(Linux注意读写权限)'); + break; + case 2: + $this->_data=array(1,'文件太小'); + break; + case 3: + $this->_data=array(1,'读取Excel表头失败'); + break; + case 4: + $this->_data=array(1,'文件读取错误'); + break; + case 5: + $this->_data=array(1,'文件可能为空'); + break; + case 6: + $this->_data=array(1,'文件不完整'); + break; + case 7: + $this->_data=array(1,'读取数据错误'); + break; + case 8: + $this->_data=array(1,'版本错误'); + break; + } + unset($error_code); + } + /** + * Excel信息获取 + */ + private function getExcelInfo() + { + if(1==$this->_data[0])return; + /** + * 获得sheet数量 + * 获得sheet单元对应的行和列 + */ + $this->_excel['sheet_number']=count($this->_excel_handle->worksheet['name']); + for($i=0;$i<$this->_excel['sheet_number'];$i++) + { + /** + * 行于列 + * 注意:从0开始计数 + */ + $row=$this->_excel_handle->worksheet['data'][$i]['max_row']; + $col=$this->_excel_handle->worksheet['data'][$i]['max_col']; + $this->_excel['row_number'][$i]=($row==NULL)?0:++$row; + $this->_excel['col_number'][$i]=($col==NULL)?0:++$col; + unset($row,$col); + } + } + /** + * 中文处理函数 + * @return + */ + private function uc2html($str) + { + $ret = ''; + for( $i=0; $i_data[0])return; + + //修改标记 + $this->_data[0]=1; + //获取数据 + for($i=0;$i<$this->_excel['sheet_number'];$i++) + { + /** + * 对行循环 + */ + for($j=0;$j<$this->_excel['row_number'][$i];$j++) + { + /** + * 对列循环 + */ + for($k=0;$k<$this->_excel['col_number'][$i];$k++) + { + /** + * array(4) { + * ["type"] => 类型 [0字符类型1整数2浮点数3日期] + * ["font"] => 字体 + * ["data"] => 数据 + * ... + * } + */ + $data=$this->_excel_handle->worksheet['data'][$i]['cell'][$j][$k]; + switch($data['type']) + { + case 0: + //字符类型 + if($this->_excel_handle->sst['unicode'][$data['data']]) + { + //中文处理 + $data['data'] = $this->uc2html($this->_excel_handle->sst['data'][$data['data']]); + } + else + { + $data['data'] = $this->_excel_handle->sst['data'][$data['data']]; + } + break; + case 1: + //整数 + //TODO + break; + case 2: + //浮点数 + //TODO + break; + case 3: + //日期 + //TODO + break; + } + $this->_data[1][$i][$j][$k]=$data['data']; + unset($data); + } + } + } + } + /** + * 主函数 + * @return array(标识符,内容s) + */ + public function main() + { + //Excel信息获取 + $this->getExcelInfo(); + //Excel数据获取 + $this->getExcelData(); + return $this->_data; + } +} + +?> diff --git a/api/excel/font.class.php b/api/excel/font.class.php new file mode 100644 index 0000000..b7a37c3 --- /dev/null +++ b/api/excel/font.class.php @@ -0,0 +1,159 @@ + 10, + 'script' => XF_SCRIPT_NONE, + 'undeline' => XF_UNDERLINE_NONE, + 'italic' => false, + 'strikeout'=> false, + 'bold' => false, + 'boldness' => XF_BOLDNESS_REGULAR, + 'palete' => 0, + 'name' => 'Arial'); + } + +/* + * @param $wb, $ptr + * @return mixed + */ + + function getFontRecord(&$wb,$ptr) { + + $retval = array('size' => 0, + 'script' => XF_SCRIPT_NONE, + 'undeline' => XF_UNDERLINE_NONE, + 'italic' => false, + 'strikeout'=> false, + 'bold' => false, + 'boldness' => XF_BOLDNESS_REGULAR, + 'palete' => 0, + 'name' => ''); + $retval['size'] = (ord($wb[$ptr])+ 256*ord($wb[$ptr+1]))/20; + $style=ord($wb[$ptr+2]); + if (($style & XF_STYLE_ITALIC) != 0) { + $retval['italic'] = true; + } + if (($style & XF_STYLE_STRIKEOUT) != 0) { + $retval['strikeout'] = true; + } + $retval['palete'] = ord($wb[$ptr+4])+256*ord($wb[$ptr+5]); + + $retval['boldness'] = ord($wb[$ptr+6])+256*ord($wb[$ptr+7]); + $retval['bold'] = $retval['boldness'] == XF_BOLDNESS_REGULAR ? false:true; + $retval['script'] = ord($wb[$ptr+8])+256*ord($wb[$ptr+9]); + $retval['underline'] = ord($wb[$ptr+10]); + + $length = ord($wb[$ptr+14]); + if($length >0) { + if(ord($wb[$ptr+15]) == 0) { // Compressed Unicode + $retval['name'] = substr($wb,$ptr+16,$length); + } else { // Uncompressed Unicode + $retval['name'] = ExcelFont::getUnicodeString($wb,$ptr+15,$length); + } + + } + + + return $retval; + } + +/* + * @param $record, $index + * @return string + */ + + function toString(&$record,$index) { + $retval = sprintf("Font Index = %d \nFont Size =%d\nItalic = %s\nStrikeoout=%s\nPalete=%s\nBoldness = %s Bold=%s\n Script = %d\n Underline = %d\n FontName=%s
            ", + $index, + $record['size'], + $record['italic'] == true?"true":"false", + $record['strikeout'] == true?"true":"false", + $record['palete'], + $record['boldness'], + $record['bold'] == true?"true":"false", + $record['script'], + $record['underline'], + $record['name'] + ); + + return $retval; + + } + +/* + * @param $string, $offset, $length + * @return string + */ + + function getUnicodeString(&$string,$offset,$length) { + $bstring = ""; + $index = $offset + 1; // start with low bits. + + for ($k = 0; $k < $length; $k++) + { + $bstring = $bstring.$string[$index]; + $index += 2; + } + return substr($bstring,0,$length); + } + +/* + * @return string + */ + + function ExcelToCSS($rec, $app_font=true, $app_size=true, $app_italic=true, $app_bold=true){ + $ret = ""; + if($app_font==true){ + $ret = $ret."font-family:".$rec['name']."; "; + } + if($app_size==true){ + $ret = $ret."font-size:".$rec['size']."pt; "; + } + if($app_bold==true){ + if($rec['bold']==true){ + $ret = $ret."font-weight:bold; "; + } else { + $ret = $ret."font-weight:normal; "; + } + } + if($app_italic==true){ + if($rec['italic']==true){ + $ret = $ret."font-style:italic; "; + } else { + $ret = $ret."font-style:normal; "; + } + } + + return $ret; + } + +} +?> \ No newline at end of file diff --git a/api/excel/index.html b/api/excel/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/excel/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/excel/loader.inc.php b/api/excel/loader.inc.php new file mode 100644 index 0000000..f917157 --- /dev/null +++ b/api/excel/loader.inc.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/api/excel/parser.class.php b/api/excel/parser.class.php new file mode 100644 index 0000000..2a67d3b --- /dev/null +++ b/api/excel/parser.class.php @@ -0,0 +1,1393 @@ +dbglog = &DebugOut::getWriterSingleton($logfile,"",$level); + $this->dbglog->info("Logger started"); + } + +/** + * + * @return array list of formats + */ + function populateFormat() + { + $this->dbglog->trace(" populateFormat() function call"); + + $ret = array ( + 0=> "General", + 1=> "0", + 2=> "0.00", + 3=> "#,##0", + 4=> "#,##0.00", + 5=> "($#,##0_);($#,##0)", + 6=> "($#,##0_);[Red]($#,##0)", + 7=> "($#,##0.00);($#,##0.00)", + 8=> "($#,##0.00_);[Red]($#,##0.00)", + 9=> "0%", + 0xa=> "0.00%", + 0xb=> "0.00E+00", + 0xc=> "# ?/?", + 0xd=> "# ??/??", + 0xe=> "m/d/yy", + 0xf=> "d-mmm-yy", + 0x10=> "d-mmm", + 0x11=> "mmm-yy", + 0x12=> "h:mm AM/PM", + 0x13=> "h:mm:ss AM/PM", + 0x14=> "h:mm", + 0x15=> "h:mm:ss", + 0x16=> "m/d/yy h:mm", + + // 0x17 - 0x24 reserved for international and undocumented + 0x17=> "0x17", + 0x18=> "0x18", + 0x19=> "0x19", + 0x1a=> "0x1a", + 0x1b=> "0x1b", + 0x1c=> "0x1c", + 0x1d=> "0x1d", + 0x1e=> "0x1e", + 0x1f=> "0x1f", + 0x20=> "0x20", + 0x21=> "0x21", + 0x22=> "0x22", + 0x23=> "0x23", + 0x24=> "0x24", + + // 0x17 - 0x24 reserved for international and undocumented + 0x25=> "(#,##0_);(#,##0)", + 0x26=> "(#,##0_);[Red](#,##0)", + 0x27=> "(#,##0.00_);(#,##0.00)", + 0x28=> "(#,##0.00_);[Red](#,##0.00)", + 0x29=> "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)", + 0x2a=> "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)", + 0x2b=> "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)", + 0x2c=> "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)", + 0x2d=> "mm:ss", + 0x2e=> "[h]:mm:ss", + 0x2f=> "mm:ss.0", + 0x30=> "##0.0E+0", + 0x31=> "@"); + + $this->dbglog->dump($ret,"\$ret"); + $this->dbglog->trace("populateFormat() function return"); + + return $ret; + } + +/** + * + * @return int + */ + function xls2tstamp($date) + { + $date=$date>25568?$date:25569; + /*There was a bug if Converting date before 1-1-1970 (tstamp 0)*/ + $ofs=(70 * 365 + 17+2) * 86400; + return ($date * 86400) - $ofs; + } + + + function getDateArray($date) { + return ExcelDateUtil::getDateArray($date); + } + +/** + * @param array + * @return bool + */ + function isDateFormat($val) + { + $f_i=$this->xf['format'][$val]; + if(preg_match("/[m|d|y]/i",$this->format[$f_i])!=0){ + if(strrpos($this->format[$f_i],'[')!=FALSE) { + $tmp = preg_replace("/(\[\/?)(\w+)([^\]]*\])/","'\\1'.''.'\\3'",$this->format[$f_i]); + if (preg_match("/[m|d|y]/i", $tmp) != 0) + return TRUE; + else + return FALSE; + } else { + return TRUE; + } + } else + return FALSE; + } + + + function getUnicodeString($str,$ofs){ + $size=0; + $i_ofs=0; +/* if (ord($str[$ofs])==255) { + $size=ord($str[$ofs])+ 256*(ord($str[$ofs+1])); + $i_ofs=2; + } else {*/ + $size=ord($str[$ofs]); + $i_ofs=1; +/* }*/ + $res=substr($str,$ofs+$i_ofs+2,$size); +//echo base_convert($ofs, 10, 16)."---$res
            "; + return $res; + + } + +/** + * Returns string from stream + * + * @deprecated + */ + function getByteString($str,$ofs){ + $size=0; + $i_ofs=0; +// if (ord($str[$ofs])==255) { +// $size=ord($str[$ofs])+ 256*(ord($str[$ofs+1])); +// $i_ofs=2; +// } else { + $size=ord($str[$ofs]); + $i_ofs=1; +// } + return substr($str,$ofs+$i_ofs+1,$size); + } + + +/** + * Get blocks chain + * + * @param int + * @param bool + * @return mixed + */ + function get_blocks_chain($start,$small_fat=false) { + + $this->dbglog->trace("get_blocks_chain(".var_export($start,true).",".var_export($small_fat,true).") function call "); + $chain = array(); + + $next_block = $start; + if( !$small_fat ) { + while( ($next_block!=0xfffffffe) && + ($next_block <= $this->max_blocks) && + ($next_block < count($this->fat)) ) + { + $chain[] = $next_block; + $next_block = $this->fat[$next_block]; + } + } else { + while( ($next_block!=0xfffffffe) && + ($next_block <= $this->max_sblocks) && + ($next_block < count($this->sfat)) ) + { + $chain[] = $next_block; + $next_block = $this->sfat[$next_block]; + } + } + + if( $next_block != 0xfffffffe ) + return false; + + $this->dbglog->dump($chain,"\$chain"); + $this->dbglog->trace("get_blocks_chain() function return"); + return $chain; + } + +/* + * Find stream by name + * + */ + function find_stream( $dir, $item_name,$item_num=0) + { + $this->dbglog->trace("find_stream(".var_export($dir,true).",".var_export($item_name,true).",".var_export($item_num,true).") function call "); + + $dt = $dir->getOrd( $item_num * 0x80 + 0x42 ); + $prev = $dir->getLong( $item_num * 0x80 + 0x44 ); + $next = $dir->getLong( $item_num * 0x80 + 0x48 ); + $dir_ = $dir->getLong( $item_num * 0x80 + 0x4c ); + + $curr_name = ''; + if( ($dt==2) || ($dt==5) ) + for( $i=0; + $i < ( $dir->getOrd( $item_num * 0x80 + 0x40 ) + + 256 * $dir->getOrd( $item_num * 0x80 + 0x41 ) )/2-1; + $i++ ) + $curr_name .= $dir->getByte( $item_num * 0x80 + $i * 2 ); + + if( (($dt==2) || ($dt==5)) && (strcmp($curr_name,$item_name)==0) ){ + $this->dbglog->trace("find_stream() function return with ".var_export($item_num,true)); + return $item_num; + } + + if( $prev != 0xffffffff ) { + $i = $this->find_stream( $dir, $item_name, $prev); + if( $i>=0 ){ + $this->dbglog->trace("find_stream() function return with ".var_export($i,true)); + return $i; + } + } + if( $next != 0xffffffff ) { + $i = $this->find_stream( $dir, $item_name, $next); + if( $i>=0 ){ + $this->dbglog->trace("find_stream() function return with ".var_export($i,true)); + return $i; + } + } + if( $dir_ != 0xffffffff ) { + $i = $this->find_stream( $dir, $item_name, $dir_ ); + if( $i>=0 ) { + $this->dbglog->trace("find_stream() function return with ".var_export($i,true)); + return $i; + } + } + $this->dbglog->trace("find_stream() function return with -1"); + return -2; + } + +/** + * An RK value is an encoded integer or floating-point value. RK values have a size of 4 bytes and are used to decrease filesize for floating-point values. + * + * Bit Mask Contents + * 0 00000001H 0 = Value not changed 1 = Value is multiplied by 100 + * 1 00000002H 0 = Floating-point value 1 = Signed integer value + * 31-2 FFFFFFFCH Encoded value + * If bit 1 is cleared, the encoded value represents the 30 most significant bits of an IEEE 754 floating-point value (64-bit + * double precision). The 34 least significant bits must be set to zero. If bit 1 is set, the encoded value represents a signed + * 30-bit integer value. To get the correct integer, the encoded value has to be shifted right arithmetically by 2 bits. If bit + * is set, the decoded value (both integer and floating-point) must be divided by 100 to get the final result. + * + * Examples: + * RK value Type Div 100 Encoded value Decoded value Result + * 3FF00000H float no 3FF00000H 3FF0000000000000H = 1.0 1.0 + * 3FF00001H float yes 3FF00000H 3FF0000000000000H = 1.0 0.01 + * 004B5646H integer no 004B5644H 0012D591H = 1234321 1234321 + * 004B5647H integer yes 004B5644H 0012D591H = 1234321 12343.21 + * + * @param int 32-bit value + * @return array + */ + function rk_decode($rk) + { +// $this->dbglog->trace("rk_decode(".var_export($rk,true).") function call"); + $res = array(); + + // bit 1 integer value + if( $rk & 2 ) { + // integer + $val = ($rk & 0xfffffffc) >> 2; + if (((float)$val) == floor((float)$val)) { + $res['val'] = (int)$val; + $res['type'] = 1; + } else { + $res['val'] = (float)$val; + $res['type'] = 2; + } + } else { + // floating-point + $res['type'] = 2; + $frk = $rk; + + $fexp = (($frk & 0x7ff00000) >> 20) - 1023; + $val = 1+(($frk & 0x000fffff) >> 2)/262144; + if( $fexp > 0 ) { + for( $i=0; $i<$fexp; $i++ ) + $val *= 2; + } else { + if( $fexp==-1023 ) { + $val=0; + } else { + for( $i=0; $i> 31) { + $val = -($val); + } + $res['val'] = (float)$val; + } +// $this->dbglog->trace("rk_decode() function returns"); + return $res; + } + +/** + * Parse worksheet + * + * @param string + * @param int + */ + function parse_worksheet($ws, $_format_needed=1) + { + $this->dbglog->debug("parse_worksheet(DATA) function"); + if( strlen($ws) <= 0 ){ + $this->dbglog->trace("parse_worksheet() function returns 7 (Data not Found)"); + return 7; + } + if( strlen($ws) < 4 ){ + $this->dbglog->trace("parse_worksheet() function returns 6 (File Corrupted)"); + return 6; + } + + // parse workbook header + if( strlen($ws) < 256*ord($ws[3])+ord($ws[2]) ) return 6; + + if( ord($ws[0]) != 0x09 ) return 6; + $vers = ord($ws[1]); + if( ($vers!=0) && ($vers!=2) && ($vers!=4) && ($vers!=8) ) + return 8; + + if( $vers!=8 ) { + $biff_ver = ($ver+4)/2; + } else { + if( strlen($ws) < 12 ) return 6; + switch( ord($ws[4])+256*ord($ws[5]) ) { + case 0x0500: + if( ord($ws[0x0a])+256*ord($ws[0x0b]) < 1994 ) { + $biff_ver = 5; + } else { + switch(ord( $ws[8])+256*ord($ws[9]) ) { + case 2412: + case 3218: + case 3321: +/*dbg*/ $this->dbglog->debug("Parsed BIFF version is 5"); + $biff_ver = 5; + break; + default: + $this->dbglog->debug("Parsed BIFF version is 7"); + $biff_ver = 7; + break; + } + } + break; + case 0x0600: +/*DBG*/ $this->dbglog->debug("Parsed BIFF version is 8"); + $biff_ver = 8; + break; + default: + return 8; + } + } + + if( $biff_ver < 5 ) { +/*DBG*/ $this->dbglog->debug("parse_worksheet() function found ($biff_ver < 5) return 8"); + return 8; + } + $ptr = 0; + $data = array('biff_version' => $biff_ver ); + + while( (ord($ws[$ptr])!=0x0a) && ($ptrdbglog->trace("found NUMBER"); + + if( ($biff_ver < 3) ){ +/*DBG*/ $this->dbglog->trace("$biff_ver < 3 break;"); + break; + } + if( (ord($ws[$ptr+2])+256*ord($ws[$ptr+3])) < 14 ){ +/*DBG*/ $this->dbglog->debug("parse_worksheet() return 6"); + return 6; + } + + $row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]); + $col = ord($ws[$ptr+6])+256*ord($ws[$ptr+7]); + $num_lo = str2long(substr($ws,$ptr+10,4)); + $num_hi = str2long(substr($ws,$ptr+14,4)); + $xf_i = ord($ws[$ptr+8])+256*ord($ws[$ptr+9]); + + $data['cell'][$row][$col]['format']=$this->format[$this->xf['format'][$xf_i]]; + + if($this->isDateFormat($xf_i)){ + $data['cell'][$row][$col]['type'] = 3; + } else { + $data['cell'][$row][$col]['type'] = 2; + } + + $fonti = $this->xf['font'][$xf_i]; + $data['cell'][$row][$fc+$i]['font'] = $fonti; + + $fexp = (($num_hi & 0x7ff00000) >> 20) - 1023; + $val = 1+(($num_hi & 0x000fffff) + $num_lo/4294967296)/1048576; + + if( $fexp > 0 ) { + for( $i=0; $i<$fexp; $i++ ) + $val *= 2; + } else { + for( $i=0; $i> 31 ) { + $val = -($val) ; + } + + $data['cell'][$row][$col]['data'] = (float)$val; + + if( !isset($data['max_row']) || + ($data['max_row'] < $row) ) + $data['max_row'] = $row; + + if( !isset($data['max_col']) || + ($data['max_col'] < $col) ) + $data['max_col'] = $col; + + break; + + // RK + case 0x027e: +/*DBG*/ $this->dbglog->trace("found RK"); + if( ($biff_ver < 3) ) break; + if( (ord($ws[$ptr+2])+256*ord($ws[$ptr+3])) < 0x0a ) + return 6; + $row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]); + $col = ord($ws[$ptr+6])+256*ord($ws[$ptr+7]); + $xf_i = ord($ws[$ptr+8])+256*ord($ws[$ptr+9]); + $val = $this->rk_decode( + str2long(substr($ws,$ptr+10,4)) + ); + + if($this->isDateFormat($xf_i)==TRUE){ + $data['cell'][$row][$col]['type'] = 3; + } else { + $data['cell'][$row][$col]['type'] = $val['type']; + } + $fonti = $this->xf['font'][$xf_i]; + + $data['cell'][$row][$col]['font'] = $fonti; + $data['cell'][$row][$col]['data'] = $val['val']; + $data['cell'][$row][$col]['format']=$this->format[$this->xf['format'][$xf_i]]; + + + if( !isset($data['max_row']) || + ($data['max_row'] < $row) ) + $data['max_row'] = $row; + + if( !isset($data['max_col']) || + ($data['max_col'] < $col) ) + $data['max_col'] = $col; + + break; + + // MULRK + case 0x00bd: +/*DBG*/ $this->dbglog->trace("found MULL RK"); + if( ($biff_ver < 5) ) break; + $sz = ord($ws[$ptr+2])+256*ord($ws[$ptr+3]); + if( $sz < 6 ) return 6; + + $row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]); + $fc = ord($ws[$ptr+6])+256*ord($ws[$ptr+7]); + $lc = ord($ws[$ptr+$sz+2])+256*ord($ws[$ptr+$sz+3]); + + for( $i=0; $i<=$lc-$fc; $i++) { + $val = $this->rk_decode( + str2long(substr($ws,$ptr+10+$i*6,4)) + ); + + $xf_i=ord($ws[$ptr+8+$i*6])+256*ord($ws[($ptr+9+$i*6)]); + if($this->isDateFormat($xf_i)==TRUE) { + $data['cell'][$row][$fc+$i]['type'] = 3; + } else { + $data['cell'][$row][$fc+$i]['type'] = $val['type']; + } + $fonti = $this->xf['font'][$xf_i]; + $data['cell'][$row][$fc+$i]['font'] = $fonti; + $data['cell'][$row][$fc+$i]['data'] = $val['val']; + $data['cell'][$row][$fc+$i]['format']=$this->format[$this->xf['format'][$xf_i]]; + } + + if( !isset($data['max_row']) || + ($data['max_row'] < $row) ) + $data['max_row'] = $row; + + if( !isset($data['max_col']) || + ($data['max_col'] < $lc) ) + $data['max_col'] = $lc; + + break; + + // LABEL + case 0x0204: +/*DBG*/ $this->dbglog->trace("found LABEL"); + if( ($biff_ver < 3) ){ + break; + } + if( (ord($ws[$ptr+2])+256*ord($ws[$ptr+3])) < 8 ){ + return 6; + } + $row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]); + $col = ord($ws[$ptr+6])+256*ord($ws[$ptr+7]); + $xf = ord($ws[$ptr+8])+256*ord($ws[$ptr+9]); + $fonti = $this->xf['font'][$xf]; + $font = $this->fonts[$fonti]; + + + $str_len = ord($ws[$ptr+10])+256*ord($ws[$ptr+11]); + + if( $ptr+12+$str_len > strlen($ws) ) + return 6; + $this->sst['unicode'][] = false; + $this->sst['data'][] = substr($ws,$ptr+12,$str_len); + $data['cell'][$row][$col]['type'] = 0; + $sst_ind = count($this->sst['data'])-1; + $data['cell'][$row][$col]['data'] = $sst_ind; + $data['cell'][$row][$col]['font'] = $fonti; + +/* echo str_replace("\n","
            \n", ExcelFont::toString($font,$fonti)); + echo "FontRecord for sting ".$this->sst['data'][$sst_ind]."
            ";*/ + + if( !isset($data['max_row']) || + ($data['max_row'] < $row) ) + $data['max_row'] = $row; + + if( !isset($data['max_col']) || + ($data['max_col'] < $col) ) + $data['max_col'] = $col; + + + + break; + + // LABELSST + case 0x00fd: + if( $biff_ver < 8 ) break; + if( (ord($ws[$ptr+2])+256*ord($ws[$ptr+3])) < 0x0a ) + return 6; + $row = ord($ws[$ptr+4])+256*ord($ws[$ptr+5]); + $col = ord($ws[$ptr+6])+256*ord($ws[$ptr+7]); + $xf = ord($ws[$ptr+8])+256*ord($ws[$ptr+9]); + $fonti = $this->xf['font'][$xf]; + $font = &$this->fonts[$fonti]; + + $data['cell'][$row][$col]['type'] = 0; + $sst_ind = str2long(substr($ws,$ptr+10,4)); + $data['cell'][$row][$col]['data'] = $sst_ind; + $data['cell'][$row][$col]['font'] = $fonti; + +/* echo "FontRecord for sting at $row,$col
            "; + echo str_replace("\n","
            \n", ExcelFont::toString($font,$fonti));*/ + + if( !isset($data['max_row']) || + ($data['max_row'] < $row) ) + $data['max_row'] = $row; + + if( !isset($data['max_col']) || + ($data['max_col'] < $col) ) + $data['max_col'] = $col; + + break; + + // unknown, unsupported or unused opcode + default: + break; + } + + $ptr += 4+256*ord($ws[$ptr+3])+ord($ws[$ptr+2]); + } + //$this->dbglog->debug("parse_worksheet() function returns ".var_export($data,true)); + + if(is_array($data['cell'])&&$_format_needed) + foreach($data['cell'] as $row=>$_value) + if(is_array($_value)) + foreach($_value as $col=>$_value) + { + if($_value['format']!='') + { + $_format=$_value['format']; + + + $format_type=''; + if($_format=='General') + { + $format_type='general'; + if(is_infinite($_value['data'])) + $_value['data']=''; + } + preg_match_all('/(0+)((\.(0+))?)(%?)/is', $_format, $matches); + if(is_array($matches[1])&&count($matches[1])>0&&is_array($matches[2])&&count($matches[2])>0) + //Percentage formatting + { + $format_type='numeric'; + $_value['data']*=$matches[5][0]=='%'?100:1; + $format_str="%.".strlen($matches[4][0])."f".str_replace('%', '%%', $matches[5][0]); + } + if($format_type=='') + { + preg_match_all('/([^\\\ :\/;@\[\]\$]+)(\\\.{1,1}|:|\/|;|@|\[|\]|\$)?/is', $_format, $matches); + if(is_array($matches)&&is_array($matches[1])) + { + //Date/Time formatting + $format_type='datetime'; + $format_str=''; + foreach($matches[1] as $key=>$value) + { + $_format_char=''; + switch($value) + { + case 'd': + $_format_char='j'; + break; + case 'dd': + $_format_char='d'; + break; + case 'ddd': + $_format_char='D'; + break; + case 'dddd': + $_format_char='d'; + break; + case 'm': + $_format_char=$matches[2][$key]==':'?'i':'n'; + break; + case 'mm': + $_format_char=(($matches[2][$key-1]==':'||$matches[2][$key-1]==';'||$matches[2][$key]==':'||$matches[2][$key]==';')?'i':'m'); + break; + case 'mmm': + $_format_char='M'; + break; + case 'mmmm': + $_format_char='F'; + break; + case 'mmmmm': + $_format_char='F'; + break; + case 'y': + $_format_char='y'; + break; + case 'yy': + $_format_char='y'; + break; + case 'yyy': + $_format_char='Y'; + break; + case 'yyyy': + $_format_char='Y'; + break; + case 'h': + $_format_char='G'; + break; + case 'hh': + $_format_char='H'; + break; + case 's': + $_format_char='s'; + break; + case 'ss': + $_format_char='s'; + break; + } + if($_format_char!='') + { + $end=stripslashes($matches[2][$key]); + $end=$end==']'?':':$end; + $end=$end=='/'?'.':$end; + + $format_str.=$_format_char.($end!=';'?$end:''); + } + } + } + } + switch($format_type) + { +/** + * Warning: + * Negative timestamps are not supported under any known version of Windows. + * Therefore the range of valid years includes only 1970 through 2038. + */ + case 'datetime': + $_data=str_replace(',', '.', $_value['data']); + $date=floor($_data); + $time=60*60*24*("0.".substr($_data, strlen($date)+1)); + if($date==0) { + $_mk=gmmktime(0, 0, ceil($time));//, 1, 1, 1970); + } else { + $_mk=gmmktime(0, 0, ceil($time), 1, $date-25568,1970); + } + $res=gmdate($format_str, $_mk); + break; + case 'numeric': + $res=sprintf($format_str, $_value['data']); + break; + case 'general': + $res=$_value['data']; + break; + } + $data['cell'][$row][$col]['data']=$res;//."(".$_value['data'].", $format_str)"; + } + } + return $data; + } + +/** + * Parse workbook + */ + function parse_workbook( $f_header, $dp ) + { +/*DBG*/ $this->dbglog->debug("parse_workbook() function"); + $root_entry_block = $f_header->getLong(0x30); + $num_fat_blocks = $f_header->getLong(0x2c); + +/*TRC*/ $this->dbglog->trace("Header parsed"); + + $this->fat = array(); + $num_fat_blocks1 = $num_fat_blocks>108? 109: $num_fat_blocks; + $pos = 0x4c; + for( $i = 0; $i < $num_fat_blocks1; $i++ ){ +/*TRC*/ $this->dbglog->trace("FOR LOOP iteration i =".$i. " of " .$num_fat_blocks); + + $fat_block = $f_header->getLong($pos); + $fatbuf = $dp->get( $fat_block * 0x200, 0x200 ); + + $fat = new DataProvider( $fatbuf, DP_STRING_SOURCE ); + + if( $fat->getSize() < 0x200 ){ +/*DBG*/ $this->dbglog->debug("parse_workbook() function found (strlen($fat) < 0x200) returns 6"); + return 6; + } + + for( $j=0; $j<0x80; $j++ ) + $this->fat[] = $fat->getLong( $j * 4 ); + + $fat->close(); + unset( $fat_block, $fatbuf, $fat ); + $pos += 4; + } +// read XBAT +$pos = ($f_header->getLong(XBAT_START)) * 512; +$blockstart = 109; +for ($j=0;$j<$f_header->getLong(XBAT_COUNT);$j++) { + $nblocks = min($f_header->getLong(BAT_COUNT) - $blockstart, 127); + for ($i=$blockstart;$i<$nblocks+ $blockstart;$i++) { +/*TRC*/ $this->dbglog->trace("FOR LOOP iteration (XBAT) i =".$i. " of " .$num_fat_blocks); + + $fat_block = $dp->getLong($pos); + $fatbuf = $dp->get( $fat_block * 0x200, 0x200 ); + + $fat = new DataProvider( $fatbuf, DP_STRING_SOURCE ); + + if( $fat->getSize() < 0x200 ){ +/*DBG*/ $this->dbglog->debug("parse_workbook() function found (strlen($fat) < 0x200) returns 6"); + return 6; + } + + for( $j=0; $j<0x80; $j++ ) + $this->fat[] = $fat->getLong( $j * 4 ); + + $fat->close(); + unset( $fat_block, $fatbuf, $fat ); + $pos += 4; + } + $blockstart += $nblocks; + if ($blockstart < $f_header->getLong(BAT_COUNT)) { +// $pos = getlong($pos); + } +} + + + + +/*DBG*/ $this->dbglog->dump( $this->fat, "\$fat" ); + + if( count($this->fat) < $num_fat_blocks ) { +/*DBG*/ $this->dbglog->debug("parse_workbook() function found (count($this->fat) < $num_fat_blocks) returns 6"); + return 6; + } + + $chain = $this->get_blocks_chain($root_entry_block); + $dir = new DataProvider( $dp->ReadFromFat( $chain ), DP_STRING_SOURCE ); + unset( $chain ); + + $this->sfat = array(); + $small_block = $f_header->getLong( 0x3c ); + if( $small_block != 0xfeffffff ) { + + $root_entry_index = $this->find_stream( $dir, 'Root Entry'); + + // Deleted for support MAC files + + //if( $root_entry_index < 0 ) { +/*DBG*/ //$this->dbglog->debug("parse_workbook() function dont found Root Entry returns 6"); + //return 6; + //} + + $sdc_start_block = $dir->getLong( $root_entry_index * 0x80 + 0x74 ); + $small_data_chain = $this->get_blocks_chain($sdc_start_block); + $this->max_sblocks = count($small_data_chain) * 8; + + $schain = $this->get_blocks_chain($small_block); + for( $i = 0; $i < count( $schain ); $i++ ) { + + $sfatbuf = $dp->get( $schain[$i] * 0x200, 0x200 ); + $sfat = new DataProvider( $sfatbuf, DP_STRING_SOURCE ); + + //$this->dbglog->dump( strlen($sfatbuf), "strlen(\$sftabuf)"); + //$this->dbglog->dump( $sfat, "\$sfat"); + + if( $sfat->getSize() < 0x200 ) { +/*DBG*/ $this->dbglog->debug("parse_workbook() function found (strlen($sfat) < 0x200) returns 6"); + return 6; + } + + for( $j=0; $j<0x80; $j++ ) + $this->sfat[] = $sfat->getLong( $j * 4 ); + + $sfat->close(); + unset( $sfatbuf, $sfat ); + } + unset( $schain ); + + $sfcbuf = $dp->ReadFromFat( $small_data_chain ); + $sdp = new DataProvider( $sfcbuf, DP_STRING_SOURCE ); + unset( $sfcbuf, $small_data_chain ); + } + + $workbook_index = $this->find_stream( $dir, 'Workbook' ); + if( $workbook_index<0 ) { + $workbook_index = $this->find_stream( $dir, 'Book' ); + if( $workbook_index<0 ){ +/*DBG*/ $this->dbglog->debug("parse_workbook() function workbook index not found returns 7"); + return 7; + } + } + + $workbook_start_block = $dir->getLong( $workbook_index * 0x80 + 0x74 ); + $workbook_length = $dir->getLong( $workbook_index * 0x80 + 0x78 ); + $wb = ''; + + if( $workbook_length > 0 ) { + if( $workbook_length >= 0x1000 ) { + $chain = $this->get_blocks_chain($workbook_start_block); + $wb = $dp->ReadFromFat( $chain ); + } else { + $chain = $this->get_blocks_chain($workbook_start_block,true); + $wb = $sdp->ReadFromFat( $chain, 0x40 ); + unset( $sdp ); + } + $wb = substr($wb,0,$workbook_length); + if( strlen($wb) != $workbook_length ) + return 6; + unset( $chain ); + } + + // Unset fat arrays + unset( $this->fat, $this->sfat ); + + if( strlen($wb) <= 0 ) { +/*DBG*/ $this->dbglog->debug("parse_workbook() function workbook found (strlen($wb) <= 0) returns 7"); + return 7; + } + if( strlen($wb) < 4 ) { +/*DBG*/ $this->dbglog->debug("parse_workbook() function workbook found (strlen($wb) < 4) returns 6"); + return 6; + } + + // parse workbook header + if( strlen($wb) < 256*ord($wb[3])+ord($wb[2]) ){ +/*DBG*/ $this->dbglog->debug("parse_workbook() function workbook found (strlen($wb) < 256*ord($wb[3])+ord($wb[2])) < 4) returns 6"); + return 6; + } + + if( ord($wb[0]) != 0x09 ){ +/*DBG*/ $this->dbglog->debug("parse_workbook() function workbook found (ord($wb[0]) != 0x09) returns 6"); + return 6; + } + + $vers = ord($wb[1]); + if( ($vers!=0) && ($vers!=2) && ($vers!=4) && ($vers!=8) ){ + return 8; + } + if( $vers!=8 ) + $biff_ver = ($ver+4)/2; + else { + + if (strlen($wb) < 12) return 6; + switch (ord($wb[4])+256*ord($wb[5]) ) + { + case 0x0500: + if( ord($wb[0x0a])+256*ord($wb[0x0b]) < 1994 ) + $biff_ver = 5; + else { + switch(ord( $wb[8])+256*ord($wb[9]) ) { + case 2412: + case 3218: + case 3321: + $biff_ver = 5; + break; + default: + $biff_ver = 7; + break; + } + } + break; + case 0x0600: + $biff_ver = 8; + break; + default: + return 8; + } + } + + if( $biff_ver < 5 ) return 8; + + $ptr = 0; + $this->worksheet['offset'] = array(); + $this->worksheet['options'] = array(); + $this->worksheet['unicode'] = array(); + $this->worksheet['name'] = array(); + $this->worksheet['data'] = array(); + $this->format = $this->populateFormat(); + $this->fonts = array(); + $this->fonts[0] = ExcelFont::basicFontRecord(); + + $this->xf = array(); + $this->xf['format'] = array(); + $this->xf['font'] = array(); + $this->xf['type_prot'] = array(); + $this->xf['alignment'] = array(); + $this->xf['decoration'] = array(); + + $xf_cnt=0; + + $this->sst['unicode'] = array(); + $this->sst['data'] = array(); + + $opcode = 0; + $sst_defined = false; + $wblen = strlen($wb); + + while( (ord($wb[$ptr])!=0x0a) && ($ptr<$wblen) ) + { + $oc = ord($wb[$ptr])+256*ord($wb[$ptr+1]); + if( $oc != 0x3c ) + $opcode = $oc; + + switch ($opcode) + { + + case 0x0085: + $ofs = str2long(substr($wb,$ptr+4,4)); + $this->worksheet['offset'][] = $ofs; + $this->worksheet['options'][] = ord($wb[$ptr+8])+256*ord($wb[$ptr+9]); + if( $biff_ver==8 ) { + $len = ord($wb[$ptr+10]); + if( (ord($wb[$ptr+11]) & 1) > 0 ) { + $this->worksheet['unicode'][] = true; + $len = $len*2; + } else { + $this->worksheet['unicode'][] = false; + } + $this->worksheet['name'][] = substr($wb,$ptr+12,$len); + } else { + $this->worksheet['unicode'][] = false; + $len = ord($wb[$ptr+10]); + $this->worksheet['name'][] = substr($wb,$ptr+11,$len); + } + + $pws = $this->parse_worksheet(substr($wb,$ofs)); + if( is_array($pws) ) + $this->worksheet['data'][] = $pws; + else + return $pws; + break; + + // Format + case 0x041e: + $fidx = ord($wb[$ptr+4])+256*ord($wb[$ptr+5]); + if($fidx<0x31 ||$fidx==0x31 ) + break; + elseif($biff_ver>7) + $this->format[$fidx] = $this->getUnicodeString($wb,$ptr+6); +// echo $wb."---".$this->format[$fidx]."*****
            "; + + // FONT 0x31 + case EXCEL_FONT_RID: + $rec = ExcelFont::getFontRecord($wb,$ptr+4); + $this->fonts[count($this->fonts)] = $rec; +/*echo str_replace("\n","
            \n",ExcelFont::toString($rec,count($this->fonts)-1)); +echo "FontRecord
            " */; + break; + + // XF + case 0x00e0: + $this->xf['font'][$xf_cnt] = ord($wb[$ptr+4])+256*ord($wb[$ptr+5]); + $this->xf['format'][$xf_cnt] = ord($wb[$ptr+6])+256*ord($wb[$ptr+7]); + $this->xf['type'][$xf_cnt] = "1"; + $this->xf['bitmask'][$xf_cnt] = "1"; + $xf_cnt++; + break; + + // SST + case 0x00fc: + if( $biff_ver < 8 ) break; + + $sbuflen = ord($wb[$ptr+2]) + 256*ord($wb[$ptr+3]); + + if( $oc != 0x3c ) { + if( $sst_defined ) return 6; + $snum = str2long(substr($wb,$ptr+8,4)); + $sptr = $ptr+12; + $sst_defined = true; + } else { + if( $rslen > $slen ) { + $sptr = $ptr+4; + $rslen -= $slen; + $slen = $rslen; + + if( (ord($wb[$sptr]) & 1) > 0 ) { + if( $char_bytes == 1 ) { + $sstr = ''; + for( $i=0; $i $ptr+4+$sbuflen ) + $slen = ($ptr+$sbuflen-$sptr+3)/$schar_bytes; + + $sstr = substr($wb,$sptr+1,$slen*$schar_bytes); + + if( ($char_bytes == 2) && ($schar_bytes == 1) ) + { + $sstr2 = ''; + for( $i=0; $i= strlen($wb)) || + ($sptr < $ptr+4+$sbuflen) || + (ord($wb[$sptr]) != 0x3c) ) + { + return 6; + } + break; + } else { + if( $char_bytes == 2 ) { + $this->sst['unicode'][] = true; + } else { + $this->sst['unicode'][] = false; + } + $this->sst['data'][] = $str; + $snum--; + } + } else { + $sptr = $ptr+4; + if( $sptr > $ptr ) $sptr += 4*$rt+$fesz; + } + } + + while( ($sptr < $ptr+4+$sbuflen) && + ($sptr < strlen($wb)) && + ($snum > 0) ) + { + $rslen = ord($wb[$sptr])+256*ord($wb[$sptr+1]); + $slen = $rslen; + + if( (ord($wb[$sptr+2]) & 1) > 0 ) { + $char_bytes = 2; + } else { + $char_bytes = 1; + } + + $rt = 0; + $fesz = 0; + switch (ord($wb[$sptr+2]) & 0x0c) { + // Rich-Text with Far-East + case 0x0c: + $rt = ord($wb[$sptr+3])+256*(ord($wb[$sptr+4])); + $fesz = str2long(substr($wb,$sptr+5,4)); + if( $sptr+9+$slen*$char_bytes > $ptr+4+$sbuflen ) + $slen = ($ptr+$sbuflen-$sptr-5)/$char_bytes; + $str = substr($wb,$sptr+9,$slen*$char_bytes); + $sptr += $slen*$char_bytes+9; + break; + + // Rich-Text + case 8: + $rt = ord($wb[$sptr+3])+256*(ord($wb[$sptr+4])); + if( $sptr+5+$slen*$char_bytes > $ptr+4+$sbuflen ) + $slen = ($ptr+$sbuflen-$sptr-1)/$char_bytes; + $str = substr($wb,$sptr+5,$slen*$char_bytes); + $sptr += $slen*$char_bytes+5; + break; + + // Far-East + case 4: + $fesz = str2long(substr($wb,$sptr+3,4)); + if( $sptr+7+$slen*$char_bytes > $ptr+4+$sbuflen ) + $slen = ($ptr+$sbuflen-$sptr-3)/$char_bytes; + $str = substr($wb,$sptr+7,$slen*$char_bytes); + $sptr += $slen*$char_bytes+7; + break; + + // Compressed or uncompressed unicode + case 0: + if( $sptr+3+$slen*$char_bytes > $ptr+4+$sbuflen ) + $slen = ($ptr+$sbuflen-$sptr+1)/$char_bytes; + $str = substr($wb,$sptr+3,$slen*$char_bytes); + $sptr += $slen*$char_bytes+3; + break; + } + + if( $slen < $rslen ) { + if( ($sptr >= strlen($wb)) || + ($sptr < $ptr+4+$sbuflen) || + (ord($wb[$sptr]) != 0x3c) ) return 6; + } else { + if( $char_bytes == 2 ) { + $this->sst['unicode'][] = true; + } else { + $this->sst['unicode'][] = false; + } + $sptr += 4*$rt+$fesz; + $this->sst['data'][] = $str; + $snum--; + } + } // switch + break; + } // switch + + // !!! Optimization: + // $this->wsb[] = substr($wb,$ptr,4+256*ord($wb[$ptr+3])+ord($wb[$ptr+2])); + + $ptr += 4+256*ord($wb[$ptr+3])+ord($wb[$ptr+2]); + } // while + + // !!! Optimization: + // $this->workbook = $wb; + $this->biff_version = $biff_ver; +/*DBG*/ $this->dbglog->debug("parse_workbook() function returns 0"); + return 0; + } +/** + * ParseFromString + * + * This function is not optimized for memory usage, but the script takes less times + * to be completely executed and to parse the selected data. Use when parsing speed + * is critical (PHP memory limit can be exceed for huge files and script will terminate!). + * + * IN: + * string contents - File contents + * string filename - File name of an existing Excel file. + * + * @return int + * 0 - success + * 1 - can't open file + * 2 - file too small to be an Excel file + * 3 - error reading header + * 4 - error reading file + * 5 - This is not an Excel file or file stored in < Excel 5.0 + * 6 - file corrupted + * 7 - data not found + * 8 - Unsupported file version + * + * @param string + * + */ + function ParseFromString( $contents ) + { + $this->dbglog->info("ParseFromString() enter."); + $this->dp = new DataProvider( $contents, DP_STRING_SOURCE ); + return $this->InitParser(); + } + +/** + * Parse Excel file + * + * This function is optimized for memory usage, but the script takes more times + * to be completely executed and to parse the selected data. Use with large files. + * @param string $filename file name + */ + function ParseFromFile( $filename ) + { + $this->dbglog->info("ParseFromFile() enter."); + $this->dp = new DataProvider( $filename, DP_FILE_SOURCE ); + return $this->InitParser(); + } + +/** + * + * @return mixed + */ + function InitParser() + { + $this->dbglog->info("InitParser() enter."); + if( !$this->dp->isValid() ) + { + $this->dbglog->error("InitParser() Failed to open file."); + $this->dbglog->error("InitParser() function returns 1"); + return 1; + } + if( $this->dp->getSize() <= 0x200 ) + { + $this->dbglog->error("InitParser() File too small to be an Excel file."); + $this->dbglog->error("InitParser() function returns 2"); + return 2; + } + + $this->max_blocks = $this->dp->getBlocks(); + + // read file header + $hdrbuf = $this->dp->get( 0, 0x200 ); + if( strlen( $hdrbuf ) < 0x200 ) + { + $this->dbglog->error("InitParser() Error reading header."); + $this->dbglog->error("InitParser() function returns 3"); + return 3; + } + + // check file header + $header_sig = array(0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1); + for( $i = 0; $i < count($header_sig); $i++ ) + if( $header_sig[$i] != ord( $hdrbuf[$i] ) ){ +/*DBG*/ $this->dbglog->error("InitParser() function founds invalid header"); +/*DBG*/ $this->dbglog->error("InitParser() function returns 5"); + return 5; + } + + $f_header = new DataProvider( $hdrbuf, DP_STRING_SOURCE ); + unset( $hdrbuf, $header_sig, $i ); + + $this->dp->_baseOfs = 0x200; + $rc = $this->parse_workbook($f_header, $this->dp); + unset( $f_header ); + unset( $this->dp, $this->max_blocks, $this->max_sblocks ); + + return $rc; + } +} + +/** + * Make 32-bit integer from dump + * + * @param mixed + * @return int + */ + function str2long($str) + { + return ord($str[0]) | ((ord($str[1])) << 8) | ((ord($str[2])) << 16) | ((ord($str[3])) << 24); + } +?> \ No newline at end of file diff --git a/api/express.php b/api/express.php new file mode 100644 index 0000000..911031c --- /dev/null +++ b/api/express.php @@ -0,0 +1,34 @@ + \ No newline at end of file diff --git a/api/extend.func.php b/api/extend.func.php new file mode 100644 index 0000000..3fe4698 --- /dev/null +++ b/api/extend.func.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/api/im.func.php b/api/im.func.php new file mode 100644 index 0000000..51eb7ee --- /dev/null +++ b/api/im.func.php @@ -0,0 +1,33 @@ +' : ''; +} + +function im_qq($id, $style = 0) { + return $id ? '' : ''; +} + +function im_wx($id, $username = '', $style = 0) { + global $DT_PC; + return $id ? '' : ''; +} + +function im_ali($id, $style = 0) { + if($id) { + $tb = 0; + if(substr($id, 0, 3) == 'TB:') { + $tb = 1; + $id = substr($id, 3); + } + $id = urlencode($id); + return ($tb ? ''; + } + return ''; +} + +function im_skype($id, $style = 0) { + return $id ? '' : ''; +} +?> \ No newline at end of file diff --git a/api/image.png.php b/api/image.png.php new file mode 100644 index 0000000..41c8591 --- /dev/null +++ b/api/image.png.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/api/index.html b/api/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/js.php b/api/js.php new file mode 100644 index 0000000..998f60f --- /dev/null +++ b/api/js.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/api/json.php b/api/json.php new file mode 100644 index 0000000..babe142 --- /dev/null +++ b/api/json.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/api/json/demo.inc.php b/api/json/demo.inc.php new file mode 100644 index 0000000..fa5a9a3 --- /dev/null +++ b/api/json/demo.inc.php @@ -0,0 +1,10 @@ +query("SELECT itemid,title FROM {$DT_PRE}webpage ORDER BY listorder"); +while($r = $db->fetch_array($result)) { + $lists[] = $r; +} +echo json_encode($lists); +?> \ No newline at end of file diff --git a/api/json/demo.php b/api/json/demo.php new file mode 100644 index 0000000..f56eafa --- /dev/null +++ b/api/json/demo.php @@ -0,0 +1,10 @@ +query("SELECT itemid,title FROM {$DT_PRE}webpage ORDER BY listorder"); +while($r = $db->fetch_array($result)) { + $lists[] = $r; +} +echo json_encode($lists); +?> \ No newline at end of file diff --git a/api/json/index.html b/api/json/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/json/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/kf/index.html b/api/kf/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/kf/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/kf/qiao/index.html b/api/kf/qiao/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/kf/qiao/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/kf/qiao/post.inc.php b/api/kf/qiao/post.inc.php new file mode 100644 index 0000000..f2dfab9 --- /dev/null +++ b/api/kf/qiao/post.inc.php @@ -0,0 +1,16 @@ + + +在线客服帐号 + +   + +帐号管理 + +帐号申请 +

            +提示:注册后获取的客服代码“...hm.baidu.com/h.js%3F321c361fa45809b610d5ec4ae9a392c2' type=...”中321c361fa45809b610d5ec4ae9a392c2即为客服帐号 + + \ No newline at end of file diff --git a/api/kf/qiao/show.inc.php b/api/kf/qiao/show.inc.php new file mode 100644 index 0000000..a2e1a9f --- /dev/null +++ b/api/kf/qiao/show.inc.php @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/api/kf/qq/index.html b/api/kf/qq/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/kf/qq/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/kf/qq/post.inc.php b/api/kf/qq/post.inc.php new file mode 100644 index 0000000..ad5a209 --- /dev/null +++ b/api/kf/qq/post.inc.php @@ -0,0 +1,16 @@ + + +在线客服帐号 + +   + +帐号管理 + +帐号申请 +

            +提示:注册后获取的客服代码“...src="http://wpa.b.qq.com/cgi/wpa.php?key=XzgwMDAsTA2M18xNDAzMzhf08AwMDYxMDYzXw">...”中XzgwMDAsTA2M18xNDAzMzhf08AwMDYxMDYzXw即为客服帐号 + + \ No newline at end of file diff --git a/api/kf/qq/show.inc.php b/api/kf/qq/show.inc.php new file mode 100644 index 0000000..3888279 --- /dev/null +++ b/api/kf/qq/show.inc.php @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/api/kf/these.name.php b/api/kf/these.name.php new file mode 100644 index 0000000..17737bc --- /dev/null +++ b/api/kf/these.name.php @@ -0,0 +1,6 @@ + '企业QQ(b.qq.com)', + 'qiao' => '百度商桥(qiao.baidu.com)', +); +?> \ No newline at end of file diff --git a/api/map/51ditu/config.inc.php b/api/map/51ditu/config.inc.php new file mode 100644 index 0000000..6cf1113 --- /dev/null +++ b/api/map/51ditu/config.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/map/51ditu/index.html b/api/map/51ditu/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/map/51ditu/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/map/51ditu/mark.php b/api/map/51ditu/mark.php new file mode 100644 index 0000000..ac53a74 --- /dev/null +++ b/api/map/51ditu/mark.php @@ -0,0 +1,62 @@ + + + + + + +灵图 - 双击标注位置 + + + + + + + + + +
            + + \ No newline at end of file diff --git a/api/map/51ditu/post.inc.php b/api/map/51ditu/post.inc.php new file mode 100644 index 0000000..74b36e4 --- /dev/null +++ b/api/map/51ditu/post.inc.php @@ -0,0 +1,19 @@ + + +公司地图标注 + +   +标注 | 清空 + + + \ No newline at end of file diff --git a/api/map/51ditu/show.inc.php b/api/map/51ditu/show.inc.php new file mode 100644 index 0000000..445b808 --- /dev/null +++ b/api/map/51ditu/show.inc.php @@ -0,0 +1,18 @@ + +
            + + \ No newline at end of file diff --git a/api/map/baidu/config.inc.php b/api/map/baidu/config.inc.php new file mode 100644 index 0000000..a418bf8 --- /dev/null +++ b/api/map/baidu/config.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/map/baidu/index.html b/api/map/baidu/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/map/baidu/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/map/baidu/mark.php b/api/map/baidu/mark.php new file mode 100644 index 0000000..aa552b5 --- /dev/null +++ b/api/map/baidu/mark.php @@ -0,0 +1,102 @@ + + + + + + +Baidu Map - 双击标注位置 + + + + + +
            + + + \ No newline at end of file diff --git a/api/map/baidu/post.inc.php b/api/map/baidu/post.inc.php new file mode 100644 index 0000000..afe9661 --- /dev/null +++ b/api/map/baidu/post.inc.php @@ -0,0 +1,19 @@ + + +公司地图标注 + +   +标注 | 清空 + + + \ No newline at end of file diff --git a/api/map/baidu/show.inc.php b/api/map/baidu/show.inc.php new file mode 100644 index 0000000..8e6423a --- /dev/null +++ b/api/map/baidu/show.inc.php @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/api/map/baidu/show.php b/api/map/baidu/show.php new file mode 100644 index 0000000..4d8f699 --- /dev/null +++ b/api/map/baidu/show.php @@ -0,0 +1,43 @@ + + + + + + +Baidu Map + + + + + +
            + + + \ No newline at end of file diff --git a/api/map/google/config.inc.php b/api/map/google/config.inc.php new file mode 100644 index 0000000..ea11163 --- /dev/null +++ b/api/map/google/config.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/map/google/index.html b/api/map/google/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/map/google/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/map/google/mark.php b/api/map/google/mark.php new file mode 100644 index 0000000..ec1a0bd --- /dev/null +++ b/api/map/google/mark.php @@ -0,0 +1,72 @@ + + + + + +Google Map - 点击标注位置 + + + + + + + + + \ No newline at end of file diff --git a/api/map/google/post.inc.php b/api/map/google/post.inc.php new file mode 100644 index 0000000..3b2326c --- /dev/null +++ b/api/map/google/post.inc.php @@ -0,0 +1,19 @@ + + +公司地图标注 + +   +标注 | 清空 + + + \ No newline at end of file diff --git a/api/map/google/show.inc.php b/api/map/google/show.inc.php new file mode 100644 index 0000000..d187222 --- /dev/null +++ b/api/map/google/show.inc.php @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/api/map/google/show.php b/api/map/google/show.php new file mode 100644 index 0000000..aef262a --- /dev/null +++ b/api/map/google/show.php @@ -0,0 +1,70 @@ + + + + + +Google Map + + + + + + + + + + \ No newline at end of file diff --git a/api/map/index.html b/api/map/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/map/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/map/mapabc/config.inc.php b/api/map/mapabc/config.inc.php new file mode 100644 index 0000000..c9e0994 --- /dev/null +++ b/api/map/mapabc/config.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/map/mapabc/index.html b/api/map/mapabc/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/map/mapabc/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/map/mapabc/mark.php b/api/map/mapabc/mark.php new file mode 100644 index 0000000..718dcc8 --- /dev/null +++ b/api/map/mapabc/mark.php @@ -0,0 +1,44 @@ + + + + + +MapABC - 点击标注位置 + + + + + + +
            + + \ No newline at end of file diff --git a/api/map/mapabc/post.inc.php b/api/map/mapabc/post.inc.php new file mode 100644 index 0000000..e90d52f --- /dev/null +++ b/api/map/mapabc/post.inc.php @@ -0,0 +1,19 @@ + + +公司地图标注 + +   +标注 | 清空 + + + \ No newline at end of file diff --git a/api/map/mapabc/show.inc.php b/api/map/mapabc/show.inc.php new file mode 100644 index 0000000..f9565d6 --- /dev/null +++ b/api/map/mapabc/show.inc.php @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/api/map/mapabc/show.php b/api/map/mapabc/show.php new file mode 100644 index 0000000..b041faf --- /dev/null +++ b/api/map/mapabc/show.php @@ -0,0 +1,81 @@ + + + + + +MapABC + + + + + + +
            + + \ No newline at end of file diff --git a/api/map/qq/config.inc.php b/api/map/qq/config.inc.php new file mode 100644 index 0000000..f50378f --- /dev/null +++ b/api/map/qq/config.inc.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/api/map/qq/index.html b/api/map/qq/index.html new file mode 100644 index 0000000..c1e1f00 --- /dev/null +++ b/api/map/qq/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/api/map/qq/mark.php b/api/map/qq/mark.php new file mode 100644 index 0000000..f31e60f --- /dev/null +++ b/api/map/qq/mark.php @@ -0,0 +1,56 @@ + + + + + + +腾讯地图 - 双击标注位置 + + + + + + +
            + + \ No newline at end of file diff --git a/api/map/qq/post.inc.php b/api/map/qq/post.inc.php new file mode 100644 index 0000000..055ff67 --- /dev/null +++ b/api/map/qq/post.inc.php @@ -0,0 +1,19 @@ + + +公司地图标注 + +   +标注 | 清空 + + + \ No newline at end of file diff --git a/api/map/qq/show.inc.php b/api/map/qq/show.inc.php new file mode 100644 index 0000000..5fa6d5f --- /dev/null +++ b/api/map/qq/show.inc.php @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/api/map/qq/show.php b/api/map/qq/show.php new file mode 100644 index 0000000..c249832 --- /dev/null +++ b/api/map/qq/show.php @@ -0,0 +1,42 @@ + + + + + + +Tencent Map + + + + + + +
            + + \ No newline at end of file diff --git a/api/map/these.name.php b/api/map/these.name.php new file mode 100644 index 0000000..4b863f6 --- /dev/null +++ b/api/map/these.name.php @@ -0,0 +1,9 @@ + '百度地图(baidu)', + 'qq' => '腾讯地图(qq)', + '51ditu' => '灵图地图(51ditu)', + 'mapabc' => '高德地图(mapabc)', + 'google' => '谷歌地图(google)', +); +?> \ No newline at end of file diff --git a/api/memcache.php b/api/memcache.php new file mode 100644 index 0000000..49505a2 --- /dev/null +++ b/api/memcache.php @@ -0,0 +1,908 @@ + 0 && $_groupid == 1 && is_founder($_userid)) or exit('Access Denied'); +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Harun Yayli | + +----------------------------------------------------------------------+ +*/ + +$VERSION='$Id: memcache.php 309747 2011-03-27 17:28:56Z hradtke $'; + +define('ADMIN_USERNAME',''); // Admin Username +define('ADMIN_PASSWORD',''); // Admin Password +define('DATE_FORMAT','Y/m/d H:i:s'); +define('GRAPH_SIZE',200); +define('MAX_ITEM_DUMP',50); + +#$MEMCACHE_SERVERS[] = '127.0.0.1:11211'; // add more as an array +#$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array +include DT_ROOT.'/file/config/memcache.inc.php'; +$MEMCACHE_SERVERS = array(); +foreach($MemServer as $v) { + $MEMCACHE_SERVERS[] = $v['host'].':'.$v['port']; +} +////////// END OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////// + +///////////////// Password protect //////////////////////////////////////////////////////////////// +/* +if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || + $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) { + Header("WWW-Authenticate: Basic realm=\"Memcache Login\""); + Header("HTTP/1.0 401 Unauthorized"); + + echo << +

            Rejected!

            + Wrong Username or Password! + +EOB; + exit; +} +*/ + +///////////MEMCACHE FUNCTIONS ///////////////////////////////////////////////////////////////////// + +function get_host_port_from_server($server){ + $values = explode(':', $server); + if (($values[0] == 'unix') && (!is_numeric( $values[1]))) { + return array($server, 0); + } + else { + return $values; + } +} + +function sendMemcacheCommands($command){ + global $MEMCACHE_SERVERS; + $result = array(); + + foreach($MEMCACHE_SERVERS as $server){ + $strs = get_host_port_from_server($server); + $host = $strs[0]; + $port = $strs[1]; + $result[$server] = sendMemcacheCommand($host,$port,$command); + } + return $result; +} +function sendMemcacheCommand($server,$port,$command){ + + $s = @fsockopen($server,$port); + if (!$s){ + die("Cant connect to:".$server.':'.$port); + } + + fwrite($s, $command."\r\n"); + + $buf=''; + while ((!feof($s))) { + $buf .= fgets($s, 256); + if (strpos($buf,"END\r\n")!==false){ // stat says end + break; + } + if (strpos($buf,"DELETED\r\n")!==false || strpos($buf,"NOT_FOUND\r\n")!==false){ // delete says these + break; + } + if (strpos($buf,"OK\r\n")!==false){ // flush_all says ok + break; + } + } + fclose($s); + return parseMemcacheResults($buf); +} +function parseMemcacheResults($str){ + + $res = array(); + $lines = explode("\r\n",$str); + $cnt = count($lines); + for($i=0; $i< $cnt; $i++){ + $line = $lines[$i]; + $l = explode(' ',$line,3); + if (count($l)==3){ + $res[$l[0]][$l[1]]=$l[2]; + if ($l[0]=='VALUE'){ // next line is the value + $res[$l[0]][$l[1]] = array(); + list ($flag,$size)=explode(' ',$l[2]); + $res[$l[0]][$l[1]]['stat']=array('flag'=>$flag,'size'=>$size); + $res[$l[0]][$l[1]]['value']=$lines[++$i]; + } + }elseif($line=='DELETED' || $line=='NOT_FOUND' || $line=='OK'){ + return $line; + } + } + return $res; + +} + +function dumpCacheSlab($server,$slabId,$limit){ + list($host,$port) = get_host_port_from_server($server); + $resp = sendMemcacheCommand($host,$port,'stats cachedump '.$slabId.' '.$limit); + + return $resp; + +} + +function flushServer($server){ + list($host,$port) = get_host_port_from_server($server); + $resp = sendMemcacheCommand($host,$port,'flush_all'); + return $resp; +} +function getCacheItems(){ + $items = sendMemcacheCommands('stats items'); + $serverItems = array(); + $totalItems = array(); + foreach ($items as $server=>$itemlist){ + $serverItems[$server] = array(); + $totalItems[$server]=0; + if (!isset($itemlist['STAT'])){ + continue; + } + + $iteminfo = $itemlist['STAT']; + + foreach($iteminfo as $keyinfo=>$value){ + if (preg_match('/items\:(\d+?)\:(.+?)$/',$keyinfo,$matches)){ + $serverItems[$server][$matches[1]][$matches[2]] = $value; + if ($matches[2]=='number'){ + $totalItems[$server] +=$value; + } + } + } + } + return array('items'=>$serverItems,'counts'=>$totalItems); +} +function getMemcacheStats($total=true){ + $resp = sendMemcacheCommands('stats'); + if ($total){ + $res = array(); + foreach($resp as $server=>$r){ + foreach($r['STAT'] as $key=>$row){ + if (!isset($res[$key])){ + $res[$key]=null; + } + switch ($key){ + case 'pid': + $res['pid'][$server]=$row; + break; + case 'uptime': + $res['uptime'][$server]=$row; + break; + case 'time': + $res['time'][$server]=$row; + break; + case 'version': + $res['version'][$server]=$row; + break; + case 'pointer_size': + $res['pointer_size'][$server]=$row; + break; + case 'rusage_user': + $res['rusage_user'][$server]=$row; + break; + case 'rusage_system': + $res['rusage_system'][$server]=$row; + break; + case 'curr_items': + $res['curr_items']+=$row; + break; + case 'total_items': + $res['total_items']+=$row; + break; + case 'bytes': + $res['bytes']+=$row; + break; + case 'curr_connections': + $res['curr_connections']+=$row; + break; + case 'total_connections': + $res['total_connections']+=$row; + break; + case 'connection_structures': + $res['connection_structures']+=$row; + break; + case 'cmd_get': + $res['cmd_get']+=$row; + break; + case 'cmd_set': + $res['cmd_set']+=$row; + break; + case 'get_hits': + $res['get_hits']+=$row; + break; + case 'get_misses': + $res['get_misses']+=$row; + break; + case 'evictions': + $res['evictions']+=$row; + break; + case 'bytes_read': + $res['bytes_read']+=$row; + break; + case 'bytes_written': + $res['bytes_written']+=$row; + break; + case 'limit_maxbytes': + $res['limit_maxbytes']+=$row; + break; + case 'threads': + $res['rusage_system'][$server]=$row; + break; + } + } + } + return $res; + } + return $resp; +} + +////////////////////////////////////////////////////// + +// +// don't cache this page +// +header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1 +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); // HTTP/1.0 + +function duration($ts) { + global $time; + $years = (int)((($time - $ts)/(7*86400))/52.177457); + $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400)); + $weeks = (int)(($rem)/(7*86400)); + $days = (int)(($rem)/86400) - $weeks*7; + $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24; + $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60; + $str = ''; + if($years==1) $str .= "$years year, "; + if($years>1) $str .= "$years years, "; + if($weeks==1) $str .= "$weeks week, "; + if($weeks>1) $str .= "$weeks weeks, "; + if($days==1) $str .= "$days day,"; + if($days>1) $str .= "$days days,"; + if($hours == 1) $str .= " $hours hour and"; + if($hours>1) $str .= " $hours hours and"; + if($mins == 1) $str .= " 1 minute"; + else $str .= " $mins minutes"; + return $str; +} + +// create graphics +// +function graphics_avail() { + return extension_loaded('gd'); +} + +function bsize($s) { + foreach (array('','K','M','G') as $i => $k) { + if ($s < 1024) break; + $s/=1024; + } + return sprintf("%5.1f %sBytes",$s,$k); +} + +// create menu entry +function menu_entry($ob,$title) { + global $PHP_SELF; + if ($ob==$_GET['op']){ + return "
          • $title
          • "; + } + return "
          • $title
          • "; +} + +function getHeader(){ + $header = << + +MEMCACHE INFO + + + +
            +

            + + memcache.php by Harun Yayli +

            +
            +
            +
            +EOB; + + return $header; +} +function getFooter(){ + global $VERSION; + $footer = '
            + +'; + + return $footer; + +} +function getMenu(){ + global $PHP_SELF; +echo "
          • '+ titles[i+1] +''+ nums +'