├── .gitmodules ├── admin ├── js │ └── Moxie.swf ├── img │ ├── editor.png │ ├── editor@2x.png │ ├── noscreen.png │ ├── ajax-loader.gif │ ├── editor │ │ ├── editor-hr.png │ │ ├── editor-bold.png │ │ ├── editor-code.png │ │ ├── editor-image.png │ │ ├── editor-link.png │ │ ├── editor-more.png │ │ ├── editor-olist.png │ │ ├── editor-quote.png │ │ ├── editor-redo.png │ │ ├── editor-ulist.png │ │ ├── editor-undo.png │ │ ├── editor-heading.png │ │ ├── editor-italic.png │ │ ├── 2x │ │ │ ├── editor-bold@2x.png │ │ │ ├── editor-code@2x.png │ │ │ ├── editor-hr@2x.png │ │ │ ├── editor-link@2x.png │ │ │ ├── editor-more@2x.png │ │ │ ├── editor-redo@2x.png │ │ │ ├── editor-undo@2x.png │ │ │ ├── editor-image@2x.png │ │ │ ├── editor-italic@2x.png │ │ │ ├── editor-olist@2x.png │ │ │ ├── editor-quote@2x.png │ │ │ ├── editor-ulist@2x.png │ │ │ ├── editor-exitfull@2x.png │ │ │ ├── editor-heading@2x.png │ │ │ └── editor-fullscreen@2x.png │ │ ├── editor-exitfull.png │ │ └── editor-fullscreen.png │ ├── icons │ │ ├── icon-edit.png │ │ ├── mime-audio.png │ │ ├── mime-html.png │ │ ├── mime-image.png │ │ ├── mime-text.png │ │ ├── mime-video.png │ │ ├── icon-delete.png │ │ ├── icon-exlink.png │ │ ├── icon-upload.png │ │ ├── mime-archive.png │ │ ├── mime-office.png │ │ ├── mime-script.png │ │ ├── mime-unknow.png │ │ ├── icon-upload-active.png │ │ └── mime-application.png │ ├── icons-2x │ │ ├── icon-edit.png │ │ ├── mime-audio.png │ │ ├── mime-html.png │ │ ├── mime-image.png │ │ ├── mime-text.png │ │ ├── mime-video.png │ │ ├── icon-delete.png │ │ ├── icon-exlink.png │ │ ├── icon-upload.png │ │ ├── mime-archive.png │ │ ├── mime-office.png │ │ ├── mime-script.png │ │ ├── mime-unknow.png │ │ ├── mime-application.png │ │ └── icon-upload-active.png │ ├── icons-s0c4f1c5ae6.png │ └── icons-2x-s481937020b.png ├── scss │ ├── _components.scss │ ├── _footer.scss │ ├── components │ │ ├── _retina.scss │ │ ├── _tokeninput.scss │ │ └── _timepicker.scss │ ├── _pagenavi.scss │ ├── _messages.scss │ ├── _hidden.scss │ ├── _forms.scss │ ├── _buttons.scss │ └── _header.scss ├── footer.php ├── page-title.php ├── extending.php ├── table-js.php ├── user.php ├── category.php ├── options-general.php ├── options-plugin.php ├── options-discussion.php ├── options-permalink.php ├── copyright.php ├── form-js.php ├── menu.php ├── options-reading.php ├── options-theme.php ├── file-upload.php ├── upgrade.php ├── welcome.php ├── header.php ├── custom-fields-js.php ├── register.php ├── login.php ├── common.php ├── profile.php └── theme-editor.php ├── todo.txt ├── tools ├── yuicompressor-2.4.2.jar ├── updateForkTypecho.sh ├── tc.php ├── list.php ├── Makefile └── transfer.php ├── usr ├── themes │ └── default │ │ ├── screenshot.png │ │ ├── img │ │ ├── icon-search.png │ │ └── icon-search@2x.png │ │ ├── footer.php │ │ ├── 404.php │ │ ├── page.php │ │ ├── functions.php │ │ ├── post.php │ │ ├── index.php │ │ ├── archive.php │ │ ├── comments.php │ │ └── sidebar.php └── plugins │ └── HelloWorld │ └── Plugin.php ├── .travis.yml ├── README.md ├── .gitignore ├── install ├── SQLite.php ├── Pgsql.php └── SQLite.sql ├── .gitattributes ├── var ├── Typecho │ ├── Db │ │ ├── Exception.php │ │ ├── Query │ │ │ └── Exception.php │ │ ├── Adapter │ │ │ ├── Exception.php │ │ │ └── Pdo │ │ │ │ ├── Mysql.php │ │ │ │ ├── Pgsql.php │ │ │ │ └── SQLite.php │ │ └── Adapter.php │ ├── Plugin │ │ ├── Exception.php │ │ └── Interface.php │ ├── Router │ │ ├── Exception.php │ │ └── Parser.php │ ├── Widget │ │ ├── Exception.php │ │ └── Helper │ │ │ ├── Empty.php │ │ │ ├── Form │ │ │ └── Element │ │ │ │ ├── Submit.php │ │ │ │ ├── Textarea.php │ │ │ │ ├── Text.php │ │ │ │ ├── Password.php │ │ │ │ ├── Hidden.php │ │ │ │ ├── Fake.php │ │ │ │ ├── Select.php │ │ │ │ ├── Radio.php │ │ │ │ └── Checkbox.php │ │ │ ├── PageNavigator │ │ │ └── Classic.php │ │ │ └── PageNavigator.php │ ├── Http │ │ ├── Client │ │ │ └── Exception.php │ │ └── Client.php │ ├── Exception.php │ ├── I18n │ │ └── GetTextMulti.php │ ├── Date.php │ └── Cookie.php ├── Widget │ ├── Interface │ │ └── Do.php │ ├── ExceptionHandle.php │ ├── Logout.php │ ├── Users │ │ ├── Author.php │ │ └── Admin.php │ ├── Contents │ │ ├── Post │ │ │ ├── Recent.php │ │ │ └── Date.php │ │ ├── Attachment │ │ │ ├── Unattached.php │ │ │ └── Related.php │ │ ├── Page │ │ │ ├── List.php │ │ │ └── Admin.php │ │ ├── Related │ │ │ └── Author.php │ │ └── Related.php │ ├── Metas │ │ ├── Tag │ │ │ ├── Admin.php │ │ │ └── Cloud.php │ │ └── Category │ │ │ └── Admin.php │ ├── Comments │ │ └── Recent.php │ ├── Notice.php │ ├── Themes │ │ ├── Config.php │ │ └── List.php │ ├── Init.php │ ├── Abstract │ │ └── Options.php │ ├── Login.php │ ├── Abstract.php │ ├── Security.php │ ├── Do.php │ └── Plugins │ │ └── Config.php ├── IXR │ ├── Exception.php │ ├── Base64.php │ ├── Request.php │ ├── ClientMulticall.php │ ├── Error.php │ └── Date.php └── Markdown.php ├── index.php └── changelog.txt /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /admin/js/Moxie.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/js/Moxie.swf -------------------------------------------------------------------------------- /admin/img/editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor.png -------------------------------------------------------------------------------- /admin/img/editor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor@2x.png -------------------------------------------------------------------------------- /admin/img/noscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/noscreen.png -------------------------------------------------------------------------------- /admin/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/ajax-loader.gif -------------------------------------------------------------------------------- /todo.txt: -------------------------------------------------------------------------------- 1 | 0.9 版 2 | 3 | 1. 干掉mootools,上jquery 4 | 2. 后台UI更新 5 | 3. 撰写页面更新,加入markdown支持 6 | 4. 增加bae支持 7 | 8 | -------------------------------------------------------------------------------- /admin/img/editor/editor-hr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-hr.png -------------------------------------------------------------------------------- /admin/img/icons/icon-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/icon-edit.png -------------------------------------------------------------------------------- /admin/img/icons/mime-audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-audio.png -------------------------------------------------------------------------------- /admin/img/icons/mime-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-html.png -------------------------------------------------------------------------------- /admin/img/icons/mime-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-image.png -------------------------------------------------------------------------------- /admin/img/icons/mime-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-text.png -------------------------------------------------------------------------------- /admin/img/icons/mime-video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-video.png -------------------------------------------------------------------------------- /tools/yuicompressor-2.4.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/tools/yuicompressor-2.4.2.jar -------------------------------------------------------------------------------- /admin/img/editor/editor-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-bold.png -------------------------------------------------------------------------------- /admin/img/editor/editor-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-code.png -------------------------------------------------------------------------------- /admin/img/editor/editor-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-image.png -------------------------------------------------------------------------------- /admin/img/editor/editor-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-link.png -------------------------------------------------------------------------------- /admin/img/editor/editor-more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-more.png -------------------------------------------------------------------------------- /admin/img/editor/editor-olist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-olist.png -------------------------------------------------------------------------------- /admin/img/editor/editor-quote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-quote.png -------------------------------------------------------------------------------- /admin/img/editor/editor-redo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-redo.png -------------------------------------------------------------------------------- /admin/img/editor/editor-ulist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-ulist.png -------------------------------------------------------------------------------- /admin/img/editor/editor-undo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-undo.png -------------------------------------------------------------------------------- /admin/img/icons-2x/icon-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/icon-edit.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-audio.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-html.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-image.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-text.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-video.png -------------------------------------------------------------------------------- /admin/img/icons-s0c4f1c5ae6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-s0c4f1c5ae6.png -------------------------------------------------------------------------------- /admin/img/icons/icon-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/icon-delete.png -------------------------------------------------------------------------------- /admin/img/icons/icon-exlink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/icon-exlink.png -------------------------------------------------------------------------------- /admin/img/icons/icon-upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/icon-upload.png -------------------------------------------------------------------------------- /admin/img/icons/mime-archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-archive.png -------------------------------------------------------------------------------- /admin/img/icons/mime-office.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-office.png -------------------------------------------------------------------------------- /admin/img/icons/mime-script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-script.png -------------------------------------------------------------------------------- /admin/img/icons/mime-unknow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-unknow.png -------------------------------------------------------------------------------- /usr/themes/default/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/usr/themes/default/screenshot.png -------------------------------------------------------------------------------- /admin/img/editor/editor-heading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-heading.png -------------------------------------------------------------------------------- /admin/img/editor/editor-italic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-italic.png -------------------------------------------------------------------------------- /admin/img/icons-2x-s481937020b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x-s481937020b.png -------------------------------------------------------------------------------- /admin/img/icons-2x/icon-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/icon-delete.png -------------------------------------------------------------------------------- /admin/img/icons-2x/icon-exlink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/icon-exlink.png -------------------------------------------------------------------------------- /admin/img/icons-2x/icon-upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/icon-upload.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-archive.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-office.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-office.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-script.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-unknow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-unknow.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-bold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-bold@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-code@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-code@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-hr@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-hr@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-link@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-link@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-more@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-more@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-redo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-redo@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-undo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-undo@2x.png -------------------------------------------------------------------------------- /admin/img/editor/editor-exitfull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-exitfull.png -------------------------------------------------------------------------------- /admin/img/editor/editor-fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/editor-fullscreen.png -------------------------------------------------------------------------------- /admin/img/icons/icon-upload-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/icon-upload-active.png -------------------------------------------------------------------------------- /admin/img/icons/mime-application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons/mime-application.png -------------------------------------------------------------------------------- /admin/scss/_components.scss: -------------------------------------------------------------------------------- 1 | @import "components/editor"; 2 | @import "components/timepicker"; 3 | @import "components/tokeninput"; -------------------------------------------------------------------------------- /usr/themes/default/img/icon-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/usr/themes/default/img/icon-search.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-image@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-italic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-italic@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-olist@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-olist@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-quote@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-quote@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-ulist@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-ulist@2x.png -------------------------------------------------------------------------------- /admin/img/icons-2x/mime-application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/mime-application.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-exitfull@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-exitfull@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-heading@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-heading@2x.png -------------------------------------------------------------------------------- /admin/img/icons-2x/icon-upload-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/icons-2x/icon-upload-active.png -------------------------------------------------------------------------------- /usr/themes/default/img/icon-search@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/usr/themes/default/img/icon-search@2x.png -------------------------------------------------------------------------------- /admin/img/editor/2x/editor-fullscreen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneasystone/typecho/master/admin/img/editor/2x/editor-fullscreen@2x.png -------------------------------------------------------------------------------- /admin/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | end(); 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 5.5 6 | - 5.4 7 | - 5.3 8 | - 5.2 9 | - hhvm 10 | 11 | script: cd ./tools/ && set -e && make test 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Typecho Blogging Platform 2 | ========================= 3 | 4 | ####Homepage 5 | http://typecho.org/ 6 | 7 | ####Document 8 | http://docs.typecho.org/ 9 | 10 | ####Forum 11 | http://forum.typecho.org/ 12 | 13 | ####Download 14 | http://typecho.org/download 15 | 16 | -------------------------------------------------------------------------------- /admin/page-title.php: -------------------------------------------------------------------------------- 1 | 2 |
3 |

title; ?>addLink)) { 5 | echo "addLink}\">" . _t("新增") . ""; 6 | } 7 | ?>

