├── .gitignore ├── CHANGELOG ├── LICENSE ├── README.md ├── admin.php ├── api.php ├── category.php ├── composer.json ├── conf ├── default.png ├── index.php └── profile.png ├── extension ├── google_code_prettify │ ├── assets │ │ ├── lang-apollo.js │ │ ├── lang-basic.js │ │ ├── lang-clj.js │ │ ├── lang-css.js │ │ ├── lang-dart.js │ │ ├── lang-erlang.js │ │ ├── lang-go.js │ │ ├── lang-hs.js │ │ ├── lang-lisp.js │ │ ├── lang-llvm.js │ │ ├── lang-lua.js │ │ ├── lang-matlab.js │ │ ├── lang-ml.js │ │ ├── lang-mumps.js │ │ ├── lang-n.js │ │ ├── lang-pascal.js │ │ ├── lang-proto.js │ │ ├── lang-r.js │ │ ├── lang-rd.js │ │ ├── lang-scala.js │ │ ├── lang-sql.js │ │ ├── lang-tcl.js │ │ ├── lang-tex.js │ │ ├── lang-vb.js │ │ ├── lang-vhdl.js │ │ ├── lang-wiki.js │ │ ├── lang-xq.js │ │ ├── lang-yaml.js │ │ ├── prettify.css │ │ ├── prettify.js │ │ └── run_prettify.js │ ├── define.php │ ├── do.php │ └── icon.png └── hello_world │ ├── define.php │ ├── do.php │ └── icon.png ├── inc ├── admin.inc.php ├── api.inc.php ├── article.inc.php ├── bw.inc.php ├── canonicalization.inc.php ├── category.inc.php ├── comment.inc.php ├── database.inc.php ├── index.php ├── script │ ├── autocomplete │ │ ├── README.md │ │ ├── jquery.autocomplete.css │ │ └── jquery.autocomplete.min.js │ ├── dbmanage │ │ └── DbManage.class.php │ ├── editor │ │ ├── README.md │ │ ├── jquery.markbar.js │ │ └── themes │ │ │ └── default │ │ │ ├── default.css │ │ │ └── icons.png │ ├── html5sortable │ │ ├── LICENSE.md │ │ ├── README.md │ │ └── html.sortable.min.js │ ├── hyperdown │ │ ├── LICENSE │ │ ├── Parser.php │ │ └── README.md │ ├── jquery.min.js │ ├── loader.js │ ├── main.js │ ├── mysql-backup │ │ └── backup.php │ ├── parsedown │ │ └── Parsedown.php │ ├── pclzip │ │ └── pclzip.lib.php │ ├── pinyin │ │ └── pinyin.php │ ├── qiniu │ │ ├── QiniuClient.php │ │ └── README.md │ ├── rnd-avatar │ │ └── avatar.js │ ├── sina-weibo │ │ └── saetv2.ex.class.php │ ├── smtp │ │ ├── LICENSE │ │ └── email.php │ ├── timers │ │ └── jquery.timers.js │ └── urlrewrite │ │ ├── apache.txt │ │ └── nginx.txt ├── system.php ├── template │ ├── cd-review.tpl.php │ ├── film-review.tpl.php │ └── photo-album.tpl.php ├── view.inc.php └── zip.inc.php ├── index.php ├── install ├── cli ├── en.lang.php ├── index.php ├── install.css ├── install_action.php ├── jquery.scrollTo.min.js ├── zh-cn.lang.php └── zh-tw.lang.php ├── lang ├── en.php ├── index.php ├── zh-cn.php └── zh-tw.php ├── mode ├── admin.mod.php ├── api.mod.php ├── article.mod.php ├── cate.mod.php ├── list.mod.php ├── page.mod.php ├── send.mod.php └── tag.mod.php ├── page.php ├── read.php ├── rss.php ├── send.php ├── sitemap.php ├── storage ├── firstrun.jpg └── index.php ├── tag.php ├── theme └── default │ ├── admin.css │ ├── admin.php │ ├── adminarticles.php │ ├── admincenter.php │ ├── admincomments.php │ ├── admindashboard.php │ ├── adminextensions.php │ ├── adminservices.php │ ├── adminwriter.php │ ├── article.php │ ├── components.php │ ├── dark.png │ ├── duoshuo.css │ ├── error.php │ ├── font.css │ ├── fonts │ ├── icomoon.eot │ ├── icomoon.svg │ ├── icomoon.ttf │ └── icomoon.woff │ ├── icon.jpg │ ├── index.php │ ├── info.php │ ├── loading.gif │ ├── logo.png │ ├── page.php │ ├── plainpage.php │ ├── singlepage.php │ ├── style.css │ └── summary.php └── update ├── index.php ├── update.mysql.sql └── update.sqlite.sql /.gitignore: -------------------------------------------------------------------------------- 1 | .htaccess 2 | _zip.php 3 | _test.php 4 | trash/ 5 | Thumbs.db 6 | .git 7 | theme/light 8 | theme/mill 9 | theme/minimalism 10 | theme/minimalmill 11 | theme/mint 12 | .DS_Store 13 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 1.7.0 2 | - 修复:某些情况下Tag保存和打开异常。 3 | - 改进:社交链接增加GitHub。 4 | - 新增:第三方评论现在支持GitTalk, Gitment。 5 | - 改进:在编辑草稿时,在为草稿选择分类前隐藏发布按钮以避免误解。 6 | - 修复:修复了一个只有管理员登陆后才能利用的SQL注入漏洞。 7 | - 移除了自带的七牛支持。 8 | 9 | 1.6.0 10 | - 新增:为新评论、更改密码和失败的登陆添加了邮件通知功能。 11 | - 改进:微调了默认主题。 12 | - 修复:更换了陈旧的MySQL备份类,现可工作在PHP 7下。 13 | - 改进:文章ID和分类ID都加了检测,不允许使用特殊字符。 14 | - 修复:评论者填写的网址未带协议时自动补全http,该功能有时不工作的问题。 15 | - 修复:优酷、网易云音乐链默认用https地址。由于虾米外链机制改变,已将其移除。 16 | 17 | 1.5.0 18 | - 新增:评论管理。可从文章管理界面进入。 19 | - 新增:可将文件拖拽到编辑器区域开始上传。 20 | - 修复:安装bug导致使用MySQL时无法评论。 21 | - 修复:默认主题在头像过大时登陆界面的问题。 22 | 23 | 1.4.0 24 | - 新增:内置评论回归。取消已停运的多说服务设置。 25 | - 改进:完善了翻页,现在可以快速定位到特定分页。(默认主题) 26 | - 新增:可选择常用搜索引擎作为站内搜索使用。(默认主题) 27 | - 改进:检测到新版时可以将升级包下载下来以便手动更新。 28 | 29 | 1.3.0 30 | - 新增:每分钟自动保存草稿。 31 | - 改进:在输入Tag时,使用中文逗号也能完成添加。 32 | - 改进:在iOS系统下的字体显示问题。 33 | - 新增:可以禁用内部计数功能减少数据库写入操作。 34 | - 微调了默认主题,改进了logo的显示方式和移动版的下拉菜单。 35 | 36 | 1.2.1 37 | - 新增:分类和自定义模块可以拖动排序了。 38 | - 新增:支持将文件上传到阿里云OSS储存。(特别鸣谢 fanbili 提供测试环境) 39 | - 新增:可以在创建文章时,从中文标题转换出拼音并自动填入文章ID (需支持 mbstring 扩展的服务器)。 40 | - 新增:RESTful API接口,暂支持 articles (日志)的GET接口和 users (作者)的GET接口。 41 | 42 | 1.1.1 43 | - 紧急修复JS错误等。 44 | 45 | 1.1.0 46 | - 修复:文章发布后的跳转错误。 47 | - 改进:调整了“管理”按钮的位置。 48 | - 新增:手动上传更新包进行更新。 49 | - 新增:文字模板功能,可快速插入格式化的文本排版。 50 | - 新增:可在markdown中通过 -L -R 参数令图片居左或居右(插入图片时将 -L 或 -R 填写到中括号里即可)。 51 | - 新增:可在markdown中通过 “-Album: 描述” 参数在一篇文章里生成可以Lightbox方式播放的相册(插入图片时将 -Album: 图片描述 填写到中括号里)。 52 | 53 | 54 | 1.0.9 55 | - 改进:对编辑器进行了一些改进,使用更顺手。 56 | - 改进:自动更新脚本启用了 HTTPS 地址。 57 | - 修复:windows下上传文件到云存储后的文件名错误。 58 | - 修复:模块名称为中文时不能移除或停用。 59 | - 新增:通过后台直接移除主题。 60 | - 新增:可在命令行下静默安装。运行 php /install/cli install 进行安装。 61 | - 屏蔽了内置评论功能。专注在将写作做好,把评论交给第三方去支持更方便和安全。 62 | 63 | 1.0.8 64 | - 改进:可以在文章管理页面搜索文章。 65 | - 改进:分离了前后台的 css 文件,减少前台载入体积。 66 | - 改进:上传文件到七牛后保留原扩展名。 67 | - 新增:给出了一个nginx用的 URL rewrite 模板。 68 | - 一些手机浏览时的细节调整。 69 | 70 | 1.0.7 71 | - 修复:解析器单回车换行。 72 | - 新增:可以为每个分类设置单独的主题。 73 | 74 | 1.0.6 75 | - 新增:草稿箱功能。 76 | - 新增:独立于任何分类之外的单页功能,用于创建一些非日志页面。 77 | - 修复:安装时选择SQLite3数据库无法使用相对路径的问题。 78 | - 修复:友情链接特殊字符偶尔会导致崩溃。 79 | - 修复:文章管理界面无法列出发布时间在未来的文章。 80 | - 更改:将Markdown解析器重新换回兼容性更好的Parsedown,因为HyperDown解析器需要最低PHP 5.4的支持。 81 | - 修复:RSS和google sitemap的XML错误。 82 | - 改进:上传器终于可以上传图片以外的文件了。 83 | - 改进:文章数为零的分类和首页打开也不会报错了。 84 | 85 | 1.0.5 86 | - 更改:对目录结构进行了调整,使程序目录结构和文件用途更清晰。 87 | - 改进:支持传统的Ugly URL传参,兼容未做rewrite设置的nginx服务器和某些特殊的环境。 88 | - 改进:改善了友情链接的设置方式,提高了特殊URL的兼容性。 89 | - 改进:将Markdown解析器替换为HyperDown,取代代码较为陈旧的Parsedown。 90 | - 新增:访问 admin.php 可直接访问后台,不再需要从前台点击按钮进入。 91 | - 新增:自动更新机制中增加了数据库结构自动更新的能力。 92 | - 改进:编辑文章时新建分类;更方便地选择日期。 93 | - 新增:文章批量管理。 94 | 95 | 1.0.4 96 | - 修复:正文内页分类错误。 97 | - 修复:引用和代码无法换行。 98 | - 修复:插入虾米音乐时重复插入。 99 | - 合并为第一个Master版本。 100 | 101 | 1.0.3 102 | - 修复:更新了第三方markdown类库,现已兼容PHP 7。 103 | - 新增:可通过专用安装包自动安装第三方主题和扩展。 104 | - 新增:社交网络链接补全了推特和FB。 105 | - 新增:内置社会化评论系统现在支持Disqus。 106 | - 修复:Error页面“返回前页”链接为空的bug。 107 | - 新增:支持插入网易云音乐播放器。 108 | - 可以正常运行在设置过 path_info 的 nginx 下了。 109 | - 一些为静态生成项目Mill提供支持的小改动。 110 | 111 | 1.0.2 112 | - 修复:后台管理界面帖子列表翻页问题。 113 | - 新增:可将你的手机与博客关联起来。关联后,手机不用输入密码即可登录后台。在PC机上也可用已关联手机扫描二维码快速登录。 114 | - 改进:备份现在可以正常使用了。并且可以选择直接将备份文件上传到七牛云服务。 115 | 116 | 1.0.1 117 | - 修复:写帖子页面在IE10和Edge下无响应。 118 | - 改进:提高了撰写时自动提示tag功能的效率。 119 | - 新增:编辑器可以插入优酷和虾米的视频/音乐了。 120 | - 新增:为编辑器载入增加了一个接口,留待以后增加其他编辑器使用。 121 | - “市场”暂时被屏蔽了,直到正式开发完成为止。 122 | 123 | 1.0.0 124 | - 更改:新的在线升级方式防止某些服务器下升级失败。 125 | - 改进:七牛的图片现在默认载入较小的缩略图以节省流量。 126 | - 改进:编辑器:现在支持预览模式,可以方便的查看最终显示效果。 127 | - 改进:编辑器:现在根据大多数人直觉的使用习惯,支持“敲一下回车键”即换行,“两下回车键”新开段落。 128 | - 改进:为“扩展”增加缩略图显示。 129 | - 恢复:备份功能现在可用且可分卷备份数据。 130 | - “市场”的架构初步完成,等待后续开通。 131 | 132 | 0.9.9 133 | - 新增:后台可上传替换头像。 134 | - 新增:可支持Apache的伪静态(URL重写)。 135 | - 新增:安装程序多语言化,包含中文。 136 | - 新增:繁体中文语言包。 137 | - 暂时取消了备份功能,以待进一步完善。 138 | 139 | 0.9.8 alpha 140 | - 新增:在线自动升级。 141 | 142 | 0.9.5 alpha 143 | - 修正bug:版本号 144 | - 修正bug:文章管理分页不正常 145 | 146 | 0.9.4 alpha 147 | - 新增:原生评论启用后,管理员可以登录身份回复 148 | - 新增:原生评论启用后,游客可使用新浪微博登录并评论(站长应自行申请新浪API) 149 | - 改进:新建文章时,默认给出一个日志ID 150 | - 改进:新建分类时,明确要求填写的内容(原来的方式很多人不会用) 151 | - 改进:原生评论的分页载入 152 | - 修正bug:评论提交会计入已访问页面的统计 153 | - 修正bug:打包时少了一个用户评论默认头像 154 | 155 | 0.9.3 alpha 156 | - 新增:原生评论 157 | - 修正bug:无法安装在根目录下 158 | 159 | 0.9.1 alpha-rc1 160 | - 修正bug:无法更改分类名 161 | - 修正bug:无法访问分类页面 162 | - 修正bug:error_reporting 等级为E_Strict时报错 163 | - 修正bug:部分服务器上显示乱码 164 | - 修正bug:普通的上传功能按钮点击无效 165 | - 修正bug:模块设置的语言包未剥离 166 | - 修正bug:模块自定义HTML包含换行和特殊字符时出错 167 | - 微调了图标 168 | - 增加了简单的 MarkDown 编辑器 169 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 bW Development Team 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://i.loli.net/2018/11/18/5bf1027f64cf6.jpg) 2 | 3 | 2013年底,正当微信朋友圈占据了身边几乎所有人(也包括为自己)的碎片化时间之际,我开始怀念那些在网络上严肃地写字的日子。所谓的严肃,不是指话题有多庄重,而是写帖子的态度。我意识到无论是微信朋友圈还是微博,都无法取代在自己的博客空间里肆意书写的那份自由。朋友圈和微信也许是便捷的,但在使用它们的同时,我们也不得不成为了它们的奴隶,被迫让自己暴露在良莠不齐的嘈杂之下,也无意识地让无数的time killer“晒”走了本该静下心思索的时间。 4 | 5 | 所以,为了捡起曾经被丢弃的网络书写习惯,为了让自己以最舒适的方式继续书写,在面向移动化的前提下,经过一些时日的忙活,有了**bW** - 即Bo-Blog Wind Version。 6 | 7 | 顾名思义,我希望bW是一个“轻”博客。它只是为了让我们可以有一个自主的、不依附于任何网络大鳄的在线书写工具。它不会成为又一个大而全的Bo-Blog 2.0,它也绝不会变成CMS。我也希望它用起来足够简单,所以它不会需要在终端里更新,也不会过度重视SEO、静态化等。满足这些更宏大、更专业、更geek需求的选择比比皆是,比如[WordPress](https://cn.wordpress.org/),比如[Hexo](https://hexo.io/zh-cn/)。它们都足够优秀,不必再重复劳动。 8 | 9 | 讲完了初衷,如果你都认同,而且也正好想用一个不主流的博客程序来开始一段新的书写之旅,那么我期待bW可以成为你的一个选择。 10 | 11 | bW正在做的、准备做到的有哪些特点呢? 12 | 13 | **首先,它是便携的。** 14 | 它可以很好地通过手机更新和维护,随身带好你的私人手机,无论是直接在手机上打开,还是扫一扫二维码、在别人的PC上临时登录,都能方便地使用bW。在安装时默认的选项是SQLite,也是出于迁移数据的便捷考虑。 15 | 16 | **其次,它不需要太多设置。** 17 | bW是完全推到重写的,所以和bo-blog 2.0没有直接的关系,除了名字。前作固然有非常完善的功能和设置选项,但想要兼顾太多人的需求,导致了自身的臃肿和难以维护,出差错和漏洞也难免。bW在安装完成后,就可以直接拿来使用了,可能只要改一下博客的名字和描述而已。 18 | 19 | **此外,它不会频繁更新。** 20 | 我更希望bW保持简洁、相对稳定。如果说前作一度陷入为了加功能而不断更新的死胡同,这一次我会在增加任何特性前多加思考。除非必要,否则不做。它的目标是够用,不至于周周升级月月更新,而违背了搭建一个博客的初衷。 21 | 22 | **当然,它也是可以扩展的。** 23 | bW还是为插件、主题留出了相当大的发挥空间,自定义的可能性甚至超越了bo-blog 2.0。 24 | 25 | 好了,吹嘘的时间结束了。以下是全文唯一的技术部分,供你进一步参考。 26 | 27 | **bW 安装需求:** 28 | PHP 5.3以上,支持MySQL或SQLite数据库。 29 | 30 | **官网:** 31 | https://www.bo-blog.com 32 | 33 | **演示/日志:** 34 | https://www.bo-blog.com/bw/ 35 | 36 | *Life is like a wind. It goes wherever your heart wants to.* 37 | -------------------------------------------------------------------------------- /admin.php: -------------------------------------------------------------------------------- 1 | =5.3.0" 13 | } 14 | } -------------------------------------------------------------------------------- /conf/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/conf/default.png -------------------------------------------------------------------------------- /conf/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /conf/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/conf/profile.png -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-apollo.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\n\r]*/,null,"#"],["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/, 2 | null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[ES]?BANK=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[!-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["apollo","agc","aea"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-basic.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^"(?:[^\n\r"\\]|\\.)*(?:"|$)/,a,'"'],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["com",/^REM[^\n\r]*/,a],["kwd",/^\b(?:AND|CLOSE|CLR|CMD|CONT|DATA|DEF ?FN|DIM|END|FOR|GET|GOSUB|GOTO|IF|INPUT|LET|LIST|LOAD|NEW|NEXT|NOT|ON|OPEN|OR|POKE|PRINT|READ|RESTORE|RETURN|RUN|SAVE|STEP|STOP|SYS|THEN|TO|VERIFY|WAIT)\b/,a],["pln",/^[a-z][^\W_]?(?:\$|%)?/i,a],["lit",/^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/i,a,"0123456789"],["pun", 3 | /^.[^\s\w"$%.]*/,a]]),["basic","cbm"]); 4 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-clj.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Google Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | var a=null; 17 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[([{]+/,a,"([{"],["clo",/^[)\]}]+/,a,")]}"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,a], 18 | ["typ",/^:[\dA-Za-z-]+/]]),["clj"]); 19 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n\u000c"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]+)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//], 2 | ["com",/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}\b/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-dart.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"]],[["com",/^#!.*/],["kwd",/^\b(?:import|library|part of|part|as|show|hide)\b/i],["com",/^\/\/.*/],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["kwd",/^\b(?:class|interface)\b/i],["kwd",/^\b(?:assert|break|case|catch|continue|default|do|else|finally|for|if|in|is|new|return|super|switch|this|throw|try|while)\b/i],["kwd",/^\b(?:abstract|const|extends|factory|final|get|implements|native|operator|set|static|typedef|var)\b/i], 2 | ["typ",/^\b(?:bool|double|dynamic|int|num|object|string|void)\b/i],["kwd",/^\b(?:false|null|true)\b/i],["str",/^r?'''[\S\s]*?[^\\]'''/],["str",/^r?"""[\S\s]*?[^\\]"""/],["str",/^r?'('|[^\n\f\r]*?[^\\]')/],["str",/^r?"("|[^\n\f\r]*?[^\\]")/],["pln",/^[$_a-z]\w*/i],["pun",/^[!%&*+/:<-?^|~-]/],["lit",/^\b0x[\da-f]+/i],["lit",/^\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i],["lit",/^\b\.\d+(?:e[+-]?\d+)?/i],["pun",/^[(),.;[\]{}]/]]), 3 | ["dart"]); 4 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-erlang.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n\u000b\u000c\r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["lit",/^[a-z]\w*/],["lit",/^'(?:[^\n\f\r'\\]|\\[^&])+'?/,null,"'"],["lit",/^\?[^\t\n ({]+/,null,"?"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^%[^\n]*/],["kwd",/^(?:module|attributes|do|let|in|letrec|apply|call|primop|case|of|end|when|fun|try|catch|receive|after|char|integer|float,atom,string,var)\b/], 2 | ["kwd",/^-[_a-z]+/],["typ",/^[A-Z_]\w*/],["pun",/^[,.;]/]]),["erlang","erl"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-go.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["pln",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])+(?:'|$)|`[^`]*(?:`|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\/\*[\S\s]*?\*\/)/],["pln",/^(?:[^"'/`]|\/(?![*/]))+/]]),["go"]); 2 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-hs.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n\u000b\u000c\r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^\n\f\r'\\]|\\[^&])'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:--+[^\n\f\r]*|{-(?:[^-]|-+[^}-])*-})/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^\d'A-Za-z]|$)/, 2 | null],["pln",/^(?:[A-Z][\w']*\.)*[A-Za-z][\w']*/],["pun",/^[^\d\t-\r "'A-Za-z]+/]]),["hs"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-lisp.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,a,"("],["clo",/^\)+/,a,")"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,a], 3 | ["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["cl","el","lisp","lsp","scm","ss","rkt"]); 4 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-llvm.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^!?"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["com",/^;[^\n\r]*/,null,";"]],[["pln",/^[!%@](?:[$\-.A-Z_a-z][\w$\-.]*|\d+)/],["kwd",/^[^\W\d]\w*/,null],["lit",/^\d+\.\d+/],["lit",/^(?:\d+|0[Xx][\dA-Fa-f]+)/],["pun",/^[(-*,:<->[\]{}]|\.\.\.$/]]),["llvm","ll"]); 2 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-lua.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$))/,null,"\"'"]],[["com",/^--(?:\[(=*)\[[\S\s]*?(?:]\1]|$)|[^\n\r]*)/],["str",/^\[(=*)\[[\S\s]*?(?:]\1]|$)/],["kwd",/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i], 2 | ["pln",/^[_a-z]\w*/i],["pun",/^[^\w\t\n\r \xa0][^\w\t\n\r "'+=\xa0-]*/]]),["lua"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-ml.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^#(?:if[\t\n\r \xa0]+(?:[$_a-z][\w']*|``[^\t\n\r`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])(?:'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\(\*[\S\s]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/], 2 | ["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^(?:[_a-z][\w']*[!#?]?|``[^\t\n\r`]*(?:``|$))/i],["pun",/^[^\w\t\n\r "'\xa0]+/]]),["fs","ml"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-mumps.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"]|\\.)*"/,null,'"']],[["com",/^;[^\n\r]*/,null,";"],["dec",/^\$(?:d|device|ec|ecode|es|estack|et|etrap|h|horolog|i|io|j|job|k|key|p|principal|q|quit|st|stack|s|storage|sy|system|t|test|tl|tlevel|tr|trestart|x|y|z[a-z]*|a|ascii|c|char|d|data|e|extract|f|find|fn|fnumber|g|get|j|justify|l|length|na|name|o|order|p|piece|ql|qlength|qs|qsubscript|q|query|r|random|re|reverse|s|select|st|stack|t|text|tr|translate|nan)\b/i, 2 | null],["kwd",/^(?:[^$]b|break|c|close|d|do|e|else|f|for|g|goto|h|halt|h|hang|i|if|j|job|k|kill|l|lock|m|merge|n|new|o|open|q|quit|r|read|s|set|tc|tcommit|tre|trestart|tro|trollback|ts|tstart|u|use|v|view|w|write|x|xecute)\b/i,null],["lit",/^[+-]?(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?/i],["pln",/^[a-z][^\W_]*/i],["pun",/^[^\w\t\n\r"$%;^\xa0]|_/]]),["mumps"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-n.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:'(?:[^\n\r'\\]|\\.)*'|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,a,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,a,"#"],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["str",/^@"(?:[^"]|"")*(?:"|$)/,a],["str",/^<#[^#>]*(?:#>|$)/,a],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,a],["com",/^\/\/[^\n\r]*/,a],["com",/^\/\*[\S\s]*?(?:\*\/|$)/, 3 | a],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/, 4 | a],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,a],["lit",/^@[$_a-z][\w$@]*/i,a],["typ",/^@[A-Z]+[a-z][\w$@]*/,a],["pln",/^'?[$_a-z][\w$@]*/i,a],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,a,"0123456789"],["pun",/^.[^\s\w"-$'./@`]*/,a]]),["n","nemerle"]); 5 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-pascal.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^'(?:[^\n\r'\\]|\\.)*(?:'|$)/,a,"'"],["pln",/^\s+/,a," \r\n\t\u00a0"]],[["com",/^\(\*[\S\s]*?(?:\*\)|$)|^{[\S\s]*?(?:}|$)/,a],["kwd",/^(?:absolute|and|array|asm|assembler|begin|case|const|constructor|destructor|div|do|downto|else|end|external|for|forward|function|goto|if|implementation|in|inline|interface|interrupt|label|mod|not|object|of|or|packed|procedure|program|record|repeat|set|shl|shr|then|to|type|unit|until|uses|var|virtual|while|with|xor)\b/i,a], 3 | ["lit",/^(?:true|false|self|nil)/i,a],["pln",/^[a-z][^\W_]*/i,a],["lit",/^(?:\$[\da-f]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?)/i,a,"0123456789"],["pun",/^.[^\s\w$'./@]*/,a]]),["pascal"]); 4 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-proto.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]); 2 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-r.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^'\\]|\\[\S\s])*(?:'|$)/,null,"'"]],[["com",/^#.*/],["kwd",/^(?:if|else|for|while|repeat|in|next|break|return|switch|function)(?![\w.])/],["lit",/^0[Xx][\dA-Fa-f]+([Pp]\d+)?[Li]?/],["lit",/^[+-]?(\d+(\.\d+)?|\.\d+)([Ee][+-]?\d+)?[Li]?/],["lit",/^(?:NULL|NA(?:_(?:integer|real|complex|character)_)?|Inf|TRUE|FALSE|NaN|\.\.(?:\.|\d+))(?![\w.])/], 2 | ["pun",/^(?:<>?|-|==|<=|>=|<|>|&&?|!=|\|\|?|[!*+/^]|%.*?%|[$=@~]|:{1,3}|[(),;?[\]{}])/],["pln",/^(?:[A-Za-z]+[\w.]*|\.[^\W\d][\w.]*)(?![\w.])/],["str",/^`.+`/]]),["r","s","R","S","Splus"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-rd.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\n\r]*/,null,"%"]],[["lit",/^\\(?:cr|l?dots|R|tab)\b/],["kwd",/^\\[@-Za-z]+/],["kwd",/^#(?:ifn?def|endif)/],["pln",/^\\[{}]/],["pun",/^[()[\]{}]+/]]),["Rd","rd"]); 2 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-scala.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^"(?:""(?:""?(?!")|[^"\\]|\\.)*"{0,3}|(?:[^\n\r"\\]|\\.)*"?)/,null,'"'],["lit",/^`(?:[^\n\r\\`]|\\.)*`?/,null,"`"],["pun",/^[!#%&(--:-@[-^{-~]+/,null,"!#%&()*+,-:;<=>?@[\\]^{|}~"]],[["str",/^'(?:[^\n\r'\\]|\\(?:'|[^\n\r']+))'/],["lit",/^'[$A-Z_a-z][\w$]*(?![\w$'])/],["kwd",/^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/], 2 | ["lit",/^(?:true|false|null|this)\b/],["lit",/^(?:0(?:[0-7]+|x[\da-f]+)l?|(?:0|[1-9]\d*)(?:(?:\.\d+)?(?:e[+-]?\d+)?f?|l?)|\\.\d+(?:e[+-]?\d+)?f?)/i],["typ",/^[$_]*[A-Z][\d$A-Z_]*[a-z][\w$]*/],["pln",/^[$A-Z_a-z][\w$]*/],["com",/^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/],["pun",/^(?:\.+|\/)/]]),["scala"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-sql.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\n\r]*|\/\*[\S\s]*?(?:\*\/|$))/],["kwd",/^(?:add|all|alter|and|any|apply|as|asc|authorization|backup|begin|between|break|browse|bulk|by|cascade|case|check|checkpoint|close|clustered|coalesce|collate|column|commit|compute|connect|constraint|contains|containstable|continue|convert|create|cross|current|current_date|current_time|current_timestamp|current_user|cursor|database|dbcc|deallocate|declare|default|delete|deny|desc|disk|distinct|distributed|double|drop|dummy|dump|else|end|errlvl|escape|except|exec|execute|exists|exit|fetch|file|fillfactor|following|for|foreign|freetext|freetexttable|from|full|function|goto|grant|group|having|holdlock|identity|identitycol|identity_insert|if|in|index|inner|insert|intersect|into|is|join|key|kill|left|like|lineno|load|match|matched|merge|natural|national|nocheck|nonclustered|nocycle|not|null|nullif|of|off|offsets|on|open|opendatasource|openquery|openrowset|openxml|option|or|order|outer|over|partition|percent|pivot|plan|preceding|precision|primary|print|proc|procedure|public|raiserror|read|readtext|reconfigure|references|replication|restore|restrict|return|revoke|right|rollback|rowcount|rowguidcol|rows?|rule|save|schema|select|session_user|set|setuser|shutdown|some|start|statistics|system_user|table|textsize|then|to|top|tran|transaction|trigger|truncate|tsequal|unbounded|union|unique|unpivot|update|updatetext|use|user|using|values|varying|view|waitfor|when|where|while|with|within|writetext|xml)(?=[^\w-]|$)/i, 2 | null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^[_a-z][\w-]*/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'+\xa0-]*/]]),["sql"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-tcl.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^{+/,a,"{"],["clo",/^}+/,a,"}"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \u00a0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:after|append|apply|array|break|case|catch|continue|error|eval|exec|exit|expr|for|foreach|if|incr|info|proc|return|set|switch|trace|uplevel|upvar|while)\b/,a],["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit", 3 | /^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["tcl"]); 4 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-tex.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"],["com",/^%[^\n\r]*/,null,"%"]],[["kwd",/^\\[@-Za-z]+/],["kwd",/^\\./],["typ",/^[$&]/],["lit",/[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i],["pun",/^[()=[\]{}]+/]]),["latex","tex"]); 2 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-vb.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0\u2028\u2029]+/,null,"\t\n\r \u00a0\u2028\u2029"],["str",/^(?:["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})(?:["\u201c\u201d]c|$)|["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})*(?:["\u201c\u201d]|$))/i,null,'"\u201c\u201d'],["com",/^['\u2018\u2019](?:_(?:\r\n?|[^\r]?)|[^\n\r_\u2028\u2029])*/,null,"'\u2018\u2019"]],[["kwd",/^(?:addhandler|addressof|alias|and|andalso|ansi|as|assembly|auto|boolean|byref|byte|byval|call|case|catch|cbool|cbyte|cchar|cdate|cdbl|cdec|char|cint|class|clng|cobj|const|cshort|csng|cstr|ctype|date|decimal|declare|default|delegate|dim|directcast|do|double|each|else|elseif|end|endif|enum|erase|error|event|exit|finally|for|friend|function|get|gettype|gosub|goto|handles|if|implements|imports|in|inherits|integer|interface|is|let|lib|like|long|loop|me|mod|module|mustinherit|mustoverride|mybase|myclass|namespace|new|next|not|notinheritable|notoverridable|object|on|option|optional|or|orelse|overloads|overridable|overrides|paramarray|preserve|private|property|protected|public|raiseevent|readonly|redim|removehandler|resume|return|select|set|shadows|shared|short|single|static|step|stop|string|structure|sub|synclock|then|throw|to|try|typeof|unicode|until|variant|wend|when|while|with|withevents|writeonly|xor|endif|gosub|let|variant|wend)\b/i, 2 | null],["com",/^rem\b.*/i],["lit",/^(?:true\b|false\b|nothing\b|\d+(?:e[+-]?\d+[dfr]?|[dfilrs])?|(?:&h[\da-f]+|&o[0-7]+)[ils]?|\d*\.\d+(?:e[+-]?\d+)?[dfr]?|#\s+(?:\d+[/-]\d+[/-]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:am|pm))?)?|\d+:\d+(?::\d+)?(\s*(?:am|pm))?)\s+#)/i],["pln",/^(?:(?:[a-z]|_\w)\w*(?:\[[!#%&@]+])?|\[(?:[a-z]|_\w)\w*])/i],["pun",/^[^\w\t\n\r "'[\]\xa0\u2018\u2019\u201c\u201d\u2028\u2029]+/],["pun",/^(?:\[|])/]]),["vb","vbs"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-vhdl.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r \u00a0"]],[["str",/^(?:[box]?"(?:[^"]|"")*"|'.')/i],["com",/^--[^\n\r]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i, 2 | null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^'(?:active|ascending|base|delayed|driving|driving_value|event|high|image|instance_name|last_active|last_event|last_value|left|leftof|length|low|path_name|pos|pred|quiet|range|reverse_range|right|rightof|simple_name|stable|succ|transaction|val|value)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w.\\]+#(?:[+-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:e[+-]?\d+(?:_\d+)*)?)/i], 3 | ["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'\xa0-]*/]]),["vhdl","vhd"]); 4 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-wiki.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\d\t a-gi-z\xa0]+/,null,"\t \u00a0abcdefgijklmnopqrstuvwxyz0123456789"],["pun",/^[*=[\]^~]+/,null,"=*~^[]"]],[["lang-wiki.meta",/(?:^^|\r\n?|\n)(#[a-z]+)\b/],["lit",/^[A-Z][a-z][\da-z]+[A-Z][a-z][^\W_]+\b/],["lang-",/^{{{([\S\s]+?)}}}/],["lang-",/^`([^\n\r`]+)`/],["str",/^https?:\/\/[^\s#/?]*(?:\/[^\s#?]*)?(?:\?[^\s#]*)?(?:#\S*)?/i],["pln",/^(?:\r\n|[\S\s])[^\n\r#*=A-[^`h{~]*/]]),["wiki"]); 2 | PR.registerLangHandler(PR.createSimpleLexer([["kwd",/^#[a-z]+/i,null,"#"]],[]),["wiki.meta"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/lang-yaml.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:>?|]+/,a,":|>?"],["dec",/^%(?:YAML|TAG)[^\n\r#]+/,a,"%"],["typ",/^&\S+/,a,"&"],["typ",/^!\S*/,a,"!"],["str",/^"(?:[^"\\]|\\.)*(?:"|$)/,a,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,a,"'"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^\s+/,a," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\n\r]|$)/],["pun",/^-/],["kwd",/^\w+:[\n\r ]/],["pln",/^\w+/]]),["yaml","yml"]); 3 | -------------------------------------------------------------------------------- /extension/google_code_prettify/assets/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | pre {font-family: Consolas, Monaco, "Microsoft Yahei", "Microsoft JhengHei", "Meiryo UI"} -------------------------------------------------------------------------------- /extension/google_code_prettify/define.php: -------------------------------------------------------------------------------- 1 | ; 2 | ID='google_code_prettify' 3 | name='Google Code Prettify' 4 | intro='Highlight code in articles with Google Code Prettify.' 5 | author='Open Source' 6 | url='https://code.google.com/p/google-code-prettify/' 7 | hooks='footer,textParser' -------------------------------------------------------------------------------- /extension/google_code_prettify/do.php: -------------------------------------------------------------------------------- 1 | $("").attr({rel:"stylesheet", type:"text/css", href: "[[::siteURL]]/extension/google_code_prettify/assets/prettify.css"}).appendTo("head"); 13 | $(""+"").attr({src: "[[::siteURL]]/extension/google_code_prettify/assets/prettify.js"}).appendTo("head"); 14 | prettyPrint();'; 15 | } 16 | 17 | public static function textParser ($text) 18 | { 19 | return str_replace (array ('
'), $text);
20 | 	} 
21 | } 
22 | 