8 |
9 | -------------------------------------------------------------------------------- /admin/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 注脚 3 | */ 4 | .typecho-foot { 5 | padding: 4em 0 3em; 6 | color: #999; 7 | line-height: 1.8; 8 | text-align: center; 9 | 10 | .copyright p { 11 | margin: 10px 0 0; 12 | } 13 | .resource { 14 | color: #CCC; 15 | } 16 | .resource a { 17 | margin: 0 3px; 18 | color: #999; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | .*.swo 3 | ._* 4 | .DS_Store 5 | /ImgCache/ 6 | /Backup_rar/ 7 | /Debug/ 8 | /debug/ 9 | /upload/ 10 | /avatar/ 11 | /.idea/ 12 | .svn/ 13 | *.orig 14 | *.aps 15 | *.APS 16 | *.chm 17 | *.exp 18 | *.pdb 19 | *.rar 20 | *.mo 21 | *.po 22 | *.pot 23 | .smbdelete* 24 | *.sublime* 25 | .sass-cache 26 | config.rb 27 | /config.inc.php 28 | /usr/uploads/ 29 | -------------------------------------------------------------------------------- /admin/scss/components/_retina.scss: -------------------------------------------------------------------------------- 1 | @import "compass/css3/background-size"; 2 | 3 | @mixin image-2x($image, $width, $height) { 4 | @media (-webkit-min-device-pixel-ratio: 1.3), 5 | (min-resolution: 124.8dpi), 6 | (min-resolution: 1.3dppx) { 7 | & { 8 | background-image: url($image); 9 | @include background-size($width $height); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tools/updateForkTypecho.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #更新fork之后的Typecho至最新代码 3 | 4 | #切换到主目录 5 | cd .. 6 | 7 | #增加Typecho源分支地址到本地项目远程分支列表 8 | git remote add official https://github.com/typecho/typecho.git 9 | 10 | #查看远程分支列表 11 | #git remote -v 12 | 13 | #更新Typecho源分支的新版本到本地 14 | git fetch official 15 | 16 | #合并Typecho源分支的代码 17 | git merge official/master 18 | 19 | #将合并后的代码push到你自己fork的Tyepcho项目上去 20 | git push origin master 21 | -------------------------------------------------------------------------------- /install/SQLite.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
  • 4 | 5 | 6 |

    7 |
  • 8 | -------------------------------------------------------------------------------- /admin/extending.php: -------------------------------------------------------------------------------- 1 | get('panel'); 5 | $panelTable = unserialize($options->panelTable); 6 | 7 | if (!isset($panelTable['file']) || !in_array(urlencode($panel), $panelTable['file'])) { 8 | throw new Typecho_Plugin_Exception(_t('页面不存在'), 404); 9 | } 10 | 11 | list ($pluginName, $file) = explode('/', trim($panel, '/'), 2); 12 | 13 | require_once $options->pluginDir($pluginName) . '/' . $panel; 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files we want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.php text eol=lf 7 | *.js text eol=lf 8 | *.css text eol=lf 9 | *.html text eol=lf 10 | *.xml text eol=lf 11 | 12 | # Denote all files that are truly binary and should not be modified. 13 | *.png binary 14 | *.jpg binary 15 | 16 | -------------------------------------------------------------------------------- /var/Typecho/Db/Exception.php: -------------------------------------------------------------------------------- 1 | 9 | * @license GNU General Public License 2.0 10 | */ 11 | interface Widget_Interface_Do 12 | { 13 | /** 14 | * 接口需要实现的入口函数 15 | * 16 | * @access public 17 | * @return void 18 | */ 19 | public function action(); 20 | } 21 | -------------------------------------------------------------------------------- /usr/themes/default/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | footer(); ?> 13 | 14 | 15 | -------------------------------------------------------------------------------- /var/IXR/Exception.php: -------------------------------------------------------------------------------- 1 | htmlspecialchars) 6 | Site: http://scripts.incutio.com/xmlrpc/ 7 | Manual: http://scripts.incutio.com/xmlrpc/manual.php 8 | Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php 9 | */ 10 | 11 | /** 12 | * IXR异常类 13 | * 14 | * @package IXR 15 | */ 16 | class IXR_Exception extends Exception 17 | {} 18 | -------------------------------------------------------------------------------- /var/Typecho/Exception.php: -------------------------------------------------------------------------------- 1 | message = $message; 22 | $this->code = $code; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /admin/table-js.php: -------------------------------------------------------------------------------- 1 | 2 | 19 | -------------------------------------------------------------------------------- /admin/user.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 | form()->render(); ?> 13 |
    14 |
    15 |
    16 |
    17 | 18 | 24 | -------------------------------------------------------------------------------- /admin/category.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 | form()->render(); ?> 13 |
    14 |
    15 |
    16 |
    17 | 18 | 24 | -------------------------------------------------------------------------------- /admin/options-general.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 | form()->render(); ?> 13 |
    14 |
    15 |
    16 |
    17 | 18 | 24 | -------------------------------------------------------------------------------- /admin/options-plugin.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 | config()->render(); ?> 13 |
    14 |
    15 |
    16 |
    17 | 18 | 24 | -------------------------------------------------------------------------------- /admin/options-discussion.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 | form()->render(); ?> 13 |
    14 |
    15 |
    16 |
    17 | 18 | 24 | -------------------------------------------------------------------------------- /admin/scss/_pagenavi.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 后台分页 3 | */ 4 | 5 | .typecho-pager { 6 | list-style: none; 7 | float: right; 8 | margin: 0; 9 | padding: 0; 10 | line-height: 1; 11 | text-align: center; 12 | zoom: 1; 13 | } 14 | 15 | .typecho-pager li { 16 | display: inline-block; 17 | margin: 0 3px; 18 | height: 28px; 19 | line-height: 28px; 20 | } 21 | 22 | .typecho-pager a { 23 | display: block; 24 | padding: 0 10px; 25 | @include border-radius(2px); 26 | } 27 | 28 | .typecho-pager a:hover { 29 | text-decoration: none; 30 | background: #E9E9E6; 31 | } 32 | 33 | .typecho-pager li.current a { 34 | background: #E9E9E6; 35 | color: #444; 36 | } -------------------------------------------------------------------------------- /admin/options-permalink.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 | form()->render(); ?> 13 |
    14 |
    15 |
    16 |
    17 | 18 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /var/Markdown.php: -------------------------------------------------------------------------------- 1 | transform($text); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /usr/themes/default/404.php: -------------------------------------------------------------------------------- 1 | 2 | need('header.php'); ?> 3 | 4 |
    5 | 6 |
    7 |

    404 -

    8 |

    9 |
    10 |

    11 |

    12 |
    13 |
    14 | 15 |
    16 | need('footer.php'); ?> 17 | -------------------------------------------------------------------------------- /usr/themes/default/page.php: -------------------------------------------------------------------------------- 1 | 2 | need('header.php'); ?> 3 | 4 |
    5 |
    6 |

    title() ?>

    7 |
    8 | content(); ?> 9 |
    10 |
    11 | need('comments.php'); ?> 12 |
    13 | 14 | need('sidebar.php'); ?> 15 | need('footer.php'); ?> 16 | -------------------------------------------------------------------------------- /tools/tc.php: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | begin(); 21 | 22 | /** 开始路由分发 */ 23 | Typecho_Router::dispatch(); 24 | 25 | /** 注册一个结束插件 */ 26 | Typecho_Plugin::factory('index.php')->end(); 27 | -------------------------------------------------------------------------------- /var/Widget/ExceptionHandle.php: -------------------------------------------------------------------------------- 1 | widget('Widget_Archive@404', 'type=404')->render(); 28 | exit; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /admin/form-js.php: -------------------------------------------------------------------------------- 1 | 2 | 27 | -------------------------------------------------------------------------------- /tools/list.php: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | -------------------------------------------------------------------------------- /admin/scss/_messages.scss: -------------------------------------------------------------------------------- 1 | @import "compass"; 2 | 3 | /** 4 | * 提示信息框 5 | */ 6 | .message { 7 | padding: 8px 10px; 8 | @include border-radius(2px); 9 | } 10 | 11 | .message a { 12 | font-weight: bold; 13 | text-decoration: underline; 14 | } 15 | 16 | .error { 17 | background: #FBE3E4; 18 | color: #8A1F11; 19 | } 20 | .error a { color: #8A1F11; } 21 | 22 | .notice { 23 | background: #FFF6BF; 24 | color: #8A6D3B; 25 | } 26 | .notice a { color: #8A6D3B; } 27 | 28 | .success { 29 | background: #E6EFC2; 30 | color: #264409; 31 | } 32 | .success a { color: #264409; } 33 | 34 | 35 | // 气泡 36 | .balloon { 37 | display: inline-block; 38 | padding: 0 4px; 39 | min-width: 10px; 40 | height: 14px; 41 | line-height: 14px; 42 | background: #B9B9B6; 43 | vertical-align: text-top; 44 | text-align: center; 45 | font-size: 12px; 46 | color: #FFF; 47 | 48 | @include border-radius(20px); 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /var/Widget/Logout.php: -------------------------------------------------------------------------------- 1 | user->logout(); 32 | $this->pluginHandle()->logout(); 33 | $this->response->goBack(NULL, $this->options->index); 34 | @session_destroy(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /admin/scss/_hidden.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Hide from both screenreaders and browsers: h5bp.com/u 3 | */ 4 | 5 | .hidden { 6 | display: none; 7 | // display: none !important; 8 | // visibility: hidden; 9 | } 10 | 11 | /* 12 | * Hide only visually, but have it available for screenreaders: h5bp.com/v 13 | */ 14 | 15 | .sr-only { 16 | border: 0; 17 | height: 1px; 18 | margin: -1px; 19 | overflow: hidden; 20 | padding: 0; 21 | position: absolute; 22 | width: 1px; 23 | } 24 | 25 | /* 26 | * Extends the .sr-only class to allow the element to be focusable 27 | * when navigated to via the keyboard: h5bp.com/p 28 | */ 29 | 30 | .sr-only.focusable:active, 31 | .sr-only.focusable:focus { 32 | clip: auto; 33 | height: auto; 34 | margin: 0; 35 | overflow: visible; 36 | position: static; 37 | width: auto; 38 | } 39 | 40 | /* 41 | * Hide visually and from screenreaders, but maintain layout 42 | */ 43 | 44 | .invisible { 45 | visibility: hidden; 46 | } -------------------------------------------------------------------------------- /var/Widget/Users/Author.php: -------------------------------------------------------------------------------- 1 | parameter->uid) { 33 | $this->db->fetchRow($this->select() 34 | ->where('uid = ?', $this->parameter->uid), array($this, 'push')); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /admin/scss/_forms.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Forms 3 | */ 4 | 5 | input[type=text], input[type=password], input[type=email], 6 | textarea { 7 | background: #FFF; 8 | border: 1px solid #D9D9D6; 9 | padding: 7px; 10 | 11 | border-radius: 2px; 12 | 13 | -webkit-box-sizing: border-box; 14 | -moz-box-sizing: border-box; 15 | box-sizing: border-box; 16 | } 17 | 18 | textarea { 19 | resize: vertical; 20 | line-height: 1.5; 21 | } 22 | 23 | input[type="radio"], input[type="checkbox"] { margin-right: 3px; } 24 | 25 | input, textarea { 26 | &.text-s { padding: 5px; } 27 | &.text-l { 28 | padding: 10px; 29 | font-size: 1.14286em; 30 | } 31 | } 32 | 33 | .w-10 { width: 10%; } 34 | .w-20 { width: 20%; } 35 | .w-30 { width: 30%; } 36 | .w-40 { width: 40%;} 37 | .w-50 { width: 50%;} 38 | .w-60 { width: 60%;} 39 | .w-70 { width: 70%;} 40 | .w-80 { width: 80%;} 41 | .w-90 { width: 90%;} 42 | .w-100 { width: 100%;} 43 | 44 | select { 45 | border: 1px solid #CCC; 46 | height: 28px; 47 | } -------------------------------------------------------------------------------- /var/IXR/Base64.php: -------------------------------------------------------------------------------- 1 | htmlspecialchars) 5 | Site: http://scripts.incutio.com/xmlrpc/ 6 | Manual: http://scripts.incutio.com/xmlrpc/manual.php 7 | Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php 8 | */ 9 | 10 | /** 11 | * IXR Base64编码 12 | * 13 | * @package IXR 14 | */ 15 | class IXR_Base64 16 | { 17 | /** 18 | * 编码数据 19 | * 20 | * @var string 21 | */ 22 | private $data; 23 | 24 | /** 25 | * 初始化数据 26 | * 27 | * @param string $data 28 | */ 29 | public function __construct($data) 30 | { 31 | $this->data = $data; 32 | } 33 | 34 | /** 35 | * 获取XML数据 36 | * 37 | * @return string 38 | */ 39 | public function getXml() 40 | { 41 | return '' . base64_encode($this->data) . ''; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /usr/themes/default/functions.php: -------------------------------------------------------------------------------- 1 | addInput($logoUrl); 7 | 8 | $sidebarBlock = new Typecho_Widget_Helper_Form_Element_Checkbox('sidebarBlock', 9 | array('ShowRecentPosts' => _t('显示最新文章'), 10 | 'ShowRecentComments' => _t('显示最近回复'), 11 | 'ShowCategory' => _t('显示分类'), 12 | 'ShowArchive' => _t('显示归档'), 13 | 'ShowOther' => _t('显示其它杂项')), 14 | array('ShowRecentPosts', 'ShowRecentComments', 'ShowCategory', 'ShowArchive', 'ShowOther'), _t('侧边栏显示')); 15 | 16 | $form->addInput($sidebarBlock->multiMode()); 17 | } 18 | 19 | 20 | /* 21 | function themeFields($layout) { 22 | $logoUrl = new Typecho_Widget_Helper_Form_Element_Text('logoUrl', NULL, NULL, _t('站点LOGO地址'), _t('在这里填入一个图片URL地址, 以在网站标题前加上一个LOGO')); 23 | $layout->addItem($logoUrl); 24 | } 25 | */ 26 | 27 | -------------------------------------------------------------------------------- /admin/options-reading.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 | form()->render(); ?> 13 |
    14 |
    15 |
    16 |
    17 | 18 | 23 | 35 | 38 | -------------------------------------------------------------------------------- /var/Widget/Contents/Post/Recent.php: -------------------------------------------------------------------------------- 1 | parameter->setDefault(array('pageSize' => $this->options->postsListSize)); 32 | 33 | $this->db->fetchAll($this->select() 34 | ->where('table.contents.status = ?', 'publish') 35 | ->where('table.contents.created < ?', $this->options->gmtTime) 36 | ->where('table.contents.type = ?', 'post') 37 | ->order('table.contents.created', Typecho_Db::SORT_DESC) 38 | ->limit($this->parameter->pageSize), array($this, 'push')); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | Version 0.8.1/12.4.1 2 | 3 | 修复同级子目录下安装多个站点引起的登录失效 4 | 增加评论黑名单插件 5 | 修复评论接口重用导致启用评论验证插件后,后台无法评论的bug 6 | 修正年份路由的bug 7 | 修正由于flash的cookie丢失bug导致的文件无法上传bug 8 | 增加对ini_get的判断 9 | 提交对Sina App Engine的兼容性判断 10 | 增加对Sina App Engine环境的支持 11 | 增加对ini_get的判断 12 | 修正新注册用户登录后跳转错误bug 13 | 修正对ssl的支持 14 | fix issue 510 15 | 修复使用多层代理时, 获取ip地址错误 16 | 修正修改文章时上传控件无法载入的问题 17 | 修改后台错别字 18 | 修正错别字 19 | 兼容server不支持http 1.1的情况,典型问题如 sae环境404页面乱码 20 | 修正由于SAE更改常用导致的数据库信息无法自动读入的问题 21 | 增加上传插件接口 22 | 提交Sina App Engine专用的文件上传插件, 23 | 使用SAE的Storage做持久化存储。 24 | 修正SaeUpload插件的说明地址 25 | new version library 26 | 只是一些小修正 27 | fix bug report on segmentfault 28 | fix issue 536 29 | fix Issue 541 30 | fix Issue 544 31 | fix Issue 544 32 | fix Issue 540 33 | fix Issue 537 34 | fix Issue 529 35 | fix Issue 532 36 | fix issue 526 37 | 文章增加待审核功能,下一步给文章增加private属性 38 | 更新后台表单样式, 新增文章预览功能 39 | css细节微调 40 | 文章增加private属性显示 41 | 修正插件显示空白问题, 预览框box修正 42 | 修改预览内容样式,修改预览选项位置,高级选项->权限控制增加“允许游客访问”选项,用于私密浏览 43 | fix Issue 545 44 | 实现文章公开度:公开、密码保护、私有、未审核 45 | little change 46 | 实现功能:1,当用户之前有审核通过的评论,再次发评论会直接为通过审核(可关闭);2,未通过审核的评论,评论作者可以在前台看到(他人不可见);3,隐藏功能; 47 | 修正后台修改或添加页面状态错误的问题;修正保存私密、审核日志时会新增一篇同样日志的问题 48 | 简单增强搜索功能 Issue 480 49 | 添加有密码和未发布图标 50 | fix Issue 551 51 | 将文章管理页的公开度草稿等信息改为文字 52 | 接受插件返回的header 53 | -------------------------------------------------------------------------------- /var/IXR/Request.php: -------------------------------------------------------------------------------- 1 | htmlspecialchars) 5 | Site: http://scripts.incutio.com/xmlrpc/ 6 | Manual: http://scripts.incutio.com/xmlrpc/manual.php 7 | Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php 8 | */ 9 | 10 | /** 11 | * IXR请求体 12 | * 13 | * @package IXR 14 | */ 15 | class IXR_Request { 16 | var $method; 17 | var $args; 18 | var $xml; 19 | function IXR_Request($method, $args) { 20 | $this->method = $method; 21 | $this->args = $args; 22 | $this->xml = << 24 | 25 | {$this->method} 26 | 27 | 28 | EOD; 29 | foreach ($this->args as $arg) { 30 | $this->xml .= ''; 31 | $v = new IXR_Value($arg); 32 | $this->xml .= $v->getXml(); 33 | $this->xml .= "\n"; 34 | } 35 | $this->xml .= ''; 36 | } 37 | function getLength() { 38 | return strlen($this->xml); 39 | } 40 | function getXml() { 41 | return $this->xml; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /var/Widget/Contents/Attachment/Unattached.php: -------------------------------------------------------------------------------- 1 | select()->where('table.contents.type = ? AND 33 | (table.contents.parent = 0 OR table.contents.parent IS NULL)', 'attachment'); 34 | 35 | /** 加上对用户的判断 */ 36 | $this->where('table.contents.authorId = ?', $this->user->uid); 37 | 38 | /** 提交查询 */ 39 | $select->order('table.contents.created', Typecho_Db::SORT_DESC); 40 | 41 | $this->db->fetchAll($select, array($this, 'push')); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /var/IXR/ClientMulticall.php: -------------------------------------------------------------------------------- 1 | htmlspecialchars) 6 | Site: http://scripts.incutio.com/xmlrpc/ 7 | Manual: http://scripts.incutio.com/xmlrpc/manual.php 8 | Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php 9 | */ 10 | 11 | /** 12 | * IXR客户端 13 | * 14 | * @package IXR 15 | */ 16 | class IXR_ClientMulticall extends IXR_Client { 17 | var $calls = array(); 18 | function IXR_ClientMulticall($server, $path = false, $port = 80) { 19 | parent::IXR_Client($server, $path, $port); 20 | $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)'; 21 | } 22 | function addCall() { 23 | $args = func_get_args(); 24 | $methodName = array_shift($args); 25 | $struct = array( 26 | 'methodName' => $methodName, 27 | 'params' => $args 28 | ); 29 | $this->calls[] = $struct; 30 | } 31 | function query() { 32 | // Prepare multicall, then call the parent::query() method 33 | return parent::query('system.multicall', $this->calls); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /admin/options-theme.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 |
      13 |
    • 14 | 15 |
    • 16 | 17 |
    • 18 |
    19 |
    20 |
    21 | config()->render(); ?> 22 |
    23 |
    24 |
    25 |
    26 | 27 | 33 | -------------------------------------------------------------------------------- /var/Typecho/Plugin/Interface.php: -------------------------------------------------------------------------------- 1 | select()->where('table.contents.type = ?', 'page') 33 | ->where('table.contents.status = ?', 'publish') 34 | ->where('table.contents.created < ?', $this->options->gmtTime) 35 | ->order('table.contents.order', Typecho_Db::SORT_ASC); 36 | 37 | //去掉自定义首页 38 | $frontPage = explode(':', $this->options->frontPage); 39 | if (2 == count($frontPage) && 'page' == $frontPage[0]) { 40 | $select->where('table.contents.cid <> ?', $frontPage[1]); 41 | } 42 | 43 | $this->db->fetchAll($select, array($this, 'push')); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /install/Pgsql.php: -------------------------------------------------------------------------------- 1 | 2 |
  • 3 | 4 | 5 |

    6 |
  • 7 |
  • 8 | 9 | 10 |

    11 |
  • 12 |
  • 13 | 14 | 15 |

    16 |
  • 17 |
  • 18 | 19 | 20 |
  • 21 |
  • 22 | 23 | 24 |

    25 |
  • 26 | 27 | -------------------------------------------------------------------------------- /usr/themes/default/post.php: -------------------------------------------------------------------------------- 1 | 2 | need('header.php'); ?> 3 | 4 |
    5 |
    6 |

    title() ?>

    7 | 12 |
    13 | content(); ?> 14 |
    15 |

    tags(', ', true, 'none'); ?>

    16 |
    17 | 18 | need('comments.php'); ?> 19 | 20 | 24 |
    25 | 26 | need('sidebar.php'); ?> 27 | need('footer.php'); ?> 28 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Submit.php: -------------------------------------------------------------------------------- 1 | setAttribute('class', 'typecho-option typecho-option-submit'); 34 | $input = new Typecho_Widget_Helper_Layout('button', array('type' => 'submit')); 35 | $this->container($input); 36 | $this->inputs[] = $input; 37 | 38 | return $input; 39 | } 40 | 41 | /** 42 | * 设置表单元素值 43 | * 44 | * @access protected 45 | * @param mixed $value 表单元素值 46 | * @return void 47 | */ 48 | protected function _value($value) 49 | { 50 | $this->input->html($value); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /var/Typecho/Http/Client.php: -------------------------------------------------------------------------------- 1 | select()->where('type = ?', 'tag')->order('mid', Typecho_Db::SORT_DESC); 32 | $this->db->fetchAll($select, array($this, 'push')); 33 | } 34 | 35 | /** 36 | * 获取菜单标题 37 | * 38 | * @access public 39 | * @return string 40 | */ 41 | public function getMenuTitle() 42 | { 43 | if (isset($this->request->mid)) { 44 | $tag = $this->db->fetchRow($this->select() 45 | ->where('type = ? AND mid = ?', 'tag', $this->request->mid)); 46 | 47 | if (!empty($tag)) { 48 | return _t('编辑标签 %s', $tag['name']); 49 | } 50 | } else { 51 | return; 52 | } 53 | 54 | throw new Typecho_Widget_Exception(_t('标签不存在'), 404); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /var/Widget/Contents/Related/Author.php: -------------------------------------------------------------------------------- 1 | parameter->setDefault('limit=5'); 33 | 34 | if ($this->parameter->author) { 35 | $this->db->fetchAll($this->select() 36 | ->where('table.contents.authorId = ?', $this->parameter->author) 37 | ->where('table.contents.cid <> ?', $this->parameter->cid) 38 | ->where('table.contents.status = ?', 'publish') 39 | ->where('table.contents.password IS NULL') 40 | ->where('table.contents.created < ?', $this->options->gmtTime) 41 | ->where('table.contents.type = ?', $this->parameter->type) 42 | ->order('table.contents.created', Typecho_Db::SORT_DESC) 43 | ->limit($this->parameter->limit), array($this, 'push')); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Textarea.php: -------------------------------------------------------------------------------- 1 | $name . '-0-' . self::$uniqueId, 'name' => $name)); 34 | $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); 35 | $this->container($input->setClose(false)); 36 | $this->inputs[] = $input; 37 | 38 | return $input; 39 | } 40 | 41 | /** 42 | * 设置表单项默认值 43 | * 44 | * @access protected 45 | * @param string $value 表单项默认值 46 | * @return void 47 | */ 48 | protected function _value($value) 49 | { 50 | $this->input->html(htmlspecialchars($value)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /admin/file-upload.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | cid : $page->cid; 6 | 7 | if ($cid) { 8 | Typecho_Widget::widget('Widget_Contents_Attachment_Related', 'parentId=' . $cid)->to($attachment); 9 | } else { 10 | Typecho_Widget::widget('Widget_Contents_Attachment_Unattached')->to($attachment); 11 | } 12 | } 13 | ?> 14 | 15 |
    16 |
    或者 %s选择文件上传%s', '', ''); ?>
    17 | 29 |
    30 | 31 | -------------------------------------------------------------------------------- /admin/upgrade.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 |
    13 |
    16 |

    17 |
      18 |
    • 19 |
    • %s 升级到 %s', $options->version, Typecho_Common::VERSION); ?>
    • 20 |
    • 21 |
    22 |

    23 |
    24 |
    25 |
    26 |
    27 |
    28 |
    29 | 30 | 34 | 41 | 42 | -------------------------------------------------------------------------------- /admin/welcome.php: -------------------------------------------------------------------------------- 1 | 6 | 7 |
    8 |
    9 | 10 |
    11 |
    12 |
    13 |
    14 |

    title); ?>

    15 |
      16 |
    1. 17 | pass('contributor', true)): ?> 18 |
    2. 19 |
    3. 20 | 21 |
    4. 22 | 23 |
    24 |

    25 |
    26 |
    27 |
    28 |
    29 |
    30 |
    31 | 32 | 37 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Text.php: -------------------------------------------------------------------------------- 1 | $name . '-0-' . self::$uniqueId, 34 | 'name' => $name, 'type' => 'text', 'class' => 'text')); 35 | $this->container($input); 36 | $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); 37 | $this->inputs[] = $input; 38 | 39 | return $input; 40 | } 41 | 42 | /** 43 | * 设置表单项默认值 44 | * 45 | * @access protected 46 | * @param mixed $value 表单项默认值 47 | * @return void 48 | */ 49 | protected function _value($value) 50 | { 51 | $this->input->setAttribute('value', htmlspecialchars($value)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Password.php: -------------------------------------------------------------------------------- 1 | $name . '-0-' . self::$uniqueId, 34 | 'name' => $name, 'type' => 'password', 'class' => 'password')); 35 | $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); 36 | $this->container($input); 37 | $this->inputs[] = $input; 38 | return $input; 39 | } 40 | 41 | /** 42 | * 设置表单项默认值 43 | * 44 | * @access protected 45 | * @param string $value 表单项默认值 46 | * @return void 47 | */ 48 | protected function _value($value) 49 | { 50 | $this->input->setAttribute('value', htmlspecialchars($value)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /usr/themes/default/index.php: -------------------------------------------------------------------------------- 1 | need('header.php'); 13 | ?> 14 | 15 |
    16 | next()): ?> 17 | 29 | 30 | 31 | pageNav('« 前一页', '后一页 »'); ?> 32 |
    33 | 34 | need('sidebar.php'); ?> 35 | need('footer.php'); ?> 36 | -------------------------------------------------------------------------------- /var/Widget/Contents/Attachment/Related.php: -------------------------------------------------------------------------------- 1 | parameter->setDefault('parentId=0&limit=0'); 32 | 33 | //如果没有cid值 34 | if (!$this->parameter->parentId) { 35 | return; 36 | } 37 | 38 | /** 构建基础查询 */ 39 | $select = $this->select()->where('table.contents.type = ?', 'attachment'); 40 | 41 | //order字段在文件里代表所属文章 42 | $select->where('table.contents.parent = ?', $this->parameter->parentId); 43 | 44 | /** 提交查询 */ 45 | $select->order('table.contents.created', Typecho_Db::SORT_ASC); 46 | 47 | if ($this->parameter->limit > 0) { 48 | $select->limit($this->parameter->limit); 49 | } 50 | 51 | if ($this->parameter->offset > 0) { 52 | $select->offset($this->parameter->offset); 53 | } 54 | 55 | $this->db->fetchAll($select, array($this, 'push')); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Hidden.php: -------------------------------------------------------------------------------- 1 | setAttribute('style', 'display:none'); 33 | } 34 | 35 | /** 36 | * 初始化当前输入项 37 | * 38 | * @access public 39 | * @param string $name 表单元素名称 40 | * @param array $options 选择项 41 | * @return Typecho_Widget_Helper_Layout 42 | */ 43 | public function input($name = NULL, array $options = NULL) 44 | { 45 | $input = new Typecho_Widget_Helper_Layout('input', array('name' => $name, 'type' => 'hidden')); 46 | $this->container($input); 47 | $this->inputs[] = $input; 48 | return $input; 49 | } 50 | 51 | /** 52 | * 设置表单项默认值 53 | * 54 | * @access protected 55 | * @param string $value 表单项默认值 56 | * @return void 57 | */ 58 | protected function _value($value) 59 | { 60 | $this->input->setAttribute('value', htmlspecialchars($value)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /admin/header.php: -------------------------------------------------------------------------------- 1 | adminStaticUrl('css')) . '"> 7 | 8 | 9 | '; 13 | 14 | /** 注册一个初始化插件 */ 15 | $header = Typecho_Plugin::factory('admin/header.php')->header($header); 16 | 17 | ?> 18 | 19 | 20 | 21 | 22 | 23 | 24 | <?php _e('%s - %s - Powered by Typecho', $menu->title, $options->title); ?> 25 | 26 | 27 | 28 | > 29 | 32 | -------------------------------------------------------------------------------- /var/IXR/Error.php: -------------------------------------------------------------------------------- 1 | htmlspecialchars) 5 | Site: http://scripts.incutio.com/xmlrpc/ 6 | Manual: http://scripts.incutio.com/xmlrpc/manual.php 7 | Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php 8 | */ 9 | 10 | /** 11 | * IXR错误 12 | * 13 | * @package IXR 14 | */ 15 | class IXR_Error 16 | { 17 | /** 18 | * 错误代码 19 | * 20 | * @access public 21 | * @var integer 22 | */ 23 | public $code; 24 | 25 | /** 26 | * 错误消息 27 | * 28 | * @access public 29 | * @var string 30 | */ 31 | public $message; 32 | 33 | /** 34 | * 构造函数 35 | * 36 | * @access public 37 | * @param integer $code 错误代码 38 | * @param string $message 错误消息 39 | * @return void 40 | */ 41 | public function __construct($code, $message) 42 | { 43 | $this->code = $code; 44 | $this->message = $message; 45 | } 46 | 47 | /** 48 | * 获取xml 49 | * 50 | * @access public 51 | * @return string 52 | */ 53 | public function getXml() 54 | { 55 | $xml = << 57 | 58 | 59 | 60 | 61 | faultCode 62 | {$this->code} 63 | 64 | 65 | faultString 66 | {$this->message} 67 | 68 | 69 | 70 | 71 | 72 | 73 | EOD; 74 | return $xml; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /var/Widget/Metas/Tag/Cloud.php: -------------------------------------------------------------------------------- 1 | parameter->setDefault(array('sort' => 'count', 'ignoreZeroCount' => false, 'desc' => true, 'limit' => 0)); 32 | $select = $this->select()->where('type = ?', 'tag')->order($this->parameter->sort, 33 | $this->parameter->desc ? Typecho_Db::SORT_DESC : Typecho_Db::SORT_ASC); 34 | 35 | /** 忽略零数量 */ 36 | if ($this->parameter->ignoreZeroCount) { 37 | $select->where('count > 0'); 38 | } 39 | 40 | /** 总数限制 */ 41 | if ($this->parameter->limit) { 42 | $select->limit($this->parameter->limit); 43 | } 44 | 45 | $this->db->fetchAll($select, array($this, 'push')); 46 | } 47 | 48 | /** 49 | * 按分割数输出字符串 50 | * 51 | * @access public 52 | * @param string $param 需要输出的值 53 | * @return void 54 | */ 55 | public function split() 56 | { 57 | $args = func_get_args(); 58 | array_unshift($args, $this->count); 59 | echo call_user_func_array(array('Typecho_Common', 'splitByCount'), $args); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /usr/plugins/HelloWorld/Plugin.php: -------------------------------------------------------------------------------- 1 | navBar = array('HelloWorld_Plugin', 'render'); 23 | } 24 | 25 | /** 26 | * 禁用插件方法,如果禁用失败,直接抛出异常 27 | * 28 | * @static 29 | * @access public 30 | * @return void 31 | * @throws Typecho_Plugin_Exception 32 | */ 33 | public static function deactivate(){} 34 | 35 | /** 36 | * 获取插件配置面板 37 | * 38 | * @access public 39 | * @param Typecho_Widget_Helper_Form $form 配置面板 40 | * @return void 41 | */ 42 | public static function config(Typecho_Widget_Helper_Form $form) 43 | { 44 | /** 分类名称 */ 45 | $name = new Typecho_Widget_Helper_Form_Element_Text('word', NULL, 'Hello World', _t('说点什么')); 46 | $form->addInput($name); 47 | } 48 | 49 | /** 50 | * 个人用户的配置面板 51 | * 52 | * @access public 53 | * @param Typecho_Widget_Helper_Form $form 54 | * @return void 55 | */ 56 | public static function personalConfig(Typecho_Widget_Helper_Form $form){} 57 | 58 | /** 59 | * 插件实现方法 60 | * 61 | * @access public 62 | * @return void 63 | */ 64 | public static function render() 65 | { 66 | echo '' 67 | . htmlspecialchars(Typecho_Widget::widget('Widget_Options')->plugin('HelloWorld')->word) 68 | . ''; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /admin/custom-fields-js.php: -------------------------------------------------------------------------------- 1 | 2 | 45 | -------------------------------------------------------------------------------- /var/IXR/Date.php: -------------------------------------------------------------------------------- 1 | htmlspecialchars) 5 | Site: http://scripts.incutio.com/xmlrpc/ 6 | Manual: http://scripts.incutio.com/xmlrpc/manual.php 7 | Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php 8 | */ 9 | 10 | /** 11 | * IXR日期 12 | * 13 | * @package IXR 14 | */ 15 | class IXR_Date { 16 | var $year; 17 | var $month; 18 | var $day; 19 | var $hour; 20 | var $minute; 21 | var $second; 22 | function IXR_Date($time) { 23 | // $time can be a PHP timestamp or an ISO one 24 | if (is_numeric($time)) { 25 | $this->parseTimestamp($time); 26 | } else { 27 | $this->parseIso($time); 28 | } 29 | } 30 | function parseTimestamp($timestamp) { 31 | $this->year = date('Y', $timestamp); 32 | $this->month = date('m', $timestamp); 33 | $this->day = date('d', $timestamp); 34 | $this->hour = date('H', $timestamp); 35 | $this->minute = date('i', $timestamp); 36 | $this->second = date('s', $timestamp); 37 | } 38 | function parseIso($iso) { 39 | $this->year = substr($iso, 0, 4); 40 | $this->month = substr($iso, 4, 2); 41 | $this->day = substr($iso, 6, 2); 42 | $this->hour = substr($iso, 9, 2); 43 | $this->minute = substr($iso, 12, 2); 44 | $this->second = substr($iso, 15, 2); 45 | } 46 | function getIso() { 47 | return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; 48 | } 49 | function getXml() { 50 | return ''.$this->getIso().''; 51 | } 52 | function getTimestamp() { 53 | return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /var/Widget/Comments/Recent.php: -------------------------------------------------------------------------------- 1 | parameter->setDefault(array('pageSize' => $this->options->commentsListSize, 'parentId' => 0, 'ignoreAuthor' => false)); 34 | } 35 | 36 | /** 37 | * 执行函数 38 | * 39 | * @access public 40 | * @return void 41 | */ 42 | public function execute() 43 | { 44 | $select = $this->select()->limit($this->parameter->pageSize) 45 | ->where('table.comments.status = ?', 'approved') 46 | ->order('table.comments.coid', Typecho_Db::SORT_DESC); 47 | 48 | if ($this->parameter->parentId) { 49 | $select->where('cid = ?', $this->parameter->parentId); 50 | } 51 | 52 | if ($this->options->commentsShowCommentOnly) { 53 | $select->where('type = ?', 'comment'); 54 | } 55 | 56 | /** 忽略作者评论 */ 57 | if ($this->parameter->ignoreAuthor) { 58 | $select->where('ownerId <> authorId'); 59 | } 60 | 61 | $this->db->fetchAll($select, array($this, 'push')); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /admin/register.php: -------------------------------------------------------------------------------- 1 | hasLogin() || !$options->allowRegister) { 5 | $response->redirect($options->siteUrl); 6 | } 7 | $rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name')); 8 | $rememberMail = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_mail')); 9 | Typecho_Cookie::delete('__typecho_remember_name'); 10 | Typecho_Cookie::delete('__typecho_remember_mail'); 11 | 12 | $bodyClass = 'body-100'; 13 | 14 | include 'header.php'; 15 | ?> 16 | 40 | 43 | 48 | 51 | -------------------------------------------------------------------------------- /usr/themes/default/archive.php: -------------------------------------------------------------------------------- 1 | 2 | need('header.php'); ?> 3 | 4 |
    5 |

    archiveTitle(array( 6 | 'category' => _t('分类 %s 下的文章'), 7 | 'search' => _t('包含关键字 %s 的文章'), 8 | 'tag' => _t('标签 %s 下的文章'), 9 | 'author' => _t('%s 发布的文章') 10 | ), '', ''); ?>

    11 | have()): ?> 12 | next()): ?> 13 | 25 | 26 | 27 |
    28 |

    29 |
    30 | 31 | 32 | pageNav('« 前一页', '后一页 »'); ?> 33 |
    34 | 35 | need('sidebar.php'); ?> 36 | need('footer.php'); ?> 37 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/PageNavigator/Classic.php: -------------------------------------------------------------------------------- 1 | prev($prevWord); 33 | $this->next($nextWord); 34 | } 35 | 36 | /** 37 | * 输出上一页 38 | * 39 | * @access public 40 | * @param string $prevWord 上一页文字 41 | * @return void 42 | */ 43 | public function prev($prevWord = 'PREV') 44 | { 45 | //输出上一页 46 | if ($this->_total > 0 && $this->_currentPage > 1) { 47 | echo ''; 49 | } 50 | } 51 | 52 | /** 53 | * 输出下一页 54 | * 55 | * @access public 56 | * @param string $prevWord 下一页文字 57 | * @return void 58 | */ 59 | public function next($nextWord = 'NEXT') 60 | { 61 | //输出下一页 62 | if ($this->_total > 0 && $this->_currentPage < $this->_totalPage) { 63 | echo ''; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Fake.php: -------------------------------------------------------------------------------- 1 | name = $name; 34 | self::$uniqueId ++; 35 | 36 | /** 运行自定义初始函数 */ 37 | $this->init(); 38 | 39 | /** 初始化表单项 */ 40 | $this->input = $this->input($name, $options); 41 | 42 | /** 初始化表单值 */ 43 | if (NULL !== $value) { 44 | $this->value($value); 45 | } 46 | } 47 | 48 | /** 49 | * 自定义初始函数 50 | * 51 | * @access public 52 | * @return void 53 | */ 54 | public function init() 55 | {} 56 | 57 | /** 58 | * 初始化当前输入项 59 | * 60 | * @access public 61 | * @param string $name 表单元素名称 62 | * @param array $options 选择项 63 | * @return Typecho_Widget_Helper_Layout 64 | */ 65 | public function input($name = NULL, array $options = NULL) 66 | { 67 | $input = new Typecho_Widget_Helper_Layout('input'); 68 | $this->inputs[] = $input; 69 | return $input; 70 | } 71 | 72 | /** 73 | * 设置表单项默认值 74 | * 75 | * @access protected 76 | * @param string $value 表单项默认值 77 | * @return void 78 | */ 79 | protected function _value($value) 80 | { 81 | $this->input->setAttribute('value', $value); 82 | } 83 | } 84 | 85 | -------------------------------------------------------------------------------- /var/Widget/Notice.php: -------------------------------------------------------------------------------- 1 | highlight = $theId; 36 | Typecho_Cookie::set('__typecho_notice_highlight', $theId, 37 | $this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400); 38 | } 39 | 40 | /** 41 | * 获取高亮的id 42 | * 43 | * @access public 44 | * @return integer 45 | */ 46 | public function getHighlightId() 47 | { 48 | return preg_match("/[0-9]+/", $this->highlight, $matches) ? $matches[0] : 0; 49 | } 50 | 51 | /** 52 | * 设定堆栈每一行的值 53 | * 54 | * @param string $value 值对应的键值 55 | * @param string $type 提示类型 56 | * @param string $typeFix 兼容老插件 57 | * @return array 58 | */ 59 | public function set($value, $type = 'notice', $typeFix = 'notice') 60 | { 61 | $notice = is_array($value) ? array_values($value) : array($value); 62 | if (empty($type) && $typeFix) { 63 | $type = $typeFix; 64 | } 65 | 66 | Typecho_Cookie::set('__typecho_notice', Json::encode($notice), 67 | $this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400); 68 | Typecho_Cookie::set('__typecho_notice_type', $type, 69 | $this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Select.php: -------------------------------------------------------------------------------- 1 | container($input->setAttribute('name', $name) 43 | ->setAttribute('id', $name . '-0-' . self::$uniqueId)); 44 | $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); 45 | $this->inputs[] = $input; 46 | 47 | foreach ($options as $value => $label) { 48 | $this->_options[$value] = new Typecho_Widget_Helper_Layout('option'); 49 | $input->addItem($this->_options[$value]->setAttribute('value', $value)->html($label)); 50 | } 51 | 52 | return $input; 53 | } 54 | 55 | /** 56 | * 设置表单元素值 57 | * 58 | * @access protected 59 | * @param mixed $value 表单元素值 60 | * @return void 61 | */ 62 | protected function _value($value) 63 | { 64 | foreach ($this->_options as $option) { 65 | $option->removeAttribute('selected'); 66 | } 67 | 68 | if (isset($this->_options[$value])) { 69 | $this->_options[$value]->setAttribute('selected', 'true'); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /admin/login.php: -------------------------------------------------------------------------------- 1 | hasLogin()) { 5 | $response->redirect($options->adminUrl); 6 | } 7 | $rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name')); 8 | Typecho_Cookie::delete('__typecho_remember_name'); 9 | 10 | $bodyClass = 'body-100'; 11 | 12 | include 'header.php'; 13 | ?> 14 | 44 | 47 | 52 | 55 | -------------------------------------------------------------------------------- /admin/common.php: -------------------------------------------------------------------------------- 1 | begin(); 19 | 20 | Typecho_Widget::widget('Widget_Options')->to($options); 21 | Typecho_Widget::widget('Widget_User')->to($user); 22 | Typecho_Widget::widget('Widget_Security')->to($security); 23 | Typecho_Widget::widget('Widget_Menu')->to($menu); 24 | 25 | /** 初始化上下文 */ 26 | $request = $options->request; 27 | $response = $options->response; 28 | 29 | /** 检测是否是第一次登录 */ 30 | $currentMenu = $menu->getCurrentMenu(); 31 | list($prefixVersion, $suffixVersion) = explode('/', $options->version); 32 | $params = parse_url($currentMenu[2]); 33 | $adminFile = basename($params['path']); 34 | 35 | if (!$user->logged && !Typecho_Cookie::get('__typecho_first_run') && !empty($currentMenu)) { 36 | 37 | if ('welcome.php' != $adminFile) { 38 | $response->redirect(Typecho_Common::url('welcome.php', $options->adminUrl)); 39 | } else { 40 | Typecho_Cookie::set('__typecho_first_run', 1); 41 | } 42 | 43 | } else { 44 | 45 | /** 检测版本是否升级 */ 46 | if ($user->pass('administrator', true) && !empty($currentMenu)) { 47 | $mustUpgrade = (!defined('Typecho_Common::VERSION') || version_compare(str_replace('/', '.', Typecho_Common::VERSION), 48 | str_replace('/', '.', $options->version), '>')); 49 | 50 | if ($mustUpgrade && 'upgrade.php' != $adminFile) { 51 | $response->redirect(Typecho_Common::url('upgrade.php', $options->adminUrl)); 52 | } else if (!$mustUpgrade && 'upgrade.php' == $adminFile) { 53 | $response->redirect($options->adminUrl); 54 | } else if (!$mustUpgrade && 'welcome.php' == $adminFile && $user->logged) { 55 | $response->redirect($options->adminUrl); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /admin/scss/components/_tokeninput.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Jquery Tokeninput 3 | */ 4 | 5 | ul.token-input-list { 6 | list-style: none; 7 | margin: 0; 8 | padding: 0 4px; 9 | min-height: 32px; 10 | border: 1px solid #D9D9D6; 11 | cursor: text; 12 | z-index: 999; 13 | background-color: #FFF; 14 | clear: left; 15 | 16 | border-radius: 2px; 17 | 18 | -webkit-box-sizing: border-box; 19 | -moz-box-sizing: border-box; 20 | box-sizing: border-box; 21 | 22 | li { 23 | margin: 4px 0; 24 | } 25 | } 26 | 27 | 28 | ul.token-input-list li input { 29 | padding: 0; 30 | border: 0; 31 | width: 100%; 32 | -webkit-appearance: caret; 33 | } 34 | 35 | li.token-input-token { 36 | padding: 0 6px; 37 | height: 27px; 38 | line-height: 27px; 39 | background-color: #F3F3F0; 40 | cursor: default; 41 | font-size: .92857em; 42 | text-align: right; 43 | white-space: nowrap; 44 | p { 45 | float: left; 46 | display: inline; 47 | margin: 0; 48 | } 49 | span { 50 | color: #BBB; 51 | font-weight: bold; 52 | cursor: pointer; 53 | } 54 | } 55 | 56 | 57 | 58 | li.token-input-selected-token { 59 | background-color: #E9E9E6; 60 | } 61 | 62 | li.token-input-input-token { 63 | padding: 0 4px; 64 | } 65 | 66 | div.token-input-dropdown { 67 | position: absolute; 68 | background-color: #FFF; 69 | overflow: hidden; 70 | border: 1px solid #D9D9D6; 71 | border-top-width: 0; 72 | cursor: default; 73 | z-index: 1; 74 | font-size: .92857em; 75 | } 76 | 77 | div.token-input-dropdown p { 78 | margin: 0; 79 | padding: 5px 10px; 80 | color: #777; 81 | font-weight: bold; 82 | } 83 | 84 | div.token-input-dropdown ul { 85 | list-style: none; 86 | margin: 0; 87 | padding: 0; 88 | } 89 | 90 | div.token-input-dropdown ul li { 91 | padding: 4px 10px; 92 | background-color: #FFF; 93 | } 94 | 95 | div.token-input-dropdown ul li.token-input-dropdown-item { 96 | background-color: #FFF; 97 | } 98 | 99 | div.token-input-dropdown ul li em { 100 | font-style: normal; 101 | } 102 | 103 | div.token-input-dropdown ul li.token-input-selected-dropdown-item { 104 | background-color: #467B96; 105 | color: #FFF; 106 | } -------------------------------------------------------------------------------- /admin/scss/_buttons.scss: -------------------------------------------------------------------------------- 1 | @import "compass"; 2 | 3 | /** 4 | * Buttons 5 | */ 6 | 7 | @mixin button($color) { 8 | border: none; 9 | background-color: $color; 10 | cursor: pointer; 11 | 12 | @include border-radius(2px); 13 | // @include transition-property(background-color); 14 | 15 | &:hover { 16 | @include transition-duration(.4s); 17 | background-color: darken($color, 6%); 18 | } 19 | &:active, &.active { 20 | background-color: darken($color, 8%); 21 | } 22 | &:disabled { 23 | background-color: lighten($color, 6%); 24 | cursor: default; 25 | } 26 | } 27 | 28 | .btn { 29 | @include button(#E9E9E6); 30 | 31 | display: inline-block; 32 | padding: 0 12px; 33 | height: 32px; 34 | color: #666; 35 | vertical-align: middle; 36 | zoom: 1; 37 | 38 | &:disabled { 39 | color: #999; 40 | } 41 | } 42 | 43 | .btn-xs { 44 | padding: 0 10px; 45 | height: 25px; 46 | font-size: 13px; 47 | } 48 | .btn-s { height: 28px; } 49 | .btn-l { 50 | height: 40px; 51 | font-size: 1.14286em; 52 | font-weight: bold; 53 | } 54 | 55 | .primary { 56 | @include button(#467B96); 57 | color: #FFF; 58 | } 59 | 60 | .btn-group { 61 | display: inline-block; 62 | } 63 | 64 | .btn-warn { 65 | @include button(#B94A48); 66 | color: #FFF; 67 | } 68 | 69 | .btn-link, 70 | .btn-link:hover, 71 | .btn-link:focus, 72 | .btn-link:active, 73 | .btn-link.active { 74 | background-color: transparent; 75 | } 76 | 77 | /* 下拉菜单 */ 78 | .btn-drop { 79 | position: relative; 80 | } 81 | .dropdown-toggle { 82 | padding-right: 8px; 83 | } 84 | .dropdown-menu { 85 | list-style: none; 86 | position: absolute; 87 | z-index: 2; 88 | left: 0; 89 | margin: 0; 90 | padding: 0; 91 | border: 1px solid #D9D9D6; 92 | background: #FFF; 93 | text-align: left; 94 | min-width: 108px; 95 | display: none; 96 | 97 | li { 98 | white-space: nowrap; 99 | &.multiline { 100 | padding: 5px 12px 12px; 101 | } 102 | } 103 | 104 | a { 105 | display: block; 106 | padding: 5px 12px; 107 | color: #666; 108 | &:hover { 109 | background: #F6F6F3; 110 | text-decoration: none !important; 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /admin/scss/_header.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 后台头部导航 3 | */ 4 | .typecho-head-nav { 5 | padding: 0 10px; 6 | background: #292D33; 7 | } 8 | 9 | .typecho-head-nav a { 10 | color: #BBB; 11 | } 12 | .typecho-head-nav a:hover, 13 | .typecho-head-nav a:focus { 14 | color: #FFF; 15 | text-decoration: none; 16 | } 17 | 18 | #typecho-nav-list { 19 | float: left; 20 | ul { 21 | list-style: none; 22 | margin: 0; 23 | padding: 0; 24 | } 25 | } 26 | 27 | #typecho-nav-list ul:first-child { 28 | border-left: 1px solid #383D45; 29 | } 30 | 31 | #typecho-nav-list .root { 32 | position: relative; 33 | float: left; 34 | } 35 | 36 | #typecho-nav-list .parent a { 37 | display: block; 38 | float: left; 39 | padding: 0 20px; 40 | border-right: 1px solid #383D45; 41 | height: 36px; 42 | line-height: 36px; 43 | color: #BBB; 44 | } 45 | 46 | #typecho-nav-list .parent a:hover, 47 | #typecho-nav-list .focus .parent a, 48 | #typecho-nav-list .root:hover .parent a { 49 | background: #202328; 50 | color: #FFF; 51 | text-decoration: none; 52 | } 53 | 54 | #typecho-nav-list .focus .parent a { 55 | font-weight: bold; 56 | } 57 | 58 | #typecho-nav-list .child { 59 | position: absolute; 60 | top: 36px; 61 | display: none; 62 | margin: 0; 63 | min-width: 160px; 64 | max-width: 240px; 65 | background: #202328; 66 | z-index: 250; 67 | } 68 | 69 | #typecho-nav-list .root:hover .child { 70 | display: block; 71 | } 72 | 73 | #typecho-nav-list .child li a { 74 | color: #BBB; 75 | display: block; 76 | padding: 0 20px; 77 | overflow: hidden; 78 | text-overflow : ellipsis; 79 | white-space: nowrap; 80 | height: 36px; 81 | line-height: 36px; 82 | } 83 | 84 | #typecho-nav-list .child li a:hover, 85 | #typecho-nav-list .child li a:focus { 86 | background: #292D33; 87 | color: #FFF; 88 | } 89 | #typecho-nav-list .child li.focus a { 90 | color: #6DA1BB; 91 | font-weight: bold; 92 | } 93 | 94 | .typecho-head-nav .operate { 95 | float: right; 96 | } 97 | .typecho-head-nav .operate a { 98 | display: inline-block; 99 | margin-left: -1px; 100 | padding: 0 20px; 101 | border: 1px solid #383D45; 102 | border-width: 0 1px; 103 | line-height: 36px; 104 | color: #BBB; 105 | } 106 | .typecho-head-nav .operate a:hover { 107 | background-color: #202328; 108 | color: #FFF; 109 | } -------------------------------------------------------------------------------- /var/Widget/Contents/Related.php: -------------------------------------------------------------------------------- 1 | db->select('DISTINCT table.contents.cid', 'table.contents.title', 'table.contents.slug', 'table.contents.created', 'table.contents.authorId', 33 | 'table.contents.modified', 'table.contents.type', 'table.contents.status', 'table.contents.text', 'table.contents.commentsNum', 'table.contents.order', 34 | 'table.contents.template', 'table.contents.password', 'table.contents.allowComment', 'table.contents.allowPing', 'table.contents.allowFeed') 35 | ->from('table.contents'); 36 | } 37 | 38 | /** 39 | * 执行函数,初始化数据 40 | * 41 | * @access public 42 | * @return void 43 | */ 44 | public function execute() 45 | { 46 | $this->parameter->setDefault('limit=5'); 47 | 48 | if ($this->parameter->tags) { 49 | $tagsGroup = implode(',', Typecho_Common::arrayFlatten($this->parameter->tags, 'mid')); 50 | $this->db->fetchAll($this->select() 51 | ->join('table.relationships', 'table.contents.cid = table.relationships.cid') 52 | ->where('table.relationships.mid IN (' . $tagsGroup . ')') 53 | ->where('table.contents.cid <> ?', $this->parameter->cid) 54 | ->where('table.contents.status = ?', 'publish') 55 | ->where('table.contents.password IS NULL') 56 | ->where('table.contents.created < ?', $this->options->gmtTime) 57 | ->where('table.contents.type = ?', $this->parameter->type) 58 | ->order('table.contents.created', Typecho_Db::SORT_DESC) 59 | ->limit($this->parameter->limit), array($this, 'push')); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /var/Widget/Contents/Page/Admin.php: -------------------------------------------------------------------------------- 1 | select(); 33 | if ($this->request->status == "publish") { 34 | // 显示已发布 35 | $select->where('table.contents.type = ? AND table.contents.status = ?', 'page', 'publish'); 36 | } 37 | else if ($this->request->status == "draft") { 38 | // 显示草稿 39 | $select->where('table.contents.type = ? AND table.contents.status = ?', 'page_draft', 'publish'); 40 | } 41 | else if ($this->request->status == "trash") { 42 | // 显示回收站 43 | $select->where('table.contents.type = ? OR (table.contents.type = ? AND table.contents.parent = ?)', 'page', 'page_draft', 0); 44 | $select->where('table.contents.status = ?', 'trash'); 45 | } 46 | else { 47 | // 显示所有(除回收站) 48 | $select->where('table.contents.type = ? OR (table.contents.type = ? AND table.contents.parent = ?)', 'page', 'page_draft', 0); 49 | $select->where('table.contents.status != ?', 'trash'); 50 | } 51 | 52 | /** 过滤标题 */ 53 | if (NULL != ($keywords = $this->request->keywords)) { 54 | $args = array(); 55 | $keywordsList = explode(' ', $keywords); 56 | $args[] = implode(' OR ', array_fill(0, count($keywordsList), 'table.contents.title LIKE ?')); 57 | 58 | foreach ($keywordsList as $keyword) { 59 | $args[] = '%' . Typecho_Common::filterSearchQuery($keyword) . '%'; 60 | } 61 | 62 | call_user_func_array(array($select, 'where'), $args); 63 | } 64 | 65 | /** 提交查询 */ 66 | $select->order('table.contents.order', Typecho_Db::SORT_ASC); 67 | 68 | $this->db->fetchAll($select, array($this, 'push')); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /var/Widget/Themes/Config.php: -------------------------------------------------------------------------------- 1 | user->pass('administrator'); 32 | 33 | if (!self::isExists()) { 34 | throw new Typecho_Widget_Exception(_t('外观配置功能不存在'), 404); 35 | } 36 | } 37 | 38 | /** 39 | * 配置功能是否存在 40 | * 41 | * @access public 42 | * @return boolean 43 | */ 44 | public static function isExists() 45 | { 46 | $options = Typecho_Widget::widget('Widget_Options'); 47 | $configFile = $options->themeFile($options->theme, 'functions.php'); 48 | 49 | if (file_exists($configFile)) { 50 | require_once $configFile; 51 | 52 | if (function_exists('themeConfig')) { 53 | return true; 54 | } 55 | } 56 | 57 | return false; 58 | } 59 | 60 | /** 61 | * 配置外观 62 | * 63 | * @access public 64 | * @return Typecho_Widget_Helper_Form 65 | */ 66 | public function config() 67 | { 68 | $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/themes-edit?config'), 69 | Typecho_Widget_Helper_Form::POST_METHOD); 70 | themeConfig($form); 71 | $inputs = $form->getInputs(); 72 | 73 | if (!empty($inputs)) { 74 | foreach ($inputs as $key => $val) { 75 | $form->getInput($key)->value($this->options->{$key}); 76 | } 77 | } 78 | 79 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); 80 | $submit->input->setAttribute('class', 'btn primary'); 81 | $form->addItem($submit); 82 | return $form; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /var/Widget/Init.php: -------------------------------------------------------------------------------- 1 | widget('Widget_Options'); 28 | 29 | /** 语言包初始化 */ 30 | if ($options->lang && $options->lang != 'zh_CN') { 31 | $dir = defined('__TYPECHO_LANG_DIR__') ? __TYPECHO_LANG_DIR__ : __TYPECHO_ROOT_DIR__ . '/usr/langs'; 32 | Typecho_I18n::setLang($dir . '/' . $options->lang . '.mo'); 33 | } 34 | 35 | /** cookie初始化 */ 36 | Typecho_Cookie::setPrefix($options->rootUrl); 37 | 38 | /** 初始化charset */ 39 | Typecho_Common::$charset = $options->charset; 40 | 41 | /** 初始化exception */ 42 | Typecho_Common::$exceptionHandle = 'Widget_ExceptionHandle'; 43 | 44 | /** 设置路径 */ 45 | if (defined('__TYPECHO_PATHINFO_ENCODING__')) { 46 | $pathInfo = $this->request->getPathInfo(__TYPECHO_PATHINFO_ENCODING__, $options->charset); 47 | } else { 48 | $pathInfo = $this->request->getPathInfo(); 49 | } 50 | 51 | Typecho_Router::setPathInfo($pathInfo); 52 | 53 | /** 初始化路由器 */ 54 | Typecho_Router::setRoutes($options->routingTable); 55 | 56 | /** 初始化插件 */ 57 | Typecho_Plugin::init($options->plugins); 58 | 59 | /** 初始化回执 */ 60 | $this->response->setCharset($options->charset); 61 | $this->response->setContentType($options->contentType); 62 | 63 | /** 默认时区 */ 64 | if (function_exists("ini_get") && !ini_get("date.timezone") && function_exists("date_default_timezone_set")) { 65 | @date_default_timezone_set('UTC'); 66 | } 67 | 68 | /** 初始化时区 */ 69 | Typecho_Date::setTimezoneOffset($options->timezone); 70 | 71 | /** 开始会话, 减小负载只针对后台打开session支持 */ 72 | if ($this->widget('Widget_User')->hasLogin()) { 73 | @session_start(); 74 | } 75 | 76 | /** 监听缓冲区 */ 77 | ob_start(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Radio.php: -------------------------------------------------------------------------------- 1 | $label) { 42 | $this->_options[$value] = new Typecho_Widget_Helper_Layout('input'); 43 | $item = $this->multiline(); 44 | $id = $this->name . '-' . $this->filterValue($value); 45 | $this->inputs[] = $this->_options[$value]; 46 | 47 | $item->addItem($this->_options[$value]->setAttribute('name', $this->name) 48 | ->setAttribute('type', 'radio') 49 | ->setAttribute('value', $value) 50 | ->setAttribute('id', $id)); 51 | 52 | $labelItem = new Typecho_Widget_Helper_Layout('label'); 53 | $item->addItem($labelItem->setAttribute('for', $id)->html($label)); 54 | $this->container($item); 55 | } 56 | 57 | return current($this->_options); 58 | } 59 | 60 | /** 61 | * 设置表单元素值 62 | * 63 | * @access protected 64 | * @param mixed $value 表单元素值 65 | * @return void 66 | */ 67 | protected function _value($value) 68 | { 69 | foreach ($this->_options as $option) { 70 | $option->removeAttribute('checked'); 71 | } 72 | 73 | if (isset($this->_options[$value])) { 74 | $this->value = $value; 75 | $this->_options[$value]->setAttribute('checked', 'true'); 76 | $this->input = $this->_options[$value]; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /admin/scss/components/_timepicker.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Jquery Timepicker 3 | */ 4 | 5 | #ui-datepicker-div { 6 | display: none; 7 | margin-top: -1px; 8 | padding: 10px; 9 | border: 1px solid #D9D9D6; 10 | background: #FFF; 11 | } 12 | .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } 13 | .ui-timepicker-div dl { text-align: left; } 14 | .ui-timepicker-div dl dt { float: left; clear:left; } 15 | .ui-timepicker-div dl dd { margin: 0 0 10px 40%; } 16 | .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } 17 | 18 | #ui-datepicker-div .ui-datepicker-header { 19 | margin-bottom: 10px; 20 | padding-bottom: 10px; 21 | border-bottom: 1px solid #EEE; 22 | } 23 | #ui-datepicker-div .ui-datepicker-prev { float: left; cursor: pointer; } 24 | #ui-datepicker-div .ui-datepicker-next { float: right; cursor: pointer; } 25 | #ui-datepicker-div .ui-datepicker-title { 26 | font-weight: bold; 27 | text-align: center; 28 | } 29 | #ui-datepicker-div .ui-datepicker-calendar th { line-height: 24px; } 30 | #ui-datepicker-div .ui-datepicker-calendar a { 31 | display: block; 32 | width: 30px; 33 | background-color: #F3F3F0; 34 | line-height: 24px; 35 | text-align: center; 36 | } 37 | #ui-datepicker-div .ui-datepicker-calendar a:hover { 38 | background-color: #E9E9E6; 39 | text-decoration: none; 40 | } 41 | #ui-datepicker-div .ui-datepicker-today a { 42 | background-color: #E9E9E6; 43 | color: #444; 44 | } 45 | #ui-datepicker-div .ui-datepicker-current-day a { 46 | background-color: #467B96 !important; 47 | color: #FFF; 48 | } 49 | #ui-datepicker-div .ui-timepicker-div { 50 | margin-top: 20px; 51 | border-top: 1px solid #EEE; 52 | } 53 | #ui-datepicker-div .ui-slider { 54 | position: relative; 55 | margin-top: 18px; 56 | border: 1px solid #E9E9E6; 57 | background-color: #F6F6F3; 58 | height: 4px; 59 | } 60 | #ui-datepicker-div .ui-slider .ui-slider-handle { 61 | position: absolute; 62 | top: -7px; 63 | margin-left: -5px; 64 | z-index: 2; 65 | width: 10px; 66 | height: 16px; 67 | background-color: #467B96; 68 | } 69 | 70 | #ui-datepicker-div .ui-datepicker-buttonpane { 71 | padding-top: 10px; 72 | border-top: 1px solid #EEE; 73 | } 74 | #ui-datepicker-div .ui-datepicker-current, 75 | #ui-datepicker-div .ui-datepicker-close { 76 | float: left; 77 | @extend .btn; 78 | @extend .btn-xs; 79 | } 80 | #ui-datepicker-div .ui-datepicker-close { 81 | float: right; 82 | } 83 | 84 | .ui-effects-transfer { border: 2px dotted #ccc; } -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/Form/Element/Checkbox.php: -------------------------------------------------------------------------------- 1 | $label) { 42 | $this->_options[$value] = new Typecho_Widget_Helper_Layout('input'); 43 | $item = $this->multiline(); 44 | $id = $this->name . '-' . $this->filterValue($value); 45 | $this->inputs[] = $this->_options[$value]; 46 | 47 | $item->addItem($this->_options[$value]->setAttribute('name', $this->name . '[]') 48 | ->setAttribute('type', 'checkbox') 49 | ->setAttribute('value', $value) 50 | ->setAttribute('id', $id)); 51 | 52 | $labelItem = new Typecho_Widget_Helper_Layout('label'); 53 | $item->addItem($labelItem->setAttribute('for', $id)->html($label)); 54 | $this->container($item); 55 | } 56 | 57 | return current($this->_options); 58 | } 59 | 60 | /** 61 | * 设置表单元素值 62 | * 63 | * @access protected 64 | * @param mixed $value 表单元素值 65 | * @return void 66 | */ 67 | protected function _value($value) 68 | { 69 | $values = is_array($value) ? $value : array($value); 70 | 71 | foreach ($this->_options as $option) { 72 | $option->removeAttribute('checked'); 73 | } 74 | 75 | foreach ($values as $value) { 76 | if (isset($this->_options[$value])) { 77 | $this->_options[$value]->setAttribute('checked', 'true'); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /var/Widget/Abstract/Options.php: -------------------------------------------------------------------------------- 1 | db->select()->from('table.options'); 45 | } 46 | 47 | /** 48 | * 插入一条记录 49 | * 50 | * @access public 51 | * @param array $options 记录插入值 52 | * @return integer 53 | */ 54 | public function insert(array $options) 55 | { 56 | return $this->db->query($this->db->insert('table.options')->rows($options)); 57 | } 58 | 59 | /** 60 | * 更新记录 61 | * 62 | * @access public 63 | * @param array $options 记录更新值 64 | * @param Typecho_Db_Query $condition 更新条件 65 | * @return integer 66 | */ 67 | public function update(array $options, Typecho_Db_Query $condition) 68 | { 69 | return $this->db->query($condition->update('table.options')->rows($options)); 70 | } 71 | 72 | /** 73 | * 删除记录 74 | * 75 | * @access public 76 | * @param Typecho_Db_Query $condition 删除条件 77 | * @return integer 78 | */ 79 | public function delete(Typecho_Db_Query $condition) 80 | { 81 | return $this->db->query($condition->delete('table.options')); 82 | } 83 | 84 | /** 85 | * 获取记录总数 86 | * 87 | * @access public 88 | * @param Typecho_Db_Query $condition 计算条件 89 | * @return integer 90 | */ 91 | public function size(Typecho_Db_Query $condition) 92 | { 93 | return $this->db->fetchObject($condition->select(array('COUNT(name)' => 'num'))->from('table.options'))->num; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /admin/profile.php: -------------------------------------------------------------------------------- 1 | 8 | 9 |
    10 |
    11 | 12 |
    13 |
    14 |

    mail, 220, 'X', 'mm', $request->isSecure()) . '" alt="' . $user->screenName . '" />'; ?>

    15 |

    screenName(); ?>

    16 |

    name(); ?>

    17 |

    %s 篇日志, 并有 %s 条关于你的评论在 %s 个分类中.', 18 | $stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>

    19 |

    logged > 0) { 21 | _e('最后登录: %s', Typecho_I18n::dateWord($user->logged + $options->timezone, $options->gmtTime + $options->timezone)); 22 | } 23 | ?>

    24 |
    25 | 26 |
    27 |
    28 |

    29 | profileForm()->render(); ?> 30 |
    31 | 32 | pass('contributor', true)): ?> 33 |
    34 |
    35 |

    36 | optionsForm()->render(); ?> 37 |
    38 | 39 | 40 |
    41 | 42 |
    43 |

    44 | personalFormList(); ?> 45 | passwordForm()->render(); ?> 46 |
    47 |
    48 |
    49 |
    50 |
    51 | 52 | bottom(); 57 | include 'footer.php'; 58 | ?> 59 | -------------------------------------------------------------------------------- /var/Typecho/I18n/GetTextMulti.php: -------------------------------------------------------------------------------- 1 | addFile($fileName); 38 | } 39 | 40 | /** 41 | * 增加一个语言文件 42 | * 43 | * @access public 44 | * @param string $fileName 语言文件名 45 | * @return void 46 | */ 47 | public function addFile($fileName) 48 | { 49 | $this->_handles[] = new Typecho_I18n_GetText($fileName, true); 50 | } 51 | 52 | /** 53 | * Translates a string 54 | * 55 | * @access public 56 | * @param string string to be translated 57 | * @return string translated string (or original, if not found) 58 | */ 59 | public function translate($string) 60 | { 61 | foreach ($this->_handles as $handle) { 62 | $string = $handle->translate($string, $count); 63 | if (-1 != $count) { 64 | break; 65 | } 66 | } 67 | 68 | return $string; 69 | } 70 | 71 | /** 72 | * Plural version of gettext 73 | * 74 | * @access public 75 | * @param string single 76 | * @param string plural 77 | * @param string number 78 | * @return translated plural form 79 | */ 80 | public function ngettext($single, $plural, $number) 81 | { 82 | foreach ($this->_handles as $handle) { 83 | $string = $handle->ngettext($single, $plural, $number, $count); 84 | if (-1 != $count) { 85 | break; 86 | } 87 | } 88 | 89 | return $string; 90 | } 91 | 92 | /** 93 | * 关闭所有句柄 94 | * 95 | * @access public 96 | * @return void 97 | */ 98 | public function __destruct() 99 | { 100 | foreach ($this->_handles as $handle) { 101 | /** 显示的释放内存 */ 102 | unset($handle); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /usr/themes/default/comments.php: -------------------------------------------------------------------------------- 1 | 2 |
    3 | comments()->to($comments); ?> 4 | have()): ?> 5 |

    commentsNum(_t('暂无评论'), _t('仅有一条评论'), _t('已有 %d 条评论')); ?>

    6 | 7 | listComments(); ?> 8 | 9 | pageNav('« 前一页', '后一页 »'); ?> 10 | 11 | 12 | 13 | allow('comment')): ?> 14 |
    15 |
    16 | cancelReply(); ?> 17 |
    18 | 19 |

    20 |
    21 | user->hasLogin()): ?> 22 |

    user->screenName(); ?>. »

    23 | 24 |

    25 | 26 | 27 |

    28 |

    29 | 30 | options->commentsRequireMail): ?> required /> 31 |

    32 |

    33 | 34 | options->commentsRequireURL): ?> required /> 35 |

    36 | 37 |

    38 | 39 | 40 |

    41 |

    42 | 43 |

    44 |
    45 |
    46 | 47 |

    48 | 49 |
    50 | -------------------------------------------------------------------------------- /var/Widget/Themes/List.php: -------------------------------------------------------------------------------- 1 | getThemes(); 53 | 54 | if ($themes) { 55 | $options = $this->widget('Widget_Options'); 56 | $siteUrl = $options->siteUrl; 57 | $adminUrl = $options->adminUrl; 58 | $activated = 0; 59 | $result = array(); 60 | 61 | foreach ($themes as $key => $theme) { 62 | $themeFile = $theme . '/index.php'; 63 | if (file_exists($themeFile)) { 64 | $info = Typecho_Plugin::parseInfo($themeFile); 65 | $info['name'] = $this->getTheme($theme, $key); 66 | 67 | if ($info['activated'] = ($options->theme == $info['name'])) { 68 | $activated = $key; 69 | } 70 | 71 | $screen = glob($theme . '/screen*.{jpg,png,gif,bmp,jpeg,JPG,PNG,GIF,BMG,JPEG}', GLOB_BRACE); 72 | if ($screen) { 73 | $info['screen'] = $options->themeUrl(basename(current($screen)), $info['name']); 74 | } else { 75 | $info['screen'] = Typecho_Common::url('noscreen.png', $options->adminStaticUrl('img')); 76 | } 77 | 78 | $result[$key] = $info; 79 | } 80 | } 81 | 82 | $clone = $result[$activated]; 83 | unset($result[$activated]); 84 | array_unshift($result, $clone); 85 | array_filter($result, array($this, 'push')); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /var/Typecho/Db/Adapter/Pdo/Mysql.php: -------------------------------------------------------------------------------- 1 | dsn) ? $config->dsn : 39 | "mysql:dbname={$config->database};host={$config->host};port={$config->port}", $config->user, $config->password); 40 | $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); 41 | $pdo->exec("SET NAMES '{$config->charset}'"); 42 | return $pdo; 43 | } 44 | 45 | /** 46 | * 对象引号过滤 47 | * 48 | * @access public 49 | * @param string $string 50 | * @return string 51 | */ 52 | public function quoteColumn($string) 53 | { 54 | return '`' . $string . '`'; 55 | } 56 | 57 | /** 58 | * 引号转义函数 59 | * 60 | * @param string $string 需要转义的字符串 61 | * @return string 62 | */ 63 | public function quoteValue($string) 64 | { 65 | return '\'' . str_replace(array('\'', '\\'), array('\'\'', '\\\\'), $string) . '\''; 66 | } 67 | 68 | /** 69 | * 合成查询语句 70 | * 71 | * @access public 72 | * @param array $sql 查询对象词法数组 73 | * @return string 74 | */ 75 | public function parseSelect(array $sql) 76 | { 77 | if (!empty($sql['join'])) { 78 | foreach ($sql['join'] as $val) { 79 | list($table, $condition, $op) = $val; 80 | $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; 81 | } 82 | } 83 | 84 | $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; 85 | $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; 86 | 87 | return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . 88 | $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /var/Typecho/Db/Adapter.php: -------------------------------------------------------------------------------- 1 | database};host={$config->host};port={$config->port}", $config->user, $config->password); 39 | $pdo->exec("SET NAMES '{$config->charset}'"); 40 | return $pdo; 41 | } 42 | 43 | /** 44 | * 对象引号过滤 45 | * 46 | * @access public 47 | * @param string $string 48 | * @return string 49 | */ 50 | public function quoteColumn($string) 51 | { 52 | return '"' . $string . '"'; 53 | } 54 | 55 | /** 56 | * 合成查询语句 57 | * 58 | * @access public 59 | * @param array $sql 查询对象词法数组 60 | * @return string 61 | */ 62 | public function parseSelect(array $sql) 63 | { 64 | if (!empty($sql['join'])) { 65 | foreach ($sql['join'] as $val) { 66 | list($table, $condition, $op) = $val; 67 | $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; 68 | } 69 | } 70 | 71 | $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; 72 | $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; 73 | 74 | return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . 75 | $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; 76 | } 77 | 78 | /** 79 | * 取出最后一次插入返回的主键值 80 | * 81 | * @param resource $resource 查询的资源数据 82 | * @param mixed $handle 连接对象 83 | * @return integer 84 | */ 85 | public function lastInsertId($resource, $handle) 86 | { 87 | /** 查看是否存在序列,可能需要更严格的检查 */ 88 | if ($handle->query('SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq'))->fetchAll()) { 89 | return $handle->lastInsertId($this->_lastTable . '_seq'); 90 | } 91 | 92 | return 0; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /var/Typecho/Date.php: -------------------------------------------------------------------------------- 1 | timeStamp = $gmtTime + (self::$timezoneOffset - self::$serverTimezoneOffset); 54 | } 55 | 56 | /** 57 | * 设置当前期望的时区偏移 58 | * 59 | * @access public 60 | * @param integer $offset 61 | * @return void 62 | */ 63 | public static function setTimezoneOffset($offset) 64 | { 65 | self::$timezoneOffset = $offset; 66 | self::$serverTimezoneOffset = idate('Z'); 67 | } 68 | 69 | /** 70 | * 获取格式化时间 71 | * 72 | * @access public 73 | * @param string $format 时间格式 74 | * @return string 75 | */ 76 | public function format($format) 77 | { 78 | return date($format, $this->timeStamp); 79 | } 80 | 81 | /** 82 | * 获取国际化偏移时间 83 | * 84 | * @access public 85 | * @return string 86 | */ 87 | public function word() 88 | { 89 | return Typecho_I18n::dateWord($this->timeStamp, self::gmtTime() + (self::$timezoneOffset - self::$serverTimezoneOffset)); 90 | } 91 | 92 | /** 93 | * 获取单项数据 94 | * 95 | * @access public 96 | * @param string $name 名称 97 | * @return integer 98 | */ 99 | public function __get($name) 100 | { 101 | switch ($name) { 102 | case 'year': 103 | return date('Y', $this->timeStamp); 104 | case 'month': 105 | return date('m', $this->timeStamp); 106 | case 'day': 107 | return date('d', $this->timeStamp); 108 | default: 109 | return; 110 | } 111 | } 112 | 113 | /** 114 | * 获取GMT时间 115 | * 116 | * @access public 117 | * @return integer 118 | */ 119 | public static function gmtTime() 120 | { 121 | return self::$gmtTimeStamp ? self::$gmtTimeStamp : (self::$gmtTimeStamp = @gmmktime()); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /var/Widget/Login.php: -------------------------------------------------------------------------------- 1 | security->protect(); 33 | 34 | /** 如果已经登录 */ 35 | if ($this->user->hasLogin()) { 36 | /** 直接返回 */ 37 | $this->response->redirect($this->options->index); 38 | } 39 | 40 | /** 初始化验证类 */ 41 | $validator = new Typecho_Validate(); 42 | $validator->addRule('name', 'required', _t('请输入用户名')); 43 | $validator->addRule('password', 'required', _t('请输入密码')); 44 | 45 | /** 截获验证异常 */ 46 | if ($error = $validator->run($this->request->from('name', 'password'))) { 47 | Typecho_Cookie::set('__typecho_remember_name', $this->request->name); 48 | 49 | /** 设置提示信息 */ 50 | $this->widget('Widget_Notice')->set($error); 51 | $this->response->goBack(); 52 | } 53 | 54 | /** 开始验证用户 **/ 55 | $valid = $this->user->login($this->request->name, $this->request->password, 56 | false, 1 == $this->request->remember ? $this->options->gmtTime + $this->options->timezone + 30*24*3600 : 0); 57 | 58 | /** 比对密码 */ 59 | if (!$valid) { 60 | /** 防止穷举,休眠3秒 */ 61 | sleep(3); 62 | 63 | $this->pluginHandle()->loginFail($this->user, $this->request->name, 64 | $this->request->password, 1 == $this->request->remember); 65 | 66 | Typecho_Cookie::set('__typecho_remember_name', $this->request->name); 67 | $this->widget('Widget_Notice')->set(_t('用户名或密码无效'), 'error'); 68 | $this->response->goBack('?referer=' . urlencode($this->request->referer)); 69 | } 70 | 71 | $this->pluginHandle()->loginSucceed($this->user, $this->request->name, 72 | $this->request->password, 1 == $this->request->remember); 73 | 74 | /** 跳转验证后地址 */ 75 | if (NULL != $this->request->referer) { 76 | $this->response->redirect($this->request->referer); 77 | } else if (!$this->user->pass('contributor', true)) { 78 | /** 不允许普通用户直接跳转后台 */ 79 | $this->response->redirect($this->options->profileUrl); 80 | } else { 81 | $this->response->redirect($this->options->adminUrl); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /var/Widget/Abstract.php: -------------------------------------------------------------------------------- 1 | db = Typecho_Db::get(); 68 | 69 | /** 初始化常用组件 */ 70 | $this->options = $this->widget('Widget_Options'); 71 | $this->user = $this->widget('Widget_User'); 72 | $this->security = $this->widget('Widget_Security'); 73 | } 74 | 75 | /** 76 | * 查询方法 77 | * 78 | * @access public 79 | * @return Typecho_Db_Query 80 | */ 81 | abstract public function select(); 82 | 83 | /** 84 | * 获得所有记录数 85 | * 86 | * @access public 87 | * @param Typecho_Db_Query $condition 查询对象 88 | * @return integer 89 | */ 90 | abstract public function size(Typecho_Db_Query $condition); 91 | 92 | /** 93 | * 增加记录方法 94 | * 95 | * @access public 96 | * @param array $rows 字段对应值 97 | * @return integer 98 | */ 99 | abstract public function insert(array $rows); 100 | 101 | /** 102 | * 更新记录方法 103 | * 104 | * @access public 105 | * @param array $rows 字段对应值 106 | * @param Typecho_Db_Query $condition 查询对象 107 | * @return integer 108 | */ 109 | abstract public function update(array $rows, Typecho_Db_Query $condition); 110 | 111 | /** 112 | * 删除记录方法 113 | * 114 | * @access public 115 | * @param Typecho_Db_Query $condition 查询对象 116 | * @return integer 117 | */ 118 | abstract public function delete(Typecho_Db_Query $condition); 119 | } 120 | -------------------------------------------------------------------------------- /var/Typecho/Cookie.php: -------------------------------------------------------------------------------- 1 | file}"); 44 | $this->_isSQLite2 = version_compare($pdo->getAttribute(PDO::ATTR_SERVER_VERSION), '3.0.0', '<'); 45 | return $pdo; 46 | } 47 | 48 | /** 49 | * @param resource $resource 50 | * @return array 51 | */ 52 | public function fetch($resource) 53 | { 54 | return Typecho_Common::filterSQLite2ColumnName(parent::fetch($resource)); 55 | } 56 | 57 | /** 58 | * @param resource $resource 59 | * @return object 60 | */ 61 | public function fetchObject($resource) 62 | { 63 | return (object) $this->fetch($resource); 64 | } 65 | 66 | /** 67 | * 对象引号过滤 68 | * 69 | * @access public 70 | * @param string $string 71 | * @return string 72 | */ 73 | public function quoteColumn($string) 74 | { 75 | return '"' . $string . '"'; 76 | } 77 | 78 | /** 79 | * 合成查询语句 80 | * 81 | * @access public 82 | * @param array $sql 查询对象词法数组 83 | * @return string 84 | */ 85 | public function parseSelect(array $sql) 86 | { 87 | if (!empty($sql['join'])) { 88 | foreach ($sql['join'] as $val) { 89 | list($table, $condition, $op) = $val; 90 | $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; 91 | } 92 | } 93 | 94 | $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; 95 | $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; 96 | 97 | $query = 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . 98 | $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset']; 99 | 100 | if ($this->_isSQLite2) { 101 | $query = Typecho_Common::filterSQLite2CountQuery($query); 102 | } 103 | 104 | return $query; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /var/Widget/Metas/Category/Admin.php: -------------------------------------------------------------------------------- 1 | 10 | * @license GNU General Public License 2.0 11 | */ 12 | class Widget_Metas_Category_Admin extends Widget_Metas_Category_List 13 | { 14 | /** 15 | * 执行函数 16 | * 17 | * @access public 18 | * @return void 19 | */ 20 | public function execute() 21 | { 22 | $select = $this->db->select('mid')->from('table.metas')->where('type = ?', 'category'); 23 | $select->where('parent = ?', $this->request->parent ? $this->request->parent : 0); 24 | 25 | $this->stack = $this->getCategories(Typecho_Common::arrayFlatten( 26 | $this->db->fetchAll($select->order('table.metas.order', Typecho_Db::SORT_ASC)), 'mid')); 27 | } 28 | 29 | /** 30 | * 向上的返回链接 31 | * 32 | * @access public 33 | * @return void 34 | */ 35 | public function backLink() 36 | { 37 | if (isset($this->request->parent)) { 38 | $category = $this->db->fetchRow($this->select() 39 | ->where('type = ? AND mid = ?', 'category', $this->request->parent)); 40 | 41 | if (!empty($category)) { 42 | $parent = $this->db->fetchRow($this->select() 43 | ->where('type = ? AND mid = ?', 'category', $category['parent'])); 44 | 45 | if ($parent) { 46 | echo ''; 47 | } else { 48 | echo ''; 49 | } 50 | 51 | echo '« '; 52 | _e('返回父级分类'); 53 | echo ''; 54 | } 55 | } 56 | } 57 | 58 | /** 59 | * 获取菜单标题 60 | * 61 | * @access public 62 | * @return string 63 | */ 64 | public function getMenuTitle() 65 | { 66 | if (isset($this->request->parent)) { 67 | $category = $this->db->fetchRow($this->select() 68 | ->where('type = ? AND mid = ?', 'category', $this->request->parent)); 69 | 70 | if (!empty($category)) { 71 | return _t('管理 %s 的子分类', $category['name']); 72 | } 73 | } else { 74 | return; 75 | } 76 | 77 | throw new Typecho_Widget_Exception(_t('分类不存在'), 404); 78 | } 79 | 80 | /** 81 | * 获取菜单标题 82 | * 83 | * @access public 84 | * @return string 85 | */ 86 | public function getAddLink() 87 | { 88 | if (isset($this->request->parent)) { 89 | return 'category.php?parent=' . $this->request->filter('int')->parent; 90 | } else { 91 | return 'category.php'; 92 | } 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /usr/themes/default/sidebar.php: -------------------------------------------------------------------------------- 1 | 2 | 60 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | #define root directory 4 | DIR=../ 5 | 6 | #update subversion 7 | update: 8 | @echo 'git update' 9 | rm -Rf build/ 10 | git clone https://github.com/typecho/typecho.git build 11 | rm -Rf build/.git 12 | rm -f build/.gitignore 13 | rm -f build/.gitattributes 14 | for i in `find build/ -name '*.css'`; do echo $$i && java -Xmx32m -jar yuicompressor-2.4.2.jar $$i --charset UTF-8 -o $$i; done; 15 | for i in `find build/admin/js/ -name '*.js'`; do echo $$i && java -Xmx32m -jar yuicompressor-2.4.2.jar $$i --charset UTF-8 -o $$i; done; 16 | for i in `find build/ -name '*.php'`; do php -l $$i; done; 17 | 18 | 19 | package: 20 | @echo 'package' 21 | rm -Rf build/tools/ 22 | rm -f build/todo.txt 23 | rm -f build/changelog.txt 24 | rm -f build/.travis.yml 25 | rm -f build/README.md 26 | rm -Rf build/admin/scss 27 | rm -Rf build/admin/img/editor 28 | rm -Rf build/admin/img/icons 29 | rm -Rf build/admin/img/icons-2x 30 | rm -Rf build/usr/langs/* 31 | mkdir build/usr/uploads/ 32 | chmod 777 build/usr/uploads/ 33 | tar -cvvzf build.tar.gz build/ 34 | 35 | 36 | clear: 37 | rm -Rf build/ 38 | 39 | 40 | upgrade: 41 | make update 42 | rm -Rf ${DIR}/admin/ 43 | cp -Rf build/admin/ ${DIR} 44 | rm -Rf ${DIR}/var/ 45 | cp -Rf build/var/ ${DIR} 46 | rm -Rf ${DIR}/index.php 47 | cp build/index.php ${DIR} 48 | make clear 49 | 50 | 51 | langs: 52 | rm -rf ../usr/langs 53 | mkdir ../usr/langs 54 | git clone https://github.com/typecho/languages.git 55 | #for i in `find . -name '*.po'`; do echo $$i && php msgfmt.php $$i; done; 56 | cd languages/ && for i in `find . -name '*.po'`; do echo `basename $$i` && msgfmt -o `basename $$i .po`.mo `basename $$i`; done; 57 | cp languages/*.mo ../usr/langs/ 58 | rm -rf languages 59 | 60 | 61 | theme: 62 | make update 63 | rm -Rf ${DIR}/usr/themes/default/ 64 | cp -Rf build/usr/themes/default/ ${DIR}/usr/themes/ 65 | make clear 66 | 67 | 68 | install: 69 | make update 70 | rm -Rf build/tools/ 71 | rm -f build/todo.txt 72 | rm -f build/changelog.txt 73 | rm -f build/.travis.yml 74 | rm -f build/README.md 75 | rm -Rf build/admin/scss 76 | rm -Rf build/admin/img/editor 77 | rm -Rf build/admin/img/icons 78 | rm -Rf build/admin/img/icons-2x 79 | mkdir build/usr/uploads/ 80 | chmod 777 build/usr/uploads/ 81 | cp -Rf build/* ${DIR} 82 | make clear 83 | 84 | 85 | pot: 86 | cd ../ && php tools/list.php ./ > tools/files.txt 87 | cd ../ && xgettext --files-from=tools/files.txt -Lphp --from-code=UTF-8 --keyword=_t --keyword=_e --keyword=_n:1,2 --no-location --copyright-holder=Typecho --package-name=Typecho --package-version=`grep -E "VERSION = '(.*)'" ./var/Typecho/Common.php | cut -d "'" -f 2` --no-wrap --output=tools/messages.pot 88 | rm -f files.txt 89 | 90 | 91 | test: 92 | for i in `find ../var/ -name '*.php'`; do php -l $$i || exit 1; done; 93 | for i in `find ../usr/ -name '*.php'`; do php -l $$i || exit 1; done; 94 | for i in `find ../admin/ -name '*.php'`; do php -l $$i || exit 1; done; 95 | 96 | 97 | all: 98 | make update 99 | make package 100 | make clear 101 | -------------------------------------------------------------------------------- /var/Typecho/Widget/Helper/PageNavigator.php: -------------------------------------------------------------------------------- 1 | _total = $total; 86 | $this->_totalPage = ceil($total / $pageSize); 87 | $this->_currentPage = $currentPage; 88 | $this->_pageSize = $pageSize; 89 | $this->_pageTemplate = $pageTemplate; 90 | 91 | if (($currentPage > $this->_totalPage || $currentPage < 1) && $total > 0) { 92 | throw new Typecho_Widget_Exception('Page Not Exists', 404); 93 | } 94 | } 95 | 96 | /** 97 | * 设置页面占位符 98 | * 99 | * @access protected 100 | * @param string $holder 页面占位符 101 | * @return void 102 | */ 103 | public function setPageHolder($holder) 104 | { 105 | $this->_pageHolder = array('{' . $holder . '}', 106 | str_replace(array('{', '}'), array('%7B', '%7D'), $holder)); 107 | } 108 | 109 | /** 110 | * 设置锚点 111 | * 112 | * @access public 113 | * @param string $anchor 锚点 114 | * @return void 115 | */ 116 | public function setAnchor($anchor) 117 | { 118 | $this->_anchor = '#' . $anchor; 119 | } 120 | 121 | /** 122 | * 输出方法 123 | * 124 | * @access public 125 | * @return void 126 | */ 127 | public function render() 128 | { 129 | throw new Typecho_Widget_Exception(get_class($this) . ':' . __METHOD__, 500); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /var/Widget/Contents/Post/Date.php: -------------------------------------------------------------------------------- 1 | db = Typecho_Db::get(); 54 | 55 | /** 初始化常用组件 */ 56 | $this->options = $this->widget('Widget_Options'); 57 | } 58 | 59 | /** 60 | * 初始化函数 61 | * 62 | * @access public 63 | * @return void 64 | */ 65 | public function execute() 66 | { 67 | /** 设置参数默认值 */ 68 | $this->parameter->setDefault('format=Y-m&type=month&limit=0'); 69 | 70 | $resource = $this->db->query($this->db->select('created')->from('table.contents') 71 | ->where('type = ?', 'post') 72 | ->where('table.contents.status = ?', 'publish') 73 | ->where('table.contents.created < ?', $this->options->gmtTime) 74 | ->order('table.contents.created', Typecho_Db::SORT_DESC)); 75 | 76 | $offset = $this->options->timezone - $this->options->serverTimezone; 77 | $result = array(); 78 | while ($post = $this->db->fetchRow($resource)) { 79 | $timeStamp = $post['created'] + $offset; 80 | $date = date($this->parameter->format, $timeStamp); 81 | 82 | if (isset($result[$date])) { 83 | $result[$date]['count'] ++; 84 | } else { 85 | $result[$date]['year'] = date('Y', $timeStamp); 86 | $result[$date]['month'] = date('m', $timeStamp); 87 | $result[$date]['day'] = date('d', $timeStamp); 88 | $result[$date]['date'] = $date; 89 | $result[$date]['count'] = 1; 90 | } 91 | } 92 | 93 | if ($this->parameter->limit > 0) { 94 | $result = array_slice($result, 0, $this->parameter->limit); 95 | } 96 | 97 | foreach ($result as $row) { 98 | $row['permalink'] = Typecho_Router::url('archive_' . $this->parameter->type, $row, $this->widget('Widget_Options')->index); 99 | $this->push($row); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /admin/theme-editor.php: -------------------------------------------------------------------------------- 1 | to($files); 7 | ?> 8 | 9 |
    10 |
    11 | 12 |
    13 | 28 | 29 |
    30 |
    31 |
    32 | 33 | 34 |

    35 | currentIsWriteable()): ?> 36 | 37 | 38 | 39 | 40 | 41 | 42 |

    43 |
    44 |
    45 |
      46 |
    • 模板文件
    • 47 | next()): ?> 48 | current): ?> class="current"> 49 | file(); ?> 50 | 51 |
    52 |
    53 |
    54 |
    55 |
    56 | 57 | bottom($files); 61 | include 'footer.php'; 62 | ?> 63 | -------------------------------------------------------------------------------- /var/Widget/Security.php: -------------------------------------------------------------------------------- 1 | _options = $this->widget('Widget_Options'); 31 | $user = $this->widget('Widget_User'); 32 | 33 | $this->_token = $this->_options->secret; 34 | if ($user->hasLogin()) { 35 | $this->_token .= '&' . $user->authCode . '&' . $user->uid; 36 | } 37 | } 38 | 39 | /** 40 | * 获取token 41 | * 42 | * @param string $suffix 后缀 43 | * @return string 44 | */ 45 | public function getToken($suffix) 46 | { 47 | return md5($this->_token . '&' . $suffix); 48 | } 49 | 50 | /** 51 | * 生成带token的路径 52 | * 53 | * @param $path 54 | * @return string 55 | */ 56 | public function getTokenUrl($path) 57 | { 58 | $parts = parse_url($path); 59 | $params = array(); 60 | 61 | if (!empty($parts['query'])) { 62 | parse_str($parts['query'], $params); 63 | } 64 | 65 | $params['_'] = $this->getToken($this->request->getRequestUrl()); 66 | $parts['query'] = http_build_query($params); 67 | 68 | return Typecho_Common::buildUrl($parts); 69 | } 70 | 71 | /** 72 | * 保护提交数据 73 | * 74 | */ 75 | public function protect() 76 | { 77 | if ($this->request->get('_') != $this->getToken($this->request->getReferer())) { 78 | $this->response->goBack(); 79 | } 80 | } 81 | 82 | /** 83 | * 获取安全的后台路径 84 | * 85 | * @param string $path 86 | * @return string 87 | */ 88 | public function getAdminUrl($path) 89 | { 90 | return Typecho_Common::url($this->getTokenUrl($path), $this->_options->adminUrl); 91 | } 92 | 93 | /** 94 | * 获取安全的路由路径 95 | * 96 | * @param $path 97 | * @return string 98 | */ 99 | public function getIndex($path) 100 | { 101 | return Typecho_Common::url($this->getTokenUrl($path), $this->_options->index); 102 | } 103 | 104 | /** 105 | * 获取绝对路由路径 106 | * 107 | * @param $path 108 | * @return string 109 | */ 110 | public function getRootUrl($path) 111 | { 112 | return Typecho_Common::url($this->getTokenUrl($path), $this->_options->rootUrl); 113 | } 114 | 115 | /** 116 | * 输出后台安全路径 117 | * 118 | * @param $path 119 | */ 120 | public function adminUrl($path) 121 | { 122 | echo $this->getAdminUrl($path); 123 | } 124 | 125 | /** 126 | * 输出安全的路由路径 127 | * 128 | * @param $path 129 | */ 130 | public function index($path) 131 | { 132 | echo $this->getIndex($path); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /var/Widget/Do.php: -------------------------------------------------------------------------------- 1 | 'Widget_Ajax', 26 | 'login' => 'Widget_Login', 27 | 'logout' => 'Widget_Logout', 28 | 'register' => 'Widget_Register', 29 | 'upgrade' => 'Widget_Upgrade', 30 | 'upload' => 'Widget_Upload', 31 | 'service' => 'Widget_Service', 32 | 'xmlrpc' => 'Widget_XmlRpc', 33 | 'comments-edit' => 'Widget_Comments_Edit', 34 | 'contents-page-edit' => 'Widget_Contents_Page_Edit', 35 | 'contents-post-edit' => 'Widget_Contents_Post_Edit', 36 | 'contents-attachment-edit' => 'Widget_Contents_Attachment_Edit', 37 | 'metas-category-edit' => 'Widget_Metas_Category_Edit', 38 | 'metas-tag-edit' => 'Widget_Metas_Tag_Edit', 39 | 'options-discussion' => 'Widget_Options_Discussion', 40 | 'options-general' => 'Widget_Options_General', 41 | 'options-permalink' => 'Widget_Options_Permalink', 42 | 'options-reading' => 'Widget_Options_Reading', 43 | 'plugins-edit' => 'Widget_Plugins_Edit', 44 | 'themes-edit' => 'Widget_Themes_Edit', 45 | 'users-edit' => 'Widget_Users_Edit', 46 | 'users-profile' => 'Widget_Users_Profile' 47 | ); 48 | 49 | /** 50 | * 入口函数,初始化路由器 51 | * 52 | * @access public 53 | * @return void 54 | * @throws Typecho_Widget_Exception 55 | */ 56 | public function execute() 57 | { 58 | /** 验证路由地址 **/ 59 | $action = $this->request->action; 60 | 61 | //兼容老版本 62 | if (empty($action)) { 63 | $widget = trim($this->request->widget, '/'); 64 | $objectName = 'Widget_' . str_replace('/', '_', $widget); 65 | 66 | if (Typecho_Common::isAvailableClass($objectName)) { 67 | $widgetName = $objectName; 68 | } 69 | } else { 70 | /** 判断是否为plugin */ 71 | $actionTable = array_merge($this->_map, unserialize($this->widget('Widget_Options')->actionTable)); 72 | 73 | if (isset($actionTable[$action])) { 74 | $widgetName = $actionTable[$action]; 75 | } 76 | } 77 | 78 | if (isset($widgetName) && class_exists($widgetName)) { 79 | $reflectionWidget = new ReflectionClass($widgetName); 80 | if ($reflectionWidget->implementsInterface('Widget_Interface_Do')) { 81 | $this->widget($widgetName)->action(); 82 | return; 83 | } 84 | } 85 | 86 | throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /var/Widget/Users/Admin.php: -------------------------------------------------------------------------------- 1 | url); 55 | return $parts['host'] . (isset($parts['path']) ? $parts['path'] : NULL); 56 | } 57 | 58 | /** 59 | * 发布文章数 60 | * 61 | * @access protected 62 | * @return integer 63 | */ 64 | protected function ___postsNum() 65 | { 66 | return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) 67 | ->from('table.contents') 68 | ->where('table.contents.type = ?', 'post') 69 | ->where('table.contents.status = ?', 'publish') 70 | ->where('table.contents.authorId = ?', $this->uid))->num; 71 | } 72 | 73 | /** 74 | * 执行函数 75 | * 76 | * @access public 77 | * @return void 78 | */ 79 | public function execute() 80 | { 81 | $this->parameter->setDefault('pageSize=20'); 82 | $select = $this->select(); 83 | $this->_currentPage = $this->request->get('page', 1); 84 | 85 | /** 过滤标题 */ 86 | if (NULL != ($keywords = $this->request->keywords)) { 87 | $select->where('name LIKE ? OR screenName LIKE ?', 88 | '%' . Typecho_Common::filterSearchQuery($keywords) . '%', 89 | '%' . Typecho_Common::filterSearchQuery($keywords) . '%'); 90 | } 91 | 92 | $this->_countSql = clone $select; 93 | 94 | $select->order('table.users.uid', Typecho_Db::SORT_ASC) 95 | ->page($this->_currentPage, $this->parameter->pageSize); 96 | 97 | $this->db->fetchAll($select, array($this, 'push')); 98 | } 99 | 100 | /** 101 | * 输出分页 102 | * 103 | * @access public 104 | * @return void 105 | */ 106 | public function pageNav() 107 | { 108 | $query = $this->request->makeUriByRequest('page={page}');; 109 | 110 | /** 使用盒状分页 */ 111 | $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, 112 | $this->_currentPage, $this->parameter->pageSize, $query); 113 | $nav->render('«', '»'); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /var/Widget/Plugins/Config.php: -------------------------------------------------------------------------------- 1 | user->pass('administrator'); 54 | $config = $this->request->filter('slug')->config; 55 | if (empty($config)) { 56 | throw new Typecho_Widget_Exception(_t('插件不存在'), 404); 57 | } 58 | 59 | /** 获取插件入口 */ 60 | list($this->_pluginFileName, $this->_className) = Typecho_Plugin::portal($config, 61 | $this->options->pluginDir($config)); 62 | $this->info = Typecho_Plugin::parseInfo($this->_pluginFileName); 63 | } 64 | 65 | /** 66 | * 获取菜单标题 67 | * 68 | * @access public 69 | * @return string 70 | */ 71 | public function getMenuTitle() 72 | { 73 | return _t('设置插件 %s', $this->info['title']); 74 | } 75 | 76 | /** 77 | * 配置插件 78 | * 79 | * @access public 80 | * @return Typecho_Widget_Helper_Form 81 | * @throws Typecho_Widget_Exception 82 | */ 83 | public function config() 84 | { 85 | /** 获取插件名称 */ 86 | $pluginName = $this->request->filter('slug')->config; 87 | 88 | /** 获取已启用插件 */ 89 | $plugins = Typecho_Plugin::export(); 90 | $activatedPlugins = $plugins['activated']; 91 | 92 | /** 判断实例化是否成功 */ 93 | if (!$this->info['config'] || !isset($activatedPlugins[$pluginName])) { 94 | throw new Typecho_Widget_Exception(_t('无法配置插件'), 500); 95 | } 96 | 97 | /** 载入插件 */ 98 | require_once $this->_pluginFileName; 99 | $form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/plugins-edit?config=' . $pluginName), 100 | Typecho_Widget_Helper_Form::POST_METHOD); 101 | call_user_func(array($this->_className, 'config'), $form); 102 | 103 | $options = $this->options->plugin($pluginName); 104 | 105 | if (!empty($options)) { 106 | foreach ($options as $key => $val) { 107 | $form->getInput($key)->value($val); 108 | } 109 | } 110 | 111 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); 112 | $submit->input->setAttribute('class', 'btn primary'); 113 | $form->addItem($submit); 114 | return $form; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /var/Typecho/Router/Parser.php: -------------------------------------------------------------------------------- 1 | _routingTable = $routingTable; 56 | 57 | $this->_defaultRegx = array( 58 | 'string' => '(.%s)', 59 | 'char' => '([^/]%s)', 60 | 'digital'=> '([0-9]%s)', 61 | 'alpha' => '([_0-9a-zA-Z-]%s)', 62 | 'alphaslash' => '([_0-9a-zA-Z-/]%s)', 63 | 'split' => '((?:[^/]+/)%s[^/]+)', 64 | ); 65 | } 66 | 67 | /** 68 | * 局部匹配并替换正则字符串 69 | * 70 | * @access public 71 | * @param array $matches 匹配部分 72 | * @return string 73 | */ 74 | public function _match(array $matches) 75 | { 76 | $params = explode(' ', $matches[1]); 77 | $paramsNum = count($params); 78 | $this->_params[] = $params[0]; 79 | 80 | if (1 == $paramsNum) { 81 | return sprintf($this->_defaultRegx['char'], '+'); 82 | } else if (2 == $paramsNum) { 83 | return sprintf($this->_defaultRegx[$params[1]], '+'); 84 | } else if (3 == $paramsNum) { 85 | return sprintf($this->_defaultRegx[$params[1]], $params[2] > 0 ? '{' . $params[2] . '}' : '*'); 86 | } else if (4 == $paramsNum) { 87 | return sprintf($this->_defaultRegx[$params[1]], '{' . $params[2] . ',' . $params[3] . '}'); 88 | } 89 | } 90 | 91 | /** 92 | * 解析路由表 93 | * 94 | * @access public 95 | * @return array 96 | */ 97 | public function parse() 98 | { 99 | $result = array(); 100 | 101 | foreach ($this->_routingTable as $key => $route) { 102 | $this->_params = array(); 103 | $route['regx'] = preg_replace_callback("/%([^%]+)%/", array($this, '_match'), 104 | preg_quote(str_replace(array('[', ']', ':'), array('%', '%', ' '), $route['url']))); 105 | 106 | /** 处理斜线 */ 107 | $route['regx'] = rtrim($route['regx'], '/'); 108 | $route['regx'] = '|^' . $route['regx'] . '[/]?$|'; 109 | 110 | $route['format'] = preg_replace("/\[([^\]]+)\]/", "%s", $route['url']); 111 | $route['params'] = $this->_params; 112 | 113 | $result[$key] = $route; 114 | } 115 | 116 | return $result; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /install/SQLite.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE typecho_comments ( "coid" INTEGER NOT NULL PRIMARY KEY, 2 | "cid" int(10) default '0' , 3 | "created" int(10) default '0' , 4 | "author" varchar(200) default NULL , 5 | "authorId" int(10) default '0' , 6 | "ownerId" int(10) default '0' , 7 | "mail" varchar(200) default NULL , 8 | "url" varchar(200) default NULL , 9 | "ip" varchar(64) default NULL , 10 | "agent" varchar(200) default NULL , 11 | "text" text , 12 | "type" varchar(16) default 'comment' , 13 | "status" varchar(16) default 'approved' , 14 | "parent" int(10) default '0' ); 15 | 16 | CREATE INDEX typecho_comments_cid ON typecho_comments ("cid"); 17 | CREATE INDEX typecho_comments_created ON typecho_comments ("created"); 18 | 19 | CREATE TABLE typecho_contents ( "cid" INTEGER NOT NULL PRIMARY KEY, 20 | "title" varchar(200) default NULL , 21 | "slug" varchar(200) default NULL , 22 | "created" int(10) default '0' , 23 | "modified" int(10) default '0' , 24 | "text" text , 25 | "order" int(10) default '0' , 26 | "authorId" int(10) default '0' , 27 | "template" varchar(32) default NULL , 28 | "type" varchar(16) default 'post' , 29 | "status" varchar(16) default 'publish' , 30 | "password" varchar(32) default NULL , 31 | "commentsNum" int(10) default '0' , 32 | "allowComment" char(1) default '0' , 33 | "allowPing" char(1) default '0' , 34 | "allowFeed" char(1) default '0' , 35 | "parent" int(10) default '0' ); 36 | 37 | CREATE UNIQUE INDEX typecho_contents_slug ON typecho_contents ("slug"); 38 | CREATE INDEX typecho_contents_created ON typecho_contents ("created"); 39 | 40 | CREATE TABLE "typecho_fields" ("cid" INTEGER NOT NULL, 41 | "name" varchar(200) NOT NULL, 42 | "type" varchar(8) default 'str', 43 | "str_value" text, 44 | "int_value" int(10) default '0', 45 | "float_value" real default '0' 46 | ); 47 | 48 | CREATE UNIQUE INDEX typecho_fields_cid_name ON typecho_fields ("cid", "name"); 49 | CREATE INDEX typecho_fields_int_value ON typecho_fields ("int_value"); 50 | CREATE INDEX typecho_fields_float_value ON typecho_fields ("float_value"); 51 | 52 | CREATE TABLE typecho_metas ( "mid" INTEGER NOT NULL PRIMARY KEY, 53 | "name" varchar(200) default NULL , 54 | "slug" varchar(200) default NULL , 55 | "type" varchar(32) NOT NULL , 56 | "description" varchar(200) default NULL , 57 | "count" int(10) default '0' , 58 | "order" int(10) default '0' , 59 | "parent" int(10) default '0'); 60 | 61 | CREATE INDEX typecho_metas_slug ON typecho_metas ("slug"); 62 | 63 | CREATE TABLE typecho_options ( "name" varchar(32) NOT NULL , 64 | "user" int(10) NOT NULL default '0' , 65 | "value" text ); 66 | 67 | CREATE UNIQUE INDEX typecho_options_name_user ON typecho_options ("name", "user"); 68 | 69 | CREATE TABLE typecho_relationships ( "cid" int(10) NOT NULL , 70 | "mid" int(10) NOT NULL ); 71 | 72 | CREATE UNIQUE INDEX typecho_relationships_cid_mid ON typecho_relationships ("cid", "mid"); 73 | 74 | CREATE TABLE typecho_users ( "uid" INTEGER NOT NULL PRIMARY KEY, 75 | "name" varchar(32) default NULL , 76 | "password" varchar(64) default NULL , 77 | "mail" varchar(200) default NULL , 78 | "url" varchar(200) default NULL , 79 | "screenName" varchar(32) default NULL , 80 | "created" int(10) default '0' , 81 | "activated" int(10) default '0' , 82 | "logged" int(10) default '0' , 83 | "group" varchar(16) default 'visitor' , 84 | "authCode" varchar(64) default NULL); 85 | 86 | CREATE UNIQUE INDEX typecho_users_name ON typecho_users ("name"); 87 | CREATE UNIQUE INDEX typecho_users_mail ON typecho_users ("mail"); 88 | -------------------------------------------------------------------------------- /tools/transfer.php: -------------------------------------------------------------------------------- 1 | getPathname(); 18 | $file = $file->getFilename(); 19 | $lists[] = $path; 20 | 21 | $dir = dirname($path); 22 | 23 | if ($file[0] == '.') { 24 | continue; 25 | } 26 | 27 | $path = ltrim(substr($path, $offset), '/\\'); 28 | list($class) = explode('.', $path); 29 | 30 | $name = str_replace(['/', '\\'], '\\', $fake . '\\' . $class); 31 | $class = str_replace(['/', '\\'], '_', $ns . '_' . $class); 32 | 33 | $map[$name] = $class; 34 | } 35 | 36 | foreach ($lists as $file) { 37 | $dir = dirname($file); 38 | $source = file_get_contents($file); 39 | $replace = []; 40 | $current = ''; 41 | 42 | $source = preg_replace_callback("/\nnamespace\s*([a-z_\\\]+);/is", function ($matches) use ($map, $file, &$replace, &$current) { 43 | $matches[1] .= '\\' . pathinfo($file, PATHINFO_FILENAME); 44 | $parts = explode('\\', $matches[1]); 45 | $last = array_pop($parts); 46 | 47 | if (isset($map[$matches[1]])) { 48 | $replace[$last] = $map[$matches[1]]; 49 | $current = $matches[1]; 50 | } 51 | 52 | return "if (!defined('__TYPECHO_ROOT_DIR__')) exit;"; 53 | }, $source); 54 | 55 | $source = preg_replace_callback("/\nuse\s*([a-z_\\\]+)(?:\s+as\s+([a-z_\\\]+))?;/is", function ($matches) use ($map, &$replace) { 56 | $parts = explode('\\', $matches[1]); 57 | $last = array_pop($parts); 58 | 59 | if (isset($map[$matches[1]])) { 60 | $replace[$last] = $map[$matches[1]]; 61 | } 62 | 63 | return ''; 64 | }, $source); 65 | 66 | foreach ($map as $key => $val) { 67 | if (count(explode('\\', $key)) == count(explode('\\', $current))) { 68 | $parts = explode('_', $val); 69 | $last = array_pop($parts); 70 | 71 | if (!isset($replace[$last])) { 72 | $replace[$last] = $val; 73 | } 74 | } 75 | } 76 | 77 | $source = str_replace(array('mb_strtoupper', 'mb_strlen'), 78 | array('Typecho_Common::strToUpper', 'Typecho_Common::strLen'), $source); 79 | 80 | $tokens = token_get_all($source); 81 | $source = ''; 82 | 83 | $last = false; 84 | foreach ($tokens as $key => $token) { 85 | if (!is_array($token)) { 86 | $source .= $token; 87 | $last = false; 88 | continue; 89 | } 90 | 91 | list ($name, $str) = $token; 92 | 93 | if (T_STRING == $name) { 94 | $str = isset($replace[$str]) ? $replace[$str] : $str; 95 | } else if (T_NS_SEPARATOR == $name) { 96 | if (T_STRING == $last) { 97 | $source = substr($source, 0, - strlen($tokens[$key - 1][1])); 98 | } 99 | 100 | $str = ''; 101 | } 102 | 103 | $last = $name; 104 | $source .= $str; 105 | } 106 | 107 | file_put_contents($file, $source); 108 | } 109 | 110 | 111 | --------------------------------------------------------------------------------