--------------------------------------------------------------------------------
/extension/google_code_prettify/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/extension/google_code_prettify/icon.png


--------------------------------------------------------------------------------
/extension/hello_world/define.php:
--------------------------------------------------------------------------------
1 | ;
2 | ID='hello_world'
3 | name='Hello, world'
4 | intro='Test extension.'
5 | author='bW'
6 | url='http://bw.bo-blog.com'
7 | hooks='header,footer,textParser,generateOutputDone'


--------------------------------------------------------------------------------
/extension/hello_world/do.php:
--------------------------------------------------------------------------------
 1 | ' . self :: $ln . '';
36 | 	} 
37 | 
38 | 	public static function footer ()
39 | 	{
40 | 		return '
Hello again, World!
'; 41 | } 42 | 43 | public static function textParser ($text) 44 | { 45 | return $text . '
I Love the World!
'; 46 | } 47 | 48 | public static function generateOutputDone ($objView) 49 | { 50 | $objView -> outputContent = str_replace ('', '
Do you love the world?
', $objView -> outputContent); 51 | } 52 | 53 | /** 54 | * Function uninstall() will be loaded when the plugin is removed. 55 | * Use this to destroy some data, delete tables, etc. 56 | */ 57 | public static function uninstall () 58 | { 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /extension/hello_world/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/extension/hello_world/icon.png -------------------------------------------------------------------------------- /inc/admin.inc.php: -------------------------------------------------------------------------------- 1 | initToken (); 32 | $this -> verified = false; 33 | } 34 | 35 | private function initToken () 36 | { 37 | $this -> token = md5(bw :: $conf['siteKey'] . bw :: $conf['myUA']); 38 | } 39 | 40 | public function verifyToken ($sToken) 41 | { 42 | if (md5(sha1($sToken) . bw :: $conf['myUA']) == $this -> token) { 43 | $this -> verified = true; 44 | } else { 45 | $this -> verified = false; 46 | } 47 | } 48 | 49 | public function verifySessionToken ($sToken) 50 | { 51 | if ($sToken == $this -> token) { 52 | $this -> verified = true; 53 | } else { 54 | $this -> verified = false; 55 | } 56 | } 57 | 58 | public function storeSessionToken ($sToken) 59 | { 60 | $_SESSION['login-token'] = md5(sha1($sToken) . bw :: $conf['myUA']); 61 | } 62 | 63 | public function storeMobileToken () 64 | { 65 | $_SESSION['login-token'] = md5(bw :: $conf['siteKey'] . bw :: $conf['myUA']); 66 | } 67 | 68 | public function getCSRFCode ($actionCode) 69 | { 70 | if (isset ($_SESSION['login-token'])) { 71 | return substr (md5 (bw :: $conf['myUA'] . bw :: $conf['siteKey'] . $actionCode), 0, 8); 72 | } else { 73 | stopError (bw :: $conf['l']['admin:msg:NeedLogin']); 74 | } 75 | } 76 | 77 | public function checkCSRFCode ($actionCode) 78 | { 79 | if (!isset ($_SESSION['login-token'])) { 80 | stopError (bw :: $conf['l']['admin:msg:NeedLogin']); 81 | } elseif (!isset ($_REQUEST['CSRFCode'])) { 82 | stopError (bw :: $conf['l']['admin:msg:CSRF']); 83 | } elseif (substr (md5 (bw :: $conf['myUA'] . bw :: $conf['siteKey'] . $actionCode), 0, 8) <> $_REQUEST['CSRFCode']) { 84 | stopError (bw :: $conf['l']['admin:msg:CSRF']); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /inc/bw.inc.php: -------------------------------------------------------------------------------- 1 | getRows ('SELECT * FROM categories ORDER BY aCateOrder DESC'); 61 | foreach ($cateList as $aRow) { 62 | self :: $cateList[$aRow['aCateURLName']] = $aRow; 63 | self :: $cateData[$aRow['aCateURLName']] = $aRow['aCateDispName']; 64 | } 65 | } 66 | 67 | public static function pageStat ($canonicalURL, $aID = false) 68 | { 69 | $canonicalURL = str_replace (self :: $conf['siteURL'], '', $canonicalURL); 70 | DBTYPE == 'MySQL' ? self :: $db -> dbExec ('INSERT IGNORE INTO statistics (pageURL, sNum) VALUES (?, 0)', array ($canonicalURL)) : self :: $db -> dbExec ('INSERT OR IGNORE INTO statistics (pageURL, sNum) VALUES (?, 0)', array ($canonicalURL)); 71 | self :: $db -> dbExec ('UPDATE statistics SET sNum=sNUM+1, lastView=? WHERE pageURL=?', array (date ('Y-m-d H:i:s'), $canonicalURL)); 72 | if ($aID) { 73 | self :: $db -> dbExec ('UPDATE articles SET aReads=aReads+1 WHERE aID=?', array ($aID)); 74 | } 75 | } 76 | 77 | public static function loadLanguage () 78 | { 79 | global $conf; 80 | self :: $conf['siteLang'] = basename (self :: $conf['siteLang']); 81 | if (file_exists (P . 'lang/' . self :: $conf['siteLang'] . '.php')) { 82 | include_once (P . 'lang/' . self :: $conf['siteLang'] . '.php'); 83 | } else { 84 | include_once (P . "lang/en.php"); 85 | } 86 | } 87 | 88 | public static function loadExtensions () 89 | { 90 | $extData = self :: $db -> getRows ('SELECT * FROM extensions WHERE extActivate=1 ORDER BY extOrder DESC'); 91 | foreach ($extData as $aExt) { 92 | self :: $extData[$aExt['extID']] = $aExt; 93 | $allHooks = @explode (',', $aExt['extHooks']); 94 | foreach ($allHooks as $aHook) { 95 | self :: $extList[$aHook][] = $aExt['extID']; 96 | } 97 | if (!$aExt['isWidget']) { 98 | if (file_exists (P . 'extension/' . basename ($aExt['extID']) . '/do.php')) { 99 | include_once (P . 'extension/' . basename ($aExt['extID']) . '/do.php'); 100 | $aExtID = 'ext_' . $aExt['extID']; 101 | $aExtID :: init(); 102 | } 103 | } 104 | } 105 | } 106 | 107 | public static function getAllExtensions () 108 | { 109 | $extDataReturn = array (); 110 | $extData = self :: $db -> getRows ('SELECT * FROM extensions WHERE isWidget=0 ORDER BY extOrder DESC'); 111 | foreach ($extData as $aExt) { 112 | $aExt['extDesc'] = @parse_ini_string ($aExt['extDesc']); 113 | $aExt['extName'] = $aExt['extDesc']['name']; 114 | $aExt['extIntro'] = $aExt['extDesc']['intro']; 115 | $aExt['extAuthor'] = $aExt['extDesc']['author']; 116 | $aExt['extURL'] = $aExt['extDesc']['url']; 117 | $extDataReturn[$aExt['extID']] = $aExt; 118 | } 119 | return $extDataReturn; 120 | } 121 | 122 | public static function getAllWidgets () 123 | { 124 | $extDataReturn = array (); 125 | $extData = self :: $db -> getRows ('SELECT * FROM extensions WHERE isWidget=1 ORDER BY extOrder DESC'); 126 | foreach ($extData as $aExt) { 127 | $extDataReturn[$aExt['extID']] = $aExt; 128 | } 129 | return $extDataReturn; 130 | } 131 | 132 | public static function getSocialLinks () 133 | { 134 | $allSocial = array('sina-weibo', 'twitter', 'weixin', 'facebook', 'douban', 'instagram', 'renren', 'linkedin', 'github'); 135 | $allSocialNames = array(self :: $conf['l']['page:social:Weibo'], self :: $conf['l']['page:social:Twitter'], self :: $conf['l']['page:social:WeChat'], self :: $conf['l']['page:social:Facebook'], self :: $conf['l']['page:social:Douban'], self :: $conf['l']['page:social:Instagram'], self :: $conf['l']['page:social:Renren'], self :: $conf['l']['page:social:Linkedin'], 'GitHub'); 136 | $allSocialLinks = array(); 137 | foreach ($allSocial as $i => $aSocial) { 138 | if (isset (self :: $conf['social-' . $aSocial])) { 139 | if (self :: $conf['social-' . $aSocial]) { 140 | $allSocialLinks[] = array ('socialLinkID' => $aSocial, 'socialLinkURL' => self :: $conf['social-' . $aSocial], 'socialLinkName' => $allSocialNames[$i]); 141 | } 142 | } 143 | } 144 | return $allSocialLinks; 145 | } 146 | 147 | public static function getExternalLinks () 148 | { 149 | $allLinks = $allLinks2 = array(); 150 | if (isset (self :: $conf['externalLinks'])) { 151 | $allLinks = parse_ini_string (self :: $conf['externalLinks']); 152 | } 153 | foreach ($allLinks as $linkURL => $linkName) { 154 | $allLinks2[] = array ('linkURL' => urldecode ($linkURL), 'linkName' => $linkName); 155 | } 156 | return $allLinks2; 157 | } 158 | 159 | public static function getTagCloud ($num = 20) 160 | { 161 | $allTags = self :: $db -> getRows ('SELECT * FROM tags ORDER BY tCount DESC LIMIT 0, ?', array(floor ($num))); 162 | return $allTags; 163 | } 164 | 165 | public static function getWidgets ($widgetType) 166 | { 167 | $allWidgets = self :: $db -> getRows ('SELECT * FROM extensions WHERE isWidget=1 AND extHooks=? ORDER BY extOrder DESC', array($widgetType)); 168 | foreach ($allWidgets as $i => $oneWidget) { 169 | $allWidgets[$i]['extStorage'] = @json_decode ($allWidgets[$i]['extStorage'], true); 170 | is_array ($allWidgets[$i]['extStorage']) ? $allWidgets[$i] += $allWidgets[$i]['extStorage'] : false; 171 | } 172 | return $allWidgets; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /inc/canonicalization.inc.php: -------------------------------------------------------------------------------- 1 | perPage = &$conf['perPage']; 28 | 29 | if (!defined ('M')) { 30 | define ('M', 'index'); 31 | } 32 | switch (M) { 33 | case 'index': 34 | $this -> argsPattern = array ('pageNum'); 35 | $this -> loaderID = 'cate'; 36 | $this -> currentScript = $conf['linkPrefixIndex']; 37 | break; 38 | case 'cate': 39 | $this -> argsPattern = array ('cateID', 'pageNum'); 40 | $this -> loaderID = 'cate'; 41 | $this -> currentScript = $conf['linkPrefixCategory']; 42 | break; 43 | case 'article': 44 | $this -> argsPattern = array ('aID'); 45 | $this -> loaderID = 'article'; 46 | $this -> currentScript = $conf['linkPrefixArticle']; 47 | break; 48 | case 'page': 49 | $this -> argsPattern = array ('aID'); 50 | $this -> loaderID = 'page'; 51 | $this -> currentScript = $conf['linkPrefixPage']; 52 | break; 53 | case 'tag': 54 | $this -> argsPattern = array ('tValue', 'pageNum'); 55 | $this -> loaderID = 'tag'; 56 | $this -> currentScript = $conf['linkPrefixTag']; 57 | break; 58 | case 'admin': 59 | $this -> argsPattern = array ('mainAction', 'subAction', 'pageNum'); 60 | $this -> loaderID = 'admin'; 61 | $this -> currentScript = 'admin.php'; 62 | break; 63 | case 'send': 64 | $this -> argsPattern = array ('mainAction', 'subAction', 'pageNum'); 65 | $this -> loaderID = 'send'; 66 | $this -> currentScript = 'send.php'; 67 | break; 68 | case 'list': 69 | $this -> argsPattern = array ('pageNum'); 70 | $this -> loaderID = 'list'; 71 | $this -> currentScript = $conf['linkPrefixIndex']; 72 | break; 73 | case 'api': 74 | $this -> argsPattern = array ('mainAPI', 'subAPI', 'pref'); 75 | $this -> loaderID = 'api'; 76 | $this -> currentScript = 'api.php'; 77 | break; 78 | default: 79 | $this -> loaderID = 'error'; 80 | $this -> currentScript = $conf['linkPrefixIndex']; 81 | hook ('setLoader', 'Execute', $this); 82 | stopError ('Requested mode does not exist.'); 83 | } 84 | 85 | $siteURLTmp = parse_url ($conf['siteURL'], PHP_URL_PATH) . '/'; 86 | 87 | if (isset ($_REQUEST['go'])) { 88 | $requestedURL = explode ('/', $_REQUEST['go']); 89 | } 90 | else { 91 | if ($siteURLTmp == '/') { 92 | $requestedURL = explode ('/', $_SERVER['PHP_SELF']); 93 | array_shift ($requestedURL); 94 | } else { 95 | $requestedURL = explode ('/', str_replace ($siteURLTmp, '', $_SERVER['PHP_SELF'])); 96 | } 97 | } 98 | array_shift ($requestedURL); 99 | if (count ($requestedURL) > count ($this -> argsPattern)) { 100 | $this -> currentArgs = array_slice ($requestedURL, 0, count ($this -> argsPattern)); 101 | } else { 102 | $this -> currentArgs = array_pad ($requestedURL, count ($this -> argsPattern), 1); 103 | } 104 | $this -> currentArgs = array_combine ($this -> argsPattern, $this -> currentArgs); 105 | 106 | if (array_key_exists ('pageNum', $this -> currentArgs)) { 107 | $this -> currentPage = $this -> currentArgs['pageNum'] = max($this -> currentArgs['pageNum'], 1); 108 | $paginableArgs = $this -> currentArgs; 109 | $paginableArgs['pageNum'] = '%d'; 110 | } else { 111 | $this -> currentPage = 1; 112 | $paginableArgs = $this -> currentArgs; 113 | } 114 | 115 | $this -> canonicalURL = $conf['canonicalURL'] = $conf['siteURL'] . '/' . $this -> currentScript . '/' . implode ('/', $this -> currentArgs) . '/'; 116 | $this -> paginableURL = $conf['siteURL'] . '/' . $this -> currentScript . '/' . implode ('/', $paginableArgs) . '/'; 117 | 118 | if (isset ($_REQUEST['ajax'])) { 119 | define ('ajax', 1); 120 | } 121 | 122 | $this -> cache = false; 123 | if (bw :: $conf['pageCache'] == '1') { 124 | if (M == 'index' || M == 'article') { 125 | $plusAjax = defined ('ajax') ? 'ajax' : 'page'; 126 | $cacheKey = md5 ($this -> canonicalURL . $plusAjax); 127 | $cached = bw :: $db -> getSingleRow ('SELECT * FROM cache WHERE caID=? LIMIT 0, 1', array($cacheKey)); 128 | if (isset ($cached['caID'])) { 129 | $this -> cache = $cached['caContent']; 130 | } else { 131 | define ('docache', $cacheKey); 132 | } 133 | } 134 | } 135 | 136 | if (!$this -> cache) { 137 | bw :: loadLanguage (); 138 | bw :: initCategories (); 139 | bw :: loadExtensions (); 140 | } 141 | 142 | if (M != 'admin' && M != 'send') { 143 | bw :: pageStat ($this -> canonicalURL, M == 'article' ? $this -> currentArgs['aID'] : false); 144 | } 145 | 146 | hook ('canonicalized', 'Execute', $this); 147 | } 148 | 149 | public function setPerPage ($num) 150 | { 151 | $this -> perPage = floor ($num); 152 | } 153 | 154 | public function setTotalPages ($num) 155 | { 156 | $this -> totalPages = floor ($num); 157 | } 158 | 159 | public function calTotalPages ($totalNum) 160 | { 161 | $this -> totalPages = ceil ($totalNum / $this -> perPage); 162 | } 163 | 164 | public function loader () 165 | { 166 | if ($this -> cache) { // Cached content: direct output 167 | if (!defined ('ajax')) { 168 | die ($this -> cache); 169 | } else { 170 | die (json_encode (array ('error' => 0, 'returnMsg' => $this -> cache))); 171 | } 172 | } else { 173 | hook ('newIndexPage', 'Execute', $this); 174 | 175 | if (!file_exists (P . "mode/{$this -> loaderID}.mod.php")) { 176 | stopError ("Invalid parameter."); 177 | } 178 | return P . "mode/{$this -> loaderID}.mod.php"; 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /inc/category.inc.php: -------------------------------------------------------------------------------- 1 | cacheClear = true; 18 | } 19 | 20 | public function getCategories () 21 | { 22 | bw :: initCategories (); 23 | } 24 | 25 | public function addCategories ($smt, $smt2 = array ()) 26 | { 27 | if (is_array ($smt)) { 28 | $dataLine = array(); 29 | foreach ($smt as $aCateURLName => $aCateDispName) { 30 | if ($aCateURLName != urlencode ($aCateURLName)) { 31 | stopError (bw :: $conf['l']['admin:msg:InvalidCateName']); 32 | } 33 | $aCateDispName = htmlspecialchars ($aCateDispName, ENT_QUOTES, 'UTF-8'); 34 | if (array_key_exists ($aCateURLName, bw :: $cateData)) { 35 | stopError (bw :: $conf['l']['admin:msg:Existed']); 36 | } else { 37 | $dataLine[] = array(':aCateURLName' => $aCateURLName, ':aCateDispName' => $aCateDispName, ':aCateTheme' => isset ($smt2[$aCateURLName]) ? $smt2[$aCateURLName] : null); 38 | } 39 | } 40 | $dataLineCounter = count ($dataLine); 41 | if ($dataLineCounter > 0) { 42 | bw :: $db -> dbExecBatch ("INSERT INTO categories (aCateURLName, aCateDispName, aCateCount, aCateOrder, aCateTheme) VALUES (:aCateURLName, :aCateDispName, 0, {$dataLineCounter}, :aCateTheme)", $dataLine); 43 | if ($this -> cacheClear) { 44 | $this -> getCategories (); //Refresh immediately 45 | clearCache (); //Clear all cache 46 | } 47 | } 48 | hook ('addCategories', 'Execute', $smt); 49 | } 50 | } 51 | 52 | public function deleteCategories ($deletedCates) 53 | { 54 | foreach ($deletedCates as $delCate => $delCateName) { 55 | $delLine = bw :: $db -> getSingleRow ('SELECT * FROM categories WHERE aCateURLName=:delCate', array(':delCate' => $delCate)); 56 | if ($delLine['aCateCount'] == 0) { 57 | bw :: $db -> dbExec ('DELETE FROM categories WHERE aCateURLName=:delCate', array(':delCate' => $delCate)); 58 | } else { 59 | stopError (bw :: $conf['l']['admin:msg:CategoryNotEmpty']); 60 | } 61 | } 62 | if ($this -> cacheClear) { 63 | $this -> getCategories (); //Refresh immediately 64 | clearCache (); //Clear all cache 65 | } 66 | hook ('deleteCategories', 'Execute', $deletedCates); 67 | } 68 | 69 | public function orderCategories ($arrayOrder) 70 | { 71 | $dataLine = array(); 72 | $i = count ($arrayOrder)-1; 73 | foreach ($arrayOrder as $order) { 74 | $dataLine[$i][':aCateOrder'] = $i; 75 | $dataLine[$i][':aCateURLName'] = $order; 76 | $i -= 1; 77 | } 78 | bw :: $db -> dbExecBatch ('UPDATE categories SET aCateOrder=:aCateOrder WHERE aCateURLName=:aCateURLName', $dataLine); 79 | if ($this -> cacheClear) { 80 | $this -> getCategories (); //Refresh immediately 81 | clearCache (); //Clear all cache 82 | } 83 | hook ('orderCategories', 'Execute', $arrayOrder); 84 | } 85 | 86 | public function renameCategories ($arrayCateID, $arrayOldNames, $arrayNewNames) 87 | { 88 | if (count ($arrayCateID) <> count ($arrayOldNames) || count ($arrayCateID) <> count ($arrayNewNames)) { 89 | return; 90 | } 91 | for ($i = 0; $i < count ($arrayCateID); $i++) { 92 | $arrayNewNames[$i] = htmlspecialchars ($arrayNewNames[$i], ENT_QUOTES, 'UTF-8'); 93 | if ($arrayOldNames[$i] <> $arrayNewNames[$i]) { 94 | bw :: $db -> dbExec ('UPDATE categories SET aCateDispName=? WHERE aCateURLName=?', array ($arrayNewNames[$i], $arrayCateID[$i])); 95 | } 96 | } 97 | if ($this -> cacheClear) { 98 | $this -> getCategories (); //Refresh immediately 99 | clearCache (); //Clear all cache 100 | } 101 | hook ('renameCategories', 'Execute', array ($arrayCateID, $arrayOldNames, $arrayNewNames)); 102 | } 103 | 104 | public function updateCategoryThemes ($arrayCateID, $arrayNewThemes) 105 | { 106 | if (count ($arrayCateID) <> count ($arrayNewThemes)) { 107 | return; 108 | } 109 | for ($i = 0; $i < count ($arrayCateID); $i++) { 110 | if ($arrayNewThemes[$i] <> bw :: $cateList[$arrayCateID[$i]]['aCateTheme']) { 111 | bw :: $db -> dbExec ('UPDATE categories SET aCateTheme=? WHERE aCateURLName=?', array ($arrayNewThemes[$i], $arrayCateID[$i])); 112 | } 113 | } 114 | if ($this -> cacheClear) { 115 | $this -> getCategories (); //Refresh immediately 116 | clearCache (); //Clear all cache 117 | } 118 | hook ('updateCategoryThemes', 'Execute', array ($arrayCateID, $arrayNewThemes)); 119 | } 120 | 121 | public function bufferCacheClear () 122 | { 123 | $this -> cacheClear = false; 124 | } 125 | 126 | public function endBufferCache () 127 | { 128 | $this -> getCategories (); //Refresh immediately 129 | clearCache (); //Clear all cache 130 | $this -> cacheClear = true; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /inc/database.inc.php: -------------------------------------------------------------------------------- 1 | silent = false; 22 | $this -> qNum = 0; 23 | 24 | try { 25 | if (strtolower (DBTYPE) == 'sqlite') { 26 | $this -> dbh = parent :: __construct ('sqlite:' . DBNAME); 27 | } elseif (strtolower (DBTYPE) == 'mysql') { 28 | $this -> dbh = parent :: __construct ('mysql:dbname=' . DBNAME . ';host=' . DBADDR, DBUSERNAME, DBPASSWORD, array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); 29 | $this -> setAttribute (PDO::ATTR_EMULATE_PREPARES, false); 30 | } 31 | else 32 | { 33 | die ('Database not supported.'); 34 | } 35 | } 36 | catch (PDOException $e) { 37 | $this -> errorMsg[] = $e -> getCode(); 38 | $this -> errorMsg[] = $e -> getMessage(); 39 | stopError ('Database Error: ' . implode(', ', $this -> errorMsg)); 40 | } 41 | } 42 | 43 | public function getSingleRow ($query, $bindarray = null, $defaultmode = false) 44 | { 45 | $stmt = $this -> dbExec ($query, $bindarray); 46 | $return = $this -> getSingleRowByStmt ($stmt, $defaultmode); 47 | return $return; 48 | } 49 | 50 | public function getRows ($query, $bindarray = null, $defaultmode = false) 51 | { 52 | $stmt = $this -> dbExec ($query, $bindarray); 53 | $return = $this -> getRowsByStmt ($stmt, $defaultmode); 54 | return $return; 55 | } 56 | 57 | public function getColumns ($query, $bindarray = null) 58 | { 59 | $stmt = $this -> dbExec ($query, $bindarray); 60 | $return = $this -> getColumnsByStmt ($stmt); 61 | return $return; 62 | } 63 | 64 | public function countRows ($query, $bindarray = null) 65 | { 66 | $stmt = $this -> dbExec ($query, $bindarray); 67 | $stmt -> setFetchMode (PDO :: FETCH_NUM); 68 | $return = $stmt -> fetchAll (); 69 | return count($return); 70 | } 71 | 72 | private function getSingleRowByStmt ($statement, $defaultmode = false) 73 | { 74 | if (!$defaultmode) { 75 | $statement -> setFetchMode (PDO :: FETCH_ASSOC); 76 | } 77 | $return = $statement -> fetch (); 78 | return $return; 79 | } 80 | 81 | private function getRowsByStmt ($statement, $defaultmode = false) 82 | { 83 | if (!$defaultmode) { 84 | $statement -> setFetchMode (PDO :: FETCH_ASSOC); 85 | } 86 | $return = $statement -> fetchAll (); 87 | return $return; 88 | } 89 | 90 | private function getColumnsByStmt ($statement) 91 | { 92 | $array = $this -> getRowsByStmt ($statement); 93 | if (!$array) { 94 | return $array; 95 | } 96 | $result = array(); 97 | for ($i = 0; $i < count($array); $i++) { 98 | foreach ($array[$i] as $key => $val) { 99 | $result[$key][$i] = $val; 100 | } 101 | } 102 | return $result; 103 | } 104 | 105 | public function dbExec ($queryStr, $bindarray = null) 106 | { 107 | $stmt = $this -> prepare ($queryStr); 108 | if ($stmt) { 109 | $return = $stmt -> execute ($bindarray); 110 | $this -> qNum++; 111 | } else { 112 | $this -> errorMsg = $this -> errorInfo(); 113 | $this -> throwError (); 114 | } 115 | if ($this -> errorCode() != '00000') { 116 | $this -> errorMsg = $this -> errorInfo(); 117 | $this -> errorMsg[] = $stmt -> queryString; 118 | $this -> throwError (); 119 | } 120 | return $stmt; 121 | } 122 | 123 | public function dbExecBatch ($queryStr, $bindarrays) 124 | { 125 | $stmt = $this -> prepare ($queryStr); 126 | if ($stmt && is_array($bindarrays)) { 127 | foreach ($bindarrays as $bindarray) { 128 | $stmt -> execute ($bindarray); 129 | $this -> qNum++; 130 | } 131 | } else { 132 | $this -> errorMsg = $this -> errorInfo(); 133 | $this -> throwError (); 134 | } 135 | if ($this -> errorCode() != '00000') { 136 | $this -> errorMsg = $this -> errorInfo(); 137 | $this -> errorMsg[] = $stmt -> queryString; 138 | $this -> throwError (); 139 | } 140 | return $stmt; 141 | } 142 | 143 | public function dbLastInsertId () 144 | { 145 | return $this -> lastInsertId(); 146 | } 147 | 148 | private function throwError () 149 | { 150 | if (!$this -> silent) { 151 | stopError ('Database Error: ' . implode(', ', $this -> errorMsg)); 152 | exit (); 153 | } 154 | } 155 | 156 | public function silentError ($status) 157 | { 158 | $this -> silent = $status ? true : false; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /inc/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inc/script/autocomplete/README.md: -------------------------------------------------------------------------------- 1 | [jQuery.AutoComplete](http://work.jiani.info/jQuery.AutoComplete/) 2 | ================= 3 | jQuery.AutoComplete是一个基于jQuery的自动补全插件。借助于jQuery优秀的跨浏览器特性,可以兼容Chrome/IE/Firefox/Opera/Safari等多种浏览器。 4 | 5 | 特性一览: 6 | 7 | * 支持补全列表的宽度设定。 8 | * 支持补全列表的最大高度设定。 9 | * 支持补全列表的行数限制。 10 | * 支持补全列表的显示位置及方向的设定。 11 | * 支持自定义匹配规则。 12 | * 支持匹配文本的渲染。 13 | * 支持自定义匹配文本的渲染样式。 14 | * 支持补全列表的样式设定。 15 | * 支持自定义补全列表项的创建。 16 | * 支持多种数据源。 17 | * 支持'json'和'xml'两种数据格式。 18 | * 支持异步处理。 19 | * 支持错误调试。 20 | 21 | 演示地址:http://autocomplete.jiani.info/demo/ 22 | 文档地址:http://autocomplete.jiani.info/doc/ 23 | -------------------------------------------------------------------------------- /inc/script/autocomplete/jquery.autocomplete.css: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery.autocomplete.css (v1.1.0) 3 | * authored by nswish (nswish@gmail.com) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | div.ac { 18 | border-style: solid; 19 | border-width: 1px; 20 | border-color: #F3F3F3; 21 | position: absolute; 22 | display: none; 23 | overflow: auto; 24 | background: #F3F3F3; 25 | box-shadow: 2px 5px 7px #DDD; 26 | max-height: 110px; 27 | } 28 | 29 | div.ac > ul { 30 | margin: 0px; 31 | padding: 0px; 32 | } 33 | 34 | div.ac > ul > li { 35 | font-size: 14px; 36 | margin: 0px; 37 | list-style-type: none; 38 | background-color: white; 39 | word-break: break-all; 40 | } 41 | 42 | div.ac > ul > li > div { 43 | display: table-row; 44 | width: 100%; 45 | } 46 | 47 | div.ac > ul > li > div em { 48 | background-color: #A8FF51; 49 | font-style: normal; 50 | } 51 | 52 | div.ac > ul > li.normal { 53 | padding: 2px 0px 2px 2px; 54 | } 55 | 56 | div.ac > ul > li.normal > div > span{ 57 | display: table-cell; 58 | vertical-align: middle; 59 | } 60 | 61 | div.ac > ul > li.iconList { 62 | padding: 0px 0px 0px 2px; 63 | } 64 | 65 | div.ac > ul > li.iconList > div > div { 66 | display: table-cell; 67 | vertical-align: middle; 68 | padding-right: 5px; 69 | } 70 | 71 | div.ac > ul > li.iconList > div > div > img { 72 | display: table; 73 | display: table-cell\9; 74 | } 75 | 76 | div.ac > ul > li.iconList > div > span { 77 | display: table-cell; 78 | vertical-align: middle; 79 | } 80 | 81 | div.ac > ul > li.selected { 82 | background-color: #DDD; 83 | cursor: pointer; 84 | } -------------------------------------------------------------------------------- /inc/script/autocomplete/jquery.autocomplete.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery.autocomplete.js (v1.1.2) 3 | * authored by nswish (nswish@gmail.com) 4 | * jQuery 1.7.1+ support 5 | * compatible: ie/chrome/firefox/opera/safari 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | (function(g){g.fn.extend({"AutoComplete":function(q){return this.each(function(){if(!(this&&this.tagName==="INPUT"&&this.type==="text")){return}if(this.controller){this.controller.setOption(q)}else{if(g.isPlainObject(q)){this.controller=new f(this,q)}}})}});var f=function(q,r){this.option=g.extend(false,{"width":320,"maxHeight":null,"itemHeight":null,"listStyle":"normal","listDirection":"down","data":[],"ajaxDataType":"json","ajaxParams":{},"ajaxTimeout":3000,"ajaxType":"GET","maxItems":20,"matchHandler":n,"emphasisHandler":m,"createItemHandler":null,"beforeLoadDataHandler":null,"afterSelectedHandler":null,"async":false,"emphasis":true,"onerror":null},r);b.apply(this,[q]);j.apply(this)};var b=function(q){var r=this;this.inputView=g(q);this.inputView.attr("autocomplete","off").keyup(this._keyup=function(s){switch(s.keyCode){case 13:case 16:case 17:case 37:case 38:case 39:case 40:break;case 27:e.apply(r);break;default:if(r.option.async){setTimeout(function(){h.apply(r)},0)}else{h.apply(r)}}}).keydown(this._keydown=function(t){switch(t.keyCode){case 38:p.apply(r,["up"]);break;case 40:p.apply(r,["down"]);break;case 13:var s=r.searchView.is(":visible");c.apply(r);if(s){return false}break}}).blur(this._blur=function(){g(document).one("click",function(){e.apply(r)})})};var j=function(){var q=this;this.searchView=g("
    ").appendTo(document.body).on("mouseenter","li",function(){q.searchView.find("li.selected").removeClass("selected");g(this).addClass("selected")}).on("mouseleave","li",function(){g(this).removeClass("selected")}).on("click","li",function(){c.apply(q);e.apply(q)}).css("font-size",this.inputView.css("font-size"));g(window).resize(function(){k.apply(q)})};var i=function(q){var s=this,r=this.searchView.find("ul").empty();if(g.inArray(this.option.listStyle,["normal","iconList","custom"])==-1){throw ["遇到未知的listStyle参数!"]}g.each(q,function(u,w){var v=g("
  • ").appendTo(r).addClass(s.option.listStyle).data("data",w).find("div");switch(s.option.listStyle){case"normal":v.append(""+w.label+"");break;case"iconList":var t=g("").attr("src",w.image);v.append(g("
    ").append(t)).append(""+w.label+"");break;case"custom":v.append(s.option.createItemHandler.apply(s,[u,w]));case"default":break}if(s.option.itemHeight>0){v.height(s.option.itemHeight).css("max-height",s.option.itemHeight)}})};var k=function(){if(this.option.listDirection==="down"){var r=this.inputView.offset().top+this.inputView.outerHeight()}else{if(this.option.listDirection==="up"){var r=this.inputView.offset().top-this.searchView.outerHeight()}else{throw"遇到未知的listDirection参数!"}}var q=this.inputView.offset().left;this.searchView.css("top",r+"px").css("left",q+"px")};var d=function(){if(typeof(this.option.width)==="string"&&this.option.width.toLowerCase()==="auto"){return this.inputView.outerWidth()-2}else{if(typeof(this.option.width)==="number"){return this.option.width}else{throw"遇到未知的width参数!"}}};var l=function(q){var s=this;if(this.option.listDirection==="up"){q=q.reverse()}try{i.apply(s,[q]);if(this.option.maxHeight>0){this.searchView.css("max-height",this.option.maxHeight+"px");if(g.browser.msie){this.searchView.css("height",this.searchView.height()>this.option.maxHeight?this.option.maxHeight+"px":"auto")}}k.apply(this);this.searchView.css("width",d.apply(this)+"px")}catch(r){o.apply(this,[r+""]);return}this.searchView.show();p.apply(this,[this.option.listDirection])};var e=function(){this.searchView.find("ul").empty();this.searchView.hide()};var p=function(s){var t=this.searchView.find("li.selected");if(t.size()){var q=s==="up"?t.prev():t.next()}else{var q=s==="up"?this.searchView.find("li").last():this.searchView.find("li").first()}if(q.size()){this.searchView.find("li").removeClass("selected");q.addClass("selected");var u=q.outerHeight();var r=q.position().top;if(u+r>this.searchView.height()){this.searchView.scrollTop(this.searchView.scrollTop()+r+u-this.searchView.height())}else{if(r<0){this.searchView.scrollTop(this.searchView.scrollTop()+r)}}}};var c=function(){var r=this,q=this.searchView.find("li.selected");if(q.size()){var s=q.data("data");this.inputView.val(s.value);if(g.isFunction(this.option.afterSelectedHandler)){try{this.option.afterSelectedHandler.apply(r,[s])}catch(t){o.apply(this,["调用afterSelectedHandler错误:"+t]);return}}e.apply(this)}};var a=function(q){jQuery.support.cors=true;var s=this,t=[],r={"async":false,"dataType":s.option.ajaxDataType,"type":s.option.ajaxType,"timeout":this.option.ajaxTimeout,"success":function(u,w,v){if(s.option.ajaxDataType==="xml"){g(u).find("item").each(function(){var z={"value":g(this).text(),"label":g(this).text()};for(var y=0;y0&&q.length>=t.option.maxItems){return false}if(g.isPlainObject(y)){var x=g.extend(false,{},y)}else{if(typeof(y)==="string"){var x={"label":y,"value":y,"image":y}}else{o.apply(t,["数据源Item类型错误!"]);return false}}if(t.option.matchHandler.apply(t,[s,x])){q.push(x)}});if(s==this.inputView.val()){if(q.length>0){l.apply(this,[q])}else{e.apply(this)}}};var o=function(q){if(g.isFunction(this.option.onerror)){this.option.onerror.apply(this,[q])}};f.prototype.setOption=function(q){if(g.isPlainObject(q)){this.option=g.extend(false,this.option,q)}else{if(typeof(q)==="string"){switch(q){case"destroy":this.destroy();break;case"show":this.show();break;default:o.apply(this,["未知的AutoComplete参数!"]);return}}else{o.apply(this,["未知的AutoComplete参数类型!"]);return}}};f.prototype.destroy=function(){this.searchView.remove();this.inputView.unbind("keyup",this._keyup).unbind("keydown",this._keydown).unbind("blur",this._blur);delete this.inputView.get(0).controller};f.prototype.show=function(){if(this.option.async){setTimeout(function(){h.apply(this)},0)}else{h.apply(this)}};var n=function(q,s){var r=RegExp(q.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1"),"i");if(this.option.emphasis&&g.isFunction(this.option.emphasisHandler)){this.option.emphasisHandler.apply(this,[q,s])}return r.test(s.value)};var m=function(q,s){var r=RegExp("("+q.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")+")","ig");s.label=s.label.replace(r,"$1")}})(jQuery); -------------------------------------------------------------------------------- /inc/script/editor/README.md: -------------------------------------------------------------------------------- 1 | jQuery.Markbar 2 | ============== 3 | 4 | ## Introduction 5 | 6 | Markbar is a simple jQuery plugin that adds a WYSIWYG style toolbar to "[Markdown](http://daringfireball.net/projects/markdown/) enabled" textareas. This is helpful for users not familiar with the Markdown syntax. You can view a [demo here](http://reinink.me/markbar/). 7 | 8 | [![jQuery.Markbar Screenshot](http://reinink.me/markbar/screenshot.png)](http://reinink.me/markbar/) 9 | 10 | ## Basic usage 11 | 12 | Markbar is super easy to use. Here is the most basic usage, which will enable all the available toolbar options. 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | ## Customize 27 | 28 | If you want to limit which options are displayed in the toolbar, simply disable the ones you don't want. Here is the complete list of all the available toolbar options: 29 | 30 | $('textarea').markbar( 31 | { 32 | strong: true, 33 | em: true, 34 | h1: true, 35 | h2: true, 36 | h3: true, 37 | ul: true, 38 | ol: true, 39 | a: true, 40 | img: true, 41 | blockquote: true, 42 | code: false 43 | }); 44 | 45 | ## Questions or comments? 46 | 47 | Send me a message on Twitter at [@reinink](https://twitter.com/reinink). -------------------------------------------------------------------------------- /inc/script/editor/themes/default/default.css: -------------------------------------------------------------------------------- 1 | .markbar 2 | { 3 | overflow: hidden; 4 | } 5 | 6 | .markbar a 7 | { 8 | display: block; 9 | float: left; 10 | width: 30px; 11 | height: 24px; 12 | margin: 0 3px 3px 0; 13 | background: #fff; 14 | text-indent: 8px; 15 | border: #dddddd solid 1px; 16 | border-radius: 6px; 17 | color: #000; 18 | font-size: 14px; 19 | } 20 | 21 | .markbar a:hover 22 | { 23 | background: #73D90C; 24 | color: #FFF; 25 | } 26 | 27 | 28 | @media only screen and (max-width:800px) { 29 | .markbar a.em, .markbar a.h3, .markbar a.ol, .markbar a.code, .markbar a.youkuvideo, .markbar a.xiami { 30 | display: none; 31 | } 32 | } -------------------------------------------------------------------------------- /inc/script/editor/themes/default/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/inc/script/editor/themes/default/icons.png -------------------------------------------------------------------------------- /inc/script/html5sortable/LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2015 [Lukas Oppermann](lukas@vea.re) & [Alexandru Badiu](https://github.com/voidberg) 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /inc/script/html5sortable/html.sortable.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?module.exports=t():e.sortable=t()}(this,function(){"use strict";var e,t,n,r=[],a=[],o=function(e,t,n){return void 0===n?e&&e.h5s&&e.h5s.data&&e.h5s.data[t]:(e.h5s=e.h5s||{},e.h5s.data=e.h5s.data||{},e.h5s.data[t]=n,void 0)},i=function(e){e.h5s&&delete e.h5s.data};switch(!0){case"matches"in window.Element.prototype:n="matches";break;case"mozMatchesSelector"in window.Element.prototype:n="mozMatchesSelector";break;case"msMatchesSelector"in window.Element.prototype:n="msMatchesSelector";break;case"webkitMatchesSelector"in window.Element.prototype:n="webkitMatchesSelector"}var s=function(e,t){if(!t)return Array.prototype.slice.call(e);for(var r=[],a=0;at){var c=o-t,f=p(this).top;if(ld&&a.pageY>f+o-c)return}void 0===e.oldDisplay&&(e.oldDisplay=e.style.display),e.style.display="none",lmakeHtml($text); 20 | ``` 21 | 22 | 当前支持的语法 23 | -------------- 24 | 25 | - 标题 26 | - 列表(可递归) 27 | - 引用(可递归) 28 | - 缩进风格的代码块 29 | - Github风格的代码块 30 | - 各种行内文字加粗,斜体等效果 31 | - 链接,图片 32 | - 自动链接 33 | - 段内折行 34 | - 脚标 35 | - 分隔符 36 | - 表格 37 | - 图片和链接支持互相套用 38 | 39 | 浏览器中使用请参阅 [HyperDown.js](https://github.com/SegmentFault/HyperDown.js) 40 | -------------------------------------------------------------------------------- /inc/script/loader.js: -------------------------------------------------------------------------------- 1 | $( document ).ajaxError(function(event, jqxhr, settings, thrownError) { 2 | alert (lng['AjaxFail']+'\r'+jqxhr.responseText); 3 | }); 4 | 5 | $('.pageLink').click(function () { 6 | 7 | var targetURL = $(this).attr('href'); 8 | if (history && history.pushState) { 9 | history.pushState(null, document.title, targetURL); 10 | } 11 | 12 | targetURL=conj (targetURL, 'ajax=1'); 13 | 14 | $.get(targetURL, function (data) { 15 | if (data.error==1) { 16 | alert(data.errorMsg); 17 | } 18 | else { 19 | $("#UI-loading").fadeIn(400, function() { 20 | $("#ajax-article-list").html(data.returnMsg); 21 | }); 22 | $("#UI-loading").fadeOut(400, function () { 23 | scrollToTop (); 24 | }); 25 | } 26 | }, "json"); 27 | 28 | return false; 29 | 30 | }); 31 | 32 | $('.icon-share').click(function () { 33 | var aID=$(this).attr('id'); 34 | $('#'+aID+'-layer').fadeToggle(200); 35 | }); 36 | 37 | $('.shareLayer').click(function () { 38 | $(this).fadeToggle(200); 39 | }); 40 | 41 | $('article img').click(function () { 42 | var picURL=$(this).attr('src'); 43 | if ($(this).hasClass ('ImgAlbum')) 44 | { 45 | var AlbumID = $(this).data('album'); 46 | var ImgGroups=new Array(); 47 | var ImgDesc=new Array(); 48 | var i = 0; 49 | var ImgSeq = 0; 50 | $('article .Alb'+AlbumID).each (function () { 51 | ImgGroups[i] = $(this).attr('src'); 52 | ImgDesc[i] = $(this).data ('desc'); 53 | if ($(this).attr('src') == picURL) { 54 | ImgSeq = i; 55 | } 56 | i++; 57 | }); 58 | lightboxImageAlbum (picURL, ImgGroups, ImgDesc, ImgSeq); 59 | } 60 | else { 61 | lightboxImage (picURL, false); 62 | } 63 | }); 64 | 65 | $('article .videoFrame').each (function () { 66 | var iWidth=$(this).width(); 67 | var iHeight=Math.floor(iWidth*9/16); 68 | $(this).height(iHeight); 69 | }); 70 | 71 | $('article .xiamiLoader').each (function () { 72 | var xmID=$(this).data('src'); 73 | var root=$(this).data('root'); 74 | $(this).html(""); 75 | }); 76 | 77 | 78 | $('#openPageSelector').click (function () { 79 | $('#pageSelector').fadeToggle(); 80 | }); 81 | 82 | $("#searchVal").keydown (function (event) { 83 | if(event.which == 13 && $("#searchVal").val()!='') { 84 | var searchPlus = $("#searchVal").data("searchquery").replace(/http%3A%2F%2F/, ''); 85 | searchPlus = searchPlus.replace(/https%3A%2F%2F/, ''); 86 | var searchURL = $("#searchVal").data("searchurl"); 87 | if (searchURL.indexOf ('baidu') != -1) { 88 | var tmp = searchPlus.split('%2F'); 89 | searchPlus = tmp[0]; 90 | } 91 | window.location = $("#searchVal").data("searchurl")+encodeURI($("#searchVal").val())+searchPlus; 92 | } 93 | }); 94 | -------------------------------------------------------------------------------- /inc/script/mysql-backup/backup.php: -------------------------------------------------------------------------------- 1 | config = array( 30 | 'host' => DBADDR, 31 | 'port' => 3306, 32 | 'user' => DBUSERNAME, 33 | 'password' => DBPASSWORD, 34 | 'database' => DBNAME 35 | ); 36 | $this->begin = microtime(true); 37 | $config = is_array($config) ? $config : array(); 38 | $this->config = array_merge($this->config, $config); 39 | //启动PDO连接 40 | if (!$this->handler instanceof PDO) { 41 | try { 42 | $this->handler = new PDO("mysql:host={$this->config['host']}:{$this->config['port']};dbname={$this->config['database']}", $this->config['user'], $this->config['password'], array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); 43 | } catch (PDOException $e) { 44 | $this->error = $e->getMessage(); 45 | return false; 46 | } catch (Exception $e) { 47 | $this->error = $e->getMessage(); 48 | return false; 49 | } 50 | } 51 | } 52 | 53 | /** 54 | * 备份 55 | * @param array $tables 56 | * @return bool 57 | */ 58 | public function backup($tables = array()) 59 | { 60 | //存储表定义语句的数组 61 | $ddl = array(); 62 | //存储数据的数组 63 | $data = array(); 64 | $this->setTables($tables); 65 | 66 | if (!empty($this->tables)) { 67 | foreach ($this->tables as $table) { 68 | $ddl[] = $this->getDDL($table); 69 | $data[] = $this->getData($table); 70 | } 71 | //开始写入 72 | 73 | //var_dump($data); 74 | $tu = $this->writeToFile($this->tables, $ddl, $data); 75 | return $tu; 76 | } else { 77 | $this->error = '数据库中没有表!'; 78 | return false; 79 | } 80 | } 81 | 82 | /** 83 | * 设置要备份的表 84 | * @param array $tables 85 | */ 86 | private function setTables($tables = array()) 87 | { 88 | if (!empty($tables) && is_array($tables)) { 89 | //备份指定表 90 | $this->tables = $tables; 91 | } else { 92 | //备份全部表 93 | $this->tables = $this->getTables(); 94 | } 95 | } 96 | 97 | /** 98 | * 查询 99 | * @param string $sql 100 | * @return mixed 101 | */ 102 | private function query($sql = '') 103 | { 104 | $stmt = $this->handler->query($sql); 105 | $stmt->setFetchMode(PDO::FETCH_NUM); 106 | $list = $stmt->fetchAll(); 107 | return $list; 108 | } 109 | 110 | /** 111 | * 获取全部表 112 | * @return array 113 | */ 114 | private function getTables() 115 | { 116 | $sql = 'SHOW TABLES'; 117 | $list = $this->query($sql); 118 | $tables = array(); 119 | foreach ($list as $value) { 120 | $tables[] = $value[0]; 121 | } 122 | return $tables; 123 | } 124 | 125 | /** 126 | * 获取表定义语句 127 | * @param string $table 128 | * @return mixed 129 | */ 130 | private function getDDL($table = '') 131 | { 132 | $sql = "SHOW CREATE TABLE `{$table}`"; 133 | $ddl = $this->query($sql)[0][1] . ';'; 134 | return $ddl; 135 | } 136 | 137 | /** 138 | * 获取表数据 139 | * @param string $table 140 | * @return mixed 141 | */ 142 | private function getData($table = '') 143 | { 144 | $sql = "SHOW COLUMNS FROM `{$table}`"; 145 | $list = $this->query($sql); 146 | //字段 147 | $columns = ''; 148 | //需要返回的SQL 149 | $query = ''; 150 | foreach ($list as $value) { 151 | $columns .= "`{$value[0]}`,"; 152 | } 153 | $columns = substr($columns, 0, -1); 154 | $data = $this->query("SELECT * FROM `{$table}`"); 155 | foreach ($data as $value) { 156 | $dataSql = ''; 157 | foreach ($value as $v) { 158 | $v = str_replace ("'", "\\'", $v); 159 | $v = str_replace ("\r\n", "\\r\\n", $v); 160 | $dataSql .= "'{$v}',"; 161 | } 162 | $dataSql = substr($dataSql, 0, -1); 163 | $query .= "INSERT INTO `{$table}` ({$columns}) VALUES ({$dataSql});\r\n"; 164 | } 165 | return $query; 166 | } 167 | 168 | /** 169 | * 写入文件 170 | * @param array $tables 171 | * @param array $ddl 172 | * @param array $data 173 | */ 174 | private function writeToFile($tables = array(), $ddl = array(), $data = array()) 175 | { 176 | $str = "/*\r\nMySQL Database Backup Tools\r\n"; 177 | $str .= "Server:{$this->config['host']}:{$this->config['port']}\r\n"; 178 | $str .= "Database:{$this->config['database']}\r\n"; 179 | $str .= "Data:" . date('Y-m-d H:i:s', time()) . "\r\n*/\r\n"; 180 | $str .= "SET FOREIGN_KEY_CHECKS=0;\r\n"; 181 | $i = 0; 182 | foreach ($tables as $table) { 183 | $str .= "-- ----------------------------\r\n"; 184 | $str .= "-- Table structure for {$table}\r\n"; 185 | $str .= "-- ----------------------------\r\n"; 186 | $str .= "DROP TABLE IF EXISTS `{$table}`;\r\n"; 187 | $str .= $ddl[$i] . "\r\n"; 188 | $str .= "-- ----------------------------\r\n"; 189 | $str .= "-- Records of {$table}\r\n"; 190 | $str .= "-- ----------------------------\r\n"; 191 | $str .= $data[$i] . "\r\n"; 192 | $i++; 193 | } 194 | //echo file_put_contents($this->config['target'], $str) ? '备份成功!花费时间' . (microtime(true) - $this->begin) . 'ms' : '备份失败!'; 195 | return $str; //Return string instead of write to files - bW 196 | } 197 | 198 | /** 199 | * 错误信息 200 | * @return mixed 201 | */ 202 | public function getError() 203 | { 204 | return $this->error; 205 | } 206 | 207 | public function restore($path = '') 208 | { 209 | if (!file_exists($path)) { 210 | $this->error('SQL文件不存在!'); 211 | return false; 212 | } else { 213 | $sql = $this->parseSQL($path); 214 | try { 215 | $this->handler->exec($sql); 216 | echo '还原成功!花费时间', (microtime(true) - $this->begin) . 'ms'; 217 | } catch (PDOException $e) { 218 | $this->error = $e->getMessage(); 219 | return false; 220 | } 221 | } 222 | } 223 | 224 | /** 225 | * 解析SQL文件为SQL语句数组 226 | * @param string $path 227 | * @return array|mixed|string 228 | */ 229 | private function parseSQL($path = '') 230 | { 231 | $sql = file_get_contents($path); 232 | $sql = explode("\r\n", $sql); 233 | //先消除--注释 234 | $sql = array_filter($sql, function ($data) { 235 | if (empty($data) || preg_match('/^--.*/', $data)) { 236 | return false; 237 | } else { 238 | return true; 239 | } 240 | }); 241 | $sql = implode('', $sql); 242 | //删除/**/注释 243 | $sql = preg_replace('/\/\*.*\*\//', '', $sql); 244 | return $sql; 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /inc/script/qiniu/QiniuClient.php: -------------------------------------------------------------------------------- 1 | accessKey = $accessKey; 20 | $this -> secretKey = $secretKey; 21 | $this -> err = false; 22 | } 23 | 24 | public function uploadFile($filePath, $bucket, $key = null) 25 | { 26 | if ($key) $uploadToken = $this -> uploadToken(array('scope' => $bucket . ':' . $key)); 27 | else $uploadToken = $this -> uploadToken(array('scope' => $bucket)); 28 | $data = array(); 29 | $data['file'] = "@$filePath"; 30 | $data['token'] = $uploadToken; 31 | if ($key) $data['key'] = $key; 32 | 33 | $ch = curl_init(); 34 | curl_setopt($ch, CURLOPT_URL, self :: UP_HOST); 35 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 36 | curl_setopt($ch, CURLOPT_POST, true); 37 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 38 | $result = curl_exec($ch); 39 | $this -> err = curl_error($ch); 40 | curl_close($ch); 41 | return $result; 42 | } 43 | 44 | public function upload($content, $bucket, $key = null) 45 | { 46 | $filePath = tempnam(sys_get_temp_dir(), 'UPLOAD'); 47 | file_put_contents($filePath, $content); 48 | $result = $this -> uploadFile($filePath, $bucket, $key); 49 | unlink($filePath); 50 | return $result; 51 | } 52 | 53 | public function uploadRemote($url, $bucket, $key = null) 54 | { 55 | $filePath = tempnam(sys_get_temp_dir(), 'UPLOAD'); 56 | copy($url, $filePath); 57 | $result = $this -> uploadFile($filePath, $bucket, $key); 58 | unlink($filePath); 59 | return $result; 60 | } 61 | 62 | public function stat($bucket, $key) 63 | { 64 | $encodedEntryURI = self :: urlsafe_base64_encode("{$bucket}:{$key}"); 65 | $url = "/stat/{$encodedEntryURI}"; 66 | return $this -> fileHandle($url); 67 | } 68 | 69 | public function move($bucket, $key, $bucket2, $key2 = false) 70 | { 71 | if (!$key2) { 72 | $key2 = $bucket2; 73 | $bucket2 = $bucket; 74 | } 75 | $encodedEntryURISrc = self :: urlsafe_base64_encode("{$bucket}:{$key}"); 76 | $encodedEntryURIDest = self :: urlsafe_base64_encode("{$bucket2}:{$key2}"); 77 | $url = "/move/{$encodedEntryURISrc}/{$encodedEntryURIDest}"; 78 | return $this -> fileHandle($url); 79 | } 80 | 81 | public function copy($bucket, $key, $bucket2, $key2 = false) 82 | { 83 | if (!$key2) { 84 | $key2 = $bucket2; 85 | $bucket2 = $bucket; 86 | } 87 | $encodedEntryURISrc = self :: urlsafe_base64_encode("{$bucket}:{$key}"); 88 | $encodedEntryURIDest = self :: urlsafe_base64_encode("{$bucket2}:{$key2}"); 89 | $url = "/copy/{$encodedEntryURISrc}/{$encodedEntryURIDest}"; 90 | return $this -> fileHandle($url); 91 | } 92 | 93 | public function delete($bucket, $key) 94 | { 95 | $encodedEntryURI = self :: urlsafe_base64_encode("{$bucket}:{$key}"); 96 | $url = "/delete/{$encodedEntryURI}"; 97 | return $this -> fileHandle($url); 98 | } 99 | // $operator = stat|move|copy|delete 100 | // $client->batch('stat',array('square:test/test5.txt','square:test/test13.png')); 101 | public function batch($operator, $files) 102 | { 103 | $data = ''; 104 | foreach ($files as $file) { 105 | if (!is_array($file)) { 106 | $encodedEntryURI = self :: urlsafe_base64_encode($file); 107 | $data .= "op=/{$operator}/{$encodedEntryURI}&"; 108 | } else { 109 | $encodedEntryURI = self :: urlsafe_base64_encode($file[0]); 110 | $encodedEntryURIDest = self :: urlsafe_base64_encode($file[1]); 111 | $data .= "op=/{$operator}/{$encodedEntryURI}/{$encodedEntryURIDest}&"; 112 | } 113 | } 114 | return $this -> fileHandle('/batch', $data); 115 | } 116 | 117 | public function listFiles($bucket, $limit = '', $prefix = '', $marker = '') 118 | { 119 | $params = array_filter(compact('bucket', 'limit', 'prefix', 'marker')); 120 | $url = self :: RSF_HOST . '/list?' . http_build_query($params); 121 | return $this -> fileHandle($url); 122 | } 123 | 124 | public function fileHandle($url, $data = array()) 125 | { 126 | if (strpos($url, 'http://') !== 0) $url = self :: RS_HOST . $url; 127 | 128 | if (is_array($data)) $accessToken = $this -> accessToken($url); 129 | else $accessToken = $this -> accessToken($url, $data); 130 | 131 | $ch = curl_init(); 132 | curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: QBox ' . $accessToken, 133 | )); 134 | 135 | curl_setopt($ch, CURLOPT_URL, $url); 136 | curl_setopt($ch, CURLOPT_POST, true); 137 | // If $data is an array, the Content-Type header will be set to multipart/form-data 138 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 139 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 140 | $result = curl_exec($ch); 141 | $info = curl_getinfo($ch); 142 | curl_close($ch); 143 | 144 | if ($info['http_code'] >= 300) 145 | { // throw new Exception($info['http_code'].': '.$result); 146 | $this -> err = $info['http_code'] . ': ' . $result; 147 | $result = false; 148 | } 149 | if ($info['content_type'] == 'application/json') 150 | return json_decode($result, true); 151 | 152 | return $result; 153 | } 154 | 155 | public function uploadToken($flags) 156 | { 157 | if (!isset($flags['deadline'])) 158 | $flags['deadline'] = 3600 + time(); 159 | $encodedFlags = self :: urlsafe_base64_encode(json_encode($flags)); 160 | $sign = hash_hmac('sha1', $encodedFlags, $this -> secretKey, true); 161 | $encodedSign = self :: urlsafe_base64_encode($sign); 162 | $token = $this -> accessKey . ':' . $encodedSign . ':' . $encodedFlags; 163 | return $token; 164 | } 165 | 166 | public function accessToken($url, $body = false) 167 | { 168 | $parsed_url = parse_url($url); 169 | $path = $parsed_url['path']; 170 | $access = $path; 171 | if (isset($parsed_url['query'])) { 172 | $access .= "?" . $parsed_url['query']; 173 | } 174 | $access .= "\n"; 175 | if ($body) $access .= $body; 176 | $digest = hash_hmac('sha1', $access, $this -> secretKey, true); 177 | return $this -> accessKey . ':' . self :: urlsafe_base64_encode($digest); 178 | } 179 | 180 | public static function urlsafe_base64_encode($str) 181 | { 182 | $find = array("+", "/"); 183 | $replace = array("-", "_"); 184 | return str_replace($find, $replace, base64_encode($str)); 185 | } 186 | 187 | public static function urlsafe_base64_decode($str) 188 | { 189 | $find = array("-", "_"); 190 | $replace = array("+", "/"); 191 | return base64_decode(str_replace($find, $replace, $str)); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /inc/script/qiniu/README.md: -------------------------------------------------------------------------------- 1 | 七牛云存储PHP SDK(非官方,更好用) 2 | ============================== 3 | 4 | 初始化 5 | ----- 6 | 7 | ``` 8 | $client = new QiniuClient($accessKey,$secretKey); 9 | ``` 10 | 11 | 上传 12 | ---- 13 | 14 | 15 | ###上传文件 16 | 17 | ``` 18 | $client->uploadFile('/local/files/file.txt','test_bucket_name','test/file.txt'); 19 | ``` 20 | ###上传内容作为文件存储 21 | 22 | ``` 23 | $client->upload('我是文件内容','test_bucket_name','test/file2.txt'); 24 | ``` 25 | ###存储远程文件 26 | 27 | ``` 28 | $client->uploadRemote('http://www.baidu.com/img/bdlogo.gif','test_bucket_name','test/file3.gif'); 29 | ``` 30 | 31 | ###上传凭证 - uploadToken (自制表单上传时需要) 32 | ``` 33 | $flag = array('scope'=>'test_bucket_name'); 34 | $client->uploadToken($flags); 35 | ``` 36 | $flags更多选项参加[文档](http://docs.qiniu.com/api/v6/put.html#uploadToken) 37 | 38 | 39 | 40 | 文件管理 - 单文件操作 41 | ------------------ 42 | 43 | 44 | ###查看 45 | 46 | ``` 47 | $client->stat('test_bucket_name','test/file3.gif'); 48 | ``` 49 | ###复制 50 | 51 | 复制到原bucket 52 | 53 | ``` 54 | $client->copy('test_bucket_name','test/file3.gif','test/file4.gif'); 55 | ``` 56 | 复制到其它bucket 57 | 58 | ``` 59 | $client->copy('test_bucket_name','test/file3.gif','another_bucket_name','test/file4.gif'); 60 | ``` 61 | ###移动 62 | 在原bucket中移动 63 | 64 | ``` 65 | $client->move('test_bucket_name','test/file4.gif','test/file5.gif'); 66 | ``` 67 | 移动到其它bucket 68 | 69 | ``` 70 | $client->move('test_bucket_name','test/file3.gif','another_bucket_name','test/file5.gif'); 71 | ``` 72 | 73 | ###删除 74 | 75 | ``` 76 | $client->delete('test_bucket_name','test/file.txt'); 77 | ``` 78 | 79 | 文件管理 - 批量操作 80 | ---------------- 81 | 82 | ``` 83 | $client->batch($operator,$files); 84 | ``` 85 | ###批量查看文件 86 | ``` 87 | $client->batch('stat',array('bucket_name:test/test5.txt','bucket_name:test/test6.png')); 88 | ``` 89 | ###批量复制文件 90 | test/test5.txt复制到bucket_name:test/test6.txt 91 | 92 | test/test6.txt复制到bucket_name:test/test7.txt 93 | 94 | ``` 95 | $client->batch('copy',array( 96 | array('bucket_name:test/test5.txt','bucket_name:test/test6.txt'), 97 | array('bucket_name:test/test7.txt','bucket_name:test/test8.txt') 98 | )); 99 | ``` 100 | ###批量移动文件 101 | 同复制 102 | 103 | ``` 104 | $client->batch('move',array( 105 | array('bucket_name:test/test5.txt','bucket_name:test/test6.txt'), 106 | array('bucket_name:test/test7.txt','bucket_name:test/test8.txt') 107 | )); 108 | ``` 109 | ###批量删除文件 110 | ``` 111 | $client->batch('delete',array('bucket_name:test/test5.txt','bucket_name:test/test6.png')); 112 | ``` 113 | 114 | ##列出文件 115 | 详见[官方文档](http://docs.qiniu.com/api/v6/file-handle.html#list) 116 | 117 | ``` 118 | $client->listFiles($bucket,$limit=10,$prefix='test',$marker=''); 119 | ``` 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /inc/script/rnd-avatar/avatar.js: -------------------------------------------------------------------------------- 1 | // Avatar Generator in jQuery 2 | // Written by bo-blog for Bo-Blog Wind Project 3 | // Material Design color palette from https://github.com/lincanbin/Material-Design-Avatars, Thanks 4 | 5 | 6 | function genAvatar (size, char) 7 | { 8 | var initialString = char.toString().charAt(0).toUpperCase(); 9 | var fontSize = Math.floor (size*0.7); 10 | var colors = randColor (char.toString()); 11 | var returnMsg = "" + initialString + ""; 12 | return returnMsg; 13 | } 14 | 15 | function randColor (char) { 16 | var uStr = char.charCodeAt (0); 17 | var colorSet = new Array ("255, 235, 238", "255, 205, 210", "239, 154, 154","229, 115, 115","239, 83, 80","244, 67, 54","229, 57, 53","211, 47, 47","198, 40, 40","183, 28, 28","255, 138, 128","255, 82, 82","255, 23, 68","213, 0, 0", "252, 228, 236","248, 187, 208","244, 143, 177","240, 98, 146","236, 64, 122","233, 30, 99","216, 27, 96","194, 24, 91","173, 20, 87","136, 14, 79","255, 128, 171","255, 64, 129","245, 0, 87","197, 17, 98","243, 229, 245","225, 190, 231","206, 147, 216","186, 104, 200","171, 71, 188","156, 39, 176","142, 36, 170","123, 31, 162","106, 27, 154","74, 20, 140","234, 128, 252","224, 64, 251","213, 0, 249","170, 0, 255","237, 231, 246","209, 196, 233","179, 157, 219","149, 117, 205","126, 87, 194","103, 58, 183","94, 53, 177","81, 45, 168","69, 39, 160","49, 27, 146","179, 136, 255","124, 77, 255","101, 31, 255","98, 0, 234","232, 234, 246","197, 202, 233","159, 168, 218","121, 134, 203","92, 107, 192","63, 81, 181","57, 73, 171","48, 63, 159","40, 53, 147","26, 35, 126","140, 158, 255","83, 109, 254","61, 90, 254","48, 79, 254","227, 242, 253","187, 222, 251","144, 202, 249","100, 181, 246","66, 165, 245","33, 150, 243","30, 136, 229","25, 118, 210","21, 101, 192","13, 71, 161","130, 177, 255","68, 138, 255","41, 121, 255","41, 98, 255","225, 245, 254","179, 229, 252","129, 212, 250","79, 195, 247","41, 182, 252","3, 169, 244","3, 155, 229","2, 136, 209","2, 119, 189","1, 87, 155","128, 216, 255","64, 196, 255","0, 176, 255","0, 145, 234","224, 247, 250","178, 235, 242","128, 222, 234","77, 208, 225","38, 198, 218","0, 188, 212","0, 172, 193","0, 151, 167","0, 131, 143","0, 96, 100","132, 255, 255","24, 255, 255","0, 229, 255","0, 184, 212","224, 242, 241","178, 223, 219","128, 203, 196","77, 182, 172","38, 166, 154","0, 150, 136","0, 137, 123","0, 121, 107","0, 105, 92","0, 77, 64","167, 255, 235","100, 255, 218","29, 233, 182","0, 191, 165","232, 245, 233","200, 230, 201","165, 214, 167","129, 199, 132","102, 187, 106","76, 175, 80","67, 160, 71","56, 142, 60","46, 125, 50","27, 94, 32","185, 246, 202","105, 240, 174","0, 230, 118","0, 200, 83","241, 248, 233","220, 237, 200","197, 225, 165","174, 213, 129","156, 204, 101","139, 195, 74","124, 179, 66","104, 159, 56","85, 139, 47","51, 105, 30","204, 255, 144","178, 255, 89","118, 255, 3","100, 221, 23","249, 251, 231","240, 244, 195","230, 238, 156","220, 231, 117","212, 225, 87","205, 220, 57","192, 202, 51","164, 180, 43","158, 157, 36","130, 119, 23","244, 255, 129","238, 255, 65","198, 255, 0","174, 234, 0","255, 253, 231","255, 249, 196","255, 245, 144","255, 241, 118","255, 238, 88","255, 235, 59","253, 216, 53","251, 192, 45","249, 168, 37","245, 127, 23","255, 255, 130","255, 255, 0","255, 234, 0","255, 214, 0","255, 248, 225","255, 236, 179","255, 224, 130","255, 213, 79","255, 202, 40","255, 193, 7","255, 179, 0","255, 160, 0","255, 143, 0","255, 111, 0","255, 229, 127","255, 215, 64","255, 196, 0","255, 171, 0","255, 243, 224","255, 224, 178","255, 204, 128","255, 183, 77","255, 167, 38","255, 152, 0","251, 140, 0","245, 124, 0","239, 108, 0","230, 81, 0","255, 209, 128","255, 171, 64","255, 145, 0","255, 109, 0","251, 233, 167","255, 204, 188","255, 171, 145","255, 138, 101","255, 112, 67","255, 87, 34","244, 81, 30","230, 74, 25","216, 67, 21","191, 54, 12","255, 158, 128","255, 110, 64","255, 61, 0","221, 38, 0","239, 235, 233","215, 204, 200","188, 170, 164","161, 136, 127","141, 110, 99","121, 85, 72","109, 76, 65","93, 64, 55","78, 52, 46","62, 39, 35","250, 250, 250","245, 245, 245","238, 238, 238","224, 224, 224","189, 189, 189","158, 158, 158","117, 117, 117","97, 97, 97","66, 66, 66","33, 33, 33","0, 0, 0","255, 255, 255","236, 239, 241","207, 216, 220","176, 187, 197","144, 164, 174","120, 144, 156","96, 125, 139","84, 110, 122","69, 90, 100","55, 71, 79","38, 50, 56"); 18 | var key = uStr % (colorSet.length); 19 | var codes = colorSet[key].split(', '); 20 | if (codes[0]>200 && codes[1]>200 && codes[2]>200) { 21 | var fontColor = "#000"; 22 | } 23 | else { 24 | var fontColor = "#fff" 25 | } 26 | var returnColor = new Array ("rgb("+colorSet[key]+")", fontColor); 27 | return returnColor; 28 | } 29 | -------------------------------------------------------------------------------- /inc/script/smtp/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Snipworks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /inc/script/timers/jquery.timers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery.timers - Timer abstractions for jQuery 3 | * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com) 4 | * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/). 5 | * Date: 2009/02/08 6 | * 7 | * @author Blair Mitchelmore 8 | * @version 1.1.2 9 | * 10 | **/ 11 | 12 | jQuery.fn.extend({ 13 | everyTime: function(interval, label, fn, times, belay) { 14 | return this.each(function() { 15 | jQuery.timer.add(this, interval, label, fn, times, belay); 16 | }); 17 | }, 18 | oneTime: function(interval, label, fn) { 19 | return this.each(function() { 20 | jQuery.timer.add(this, interval, label, fn, 1); 21 | }); 22 | }, 23 | stopTime: function(label, fn) { 24 | return this.each(function() { 25 | jQuery.timer.remove(this, label, fn); 26 | }); 27 | } 28 | }); 29 | 30 | jQuery.event.special 31 | 32 | jQuery.extend({ 33 | timer: { 34 | global: [], 35 | guid: 1, 36 | dataKey: "jQuery.timer", 37 | regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/, 38 | powers: { 39 | // Yeah this is major overkill... 40 | 'ms': 1, 41 | 'cs': 10, 42 | 'ds': 100, 43 | 's': 1000, 44 | 'das': 10000, 45 | 'hs': 100000, 46 | 'ks': 1000000 47 | }, 48 | timeParse: function(value) { 49 | if (value == undefined || value == null) 50 | return null; 51 | var result = this.regex.exec(jQuery.trim(value.toString())); 52 | if (result[2]) { 53 | var num = parseFloat(result[1]); 54 | var mult = this.powers[result[2]] || 1; 55 | return num * mult; 56 | } else { 57 | return value; 58 | } 59 | }, 60 | add: function(element, interval, label, fn, times, belay) { 61 | var counter = 0; 62 | 63 | if (jQuery.isFunction(label)) { 64 | if (!times) 65 | times = fn; 66 | fn = label; 67 | label = interval; 68 | } 69 | 70 | interval = jQuery.timer.timeParse(interval); 71 | 72 | if (typeof interval != 'number' || isNaN(interval) || interval <= 0) 73 | return; 74 | 75 | if (times && times.constructor != Number) { 76 | belay = !!times; 77 | times = 0; 78 | } 79 | 80 | times = times || 0; 81 | belay = belay || false; 82 | 83 | var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {}); 84 | 85 | if (!timers[label]) 86 | timers[label] = {}; 87 | 88 | fn.timerID = fn.timerID || this.guid++; 89 | 90 | var handler = function() { 91 | if (belay && this.inProgress) 92 | return; 93 | this.inProgress = true; 94 | if ((++counter > times && times !== 0) || fn.call(element, counter) === false) 95 | jQuery.timer.remove(element, label, fn); 96 | this.inProgress = false; 97 | }; 98 | 99 | handler.timerID = fn.timerID; 100 | 101 | if (!timers[label][fn.timerID]) 102 | timers[label][fn.timerID] = window.setInterval(handler,interval); 103 | 104 | this.global.push( element ); 105 | 106 | }, 107 | remove: function(element, label, fn) { 108 | var timers = jQuery.data(element, this.dataKey), ret; 109 | 110 | if ( timers ) { 111 | 112 | if (!label) { 113 | for ( label in timers ) 114 | this.remove(element, label, fn); 115 | } else if ( timers[label] ) { 116 | if ( fn ) { 117 | if ( fn.timerID ) { 118 | window.clearInterval(timers[label][fn.timerID]); 119 | delete timers[label][fn.timerID]; 120 | } 121 | } else { 122 | for ( var fn in timers[label] ) { 123 | window.clearInterval(timers[label][fn]); 124 | delete timers[label][fn]; 125 | } 126 | } 127 | 128 | for ( ret in timers[label] ) break; 129 | if ( !ret ) { 130 | ret = null; 131 | delete timers[label]; 132 | } 133 | } 134 | 135 | for ( ret in timers ) break; 136 | if ( !ret ) 137 | jQuery.removeData(element, this.dataKey); 138 | } 139 | } 140 | } 141 | }); 142 | 143 | jQuery(window).bind("unload", function() { 144 | jQuery.each(jQuery.timer.global, function(index, item) { 145 | jQuery.timer.remove(item); 146 | }); 147 | }); -------------------------------------------------------------------------------- /inc/script/urlrewrite/apache.txt: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteBase YOUR_PATH_HERE 3 | 4 | RewriteCond %{REQUEST_FILENAME} -f [OR] 5 | RewriteCond %{REQUEST_FILENAME} -d 6 | RewriteRule ^.*$ - [L] 7 | 8 | RewriteRule ^index/([0-9]+)/?$ index.php/$1/ [QSA,L] 9 | RewriteRule ^category/([^/]+)/([0-9]+)/?$ category.php/$1/$2/ [QSA,L] 10 | RewriteRule ^category/([^/]+)/?$ category.php/$1/ [QSA,L] 11 | RewriteRule ^post/([^/]+)/?$ read.php/$1/ [QSA,L] 12 | RewriteRule ^tag/([^/]+)/([0-9]+)/?$ tag.php/$1/$2/ [QSA,L] 13 | RewriteRule ^tag/([^/]+)/?$ tag.php/$1/ [QSA,L] 14 | RewriteRule ^page/([^/]+)/?$ page.php/$1/ [QSA,L] -------------------------------------------------------------------------------- /inc/script/urlrewrite/nginx.txt: -------------------------------------------------------------------------------- 1 | if (!-e $request_filename) 2 | { 3 | rewrite ^/YOUR_PATH_HERE/index/([0-9]+)?/$ /YOUR_PATH_HERE/index.php?go=/$1 last; 4 | rewrite ^/YOUR_PATH_HERE/post/(.+)?/$ /YOUR_PATH_HERE/read.php?go=/$1 last; 5 | rewrite ^/YOUR_PATH_HERE/category/(.+)?/$ /YOUR_PATH_HERE/category.php?go=/$1 last; 6 | rewrite ^/YOUR_PATH_HERE/category/(.+)/([0-9]+)?/$ /YOUR_PATH_HERE/category.php?go=/$1/$2 last; 7 | rewrite ^/YOUR_PATH_HERE/tag/(.+)?/$ /YOUR_PATH_HERE/tag.php?go=/$1 last; 8 | rewrite ^/YOUR_PATH_HERE/tag/(.+)/([0-9]+)?/$ /YOUR_PATH_HERE/tag.php?go=/$1/$2 last; 9 | rewrite ^/YOUR_PATH_HERE/send.php/(.+)$ /YOUR_PATH_HERE/send.php?go=/$1 last; 10 | rewrite ^/YOUR_PATH_HERE/admin.php/(.+)$ /YOUR_PATH_HERE/admin.php?go=/$1 last; 11 | rewrite ^/YOUR_PATH_HERE/page/(.+)?/$ /YOUR_PATH_HERE/page.php?go=/$1 last; 12 | } 13 | -------------------------------------------------------------------------------- /inc/template/cd-review.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 专辑点评 3 | 4 | 5 | 6 | 7 | 8 | 33 | 34 | 41 | 42 |
    封套:
    专辑:
    表演者:
    流派:
    发行时间:
    评分:
    曲目:
    43 | 请返回正文区域输入具体乐评。
    44 | 插入 45 | 取消 46 |
    47 | 48 | CD Review 49 | 50 | 51 | 52 | 53 | 54 | 77 | 78 | 85 | 86 |
    Cover:
    Album:
    Artist:
    Genre:
    Date:
    Score:
    Tracks:
    87 | Return to the main text area for detailed review.
    88 | Insert 89 | Cancel 90 |
    91 | 92 | 專輯點評 93 | 94 | 95 | 96 | 97 | 98 | 123 | 124 | 131 | 132 |
    封套:
    專輯:
    表演者:
    流派:
    發行時間:
    評分:
    曲目:
    133 | 請返回正文區域輸入具體樂評。
    134 | 插入 135 | 取消 136 |
    137 | -------------------------------------------------------------------------------- /inc/template/film-review.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 影评 3 | 4 | 5 | 6 | 7 | 8 | 9 | 31 | 32 | 33 | 34 | 41 | 42 |
    海报:
    名称:
    导演:
    主演:
    类型:
    上映时间:
    片长:
    IMDB链接:
    评分:
    剧情简介:
    43 | 请返回正文区域输入具体影评。
    44 | 插入 45 | 取消 46 |
    47 | 48 | Film Review 49 | 50 | 51 | 52 | 53 | 54 | 55 | 77 | 78 | 79 | 80 | 87 | 88 |
    Poster:
    Title:
    Director:
    Stars:
    Type:
    On-air date:
    Duration:
    IMDB Link:
    Score:
    Intro:
    89 | Return to the main text area for detailed review.
    90 | Insert 91 | Cancel 92 |
    93 | 94 | 影評 95 | 96 | 97 | 98 | 99 | 100 | 101 | 123 | 124 | 125 | 126 | 133 | 134 |
    海報:
    名稱:
    導演:
    主演:
    類型:
    上映時間:
    片長:
    IMDB連結:
    評分:
    劇情簡介:
    135 | 請返回正文區域輸入具體影評。
    136 | 插入 137 | 取消 138 | 139 | 140 | -------------------------------------------------------------------------------- /inc/template/photo-album.tpl.php: -------------------------------------------------------------------------------- 1 | 2 | 相册 3 | 4 | 5 | 8 | 9 | 12 | 13 | 16 | 17 |
    图片1
    6 | 配文:
    7 |
    图片2
    10 | 配文:
    11 |
    图片3
    14 | 配文:
    15 |
    18 | 多次使用本模板以插入更多图片。 19 | 插入 20 | 取消 21 |
    22 | 23 | Photo Album 24 | 25 | 26 | 29 | 30 | 33 | 34 | 37 | 38 |
    Pic 1
    27 | Description:
    28 |
    Pic 2
    31 | Description:
    32 |
    Pic 3
    35 | Description:
    36 |
    39 | Use this template several times to insert more pictures. 40 | Insert 41 | Cancel 42 |
    43 | 44 | 相冊 45 | 46 | 47 | 50 | 51 | 54 | 55 | 58 | 59 |
    圖片1
    48 | 配文:
    49 |
    圖片2
    52 | 配文:
    53 |
    圖片3
    56 | 配文:
    57 |
    60 | 多次使用本範本以插入更多圖片。 61 | 插入 62 | 取消 63 | 64 | 65 | -------------------------------------------------------------------------------- /inc/zip.inc.php: -------------------------------------------------------------------------------- 1 | $filePath, 'content' => $fileUnzipContent); 31 | if ($writeNow) { 32 | if ($overwrite || !file_exists ($filePath)) { 33 | if (!is_dir (dirname ($filePath))) { 34 | @mkdir (dirname ($filePath), 0777, true); 35 | } 36 | @file_put_contents ($filePath, $fileUnzipContent); 37 | @chmod ($filePath, 0777); 38 | } 39 | } 40 | } 41 | return $output; 42 | } 43 | 44 | public static function zipWrite ($fileNames, $zipFilePath = false) { 45 | $output = array (); 46 | foreach ($fileNames as $filePath) { 47 | $output[] = $filePath.'/#ZIP#/'.gzcompress (@file_get_contents ($filePath)); 48 | } 49 | $outputContent = @implode ('/#FILE#/', $output); 50 | if ($zipFilePath) { 51 | @file_put_contents ($zipFilePath, $outputContent); 52 | } 53 | return $outputContent; 54 | } 55 | 56 | public static function zipFolder ($folderPath, $zipFilePath = false, $addition = false) { 57 | if (!is_dir ($folderPath)) { 58 | return false; 59 | } 60 | if ($handle = opendir ($folderPath)) { 61 | while (false !== ($file = readdir ($handle))) { 62 | if (!is_dir ($folderPath . $file)) { 63 | self :: $folderFiles[] = $folderPath . $file; 64 | } 65 | elseif ($file != '.' && $file != '..') { 66 | self :: zipFolder ($folderPath . $file . '/'); 67 | } 68 | } 69 | } 70 | if (is_array ($addition)) { 71 | self :: $folderFiles = array_merge (self :: $folderFiles, $addition); 72 | } 73 | if ($zipFilePath) { 74 | return self :: zipWrite (self :: $folderFiles, $zipFilePath); 75 | } 76 | else { 77 | return self :: $folderFiles; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | loader ()); 26 | 27 | -------------------------------------------------------------------------------- /install/cli: -------------------------------------------------------------------------------- 1 | 'Your Blog', 50 | 'siteURL' => '{$argv[2]}', 51 | 'authorName' => 'admin', 52 | 'authorIntro' => 'Yet another bW blog.', 53 | 'siteKey' => '{$siteKey}', 54 | 'timeZone' => 'Asia/Shanghai', 55 | 'pageCache' => '1', 56 | 'commentOpt' => '1', 57 | 'comFrequency' => '10', 58 | 'comPerLoad' => '20', 59 | 'autoSave' => '0', 60 | 'siteTheme' => 'default', 61 | 'siteLang' => 'en', 62 | 'perPage' => '3', 63 | 'linkPrefixIndex' => 'index.php', 64 | 'linkPrefixCategory' => 'category.php', 65 | 'linkPrefixArticle' => 'read.php', 66 | 'linkPrefixTag' => 'tag.php', 67 | 'social-sina-weibo' => '', 68 | 'social-weixin' => '', 69 | 'social-twitter' => '', 70 | 'social-facebook' => '', 71 | 'social-douban' => '', 72 | 'social-instagram' => '', 73 | 'social-renren' => '', 74 | 'social-linkedin' => '', 75 | 'externalLinks' => 'http://bw.bo-blog.com=bW Home', 76 | );"; 77 | file_put_contents (P . 'conf/info.php', $infoConfContent); 78 | 79 | $servicesConfContent = " '', 82 | 'disqusID' => '', 83 | 'sinaAKey' => '', 84 | 'sinaSKey' => '', 85 | 'qiniuAKey' => '', 86 | 'qiniuSKey' => '', 87 | 'qiniuBucket' => '', 88 | 'qiniuSync' => '', 89 | 'qiniuUpload' => '0', 90 | 'qiniuDomain' => '', 91 | 'APIOpen' => '0', 92 | 'basicAPI' => 93 | array ( 94 | ), 95 | 'advancedAPI' => 96 | array ( 97 | ), 98 | 'aliyunAKey' => '', 99 | 'aliyunSKey' => '', 100 | 'aliyunBucket' => '', 101 | 'aliyunRegion' => '', 102 | );"; 103 | file_put_contents (P . 'conf/services.php', $servicesConfContent); 104 | 105 | include (P . 'inc/database.inc.php'); 106 | $db = new bwDatabase; 107 | $dbInitBind=array ( 108 | 'CREATE TABLE IF NOT EXISTS articles (aID VARCHAR(255) PRIMARY KEY NOT NULL , aTitle VARCHAR(255) NOT NULL , aCateURLName VARCHAR(255) NOT NULL , aTime DATETIME NOT NULL , aTags TEXT, aReads INTEGER NOT NULL DEFAULT 0, aContent TEXT, aCustom TEXT, aComments INTEGER DEFAULT 0)', 109 | 'CREATE TABLE IF NOT EXISTS cache (caID CHAR (32) PRIMARY KEY NOT NULL , caContent TEXT)', 110 | 'CREATE TABLE IF NOT EXISTS categories (aCateURLName VARCHAR (255) NOT NULL UNIQUE , aCateDispName TEXT NOT NULL , aCateCount INTEGER NOT NULL DEFAULT 0, aCateOrder INTEGER, aCateTheme VARCHAR (255))', 111 | 'CREATE TABLE IF NOT EXISTS extensions (extID VARCHAR (255) PRIMARY KEY NOT NULL , extDesc TEXT , extHooks TEXT NOT NULL , extActivate BOOL NOT NULL , extOrder INTEGER, extStorage TEXT , isWidget BOOL)', 112 | 'CREATE TABLE IF NOT EXISTS statistics (pageURL TEXT PRIMARY KEY NOT NULL UNIQUE , sNum INTEGER DEFAULT 0, lastView DATETIME)', 113 | 'CREATE TABLE IF NOT EXISTS tags (tValue VARCHAR (255) PRIMARY KEY NOT NULL UNIQUE , tList TEXT, tCount INTEGER NOT NULL DEFAULT 0)', 114 | 'CREATE TABLE IF NOT EXISTS comments (comID INTEGER PRIMARY KEY NOT NULL , comName TEXT, comTime DATETIME, comIP1 TEXT, comIP2 TEXT, comAvatar TEXT, comContent TEXT, comArtID TEXT, comParentID INTEGER, comSource TEXT, comURL TEXT, comBlock BOOL)', 115 | 'INSERT INTO articles VALUES (? ,?, ?, ?, ?, ?, ?, ?, ?)', 116 | 'INSERT INTO categories VALUES (? ,?, ?, ?, ?)', 117 | 'INSERT INTO extensions VALUES (? ,?, ?, ?, ?, ?, ?)', 118 | ); 119 | $dbInitBind2=array ( 120 | false, 121 | false, 122 | false, 123 | false, 124 | false, 125 | false, 126 | false, 127 | array ('hello-world', 'Hello, World!', 'default', date ('Y-m-d H:i:s'), null, 0, "Welcome to bW.\r\n\r\nThis is the first article that **bW** published on your behalf.\r\n\r\nbW allows you to [write in Markdown](http://daringfireball.net/projects/markdown/syntax).\r\n\r\nIf you need help, please do not hesitate to visit our [Official Website](http://bw.bo-blog.com)!", null, 0), 128 | array ('default', 'Uncategorized', 1, 1, null), 129 | array ('hello_world', "name='Hello, world'\r\nintro='Test extension.'\r\nauthor='bW'\r\nurl='http://bw.bo-blog.com'", 'header,footer,textParser,generateOutputDone', 0, 1, null, 0), 130 | ); 131 | 132 | foreach ($dbInitBind as $i=>$dbInit) { 133 | if ($dbInitBind2[$i]) { 134 | $db->dbExec ($dbInit, $dbInitBind2[$i]); 135 | } else { 136 | $db->dbExec ($dbInit); 137 | } 138 | } 139 | 140 | 141 | die ('Installation done. Visit ' . $argv[2] . ' and use tmp password ' . $tmpPass . ' to login.'); 142 | 143 | } 144 | 145 | else { 146 | printHelpMsg (); 147 | exit (); 148 | } 149 | 150 | function printHelpMsg () 151 | { 152 | print " 153 | (c) 2016 bW 154 | 155 | Usage: php /cli [help] [install ] [check] 156 | help: Display help message. 157 | install : Start silent setup process. Root of the site URL, like name.site/bw, must be given. 158 | check: Check the running enviornment. 159 | 160 | "; 161 | } 162 | 163 | function checkWritable () { 164 | $mustBeWritable = array ('conf', 'storage', 'extension', 'theme', 'update'); 165 | foreach ($mustBeWritable as $aFolder) { 166 | if (!is_dir (P . $aFolder . '/')) { 167 | die ('Error: '. P . $aFolder . '/ is not writable!'); 168 | return false; 169 | } elseif (!is_writable (P . $aFolder . '/')) { 170 | die ('Error: '. P . $aFolder . '/ is not writable!'); 171 | return false; 172 | } 173 | } 174 | return true; 175 | } 176 | 177 | function stopError ($msg) { 178 | die ($msg); 179 | } -------------------------------------------------------------------------------- /install/en.lang.php: -------------------------------------------------------------------------------- 1 | 'Welcome.', 4 | 'welcome.steps' => 'Only 3 steps to go.', 5 | 'welcome.chenv' => 'Check the environment.', 6 | 'welcome.basicinfo' => 'Provide basic information.', 7 | 'welcome.install' => 'Installation.', 8 | 'welcome.btn' => 'START', 9 | 'env.title' => 'Environment', 10 | 'env.wait' => 'Just a moment.', 11 | 'env.phpver' => 'PHP version', 12 | 'env.pdo' => 'PDO extension', 13 | 'env.zlib' => 'Zlib extension', 14 | 'env.curl' => 'cURL extension', 15 | 'env.sql' => 'PDO SQLite or PDO MySQL', 16 | 'env.writable' => 'Key folders writable', 17 | 'env.failure' => 'Environment check failed. bW cannot run with the current server configuration.', 18 | 'env.success' => 'Congratulations! Environment check passed.', 19 | 'env.btn' => 'CONTINUE', 20 | 'info.title' => 'Basic Info', 21 | 'info.sure' => 'Make sure all information is correct.', 22 | 'info.yourname' => 'Your name', 23 | 'info.yourpsw' => 'Your password', 24 | 'info.dbtype' => 'Click to switch database type.', 25 | 'info.dbname' => 'DB Name', 26 | 'info.dbaddr' => 'DB Address', 27 | 'info.dbuser' => 'DB User Name', 28 | 'info.dbpsw' => 'DB Password', 29 | 'info.btn' => 'CONTINUE', 30 | 'info.error' => 'Please input all necessary data.', 31 | 'install.title' => 'Installation', 32 | 'install.noclose' => 'Do not close the window.', 33 | 'install.writeconfig' => 'Write DB Config File', 34 | 'install.createtables' => 'Create tables', 35 | 'install.data' => 'Initialize data', 36 | 'install.btn' => 'ENTER SITE', 37 | 'data.sitename' => 'Your Blog', 38 | 'data.siteintro' => 'Yet another bW blog.', 39 | 'data.lang' => 'en', 40 | 'data.error' => 'Please check and make sure folder conf/ is writable.', 41 | 'data.success' => 'Congratulation! Installation succeeded.', 42 | 'data.title' => 'Hello, World!', 43 | 'data.content1' => "Welcome to bW.\r\n\r\nThis is the first article that **bW** published on your behalf.\r\n\r\nbW allows you to [write in Markdown](http://daringfireball.net/projects/markdown/syntax).\r\n\r\n", 44 | 'data.content2' => "\r\n\r\nIf you need help, please do not hesitate to visit our [Official Website](http://bw.bo-blog.com)!", 45 | 'data.cate' => 'Uncategorized', 46 | 'data.dberror' => 'Database error:', 47 | ); -------------------------------------------------------------------------------- /install/index.php: -------------------------------------------------------------------------------- 1 | = '5.3.0' ? 1 : 0; 23 | $debug=isset ($_REQUEST['debug']) ? 1 : 0; 24 | $ln='./' . basename ($_REQUEST['bwInstallLang']) . '.lang.php'; 25 | file_exists ($ln) ? include_once ($ln) : include_once ('./en.lang.php'); 26 | setcookie ('bwInstallLang', $_REQUEST['bwInstallLang']); 27 | 28 | print<< 30 | 31 | 32 | 33 | 34 | 35 | 36 | Welcome to bW 37 | 38 | 39 | 40 | 41 | 42 | 43 |
    44 |

    {$l['welcome.msg']}

    45 |

    {$l['welcome.steps']}

    46 |


    47 |

    48 |

      49 |
    • {$l['welcome.chenv']}
    • 50 |
    • {$l['welcome.basicinfo']}
    • 51 |
    • {$l['welcome.install']}
    • 52 |
    53 |

    54 |

    55 |

    {$l['welcome.btn']} 56 |

    57 |
    58 | 59 | 60 |
    61 |

    {$l['env.title']}

    62 |

    {$l['env.wait']}

    63 |


    64 |

    65 |

      66 |
    • {$l['env.phpver']} > 5.3.0
    • 67 |
    • {$l['env.pdo']}
    • 68 |
    • {$l['env.sql']}
    • 69 |
    • {$l['env.writable']}
    • 70 |

      (conf, storage, extension, theme, update) 71 |

      72 |
    73 |

    74 | 76 |

    77 |

    78 |

    79 |
    80 | 81 | 82 |
    83 |
    84 |

    {$l['info.title']}

    85 |

    {$l['info.sure']}

    86 |


    87 |

    88 |
    89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |

    96 |

    97 |
    {$l['info.btn']} 98 |

    99 |
    100 |
    101 | 102 |
    103 |

    {$l['install.title']}

    104 |

    {$l['install.noclose']}

    105 |


    106 |

    107 |

      108 |
    • {$l['install.writeconfig']}
    • 109 |
    • {$l['install.createtables']}
    • 110 |
    • {$l['install.data']}
    • 111 |
    112 |

    113 | 115 |

    116 |

    117 |

    118 |
    119 | 120 | 225 | 226 | 227 | eot; 228 | } 229 | 230 | function initiate () 231 | { 232 | 233 | print<< 235 | 236 | 237 | 238 | 239 | 240 | 241 | Welcome to bW 242 | 243 | 244 | 245 | 246 | 247 |
    248 |

    249 |

    250 |

    English   251 | 中文(简体)   252 | 中文(繁體)   253 |

    254 |
    255 | 260 | 261 | 262 | eot; 263 | } 264 | -------------------------------------------------------------------------------- /install/install.css: -------------------------------------------------------------------------------- 1 | /* css reset by Tantek Celik */ 2 | :link,:visited { text-decoration:none } 3 | ul { list-style:none } 4 | h1,h2,h3,h4,h5,h6,pre,code { font-size:1em; } 5 | ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input 6 | { margin:0; padding:0; font-weight:normal } 7 | a img,:link img,:visited img { border:none } 8 | address { font-style:normal } 9 | 10 | 11 | body { 12 | background: #FFF; 13 | font-family: "Lucida Sans Unicode", Helvetica, "Microsoft Yahei", "Microsoft JhengHei", STHei, "Meiryo UI"; 14 | height:100%; 15 | } 16 | html { 17 | height: 100%; 18 | } 19 | .layer { 20 | height: 100%; 21 | text-align: center; 22 | padding: 60px 0 60px 0; 23 | } 24 | #layer1 { 25 | background: #65CA00; 26 | color: #FFF; 27 | } 28 | #layer2 { 29 | background: #00698C; 30 | color: #FFF; 31 | } 32 | #layer3 { 33 | background: #444; 34 | color: #FFF; 35 | } 36 | #layer4 { 37 | background: #0080FF; 38 | color: #FFF; 39 | } 40 | p { 41 | margin-bottom: 20px; 42 | } 43 | .wL { 44 | font-size: 3em; 45 | } 46 | .wXM { 47 | font-size: 2em; 48 | } 49 | .wM { 50 | font-size: 1.2em; 51 | } 52 | .wS { 53 | font-size: 0.8em; 54 | } 55 | .wBox { 56 | border: 1px solid #EFEFEF; 57 | border-radius: 5px; 58 | padding: 6px; 59 | cursor: pointer; 60 | } 61 | .wBox:hover { 62 | background: #FFF; 63 | color: #333; 64 | } 65 | .wRed { 66 | color: #D93600; 67 | } 68 | .wGreen { 69 | color: #7AFF4D; 70 | } 71 | .inp { 72 | padding: 10px; 73 | background: #E8E8E8; 74 | color: #000; 75 | font-family: "Lucida Sans Unicode", Helvetica, "Microsoft Yahei", "Microsoft JhengHei", STHei, "Meiryo UI"; 76 | font-size: 16px; 77 | border: 1px solid #FFF; 78 | border-radius: 8px; 79 | margin-right: 20px; 80 | margin-bottom: 12px; 81 | } 82 | .inp:focus { 83 | box-shadow: 3px 3px 2px #111; 84 | } 85 | .inpL { 86 | width: 40%; 87 | height: 20px; 88 | } -------------------------------------------------------------------------------- /install/jquery.scrollTo.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler 3 | * Licensed under MIT 4 | * @author Ariel Flesler 5 | * @version 2.1.2 6 | */ 7 | ;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1 '欢迎', 4 | 'welcome.steps' => 'bW 是一款轻量级个人博客程序,
    旨在提供一个简单轻巧的写作工具。
    安装仅需三步。', 5 | 'welcome.chenv' => '检查环境', 6 | 'welcome.basicinfo' => '填写基本信息', 7 | 'welcome.install' => '安装', 8 | 'welcome.btn' => '开始', 9 | 'env.title' => '环境', 10 | 'env.wait' => '请稍候', 11 | 'env.phpver' => 'PHP 版本', 12 | 'env.pdo' => 'PDO 扩展库', 13 | 'env.zlib' => 'Zlib 扩展库', 14 | 'env.curl' => 'cURL 扩展库', 15 | 'env.sql' => 'PDO SQLite 或 PDO MySQL 支持', 16 | 'env.writable' => '关键文件夹写入权限', 17 | 'env.failure' => '环境检查失败。bW 不能运行在当前服务器上。', 18 | 'env.success' => '恭喜!环境检查通过。', 19 | 'env.btn' => '下一步', 20 | 'info.title' => '基本信息', 21 | 'info.sure' => '请确保填写无误', 22 | 'info.yourname' => '您的名字', 23 | 'info.yourpsw' => '您的密码', 24 | 'info.dbtype' => '点击切换数据库类型', 25 | 'info.dbname' => '数据库名', 26 | 'info.dbaddr' => '数据库地址', 27 | 'info.dbuser' => '数据库用户名', 28 | 'info.dbpsw' => '数据库密码', 29 | 'info.btn' => '下一步', 30 | 'info.error' => '请填写所有项目。', 31 | 'install.title' => '安装', 32 | 'install.noclose' => '请勿关闭窗口', 33 | 'install.writeconfig' => '创建数据库配置文件', 34 | 'install.createtables' => '创建数据表', 35 | 'install.data' => '写入初始化数据', 36 | 'install.btn' => '进入网站', 37 | 'data.sitename' => '我的博客', 38 | 'data.siteintro' => '使用bW创建', 39 | 'data.lang' => 'zh-cn', 40 | 'data.error' => '请检查 conf/ 文件夹的写入权限。', 41 | 'data.success' => '恭喜!安装成功了。', 42 | 'data.title' => '你好,世界!', 43 | 'data.content1' => "欢迎使用 bW。\r\n\r\n这是由 **bW** 以你的名义自动发布的一篇日志。\r\n\r\nbW 支持[用 Markdown 写作](http://daringfireball.net/projects/markdown/syntax)。\r\n\r\n", 44 | 'data.content2' => "\r\n\r\n如果你需要帮助,请随时访问我们的[官方网站](http://bw.bo-blog.com)!", 45 | 'data.cate' => '默认分类', 46 | 'data.dberror' => '数据库错误:', 47 | ); -------------------------------------------------------------------------------- /install/zh-tw.lang.php: -------------------------------------------------------------------------------- 1 | '歡迎', 4 | 'welcome.steps' => 'bW 是一款羽量級個人博客程式,
    旨在提供一個簡單輕巧的寫作工具。
    安裝僅需三步。', 5 | 'welcome.chenv' => '檢查環境', 6 | 'welcome.basicinfo' => '填寫基本資訊', 7 | 'welcome.install' => '安裝', 8 | 'welcome.btn' => '開始', 9 | 'env.title' => '環境', 10 | 'env.wait' => '請稍候', 11 | 'env.phpver' => 'PHP 版本', 12 | 'env.pdo' => 'PDO 擴展庫', 13 | 'env.zlib' => 'Zlib 擴展庫', 14 | 'env.curl' => 'cURL 擴展庫', 15 | 'env.sql' => 'PDO SQLite 或 PDO MySQL 支持', 16 | 'env.writable' => '關鍵文件夾寫入權限', 17 | 'env.failure' => '環境檢查失敗。bW 不能運行在當前伺服器上。', 18 | 'env.success' => '恭喜!環境檢查通過。', 19 | 'env.btn' => '下一步', 20 | 'info.title' => '基本資訊', 21 | 'info.sure' => '請確保填寫無誤', 22 | 'info.yourname' => '您的名字', 23 | 'info.yourpsw' => '您的密碼', 24 | 'info.dbtype' => '點擊切換資料庫類型', 25 | 'info.dbname' => '資料庫名', 26 | 'info.dbaddr' => '資料庫位址', 27 | 'info.dbuser' => '資料庫用戶名', 28 | 'info.dbpsw' => '資料庫密碼', 29 | 'info.btn' => '下一步', 30 | 'info.error' => '請填寫所有項目。', 31 | 'install.title' => '安裝', 32 | 'install.noclose' => '請勿關閉視窗', 33 | 'install.writeconfig' => '創建資料庫設定檔', 34 | 'install.createtables' => '創建資料表', 35 | 'install.data' => '寫入初始化資料', 36 | 'install.btn' => '進入網站', 37 | 'data.sitename' => '我的博客', 38 | 'data.siteintro' => '使用bW創建', 39 | 'data.lang' => 'zh-tw', 40 | 'data.error' => '請檢查 conf/ 資料夾的寫入許可。', 41 | 'data.success' => '恭喜!安裝成功了。', 42 | 'data.title' => '你好,世界!', 43 | 'data.content1' => "歡迎使用 bW。\r\n\r\n這是由 **bW** 以你的名義自動發佈的一篇日誌。\r\n\r\nbW 支持[用 Markdown 寫作](http://daringfireball.net/projects/markdown/syntax)。\r\n\r\n", 44 | 'data.content2' => "\r\n\r\n如果你需要幫助,請隨時訪問我們的[官方網站](http://bw.bo-blog.com)!", 45 | 'data.cate' => '默認分類', 46 | 'data.dberror' => '資料庫錯誤:', 47 | ); 48 | -------------------------------------------------------------------------------- /lang/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mode/api.mod.php: -------------------------------------------------------------------------------- 1 | auth (bw :: $conf['basicAPI'], bw :: $conf['advancedAPI']); 25 | $api -> go ($canonical -> currentArgs['mainAPI'], $canonical -> currentArgs['subAPI'], $canonical -> currentArgs['pref']); -------------------------------------------------------------------------------- /mode/article.mod.php: -------------------------------------------------------------------------------- 1 | fetchArticle ($canonical -> currentArgs['aID']); 13 | 14 | $view = new bwView; 15 | $view -> setPageTitle ($article -> articleList[$canonical -> currentArgs['aID']]['aTitle']); 16 | $view -> setMetaData ($article -> articleList[$canonical -> currentArgs['aID']]['aTags']); 17 | 18 | $aCateURLName = $article -> articleList[$canonical -> currentArgs['aID']]['aCateURLName']; 19 | $view -> setActiveNav ($aCateURLName); 20 | if (bw :: $cateList[$aCateURLName]['aCateTheme']) { 21 | $view -> setTheme (bw :: $cateList[$aCateURLName]['aCateTheme']); 22 | } 23 | $view -> setPassData ($article -> articleList[$canonical -> currentArgs['aID']]); 24 | $view -> setPassData (array ('navigation' => bw :: $cateList, 'sociallink' => bw :: getSocialLinks (), 'externallink' => bw :: getExternalLinks (), 'tagClound' => bw :: getTagCloud ())); 25 | $view -> setMaster ('page'); 26 | 27 | if ($conf['commentOpt']<>0) { 28 | loadServices (); 29 | if ($conf['commentOpt'] == 1 || $conf['commentOpt'] == 2) { //Build-in comment 30 | 31 | //Discarded on 2016/6/22 32 | //Added back on 2017/4/9 33 | //$view -> setWorkFlow (array ('nocommentarea', 'article', 'page')); 34 | 35 | 36 | @session_start (); 37 | $comment = new bwComment; 38 | $comment -> alterAID ($canonical -> currentArgs['aID']); 39 | $comment -> getComList (); 40 | $view -> setPassData (array ('comments' => $comment -> comList)); 41 | $comkey = md5 ($comment -> initComAKey () . $comment -> initComSKey ()); 42 | $view -> setPassData (array ('comkey' => $comkey)); 43 | $totalBatches = ceil ($comment -> totalCom / bw :: $conf['comPerLoad']); 44 | $view -> setPassData (array ('totalbatches' => $totalBatches, 'currentbatch' => $canonical -> currentPage, 'tmpUserName' => isset ($_COOKIE['tmpUserName']) ? $_COOKIE['tmpUserName'] : '', 'tmpUserURL' => isset ($_COOKIE['tmpUserURL']) ? $_COOKIE['tmpUserURL'] : '')); 45 | $view -> setWorkFlow (array ('ajaxcommentgroup', 'commentarea', 'article', 'page')); 46 | 47 | } elseif ($conf['commentOpt'] == 3) { 48 | if (isset ($conf['commentService'])) { 49 | $getServiceName = $conf['commentService']; 50 | } 51 | else { 52 | $getServiceName = 'nocommentarea'; 53 | } 54 | //die($getServiceName); 55 | $view -> setWorkFlow (array ($getServiceName, 'article', 'page')); 56 | } 57 | } else { 58 | $view -> setWorkFlow (array ('nocommentarea', 'article', 'page')); 59 | } 60 | 61 | $view -> finalize (); 62 | -------------------------------------------------------------------------------- /mode/cate.mod.php: -------------------------------------------------------------------------------- 1 | currentArgs['cateID'])) { 16 | $article -> alterCate($canonical -> currentArgs['cateID']); 17 | $view -> setPageTitle (bw :: $cateData[$canonical -> currentArgs['cateID']]); 18 | $view -> setActiveNav ($canonical -> currentArgs['cateID']); 19 | if (bw :: $cateList[$canonical -> currentArgs['cateID']]['aCateTheme']) { 20 | $view -> setTheme (bw :: $cateList[$canonical -> currentArgs['cateID']]['aCateTheme']); 21 | } 22 | } else { 23 | $view -> setActiveNav ('index'); 24 | } 25 | $view -> setMetaData (bw :: $conf['siteName']); 26 | $article -> getArticleList (); 27 | 28 | // Pagination 29 | $canonical -> calTotalPages ($article -> totalArticles); 30 | $view -> doPagination (); 31 | // Pass Values 32 | $view -> setPassData (array ('articlesummary' => $article -> articleList)); 33 | 34 | if (defined ('ajax')) { 35 | $view -> setMaster ('ajax-article-list'); 36 | $view -> setWorkFlow (array ('summary', 'ajax-article-list')); 37 | } else { 38 | $view -> setPassData (array ('navigation' => bw :: $cateList, 'sociallink' => bw :: getSocialLinks (), 'externallink' => bw :: getExternalLinks (), 'tagClound' => bw :: getTagCloud ())); 39 | $view -> setMaster ('page'); 40 | $view -> setWorkFlow (array ('summary', 'page')); 41 | } 42 | $view -> finalize (); 43 | -------------------------------------------------------------------------------- /mode/list.mod.php: -------------------------------------------------------------------------------- 1 | alterPerPage (50000); 34 | $view -> setActiveNav ($listMode); 35 | 36 | 37 | $groupedArticles = array (); 38 | 39 | if ($listMode == 'archives') { 40 | $article -> getArticleList (); 41 | $allStatURL = array (); 42 | foreach ($article -> articleList as $oneArticle) { 43 | $YYYY = substr ($oneArticle['aTime'], 0, 4); 44 | $groupedArticles[$YYYY][] = $oneArticle; 45 | $columnName[$YYYY] = $YYYY; 46 | $columnID[$YYYY] = $YYYY; 47 | isset ($columnCount[$YYYY]) ? $columnCount[$YYYY]++ : $columnCount[$YYYY] = 1; 48 | $allStatURL[$oneArticle['aID']] = "{$conf['siteURL']}/{$conf['linkPrefixArticle']}/{$oneArticle['aID']}/"; 49 | } 50 | file_put_contents (P. 'conf/allAIDs.php', " getRows ('SELECT tValue, tCount FROM tags ORDER BY tCount DESC'); 55 | foreach ($allTags as $aTag) { 56 | $article -> getArticleListByTag ($aTag['tValue']); 57 | $groupedArticles[$aTag['tValue']] = $article -> articleList; 58 | $columnName[$aTag['tValue']] = $aTag['tValue']; 59 | $columnID[$aTag['tValue']] = $aTag['tValue']; 60 | $columnCount[$aTag['tValue']] = $aTag['tCount']; 61 | } 62 | } 63 | if ($listMode == 'category') { 64 | $article -> getArticleList (); 65 | foreach ($article -> articleList as $oneArticle) { 66 | $cate = $oneArticle['aCateURLName']; 67 | $groupedArticles[$cate][] = $oneArticle; 68 | $columnName[$cate] = $oneArticle['aCateDispName']; 69 | $columnID[$cate] = $oneArticle['aCateURLName']; 70 | isset ($columnCount[$cate]) ? $columnCount[$cate]++ : $columnCount[$cate] = 1; 71 | } 72 | foreach (bw :: $cateList as $onecate) { 73 | if (isset ($groupedArticles[$onecate['aCateURLName']])) { 74 | $returnGroupArticles[$onecate['aCateURLName']] = $groupedArticles[$onecate['aCateURLName']] ; 75 | } 76 | } 77 | $groupedArticles = $returnGroupArticles; 78 | } 79 | 80 | 81 | $partOut = ''; 82 | foreach ($groupedArticles as $col => $val) { 83 | $view -> setMaster ('groupcolumn'); 84 | $view -> setPassData (array ('groupedArticles' => $val, 'columnName' => $columnName[$col], 'columnID' => $columnID[$col], 'columnCount' => $columnCount[$col])); 85 | $view -> setWorkFlow (array ('groupcolumn')); 86 | $partOut.= $view -> getOutput (); 87 | $view -> resetPassData (); 88 | } 89 | 90 | $view -> setMaster ('page'); 91 | $view -> setPassData (array ('navigation' => bw :: $cateList, 'sociallink' => bw :: getSocialLinks (), 'externallink' => bw :: getExternalLinks (), 'tagClound' => bw :: getTagCloud ())); 92 | $view -> setPassData (array ('listContent' => $partOut)); 93 | $view -> setWorkFlow (array ('page')); 94 | 95 | $view -> finalize (); 96 | -------------------------------------------------------------------------------- /mode/page.mod.php: -------------------------------------------------------------------------------- 1 | fetchArticle ($canonical -> currentArgs['aID'], true); 15 | 16 | $view = new bwView; 17 | $view -> setPageTitle ($article -> articleList[$canonical -> currentArgs['aID']]['aTitle']); 18 | $article -> articleList[$canonical -> currentArgs['aID']]['aContent'] = $view -> commonParser ($article -> articleList[$canonical -> currentArgs['aID']]['aContent']); 19 | $view -> setActiveNav ('index'); 20 | $view -> setPassData ($article -> articleList[$canonical -> currentArgs['aID']]); 21 | $view -> setPassData (array ('navigation' => bw :: $cateList, 'sociallink' => bw :: getSocialLinks (), 'externallink' => bw :: getExternalLinks (), 'tagClound' => bw :: getTagCloud ())); 22 | $view -> setMaster ('page'); 23 | $view -> setWorkFlow (array ('singlepage', 'page')); 24 | $view -> finalize (); 25 | -------------------------------------------------------------------------------- /mode/tag.mod.php: -------------------------------------------------------------------------------- 1 | currentArgs['tValue'])) { 16 | $view -> setPageTitle ($conf['l']['page:Tags'] . ' - ' . $canonical -> currentArgs['tValue']); 17 | $view -> setActiveNav ('index'); 18 | } else { 19 | stopError ($conf['l']['admin:msg:NoContent']); 20 | } 21 | $article -> getArticleListByTag ($canonical -> currentArgs['tValue']); 22 | loadServices (); //Load Duoshuo 23 | // Pagination 24 | $canonical -> calTotalPages ($article -> totalArticles); 25 | 26 | $view -> doPagination (); 27 | $view -> setPassData (array ('articlesummary' => $article -> articleList)); 28 | 29 | if (defined ('ajax')) { 30 | $view -> setMaster ('ajax-article-list'); 31 | $view -> setWorkFlow (array ('summary', 'ajax-article-list')); 32 | } else { 33 | $view -> setPassData (array ('navigation' => bw :: $cateList, 'sociallink' => bw :: getSocialLinks (), 'externallink' => bw :: getExternalLinks (), 'tagClound' => bw :: getTagCloud ())); 34 | $view -> setMaster ('page'); 35 | $view -> setWorkFlow (array ('summary', 'page')); 36 | } 37 | $view -> finalize (); 38 | -------------------------------------------------------------------------------- /page.php: -------------------------------------------------------------------------------- 1 | alterPerPage (20); 16 | $article -> getArticleList (); 17 | 18 | $outputxml = "\n\n\n{$conf['siteName']}\n{$conf['siteURL']}\n{$conf['authorIntro']}\n{$conf['siteURL']}/conf/profile.png{$conf['authorName']}{$conf['siteURL']}\n"; 19 | 20 | foreach ($article -> articleList as $item) { 21 | $item['aContent'] = @explode ('+++', $item['aContent']); 22 | $outputxml .= "\n{$item['aTitle']}\n{$conf['siteURL']}/{$conf['linkPrefixArticle']}/{$item['aID']}/\n{$conf['authorName']}" . date('c', strtotime($item['aTime'])) . "\n{$conf['siteURL']}/{$conf['linkPrefixArticle']}/{$item['aID']}/\n{$conf['siteURL']}/{$conf['linkPrefixArticle']}/{$item['aID']}/#comment-{$item['aID']}\n\n\n"; 23 | } 24 | 25 | $outputxml .= ""; 26 | 27 | @header("Content-Type: application/xml; charset=utf-8"); 28 | die ($outputxml); 29 | -------------------------------------------------------------------------------- /send.php: -------------------------------------------------------------------------------- 1 | alterPerPage (500); 16 | $article -> getArticleList (); 17 | 18 | $outputxml = "\n\n"; 19 | $outputxml .= "\n{$conf['siteURL']}/index.php\n" . gmdate("Y-m-d\TH:i:s+00:00") . "\nalways\n1.0\n\n"; 20 | 21 | foreach ($article -> articleList as $item) { 22 | $outputxml .= "\n{$conf['siteURL']}/{$conf['linkPrefixArticle']}/{$item['aID']}/\n" . gmdate('c', strtotime($item['aTime'])) . "\ndaily\n0.9\n\n"; 23 | } 24 | 25 | $outputxml .= ""; 26 | 27 | @header("Content-Type: application/xml; charset=utf-8"); 28 | die ($outputxml); 29 | -------------------------------------------------------------------------------- /storage/firstrun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/storage/firstrun.jpg -------------------------------------------------------------------------------- /storage/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tag.php: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | [[=page:Admin]] | [[::siteName]] 25 | 26 | 37 | [[::ext_adminhtmlhead]] 38 | 39 | 40 |
    41 |
    42 | 43 | 44 | 55 | [[::ext_adminheader]] 56 |
    57 | 58 |
    59 | [[::ext_adminMainAreaStart]] 60 | [[::load, admindashboard]][[::load, admincenter]][[::load, adminarticles]][[::load, adminwriter]][[::load, adminservices]][[::load, adminextensions]][[::load, adminmarket]][[::load, admincomments]][[::adminplainpage]] 61 |
    62 | 63 | [[::ext_adminMainAreaEnd]] 64 |
    65 |
    66 |
    67 | [[::ext_adminfooter]] 68 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /theme/default/admindashboard.php: -------------------------------------------------------------------------------- 1 | 13 | 14 |
    15 |

    [[=admin:sect:Welcome]], [[::authorName]]!

    16 |

    17 |
    18 |
    19 |

    [[=admin:item:AtAGlance]]

    20 | [[::totalArticles]] [[=admin:item:xxArticles]]
    21 | [[::totalReads]] [[=admin:item:xxArticleViews]]
    22 | [[::totalPVs]] [[=admin:item:xxPageViews]]
    23 | [[=admin:item:Sincexx]] [[::sinceWhen, dateFormat, Y.m.j]]
    24 |
    25 | 33 |
    34 |

    [[=admin:item:MostPopular]]

    35 |
      36 | [[::whatsHottest]] 37 |
    38 |
    39 |
    40 |

    [[=admin:item:RecentView]]

    41 |
      42 | [[::latestViews]] 43 |
    44 |
    45 |
    46 | 47 |


    48 |

    [[=admin:sect:SysInfo]]

    49 | bW (ver [[::thisVersion]])
    50 | [[::serverInfo]]
    51 | PHP Version [[::PHPVersion]] 52 |

    53 |

    [[=admin:sect:AutoUpdate]]

    54 | 56 |


    57 |

    [[=admin:msg:ManualUpdate]]

    58 | [[=admin:msg:ManualUpdate2]]
    59 | [[=admin:btn:DoUpdate]] 60 |
    61 | [[::ext_adminDashboard]] 62 | 95 | [[::ext_adminDashboardEnding]] 96 | -------------------------------------------------------------------------------- /theme/default/article.php: -------------------------------------------------------------------------------- 1 | 13 | 14 |
    15 | 16 |

    [[::aTitle]]

    17 |

    [[::aTime, dateFormat, Y/m/d H:i]] [[=page:InCate]] [[::aCateDispName]] 18 | [[::aComments]] 19 | 20 |

    21 |
    22 | [[::aContent, formatText, full]] 23 |
    24 | [[::aTags, hasTags,

    ]] [[::aTags, formatTags, [::tagValue]]][[::aTags, hasTags,

    ]] 25 | [[::ext_articleDetail]] 26 |
    27 | 28 |
    29 | [[::commentarea]] 30 | [[::gittalkarea]] 31 | [[::gitmentarea]] 32 | [[::disqusarea]] 33 | [[::ext_commentArea]] 34 |
    35 | -------------------------------------------------------------------------------- /theme/default/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/theme/default/dark.png -------------------------------------------------------------------------------- /theme/default/duoshuo.css: -------------------------------------------------------------------------------- 1 | .ds-highlight, .ds-comments-tabs, .ds-order-desc, .ds-order-asc, .ds-order-hot, .ds-more-services, .ds-post-likes, .ds-post-repost, .ds-post-placeholder {display: none !important;} 2 | .ds-replybox img, .ds-avatar img {width: 38px !important; height: 38px !important; border-radius: 50% !important; margin-top: 5px !important;} 3 | .ds-login-buttons {font-size: 12px !important; color: #717171 !important;} .ds-login-buttons a, .ds-login-buttons a:hover {color: #717171 !important;} 4 | .ds-gradient-bg {background: #F3F3F3 !important;} 5 | .ds-post-button {background: #F3F3F3 !important; font-size: 14px !important; font-family: "Lucida Sans Unicode", Helvetica, "Times New Roman", SimHei, Hei, "Microsoft Yahei", "Microsoft JhengHei", STHei, "Meiryo UI" !important;} 6 | .ds-post-options, .ds-post-button, .ds-rounded-top{border-radius: 0 !important;} 7 | .ds-post {border: 0 !important; font-size: 12px !important;} 8 | #ds-bubble {display: none !important;} 9 | .ds-comment-body {color: #464646 !important;} 10 | .ds-comment-footer {padding-bottom: 8px !important; border-bottom: 1px solid #F0F0F0 !important;} 11 | .ds-comments {border: 0 !important;} 12 | .ds-thread-count {vertical-align: super;} 13 | @media only screen and (max-width:600px) { 14 | .ds-replybox img, .ds-avatar img {width: 24px !important; height: 24px !important; border-radius: 50% !important; margin-top: 5px !important;} 15 | } -------------------------------------------------------------------------------- /theme/default/error.php: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | [[::siteName]] 24 | 25 | 26 |
    27 | 28 |
    29 |
    30 |

    31 |

    [[=page:Error]] [[::errorMessage]]

    32 |


    33 |

    [[=page:ErrorBack]] | [[=page:ErrorToHome]]

    34 |
    35 |
    36 | 37 |
    38 | 39 | -------------------------------------------------------------------------------- /theme/default/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src:url('fonts/icomoon.eot?70hsxc'); 4 | src:url('fonts/icomoon.eot?#iefix70hsxc') format('embedded-opentype'), 5 | url('fonts/icomoon.woff?70hsxc') format('woff'), 6 | url('fonts/icomoon.ttf?70hsxc') format('truetype'), 7 | url('fonts/icomoon.svg?70hsxc#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | font-family: 'icomoon'; 14 | speak: none; 15 | font-style: normal; 16 | font-weight: normal; 17 | font-variant: normal; 18 | text-transform: none; 19 | line-height: 1; 20 | 21 | /* Better Font Rendering =========== */ 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | 26 | .icon-newicon:before { 27 | content: "\e600"; 28 | } 29 | .icon-douban:before { 30 | content: "\e603"; 31 | } 32 | .icon-weixin:before { 33 | content: "\e604"; 34 | } 35 | .icon-image2:before { 36 | content: "\e610"; 37 | } 38 | .icon-wrench:before { 39 | content: "\e68e"; 40 | } 41 | .icon-cogs:before { 42 | content: "\e692"; 43 | } 44 | .icon-pie:before { 45 | content: "\e698"; 46 | } 47 | .icon-list2:before { 48 | content: "\e6b8"; 49 | } 50 | .icon-numbered-list:before { 51 | content: "\e6b9"; 52 | } 53 | .icon-bold:before { 54 | content: "\e747"; 55 | } 56 | .icon-italic:before { 57 | content: "\e749"; 58 | } 59 | .icon-embed:before { 60 | content: "\e75e"; 61 | } 62 | .icon-file-xml:before { 63 | content: "\e7bb"; 64 | } 65 | .icon-phone2:before { 66 | content: "\e7c6"; 67 | } 68 | .icon-mobile3:before { 69 | content: "\e7c7"; 70 | } 71 | .icon-mail5:before { 72 | content: "\e7ca"; 73 | } 74 | .icon-pencil:before { 75 | content: "\e7cc"; 76 | } 77 | .icon-paperclip:before { 78 | content: "\e7ce"; 79 | } 80 | .icon-drawer4:before { 81 | content: "\e7cf"; 82 | } 83 | .icon-reply2:before { 84 | content: "\e7d0"; 85 | } 86 | .icon-reply-all:before { 87 | content: "\e7d1"; 88 | } 89 | .icon-forward4:before { 90 | content: "\e7d2"; 91 | } 92 | .icon-user5:before { 93 | content: "\e7d3"; 94 | } 95 | .icon-users3:before { 96 | content: "\e7d4"; 97 | } 98 | .icon-user-add:before { 99 | content: "\e7d5"; 100 | } 101 | .icon-export:before { 102 | content: "\e7d7"; 103 | } 104 | .icon-location:before { 105 | content: "\e7d8"; 106 | } 107 | .icon-compass:before { 108 | content: "\e7da"; 109 | } 110 | .icon-target2:before { 111 | content: "\e7dc"; 112 | } 113 | .icon-share:before { 114 | content: "\e7dd"; 115 | } 116 | .icon-heart3:before { 117 | content: "\e7df"; 118 | } 119 | .icon-heart4:before { 120 | content: "\e7e0"; 121 | } 122 | .icon-star4:before { 123 | content: "\e7e1"; 124 | } 125 | .icon-star5:before { 126 | content: "\e7e2"; 127 | } 128 | .icon-chat:before { 129 | content: "\e7e5"; 130 | } 131 | .icon-comment:before { 132 | content: "\e7e6"; 133 | } 134 | .icon-quote:before { 135 | content: "\e7e7"; 136 | } 137 | .icon-house:before { 138 | content: "\e7e8"; 139 | } 140 | .icon-popup:before { 141 | content: "\e7e9"; 142 | } 143 | .icon-bell2:before { 144 | content: "\e7ed"; 145 | } 146 | .icon-link2:before { 147 | content: "\e7ee"; 148 | } 149 | .icon-flag2:before { 150 | content: "\e7ef"; 151 | } 152 | .icon-cog3:before { 153 | content: "\e7f0"; 154 | } 155 | .icon-tools:before { 156 | content: "\e7f1"; 157 | } 158 | .icon-tag2:before { 159 | content: "\e7f3"; 160 | } 161 | .icon-camera3:before { 162 | content: "\e7f4"; 163 | } 164 | .icon-music3:before { 165 | content: "\e7fa"; 166 | } 167 | .icon-book2:before { 168 | content: "\e7fd"; 169 | } 170 | .icon-newspaper2:before { 171 | content: "\e7fe"; 172 | } 173 | .icon-clock3:before { 174 | content: "\e803"; 175 | } 176 | .icon-cd:before { 177 | content: "\e809"; 178 | } 179 | .icon-gauge:before { 180 | content: "\e80d"; 181 | } 182 | .icon-rocket2:before { 183 | content: "\e816"; 184 | } 185 | .icon-suitcase:before { 186 | content: "\e818"; 187 | } 188 | .icon-cone:before { 189 | content: "\e819"; 190 | } 191 | .icon-earth2:before { 192 | content: "\e81a"; 193 | } 194 | .icon-keyboard2:before { 195 | content: "\e81b"; 196 | } 197 | .icon-screen2:before { 198 | content: "\e826"; 199 | } 200 | .icon-rss:before { 201 | content: "\e830"; 202 | } 203 | .icon-module:before { 204 | content: "\e834"; 205 | } 206 | .icon-pie2:before { 207 | content: "\e836"; 208 | } 209 | .icon-bars3:before { 210 | content: "\e837"; 211 | } 212 | .icon-logout:before { 213 | content: "\e83b"; 214 | } 215 | .icon-login:before { 216 | content: "\e83c"; 217 | } 218 | .icon-checkmark:before { 219 | content: "\e83d"; 220 | } 221 | .icon-cross:before { 222 | content: "\e83e"; 223 | } 224 | .icon-minus2:before { 225 | content: "\e83f"; 226 | } 227 | .icon-plus2:before { 228 | content: "\e840"; 229 | } 230 | .icon-cross2:before { 231 | content: "\e841"; 232 | } 233 | .icon-minus3:before { 234 | content: "\e842"; 235 | } 236 | .icon-plus3:before { 237 | content: "\e843"; 238 | } 239 | .icon-cross3:before { 240 | content: "\e844"; 241 | } 242 | .icon-minus4:before { 243 | content: "\e845"; 244 | } 245 | .icon-plus4:before { 246 | content: "\e846"; 247 | } 248 | .icon-erase:before { 249 | content: "\e847"; 250 | } 251 | .icon-question2:before { 252 | content: "\e84b"; 253 | } 254 | .icon-help:before { 255 | content: "\e84c"; 256 | } 257 | .icon-warning:before { 258 | content: "\e84d"; 259 | } 260 | .icon-cycle:before { 261 | content: "\e84e"; 262 | } 263 | .icon-cw:before { 264 | content: "\e84f"; 265 | } 266 | .icon-ccw:before { 267 | content: "\e850"; 268 | } 269 | .icon-list:before { 270 | content: "\e859"; 271 | } 272 | .icon-layout:before { 273 | content: "\e85b"; 274 | } 275 | .icon-list4:before { 276 | content: "\e85c"; 277 | } 278 | .icon-docs:before { 279 | content: "\e860"; 280 | } 281 | .icon-pictures:before { 282 | content: "\e862"; 283 | } 284 | .icon-video:before { 285 | content: "\e863"; 286 | } 287 | .icon-music4:before { 288 | content: "\e864"; 289 | } 290 | .icon-archive:before { 291 | content: "\e866"; 292 | } 293 | .icon-disk:before { 294 | content: "\e86a"; 295 | } 296 | .icon-cloud2:before { 297 | content: "\e86c"; 298 | } 299 | .icon-upload2:before { 300 | content: "\e86d"; 301 | } 302 | .icon-resize-enlarge:before { 303 | content: "\e879"; 304 | } 305 | .icon-resize-shrink:before { 306 | content: "\e87a"; 307 | } 308 | .icon-arrow-left4:before { 309 | content: "\e883"; 310 | } 311 | .icon-arrow-down7:before { 312 | content: "\e884"; 313 | } 314 | .icon-arrow-up-upload:before { 315 | content: "\e885"; 316 | } 317 | .icon-arrow-right4:before { 318 | content: "\e886"; 319 | } 320 | .icon-arrow-left8:before { 321 | content: "\e887"; 322 | } 323 | .icon-arrow-down5:before { 324 | content: "\e888"; 325 | } 326 | .icon-arrow-left7:before { 327 | content: "\e88f"; 328 | } 329 | .icon-arrow-down4:before { 330 | content: "\e890"; 331 | } 332 | .icon-arrow-up3:before { 333 | content: "\e891"; 334 | } 335 | .icon-arrow-right7:before { 336 | content: "\e892"; 337 | } 338 | .icon-arrow-left5:before { 339 | content: "\e893"; 340 | } 341 | .icon-arrow-down5:before { 342 | content: "\e894"; 343 | } 344 | .icon-arrow-up4:before { 345 | content: "\e895"; 346 | } 347 | .icon-arrow-right5:before { 348 | content: "\e896"; 349 | } 350 | .icon-arrow-left9:before { 351 | content: "\e897"; 352 | } 353 | .icon-arrow-down9:before { 354 | content: "\e898"; 355 | } 356 | .icon-arrow-up8:before { 357 | content: "\e899"; 358 | } 359 | .icon-arrow-right9:before { 360 | content: "\e89a"; 361 | } 362 | .icon-arrow-left10:before { 363 | content: "\e89b"; 364 | } 365 | .icon-arrow-down10:before { 366 | content: "\e89c"; 367 | } 368 | .icon-arrow-up9:before { 369 | content: "\e89d"; 370 | } 371 | .icon-uniE89E:before { 372 | content: "\e89e"; 373 | } 374 | .icon-menu3:before { 375 | content: "\e8a3"; 376 | } 377 | .icon-ellipsis:before { 378 | content: "\e8a4"; 379 | } 380 | .icon-dots:before { 381 | content: "\e8a5"; 382 | } 383 | .icon-dot:before { 384 | content: "\e8a6"; 385 | } 386 | .icon-github6:before { 387 | content: "\e8b4"; 388 | } 389 | .icon-github:before { 390 | content: "\e8b4"; 391 | } 392 | .icon-flickr5:before { 393 | content: "\e8b6"; 394 | } 395 | .icon-flickr6:before { 396 | content: "\e8b7"; 397 | } 398 | .icon-vimeo4:before { 399 | content: "\e8b8"; 400 | } 401 | .icon-vimeo5:before { 402 | content: "\e8b9"; 403 | } 404 | .icon-twitter:before { 405 | content: "\e8ba"; 406 | } 407 | .icon-twitter5:before { 408 | content: "\e8bb"; 409 | } 410 | .icon-facebook:before { 411 | content: "\e8bc"; 412 | } 413 | .icon-facebook5:before { 414 | content: "\e8bd"; 415 | } 416 | .icon-facebook6:before { 417 | content: "\e8be"; 418 | } 419 | .icon-googleplus5:before { 420 | content: "\e8bf"; 421 | } 422 | .icon-googleplus6:before { 423 | content: "\e8c0"; 424 | } 425 | .icon-pinterest3:before { 426 | content: "\e8c1"; 427 | } 428 | .icon-pinterest4:before { 429 | content: "\e8c2"; 430 | } 431 | .icon-tumblr3:before { 432 | content: "\e8c3"; 433 | } 434 | .icon-tumblr4:before { 435 | content: "\e8c4"; 436 | } 437 | .icon-linkedin:before { 438 | content: "\e8c5"; 439 | } 440 | .icon-linkedin3:before { 441 | content: "\e8c6"; 442 | } 443 | .icon-qq:before { 444 | content: "\e8d1"; 445 | } 446 | .icon-instagram:before { 447 | content: "\e8d2"; 448 | } 449 | .icon-skype2:before { 450 | content: "\e8d6"; 451 | } 452 | .icon-skype3:before { 453 | content: "\e8d7"; 454 | } 455 | .icon-renren:before { 456 | content: "\e8d8"; 457 | } 458 | .icon-sina-weibo:before { 459 | content: "\e8d9"; 460 | } 461 | .icon-picasa:before { 462 | content: "\e8db"; 463 | } 464 | .icon-vk:before { 465 | content: "\e8e0"; 466 | } 467 | .icon-smashing:before { 468 | content: "\e8e1"; 469 | } 470 | -------------------------------------------------------------------------------- /theme/default/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/theme/default/fonts/icomoon.eot -------------------------------------------------------------------------------- /theme/default/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/theme/default/fonts/icomoon.ttf -------------------------------------------------------------------------------- /theme/default/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/theme/default/fonts/icomoon.woff -------------------------------------------------------------------------------- /theme/default/icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bo-blog/bw/19b487d0b9e1e5e0ab9766746a0f44f05f49b6e3/theme/default/icon.jpg -------------------------------------------------------------------------------- /theme/default/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/default/info.php: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | [[::pageTitle]][[::siteName]] - [[::authorIntro]] 28 | 29 | 37 | 38 | [[::ext_htmlhead]] 39 | [[::widget_wghtmlhead]] 40 | 41 | 42 |
    43 |
    44 | 45 | 46 | 47 | 48 | 58 | [[::ext_header]] 59 |
    60 | 61 |
    62 | [[::ext_mainAreaStart]] 63 | 64 |
    65 | [[::loop, articlesummary]][[::load, summary]][[::/loop]] 66 | [[::load, article]][[::load, singlepage]][[::listContent]] 67 | [[::pagination]] 68 | 69 |
    70 | 71 | [[::ext_mainAreaEnd]] 72 |
    73 |
    74 | 75 | 86 | 87 |
    88 |
    89 | 95 | [[::ext_beforeEnd]] 96 | 97 | 98 | -------------------------------------------------------------------------------- /theme/default/plainpage.php: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | [[::siteName]] 24 | 25 | 33 | 34 | 35 |
    36 | 37 |
    38 |
    39 | [[::plainContent]] 40 |
    41 |
    42 | [[=page:Home]] 43 |
    44 |
    45 |
    46 | 47 | -------------------------------------------------------------------------------- /theme/default/singlepage.php: -------------------------------------------------------------------------------- 1 | 13 | 14 | 31 | -------------------------------------------------------------------------------- /theme/default/summary.php: -------------------------------------------------------------------------------- 1 | 13 | 14 |
    15 | 16 |

    [[::aTitle]]

    17 |

    [[::aTime, dateFormat, Y/m/d H:i]] [[=page:InCate]] [[::aCateDispName]] 18 | [[::aComments]] 19 |

    20 |
    21 | [[::aContent, formatText, less]] 22 | [[::aID, readMore, %s]] 23 |
    24 | 25 | [[::aTags, hasTags,

    ]] [[::aTags, formatTags, [::tagValue]]][[::aTags, hasTags,

    ]] 26 | [[::ext_summaryDetail]] 27 | 28 |
    29 | -------------------------------------------------------------------------------- /update/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /update/update.mysql.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE categories ADD aCateTheme VARCHAR (255) -------------------------------------------------------------------------------- /update/update.sqlite.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE categories ADD COLUMN aCateTheme VARCHAR (255) --------------------------------------------------------------------------------