diff --git a/.github/workflows/php-byethost.yml b/.github/workflows/php-byethost.yml index b712bb3cc..d2315fa72 100644 --- a/.github/workflows/php-byethost.yml +++ b/.github/workflows/php-byethost.yml @@ -48,3 +48,4 @@ jobs: **/.git*/** **/.github*/** **/node_modules/** + **/typecho11-webstack/** diff --git a/php/OneindexM/favicon.ico b/php/OneindexM/favicon.ico new file mode 100644 index 000000000..022ae2186 Binary files /dev/null and b/php/OneindexM/favicon.ico differ diff --git a/php/favicon.ico b/php/favicon.ico new file mode 100644 index 000000000..da7060561 Binary files /dev/null and b/php/favicon.ico differ diff --git a/php/oneindex/favicon.ico b/php/oneindex/favicon.ico new file mode 100644 index 000000000..022ae2186 Binary files /dev/null and b/php/oneindex/favicon.ico differ diff --git a/php/onemanager/favicon.ico b/php/onemanager/favicon.ico new file mode 100644 index 000000000..022ae2186 Binary files /dev/null and b/php/onemanager/favicon.ico differ diff --git a/php/typecho09/.gitattributes b/php/typecho09/.gitattributes deleted file mode 100644 index acc5026f6..000000000 --- a/php/typecho09/.gitattributes +++ /dev/null @@ -1,15 +0,0 @@ -# Set default behaviour, in case users don't have core.autocrlf set. -* text=auto - -# Explicitly declare text files we want to always be normalized and converted -# to native line endings on checkout. -*.php text eol=lf -*.js text eol=lf -*.css text eol=lf -*.html text eol=lf -*.xml text eol=lf - -# Denote all files that are truly binary and should not be modified. -*.png binary -*.jpg binary - diff --git a/php/typecho09/.gitignore b/php/typecho09/.gitignore deleted file mode 100644 index 2b9ce0a56..000000000 --- a/php/typecho09/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.inc.php \ No newline at end of file diff --git a/php/typecho09/admin/common-js.php b/php/typecho09/admin/common-js.php deleted file mode 100644 index 7b5659d2a..000000000 --- a/php/typecho09/admin/common-js.php +++ /dev/null @@ -1,106 +0,0 @@ - - - - - diff --git a/php/typecho09/admin/common.php b/php/typecho09/admin/common.php deleted file mode 100644 index 5abc62a81..000000000 --- a/php/typecho09/admin/common.php +++ /dev/null @@ -1,56 +0,0 @@ -begin(); - -Typecho_Widget::widget('Widget_Options')->to($options); -Typecho_Widget::widget('Widget_User')->to($user); -Typecho_Widget::widget('Widget_Menu')->to($menu); - -/** 初始化上下文 */ -$request = $options->request; -$response = $options->response; - -/** 检测是否是第一次登录 */ -$currentMenu = $menu->getCurrentMenu(); -list($prefixVersion, $suffixVersion) = explode('/', $options->version); -$params = parse_url($currentMenu[2]); -$adminFile = basename($params['path']); - -if (!$user->logged && !Typecho_Cookie::get('__typecho_first_run') && !empty($currentMenu)) { - - if ('welcome.php' != $adminFile) { - $response->redirect(Typecho_Common::url('welcome.php', $options->adminUrl)); - } else { - Typecho_Cookie::set('__typecho_first_run', 1); - } - -} else { - - /** 检测版本是否升级 */ - if ($user->pass('administrator', true) && !empty($currentMenu)) { - $mustUpgrade = (!defined('Typecho_Common::VERSION') || version_compare(str_replace('/', '.', Typecho_Common::VERSION), - str_replace('/', '.', $options->version), '>')); - - if ($mustUpgrade && 'upgrade.php' != $adminFile) { - $response->redirect(Typecho_Common::url('upgrade.php', $options->adminUrl)); - } else if (!$mustUpgrade && 'upgrade.php' == $adminFile) { - $response->redirect($options->adminUrl); - } else if (!$mustUpgrade && 'welcome.php' == $adminFile && $user->logged) { - $response->redirect($options->adminUrl); - } - } - -} diff --git a/php/typecho09/admin/copyright.php b/php/typecho09/admin/copyright.php deleted file mode 100644 index 722496010..000000000 --- a/php/typecho09/admin/copyright.php +++ /dev/null @@ -1,13 +0,0 @@ - - diff --git a/php/typecho09/admin/css/grid.css b/php/typecho09/admin/css/grid.css deleted file mode 100644 index 600707dfd..000000000 --- a/php/typecho09/admin/css/grid.css +++ /dev/null @@ -1 +0,0 @@ -.colgroup [class*="col-"]{float:left;min-height:1px;padding-right:10px;padding-left:10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}.colgroup [class*="push-"],.colgroup [class*="pull-"]{position:relative;}.col-mb-1{width:8.33333%;}.col-mb-2{width:16.66667%;}.col-mb-3{width:25%;}.col-mb-4{width:33.33333%;}.col-mb-5{width:41.66667%;}.col-mb-6{width:50%;}.col-mb-7{width:58.33333%;}.col-mb-8{width:66.66667%;}.col-mb-9{width:75%;}.col-mb-10{width:83.33333%;}.col-mb-11{width:91.66667%;}.col-mb-12{width:100%;}@media(min-width:768px){.container{margin-left:auto;margin-right:auto;max-width:728px;}.col-tb-1{width:8.33333%;}.col-tb-2{width:16.66667%;}.col-tb-3{width:25%;}.col-tb-4{width:33.33333%;}.col-tb-5{width:41.66667%;}.col-tb-6{width:50%;}.col-tb-7{width:58.33333%;}.col-tb-8{width:66.66667%;}.col-tb-9{width:75%;}.col-tb-10{width:83.33333%;}.col-tb-11{width:91.66667%;}.col-tb-12{width:100%;}.col-tb-offset-0{margin-left:0;}.col-tb-offset-1{margin-left:8.33333%;}.col-tb-offset-2{margin-left:16.66667%;}.col-tb-offset-3{margin-left:25%;}.col-tb-offset-4{margin-left:33.33333%;}.col-tb-offset-5{margin-left:41.66667%;}.col-tb-offset-6{margin-left:50%;}.col-tb-offset-7{margin-left:58.33333%;}.col-tb-offset-8{margin-left:66.66667%;}.col-tb-offset-9{margin-left:75%;}.col-tb-offset-10{margin-left:83.33333%;}.col-tb-offset-11{margin-left:91.66667%;}.col-tb-offset-12{margin-left:100%;}.col-tb-pull-0{right:0;}.col-tb-pull-1{right:8.33333%;}.col-tb-pull-2{right:16.66667%;}.col-tb-pull-3{right:25%;}.col-tb-pull-4{right:33.33333%;}.col-tb-pull-5{right:41.66667%;}.col-tb-pull-6{right:50%;}.col-tb-pull-7{right:58.33333%;}.col-tb-pull-8{right:66.66667%;}.col-tb-pull-9{right:75%;}.col-tb-pull-10{right:83.33333%;}.col-tb-pull-11{right:91.66667%;}.col-tb-pull-12{right:100%;}.col-tb-push-0{left:0;}.col-tb-push-1{left:8.33333%;}.col-tb-push-2{left:16.66667%;}.col-tb-push-3{left:25%;}.col-tb-push-4{left:33.33333%;}.col-tb-push-5{left:41.66667%;}.col-tb-push-6{left:50%;}.col-tb-push-7{left:58.33333%;}.col-tb-push-8{left:66.66667%;}.col-tb-push-9{left:75%;}.col-tb-push-10{left:83.33333%;}.col-tb-push-11{left:91.66667%;}.col-tb-push-12{left:100%;}.colgroup{margin-right:-10px;margin-left:-10px;}}@media(min-width:992px){.container{max-width:952px;}.col-1{width:8.33333%;}.col-2{width:16.66667%;}.col-3{width:25%;}.col-4{width:33.33333%;}.col-5{width:41.66667%;}.col-6{width:50%;}.col-7{width:58.33333%;}.col-8{width:66.66667%;}.col-9{width:75%;}.col-10{width:83.33333%;}.col-11{width:91.66667%;}.col-12{width:100%;}.col-offset-0{margin-left:0;}.col-offset-1{margin-left:8.33333%;}.col-offset-2{margin-left:16.66667%;}.col-offset-3{margin-left:25%;}.col-offset-4{margin-left:33.33333%;}.col-offset-5{margin-left:41.66667%;}.col-offset-6{margin-left:50%;}.col-offset-7{margin-left:58.33333%;}.col-offset-8{margin-left:66.66667%;}.col-offset-9{margin-left:75%;}.col-offset-10{margin-left:83.33333%;}.col-offset-11{margin-left:91.66667%;}.col-offset-12{margin-left:100%;}.col-pull-0{right:0;}.col-pull-1{right:8.33333%;}.col-pull-2{right:16.66667%;}.col-pull-3{right:25%;}.col-pull-4{right:33.33333%;}.col-pull-5{right:41.66667%;}.col-pull-6{right:50%;}.col-pull-7{right:58.33333%;}.col-pull-8{right:66.66667%;}.col-pull-9{right:75%;}.col-pull-10{right:83.33333%;}.col-pull-11{right:91.66667%;}.col-pull-12{right:100%;}.col-push-0{left:0;}.col-push-1{left:8.33333%;}.col-push-2{left:16.66667%;}.col-push-3{left:25%;}.col-push-4{left:33.33333%;}.col-push-5{left:41.66667%;}.col-push-6{left:50%;}.col-push-7{left:58.33333%;}.col-push-8{left:66.66667%;}.col-push-9{left:75%;}.col-push-10{left:83.33333%;}.col-push-11{left:91.66667%;}.col-push-12{left:100%;}}@media(min-width:1200px){.container{max-width:1160px;}.col-wd-1{width:8.33333%;}.col-wd-2{width:16.66667%;}.col-wd-3{width:25%;}.col-wd-4{width:33.33333%;}.col-wd-5{width:41.66667%;}.col-wd-6{width:50%;}.col-wd-7{width:58.33333%;}.col-wd-8{width:66.66667%;}.col-wd-9{width:75%;}.col-wd-10{width:83.33333%;}.col-wd-11{width:91.66667%;}.col-wd-12{width:100%;}.col-wd-offset-0{margin-left:0;}.col-wd-offset-1{margin-left:8.33333%;}.col-wd-offset-2{margin-left:16.66667%;}.col-wd-offset-3{margin-left:25%;}.col-wd-offset-4{margin-left:33.33333%;}.col-wd-offset-5{margin-left:41.66667%;}.col-wd-offset-6{margin-left:50%;}.col-wd-offset-7{margin-left:58.33333%;}.col-wd-offset-8{margin-left:66.66667%;}.col-wd-offset-9{margin-left:75%;}.col-wd-offset-10{margin-left:83.33333%;}.col-wd-offset-11{margin-left:91.66667%;}.col-wd-offset-12{margin-left:100%;}.col-wd-pull-0{right:0;}.col-wd-pull-1{right:8.33333%;}.col-wd-pull-2{right:16.66667%;}.col-wd-pull-3{right:25%;}.col-wd-pull-4{right:33.33333%;}.col-wd-pull-5{right:41.66667%;}.col-wd-pull-6{right:50%;}.col-wd-pull-7{right:58.33333%;}.col-wd-pull-8{right:66.66667%;}.col-wd-pull-9{right:75%;}.col-wd-pull-10{right:83.33333%;}.col-wd-pull-11{right:91.66667%;}.col-wd-pull-12{right:100%;}.col-wd-push-0{left:0;}.col-wd-push-1{left:8.33333%;}.col-wd-push-2{left:16.66667%;}.col-wd-push-3{left:25%;}.col-wd-push-4{left:33.33333%;}.col-wd-push-5{left:41.66667%;}.col-wd-push-6{left:50%;}.col-wd-push-7{left:58.33333%;}.col-wd-push-8{left:66.66667%;}.col-wd-push-9{left:75%;}.col-wd-push-10{left:83.33333%;}.col-wd-push-11{left:91.66667%;}.col-wd-push-12{left:100%;}}@media(max-width:767px){.kit-hidden-mb{display:none;}}@media(max-width:991px){.kit-hidden-tb{display:none;}}@media(max-width:1199px){.kit-hidden{display:none;}}.clearfix,.colgroup{zoom:1;}.clearfix:before,.colgroup:before,.clearfix:after,.colgroup:after{content:" ";display:table;}.clearfix:after,.colgroup:after{clear:both;} \ No newline at end of file diff --git a/php/typecho09/admin/css/normalize.css b/php/typecho09/admin/css/normalize.css deleted file mode 100644 index c37760773..000000000 --- a/php/typecho09/admin/css/normalize.css +++ /dev/null @@ -1 +0,0 @@ -/*!normalize.css v2.1.3 | MIT License | git.io/normalize */ article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden],template{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a{background:transparent;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} \ No newline at end of file diff --git a/php/typecho09/admin/css/style.css b/php/typecho09/admin/css/style.css deleted file mode 100644 index 2f72043b6..000000000 --- a/php/typecho09/admin/css/style.css +++ /dev/null @@ -1 +0,0 @@ -html{height:100%;}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;background:#F6F6F3;color:#444;font-size:87.5%;line-height:1.5;}a{color:#467B96;text-decoration:none;}a:hover{color:#499BC3;text-decoration:underline;}code,pre,.mono{font-family:Menlo,Monaco,Consolas,"Courier New",monospace;}.p{margin:1em 0;}.body-100{height:100%;}a.balloon-button{display:inline-block;padding:0 6px;min-width:12px;height:18px;line-height:18px;background:#D8E7EE;font-size:.85714em;text-align:center;text-decoration:none;zoom:1;-moz-border-radius:30px;-webkit-border-radius:30px;border-radius:30px;}a.button:hover,a.balloon-button:hover{background-color:#A5CADC;color:#FFF;text-decoration:none;}input[type=text],input[type=password],input[type=email],textarea{background:#FFF;border:1px solid #D9D9D6;padding:7px;border-radius:2px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}textarea{resize:vertical;line-height:1.5;}input[type="radio"],input[type="checkbox"]{margin-right:3px;}input.text-s,textarea.text-s{padding:5px;}input.text-l,textarea.text-l{padding:10px;font-size:1.14286em;}.w-10{width:10%;}.w-20{width:20%;}.w-30{width:30%;}.w-40{width:40%;}.w-50{width:50%;}.w-60{width:60%;}.w-70{width:70%;}.w-80{width:80%;}.w-90{width:90%;}.w-100{width:100%;}select{border:1px solid #CCC;height:28px;}button{border:none;background-color:#e9e9e6;cursor:pointer;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;display:inline-block;padding:0 12px;height:32px;color:#666;vertical-align:middle;zoom:1;}button:hover{-webkit-transition-duration:.4s;-moz-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s;background-color:#dbdbd6;}button:active,button.active{background-color:#d6d6d0;}button:disabled{background-color:#f7f7f6;cursor:default;}button:disabled{color:#999;}.btn-xs{padding:0 10px;height:25px;}.btn-s{height:28px;}.btn-l{height:40px;font-size:1.14286em;font-weight:bold;}.primary{border:none;background-color:#467b96;cursor:pointer;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;color:#FFF;}.primary:hover{-webkit-transition-duration:.4s;-moz-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s;background-color:#3c6a81;}.primary:active,.primary.active{background-color:#39647a;}.primary:disabled{background-color:#508cab;cursor:default;}.btn-group{display:inline-block;}.btn-warn{border:none;background-color:#b94a48;cursor:pointer;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;color:#FFF;}.btn-warn:hover{-webkit-transition-duration:.4s;-moz-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s;background-color:#a4403f;}.btn-warn:active,.btn-warn.active{background-color:#9c3e3c;}.btn-warn:disabled{background-color:#c1605e;cursor:default;}.btn-drop{position:relative;}.dropdown-toggle{padding-right:8px;}.dropdown-menu{list-style:none;position:absolute;z-index:2;left:0;margin:0;padding:0;border:1px solid #D9D9D6;background:#FFF;text-align:left;min-width:108px;display:none;}.dropdown-menu li{white-space:nowrap;}.dropdown-menu li.multiline{padding:5px 12px 12px;}.dropdown-menu a{display:block;padding:5px 12px;color:#666;}.dropdown-menu a:hover{background:#F6F6F3;text-decoration:none!important;}.message{padding:8px 10px;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;}.message a{font-weight:bold;text-decoration:underline;}.error{background:#FBE3E4;color:#8A1F11;}.error a{color:#8A1F11;}.notice{background:#FFF6BF;color:#8A6D3B;}.notice a{color:#8A6D3B;}.success{background:#E6EFC2;color:#264409;}.success a{color:#264409;}.balloon{display:inline-block;padding:0 4px;min-width:10px;height:14px;line-height:14px;background:#B9B9B6;vertical-align:text-top;text-align:center;font-size:12px;color:#FFF;-webkit-border-radius:20px;-moz-border-radius:20px;-ms-border-radius:20px;-o-border-radius:20px;border-radius:20px;}.typecho-pager{list-style:none;float:right;margin:0;padding:0;line-height:1;text-align:center;zoom:1;}.typecho-pager li{display:inline-block;margin:0 3px;height:28px;line-height:28px;}.typecho-pager a{display:block;padding:0 10px;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;}.typecho-pager a:hover{text-decoration:none;background:#E9E9E6;}.typecho-pager li.current a{background:#E9E9E6;color:#444;}.typecho-head-nav{padding:0 10px;background:#292D33;}.typecho-head-nav a{color:#BBB;}.typecho-head-nav a:hover,.typecho-head-nav a:focus{color:#FFF;text-decoration:none;}#typecho-nav-list{float:left;}#typecho-nav-list ul{list-style:none;margin:0;padding:0;}#typecho-nav-list ul:first-child{border-left:1px solid #383D45;}#typecho-nav-list .root{position:relative;float:left;}#typecho-nav-list .parent a{display:block;float:left;padding:0 20px;border-right:1px solid #383D45;height:36px;line-height:36px;color:#BBB;}#typecho-nav-list .parent a:hover,#typecho-nav-list .focus .parent a,#typecho-nav-list .root:hover .parent a{background:#202328;color:#FFF;text-decoration:none;}#typecho-nav-list .focus .parent a{font-weight:bold;}#typecho-nav-list .child{position:absolute;top:36px;display:none;margin:0;min-width:160px;max-width:240px;background:#202328;z-index:250;}#typecho-nav-list .root:hover .child{display:block;}#typecho-nav-list .child li a{color:#BBB;display:block;padding:0 20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;height:36px;line-height:36px;}#typecho-nav-list .child li a:hover,#typecho-nav-list .child li a:focus{background:#292D33;color:#FFF;}#typecho-nav-list .child li.focus a{color:#6DA1BB;font-weight:bold;}.typecho-head-nav .operate{float:right;}.typecho-head-nav .operate a{display:inline-block;margin-left:-1px;padding:0 20px;border:1px solid #383D45;border-width:0 1px;line-height:36px;color:#BBB;}.typecho-head-nav .operate a:hover{background-color:#202328;color:#FFF;}.typecho-foot{padding:4em 0 3em;color:#999;line-height:1.8;text-align:center;}.typecho-foot .copyright p{margin:10px 0 0;}.typecho-foot .resource{color:#CCC;}.typecho-foot .resource a{margin:0 3px;color:#999;}.browsehappy{border:none;text-align:center;}.popup{display:none;position:absolute;top:0;left:0;margin:0;padding:8px 0;border:none;width:100%;z-index:10;text-align:center;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;}.popup ul{list-style:none;margin:0;padding:0;text-align:center;}.popup ul li{display:inline-block;margin-right:10px;}.loading{padding-left:20px!important;background:transparent url(../img/ajax-loader.gif) no-repeat left center;}.typecho-option{list-style:none;margin:1em 0;padding:0;}.typecho-option-submit li{border-bottom:none;}.typecho-option label.typecho-label{display:block;margin-bottom:.5em;font-weight:bold;}.typecho-option label.required:after{content:" *";color:#B94A48;}.typecho-option span{margin-right:15px;}.typecho-option .description{margin:.5em 0 0;color:#999;font-size:.92857em;}.front-archive{padding-left:1.5em;}.profile-avatar{border:1px dashed #D9D9D6;max-width:100%;}.typecho-install-patch{margin-bottom:2em;padding:2em 0;background-color:#292D33;color:#FFF;text-align:center;}.typecho-install-patch ol{list-style:none;margin:3em 0 1em;padding:0;color:#999;}.typecho-install-patch li{display:inline-block;margin:0 .8em;}.typecho-install-patch span{display:inline-block;margin-right:5px;width:20px;height:20px;line-height:20px;border:2px solid #999;text-align:center;border-radius:2em;}.typecho-install-patch li.current{color:#FFF;font-weight:bold;}.typecho-install-patch li.current span{border-color:#FFF;}.typecho-install .typecho-install-body input{width:100%;}.typecho-install-body .typecho-option li{margin:1em 0;}#typecho-welcome{margin:1em 0;padding:1em 2em;background-color:#E9E9E6;}.welcome-board{color:#999;font-size:1.15em;}.welcome-board em{color:#444;font-size:2em;font-style:normal;font-family:Georgia,serif;}#start-link{margin-bottom:25px;padding:0 0 35px;border-bottom:1px solid #ECECEC;}#start-link li{float:left;margin-right:1.5em;}#start-link .balloon{margin-top:2px;}.latest-link li{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.latest-link span{display:inline-block;margin-right:4px;padding-right:8px;border-right:1px solid #ECECEC;width:37px;text-align:right;color:#999;}.update-check{font-size:14px;}.typecho-login-wrap{display:table;margin:0 auto;height:100%;}.typecho-login{display:table-cell;padding-bottom:100px;width:280px;text-align:center;vertical-align:middle;}.typecho-login h1{margin:0 0 1em;}.typecho-login .more-link{margin-top:2em;color:#CCC;}.typecho-login .more-link a{margin:0 3px;}.typecho-page-title h2{margin:25px 0 10px;font-size:1.28571em;}.typecho-page-title h2 a{margin-left:10px;padding:3px 8px;background:#E9E9E6;font-size:.8em;border-radius:2px;}.typecho-page-title h2 a:hover{text-decoration:none;}.typecho-dashboard ul{list-style:none;padding:0;}.typecho-dashboard li{margin-bottom:5px;}.typecho-option-tabs{list-style:none;margin:1em 0 0;padding:0;font-size:13px;text-align:center;}.typecho-option-tabs.fix-tabs{margin-bottom:1em;}.typecho-option-tabs a{display:block;margin-right:-1px;border:1px solid #D9D9D6;padding:0 15px;height:26px;line-height:26px;color:#666;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}.typecho-option-tabs a:hover{background-color:#E9E9E6;color:#666;text-decoration:none;}.typecho-option-tabs li{float:left;}.typecho-option-tabs li:first-child a{-webkit-border-radius:2px 0 0 2px;-moz-border-radius:2px 0 0 2px;-ms-border-radius:2px 0 0 2px;-o-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;}.typecho-option-tabs li:last-child a{-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;-ms-border-radius:0 2px 2px 0;-o-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;}.typecho-option-tabs.right{float:right;}.typecho-option-tabs li.current a,.typecho-option-tabs li.active a{background-color:#E9E9E6;}.typecho-list-operate{margin:1em 0;}.typecho-list-operate input,.typecho-list-operate button,.typecho-list-operate select{vertical-align:bottom;}.typecho-list-operate input[type="checkbox"]{vertical-align:text-top;}.typecho-list-operate .operate{float:left;}.typecho-list-operate .search{float:right;}.typecho-list-operate span.operate-delete,a.operate-delete,.typecho-list-operate span.operate-button-delete,a.operate-button-delete{color:#B94A48;}a.operate-edit{color:#070;}a.operate-reply{color:#545c30;}.typecho-list-operate a:hover{text-decoration:none;}.typecho-list-table-title{margin:1em 0;color:#999;text-align:center;}.typecho-table-wrap{padding:30px;background:#FFF;}.typecho-list-table{width:100%;}.typecho-list-table.deactivate{color:#999;}.typecho-list-table .right{text-align:right;}.typecho-list-table th{padding:0 10px 10px;border-bottom:2px solid #F0F0EC;text-align:left;}.typecho-list-table td{padding:10px;border-top:1px solid #F0F0EC;word-break:break-all;}.typecho-list-table .status{margin-left:5px;color:#999;font-size:.92857em;font-style:normal;}.typecho-list-table tbody tr:hover td{background-color:#F6F6F3;}.typecho-list-table tbody tr.checked td{background-color:#FFF9E8;}.warning{color:#B94A48;}.typecho-list-table tr td .hidden-by-mouse{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;}.typecho-list-table tr:hover td .hidden-by-mouse{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1;}.comment-reply-content{position:relative;margin:1em 0;padding:0 1em;border:1px solid transparent;background-color:#F0F0EC;}.comment-reply-content:after{position:absolute;right:1em;border:8px solid #F0F0EC;border-color:#F0F0EC #F0F0EC transparent transparent;content:" ";}.comment-meta span,.comment-date{font-size:.92857em;color:#999;}.comment-action a,.comment-action span{margin-right:4px;}.comment-edit label{display:block;}#typecho-respond{padding:10px;display:none;}.typecho-theme-list img{margin:1em 0;max-width:100%;max-height:240px;}.typecho-theme-list cite{font-style:normal;color:#999;}.typecho-theme-list tbody tr.current td{background-color:#FFF9E8;}.typecho-page-main .typecho-option input.text{width:100%;}.typecho-page-main .typecho-option input.num{width:40px;}.typecho-page-main .typecho-option textarea{width:100%;height:100px;}.typecho-page-main .typecho-option span.multiline{display:block;margin:.3em 0;}.typecho-select-theme{height:25px;line-height:25px;margin:15px 0;}.typecho-select-theme h5{color:#E47E00;font-weight:bold;float:left;font-size:14px;width:120px;margin-right:10px;}.typecho-select-theme select{width:150px;}.typecho-edit-theme ul{list-style:none;margin:0;padding:0;}.typecho-edit-theme li{padding:3px 10px;}.typecho-edit-theme .current{background-color:#E6E6E3;}.typecho-edit-theme .current a{color:#444;}.typecho-edit-theme textarea{font-size:.92857em;line-height:1.2;height:500px;}.typecho-post-area .edit-draft-notice{color:#999;font-size:.92857em;}.typecho-post-area .edit-draft-notice a{color:#B94A48;}.typecho-post-area .typecho-label{display:block;margin:1em 0 -0.5em;font-weight:bold;}.typecho-post-area #auto-save-message{display:block;margin-top:.5em;color:#999;font-size:.92857em;}.typecho-post-area .submit .right button{margin-left:5px;}.typecho-post-area .right{float:right;padding-left:24px;}.typecho-post-area .left{float:left;}.typecho-post-area .out-date{border:1px solid #D3DBB3;padding:3px;background:#fff;}.typecho-post-area input.title{font-size:1.17em;font-weight:bold;}.typecho-post-area .url-slug{margin-top:-0.5em;color:#AAA;font-size:.92857em;word-break:break-word;}.typecho-post-area #slug{padding:2px;border:none;background:#FFFBCC;color:#666;}.typecho-post-area #text{resize:none;font-size:.92857em;}#advance-panel-btn{font-size:.92857em;}#advance-panel{display:none;}#custom-field{margin:1em 0;padding:10px 15px;background:#FFF;}#custom-field.fold table,#custom-field.fold .description{display:none;}#custom-field .description{margin-top:10px;text-align:right;}#custom-field .description button{float:left;}#custom-field .typecho-label{margin:0;}#custom-field .typecho-label a{display:block;color:#444;}#custom-field .typecho-label a:hover{color:#467B96;text-decoration:none;}#custom-field table{margin-top:10px;}#custom-field td{padding:10px 5px;font-size:.92857em;border-bottom:1px solid #F0F0EC;vertical-align:top;}#custom-field td label{font-size:1em;font-weight:normal;}#custom-field select{height:27px;}.typecho-post-area .is-draft{background:#FFF1A8;}.typecho-post-option .description{margin-top:-0.5em;color:#999;font-size:.92857em;}.category-option ul{list-style:none;border:1px solid #D9D9D6;padding:6px 12px;background-color:#FFF;border-radius:2px;}.category-option li{margin:3px 0;}.visibility-option ul,.allow-option ul{list-style:none;padding:0;}#edit-secondary #tab-files{display:none;}.typecho-page-main ul.tag-list{list-style:none;margin:0;padding:20px;background-color:#FFF;}.typecho-page-main ul.tag-list li{display:inline-block;margin:0 0 5px 0;padding:5px 5px 5px 10px;cursor:pointer;}.typecho-page-main ul.tag-list li:hover{background-color:#E9E9E6;}.typecho-page-main ul.tag-list li input{display:none;}.typecho-page-main ul.tag-list li.checked{background-color:#FFFBCC;}.typecho-page-main ul.tag-list li.size-5{font-size:1em;}.typecho-page-main ul.tag-list li.size-10{font-size:1.2em;}.typecho-page-main ul.tag-list li.size-20{font-size:1.4em;}.typecho-page-main ul.tag-list li.size-30{font-size:1.6em;}.typecho-page-main ul.tag-list li.size-0{font-size:1.8em;}.typecho-page-main .tag-edit-link{visibility:hidden;}.typecho-page-main li:hover .tag-edit-link{visibility:visible;}.typecho-attachment-photo{border:1px solid #E6E6E3;max-width:100%;}#upload-panel{border:1px dashed #D9D9D6;background-color:#FFF;color:#999;font-size:.92857em;}#upload-panel.drag{background-color:#FFFBCC;}.upload-area{padding:15px;text-align:center;}#file-list{list-style:none;margin:0 10px;padding:0;}#file-list li{padding:8px 0;border-top:1px dashed #D9D9D6;}#file-list .file{margin-left:5px;}#file-list .insert{display:block;max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}#file-list .info{text-transform:uppercase;}.edit-media button{margin-right:6px;}.resize{display:block;margin:2px auto 0;padding:2px 0;border:1px solid #D9D9D6;border-width:1px 0;width:60px;cursor:row-resize;}.resize i{display:block;height:1px;background-color:#D9D9D6;}.tDnD_whileDrag{background-color:#FFFBCC;}.icon-sprite-hack{background:url('../img/icons-s2ebed63329.png');}.i-edit,.i-delete,.i-exlink,.mime-office,.mime-text,.mime-image,.mime-html,.mime-archive,.mime-application,.mime-audio,.mime-script,.mime-video,.mime-unknow{width:16px;height:16px;display:inline-block;vertical-align:text-bottom;background:url(../img/icons.png) no-repeat;}.i-edit:hover,.i-delete:hover,.i-exlink:hover,.mime-office:hover,.mime-text:hover,.mime-image:hover,.mime-html:hover,.mime-archive:hover,.mime-application:hover,.mime-audio:hover,.mime-script:hover,.mime-video:hover,.mime-unknow:hover{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=75);opacity:.75;}.i-edit{background-position:0 -32px;}.i-delete{background-position:0 -16px;}.i-caret-up,.i-caret-down,.i-caret-left,.i-caret-right{display:inline-block;border-style:solid;border-color:transparent transparent #BBB transparent;border-width:3px 4px 5px;}.i-caret-down{border-color:#BBB transparent transparent transparent;border-width:5px 4px 3px;}.i-caret-left{border-color:transparent #BBB transparent transparent;border-width:4px 5px 4px 3px;}.i-caret-right{border-color:transparent transparent transparent #BBB;border-width:4px 3px 4px 5px;}.i-exlink{background-position:0 0;}.mime-office{background-position:0 -80px;}.mime-text{background-position:0 -176px;}.mime-image{background-position:0 -48px;}.mime-html{background-position:0 -96px;}.mime-archive{background-position:0 -192px;}.mime-application{background-position:0 -112px;}.mime-audio{background-position:0 -224px;}.mime-script{background-position:0 -144px;}.mime-video{background-position:0 -64px;}.mime-unknow{background-position:0 -160px;}.i-logo,.i-logo-s{width:169px;height:40px;display:inline-block;background:url("../img/typecho-logo.svg") no-repeat;text-indent:-9999em;-webkit-background-size:auto 40px;-moz-background-size:auto 40px;-o-background-size:auto 40px;background-size:auto 40px;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=30);opacity:.3;}.i-logo:hover,.i-logo-s:hover{filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=20);opacity:.2;}.i-logo-s{width:26px;height:26px;-webkit-background-size:auto 26px;-moz-background-size:auto 26px;-o-background-size:auto 26px;background-size:auto 26px;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=10);opacity:.1;}.editor{margin-bottom:-0.5em;}.wmd-button-row{list-style:none;margin:0;padding:0;height:26px;line-height:1;}.wmd-button-row li{display:inline-block;margin-right:4px;padding:3px;cursor:pointer;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;}.wmd-button-row li:hover{background-color:#E9E9E6;}.wmd-button-row li.wmd-spacer{height:20px;margin:0 10px 0 6px;padding:3px 0;width:1px;background:#E9E9E6;cursor:default;}#wmd-button-row span{display:block;width:20px;height:20px;background:transparent url(../img/editor.png) no-repeat;}.wmd-edittab{float:right;margin-top:3px;font-size:.92857em;}.wmd-edittab a{display:inline-block;padding:0 8px;margin-left:5px;height:20px;line-height:20px;}.wmd-edittab a:hover{text-decoration:none;}.wmd-edittab a.active{background:#E9E9E6;color:#999;}.wmd-hidetab{display:none;}.wmd-visualhide{visibility:hidden;}.wmd-prompt-background{background-color:#000;}.wmd-prompt-dialog{position:fixed;z-index:1001;top:50%;left:50%;margin-top:-95px;margin-left:-200px;padding:20px;width:360px;background:#F6F6F3;}.wmd-prompt-dialog p{margin:0 0 5px;}.wmd-prompt-dialog form{margin-top:10px;}.wmd-prompt-dialog input[type="text"]{margin-bottom:10px;width:100%;}.wmd-prompt-dialog button{margin-right:10px;}#wmd-preview{background:#FFF;margin:1em 0;padding:0 15px;word-wrap:break-word;overflow:auto;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;}#wmd-preview img{max-width:100%;}#wmd-preview code,#wmd-preview pre{padding:2px 4px;background:#F3F3F0;font-size:.92857em;}#wmd-preview code{color:#B94A48;}#wmd-preview pre{padding:1em;}#wmd-preview pre code{padding:0;color:#444;}#wmd-preview blockquote{margin:1em 1.5em;padding-left:1.5em;border-left:4px solid #E9E9E6;color:#777;}#wmd-preview hr{margin:2em auto;width:100px;border:1px solid #E9E9E6;border-width:2px 0 0 0;}#wmd-preview .summary:after{display:block;margin:2em 0;background:#FFF9E8;color:#ce9900;font-size:.85714em;text-align:center;content:"- more -";}.fullscreen #wmd-button-bar,.fullscreen #text,.fullscreen #wmd-preview,.fullscreen .submit{position:absolute;top:0;width:50%;background:#FFF;z-index:999;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0;}.fullscreen #wmd-button-bar{left:0;padding:13px 20px;border-bottom:1px solid #F3F3F0;z-index:1000;}.fullscreen #text{top:53px;left:0;padding:20px;border:none;outline:none;}.fullscreen #wmd-preview{top:53px;right:0;margin:0;padding:5px 20px;border:none;border-left:1px solid #F3F3F0;background:#F6F6F3;overflow:auto;}.fullscreen #wmd-preview code,.fullscreen #wmd-preview pre{background:#F0F0EC;}.fullscreen .submit{right:0;margin:0;padding:10px 20px;border-bottom:1px solid #F3F3F0;}.fullscreen .wmd-edittab,.fullscreen .typecho-post-option,.fullscreen .title,.fullscreen .url-slug,.fullscreen .typecho-page-title,.fullscreen .typecho-head-nav,.fullscreen .message,.fullscreen #upload-panel{display:none;}.fullscreen .wmd-hidetab{display:block;}.fullscreen .wmd-visualhide{visibility:visible;}#ui-datepicker-div{display:none;margin-top:-1px;padding:10px;border:1px solid #D9D9D6;background:#FFF;}.ui-timepicker-div .ui-widget-header{margin-bottom:8px;}.ui-timepicker-div dl{text-align:left;}.ui-timepicker-div dl dt{float:left;clear:left;}.ui-timepicker-div dl dd{margin:0 0 10px 40%;}.ui-tpicker-grid-label{background:none;border:none;margin:0;padding:0;}#ui-datepicker-div .ui-datepicker-header{margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #EEE;}#ui-datepicker-div .ui-datepicker-prev{float:left;cursor:pointer;}#ui-datepicker-div .ui-datepicker-next{float:right;cursor:pointer;}#ui-datepicker-div .ui-datepicker-title{font-weight:bold;text-align:center;}#ui-datepicker-div .ui-datepicker-calendar th{line-height:24px;}#ui-datepicker-div .ui-datepicker-calendar a{display:block;width:30px;background-color:#F3F3F0;line-height:24px;text-align:center;}#ui-datepicker-div .ui-datepicker-calendar a:hover{background-color:#E9E9E6;text-decoration:none;}#ui-datepicker-div .ui-datepicker-today a{background-color:#E9E9E6;color:#444;}#ui-datepicker-div .ui-datepicker-current-day a{background-color:#467B96!important;color:#FFF;}#ui-datepicker-div .ui-timepicker-div{margin-top:20px;border-top:1px solid #EEE;}#ui-datepicker-div .ui-slider{position:relative;margin-top:18px;border:1px solid #E9E9E6;background-color:#F6F6F3;height:4px;}#ui-datepicker-div .ui-slider .ui-slider-handle{position:absolute;top:-7px;margin-left:-5px;z-index:2;width:10px;height:16px;background-color:#467B96;}#ui-datepicker-div .ui-datepicker-buttonpane{padding-top:10px;border-top:1px solid #EEE;}#ui-datepicker-div button{height:28px;}#ui-datepicker-div .ui-datepicker-current{float:left;}#ui-datepicker-div .ui-datepicker-close{float:right;}.ui-effects-transfer{border:2px dotted #ccc;}ul.token-input-list{list-style:none;margin:0;padding:0 4px;min-height:32px;border:1px solid #D9D9D6;cursor:text;z-index:999;background-color:#FFF;clear:left;border-radius:2px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}ul.token-input-list li{margin:4px 0;}ul.token-input-list li input{padding:0;border:0;width:100%;-webkit-appearance:caret;}li.token-input-token{padding:0 6px;height:27px;line-height:27px;background-color:#F3F3F0;cursor:default;font-size:.92857em;text-align:right;white-space:nowrap;}li.token-input-token p{float:left;display:inline;margin:0;}li.token-input-token span{color:#BBB;font-weight:bold;cursor:pointer;}li.token-input-selected-token{background-color:#E9E9E6;}li.token-input-input-token{padding:0 4px;}div.token-input-dropdown{position:absolute;background-color:#FFF;overflow:hidden;border:1px solid #D9D9D6;border-top-width:0;cursor:default;z-index:1;font-size:.92857em;}div.token-input-dropdown p{margin:0;padding:5px 10px;color:#777;font-weight:bold;}div.token-input-dropdown ul{list-style:none;margin:0;padding:0;}div.token-input-dropdown ul li{padding:4px 10px;background-color:#FFF;}div.token-input-dropdown ul li.token-input-dropdown-item{background-color:#FFF;}div.token-input-dropdown ul li em{font-style:normal;}div.token-input-dropdown ul li.token-input-selected-dropdown-item{background-color:#467B96;color:#FFF;}.hidden{display:none!important;visibility:hidden;}.sr-only{border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;}.sr-only.focusable:active,.sr-only.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto;}.invisible{visibility:hidden;} \ No newline at end of file diff --git a/php/typecho09/admin/custom-fields-js.php b/php/typecho09/admin/custom-fields-js.php deleted file mode 100644 index b6dce8fd0..000000000 --- a/php/typecho09/admin/custom-fields-js.php +++ /dev/null @@ -1,43 +0,0 @@ - diff --git a/php/typecho09/admin/custom-fields.php b/php/typecho09/admin/custom-fields.php deleted file mode 100644 index 44cfb575d..000000000 --- a/php/typecho09/admin/custom-fields.php +++ /dev/null @@ -1,73 +0,0 @@ - -getFieldItems() : $page->getFieldItems(); -$defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaultFieldItems(); -?> -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
render(); ?>render(); ?>
- - - - - - - - - - -
- - - - - - - - - - -
-
- - 帮助文档'); ?> -
-
diff --git a/php/typecho09/admin/editor-js.php b/php/typecho09/admin/editor-js.php deleted file mode 100644 index a41f29f85..000000000 --- a/php/typecho09/admin/editor-js.php +++ /dev/null @@ -1,243 +0,0 @@ - -markdown && (!$content->have() || $content->isMarkdown)): ?> - - - - - - diff --git a/php/typecho09/admin/extending.php b/php/typecho09/admin/extending.php deleted file mode 100644 index 9504da97e..000000000 --- a/php/typecho09/admin/extending.php +++ /dev/null @@ -1,11 +0,0 @@ -get('panel'); -$panelTable = unserialize($options->panelTable); - -if (!isset($panelTable['file']) || !in_array(urlencode($panel), $panelTable['file'])) { - throw new Typecho_Plugin_Exception(_t('页面不存在'), 404); -} - -require_once $panel; diff --git a/php/typecho09/admin/file-upload-js.php b/php/typecho09/admin/file-upload-js.php deleted file mode 100644 index 9b3b2e7f9..000000000 --- a/php/typecho09/admin/file-upload-js.php +++ /dev/null @@ -1,218 +0,0 @@ - -have()) { - $fileParentContent = $post; -} else if (isset($page) && $page instanceof Typecho_Widget && $page->have()) { - $fileParentContent = $page; -} -?> - - - - diff --git a/php/typecho09/admin/file-upload.php b/php/typecho09/admin/file-upload.php deleted file mode 100644 index b935db8d6..000000000 --- a/php/typecho09/admin/file-upload.php +++ /dev/null @@ -1,30 +0,0 @@ - - -cid : $page->cid; - - if ($cid) { - Typecho_Widget::widget('Widget_Contents_Attachment_Related', 'parentId=' . $cid)->to($attachment); - } else { - Typecho_Widget::widget('Widget_Contents_Attachment_Unattached')->to($attachment); - } -} -?> - -
-
或者 %s选择文件上传%s', '', ''); ?>
- -
- diff --git a/php/typecho09/admin/footer.php b/php/typecho09/admin/footer.php deleted file mode 100644 index eccc38888..000000000 --- a/php/typecho09/admin/footer.php +++ /dev/null @@ -1,6 +0,0 @@ - - - -end(); diff --git a/php/typecho09/admin/form-js.php b/php/typecho09/admin/form-js.php deleted file mode 100644 index 78d9db15a..000000000 --- a/php/typecho09/admin/form-js.php +++ /dev/null @@ -1,26 +0,0 @@ - - diff --git a/php/typecho09/admin/header.php b/php/typecho09/admin/header.php deleted file mode 100644 index 5945a535f..000000000 --- a/php/typecho09/admin/header.php +++ /dev/null @@ -1,31 +0,0 @@ -adminUrl) . '"> - - -'; - -/** 注册一个初始化插件 */ -$header = Typecho_Plugin::factory('admin/header.php')->header($header); - -?> - - - - - - - <?php _e('%s - %s - Powered by Typecho', $menu->title, $options->title); ?> - - - - > - diff --git a/php/typecho09/admin/img/ajax-loader.gif b/php/typecho09/admin/img/ajax-loader.gif deleted file mode 100644 index 32666dadf..000000000 Binary files a/php/typecho09/admin/img/ajax-loader.gif and /dev/null differ diff --git a/php/typecho09/admin/img/editor.png b/php/typecho09/admin/img/editor.png deleted file mode 100644 index d905db6d0..000000000 Binary files a/php/typecho09/admin/img/editor.png and /dev/null differ diff --git a/php/typecho09/admin/img/icons-s2ebed63329.png b/php/typecho09/admin/img/icons-s2ebed63329.png deleted file mode 100644 index 1a21b00db..000000000 Binary files a/php/typecho09/admin/img/icons-s2ebed63329.png and /dev/null differ diff --git a/php/typecho09/admin/img/icons.png b/php/typecho09/admin/img/icons.png deleted file mode 100644 index 1a21b00db..000000000 Binary files a/php/typecho09/admin/img/icons.png and /dev/null differ diff --git a/php/typecho09/admin/img/noscreen.png b/php/typecho09/admin/img/noscreen.png deleted file mode 100644 index afaaa0349..000000000 Binary files a/php/typecho09/admin/img/noscreen.png and /dev/null differ diff --git a/php/typecho09/admin/img/typecho-logo.svg b/php/typecho09/admin/img/typecho-logo.svg deleted file mode 100644 index b447bb51b..000000000 --- a/php/typecho09/admin/img/typecho-logo.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - typecho-logo - Created with Sketch (http://www.bohemiancoding.com/sketch) - - - - - - \ No newline at end of file diff --git a/php/typecho09/admin/index.php b/php/typecho09/admin/index.php deleted file mode 100644 index 268fab1b6..000000000 --- a/php/typecho09/admin/index.php +++ /dev/null @@ -1,158 +0,0 @@ - -
-
- -
-
-

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

- - - - -
-

- → - -

-
- -
- - - - - - -
-
-
- - - - - diff --git a/php/typecho09/admin/js/diff.js b/php/typecho09/admin/js/diff.js deleted file mode 100644 index e028122d6..000000000 --- a/php/typecho09/admin/js/diff.js +++ /dev/null @@ -1 +0,0 @@ -function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1000;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}var DIFF_DELETE=-1;var DIFF_INSERT=1;var DIFF_EQUAL=0;diff_match_patch.Diff;diff_match_patch.prototype.diff_main=function(b,a,d,f){if(typeof f=="undefined"){if(this.Diff_Timeout<=0){f=Number.MAX_VALUE}else{f=(new Date).getTime()+this.Diff_Timeout*1000}}var i=f;if(b==null||a==null){throw new Error("Null input. (diff_main)")}if(b==a){if(b){return[[DIFF_EQUAL,b]]}return[]}if(typeof d=="undefined"){d=true}var j=d;var e=this.diff_commonPrefix(b,a);var h=b.substring(0,e);b=b.substring(e);a=a.substring(e);e=this.diff_commonSuffix(b,a);var c=b.substring(b.length-e);b=b.substring(0,b.length-e);a=a.substring(0,a.length-e);var g=this.diff_compute_(b,a,j,i);if(h){g.unshift([DIFF_EQUAL,h])}if(c){g.push([DIFF_EQUAL,c])}this.diff_cleanupMerge(g);return g};diff_match_patch.prototype.diff_compute_=function(c,b,q,p){var j;if(!c){return[[DIFF_INSERT,b]]}if(!b){return[[DIFF_DELETE,c]]}var m=c.length>b.length?c:b;var d=c.length>b.length?b:c;var f=m.indexOf(d);if(f!=-1){j=[[DIFF_INSERT,m.substring(0,f)],[DIFF_EQUAL,d],[DIFF_INSERT,m.substring(f+d.length)]];if(c.length>b.length){j[0][0]=j[2][0]=DIFF_DELETE}return j}if(d.length==1){return[[DIFF_DELETE,c],[DIFF_INSERT,b]]}var a=this.diff_halfMatch_(c,b);if(a){var l=a[0];var h=a[1];var o=a[2];var n=a[3];var e=a[4];var k=this.diff_main(l,o,q,p);var g=this.diff_main(h,n,q,p);return k.concat([[DIFF_EQUAL,e]],g)}if(q&&c.length>100&&b.length>100){return this.diff_lineMode_(c,b,p)}return this.diff_bisect_(c,b,p)};diff_match_patch.prototype.diff_lineMode_=function(d,c,n){var k=this.diff_linesToChars_(d,c);d=k.chars1;c=k.chars2;var e=k.lineArray;var g=this.diff_main(d,c,false,n);this.diff_charsToLines_(g,e);this.diff_cleanupSemantic(g);g.push([DIFF_EQUAL,""]);var b=0;var m=0;var l=0;var i="";var h="";while(b=1&&l>=1){g.splice(b-m-l,m+l);b=b-m-l;var k=this.diff_main(i,h,false,n);for(var f=k.length-1;f>=0;f--){g.splice(b,0,k[f])}b=b+k.length}l=0;m=0;i="";h="";break}b++}g.pop();return g};diff_match_patch.prototype.diff_bisect_=function(n,l,A){var v=n.length;var g=l.length;var h=Math.ceil((v+g)/2);var r=h;var o=2*h;var e=new Array(o);var b=new Array(o);for(var m=0;mA){break}for(var k=-z+s;k<=z-p;k+=2){var q=r+k;var y;if(k==-z||(k!=z&&e[q-1]v){p+=2}else{if(f>g){s+=2}else{if(i){var a=r+B-k;if(a>=0&&a=w){return this.diff_bisectSplit_(n,l,y,f,A)}}}}}}for(var j=-z+u;j<=z-t;j+=2){var a=r+j;var w;if(j==-z||(j!=z&&b[a-1]v){t+=2}else{if(c>g){u+=2}else{if(!i){var q=r+B-j;if(q>=0&&q=w){return this.diff_bisectSplit_(n,l,y,f,A)}}}}}}}return[[DIFF_DELETE,n],[DIFF_INSERT,l]]};diff_match_patch.prototype.diff_bisectSplit_=function(d,c,i,h,k){var f=d.substring(0,i);var b=c.substring(0,h);var e=d.substring(i);var a=c.substring(h);var g=this.diff_main(f,b,false,k);var j=this.diff_main(e,a,false,k);return g.concat(j)};diff_match_patch.prototype.diff_linesToChars_=function(g,e){var d=[];var a={};d[0]="";function f(m){var k="";var i=0;var l=-1;var j=d.length;while(le){b=b.substring(g-e)}else{if(gb.length?c:b;var d=c.length>b.length?b:c;if(j.length<4||d.length*2=v.length){return[s,q,y,x,z]}else{return null}}var g=k(j,d,Math.ceil(j.length/4));var f=k(j,d,Math.ceil(j.length/2));var a;if(!g&&!f){return null}else{if(!f){a=g}else{if(!g){a=f}else{a=g[4].length>f[4].length?g:f}}}var i,h,m,l;if(c.length>b.length){i=a[0];h=a[1];m=a[2];l=a[3]}else{m=a[0];l=a[1];i=a[2];h=a[3]}var e=a[4];return[i,h,m,l,e]};diff_match_patch.prototype.diff_cleanupSemantic=function(m){var n=false;var l=[];var e=0;var f=null;var a=0;var k=0;var j=0;var i=0;var h=0;while(a0?l[e-1]:-1;k=0;j=0;i=0;h=0;f=null;n=true}}a++}if(n){this.diff_cleanupMerge(m)}this.diff_cleanupSemanticLossless(m);a=1;while(a=c){if(d>=g.length/2||d>=b.length/2){m.splice(a,0,[DIFF_EQUAL,b.substring(0,d)]);m[a-1][1]=g.substring(0,g.length-d);m[a+1][1]=b.substring(d);a++}}else{if(c>=g.length/2||c>=b.length/2){m.splice(a,0,[DIFF_EQUAL,g.substring(0,c)]);m[a-1][0]=DIFF_INSERT;m[a-1][1]=b.substring(0,b.length-c);m[a+1][0]=DIFF_DELETE;m[a+1][1]=g.substring(c);a++}}a++}a++}};diff_match_patch.prototype.diff_cleanupSemanticLossless=function(i){function c(r,y){if(!r||!y){return 6}var t=r.charAt(r.length-1);var s=y.charAt(0);var x=t.match(diff_match_patch.nonAlphaNumericRegex_);var w=s.match(diff_match_patch.nonAlphaNumericRegex_);var o=x&&t.match(diff_match_patch.whitespaceRegex_);var n=w&&s.match(diff_match_patch.whitespaceRegex_);var q=o&&t.match(diff_match_patch.linebreakRegex_);var p=n&&s.match(diff_match_patch.linebreakRegex_);var v=q&&r.match(diff_match_patch.blanklineEndRegex_);var u=p&&y.match(diff_match_patch.blanklineStartRegex_);if(v||u){return 5}else{if(q||p){return 4}else{if(x&&!o&&n){return 3}else{if(o||n){return 2}else{if(x||w){return 1}}}}}return 0}var a=1;while(a=e){e=d;g=m;h=l;f=k}}if(i[a-1][1]!=g){if(g){i[a-1][1]=g}else{i.splice(a-1,1);a--}i[a][1]=h;if(f){i[a+1][1]=f}else{i.splice(a+1,1);a--}}}a++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;diff_match_patch.prototype.diff_cleanupEfficiency=function(g){var i=false;var f=[];var c=0;var d=null;var a=0;var h=false;var j=false;var b=false;var e=false;while(a0?f[c-1]:-1;b=e=false}i=true}}a++}if(i){this.diff_cleanupMerge(g)}};diff_match_patch.prototype.diff_cleanupMerge=function(h){h.push([DIFF_EQUAL,""]);var g=0;var f=0;var e=0;var c="";var b="";var a;while(g1){if(f!==0&&e!==0){a=this.diff_commonPrefix(b,c);if(a!==0){if((g-f-e)>0&&h[g-f-e-1][0]==DIFF_EQUAL){h[g-f-e-1][1]+=b.substring(0,a)}else{h.splice(0,0,[DIFF_EQUAL,b.substring(0,a)]);g++}b=b.substring(a);c=c.substring(a)}a=this.diff_commonSuffix(b,c);if(a!==0){h[g][1]=b.substring(b.length-a)+h[g][1];b=b.substring(0,b.length-a);c=c.substring(0,c.length-a)}}if(f===0){h.splice(g-e,f+e,[DIFF_INSERT,b])}else{if(e===0){h.splice(g-f,f+e,[DIFF_DELETE,c])}else{h.splice(g-f-e,f+e,[DIFF_DELETE,c],[DIFF_INSERT,b])}}g=g-f-e+(f?1:0)+(e?1:0)+1}else{if(g!==0&&h[g-1][0]==DIFF_EQUAL){h[g-1][1]+=h[g][1];h.splice(g,1)}else{g++}}e=0;f=0;c="";b="";break}}if(h[h.length-1][1]===""){h.pop()}var d=false;g=1;while(gf){break}e=d;c=b}if(g.length!=a&&g[a][0]===DIFF_DELETE){return c}return c+(f-e)};diff_match_patch.prototype.diff_prettyHtml=function(f){var d=[];var h=/&/g;var c=//g;var g=/\n/g;for(var i=0;i");switch(e){case DIFF_INSERT:d[i]=''+j+"";break;case DIFF_DELETE:d[i]=''+j+"";break;case DIFF_EQUAL:d[i]=""+j+"";break}}return d.join("")};diff_match_patch.prototype.diff_text1=function(c){var b=[];for(var a=0;athis.Match_MaxBits){throw new Error("Pattern too long for this browser.")}var m=this.match_alphabet_(t);var a=this;function b(y,d){var s=y/t.length;var j=Math.abs(i-d);if(!a.Match_Distance){return j?1:s}return s+(j/a.Match_Distance)}var o=this.Match_Threshold;var c=l.indexOf(t,i);if(c!=-1){o=Math.min(b(0,c),o);c=l.lastIndexOf(t,i+t.length);if(c!=-1){o=Math.min(b(0,c),o)}}var v=1<<(t.length-1);c=-1;var f,k;var g=t.length+l.length;var h;for(var u=0;u=e;q--){var w=m[l.charAt(q-1)];if(u===0){p[q]=((p[q+1]<<1)|1)&w}else{p[q]=(((p[q+1]<<1)|1)&w)|(((h[q+1]|h[q])<<1)|1)|h[q+1]}if(p[q]&v){var r=b(u,q-1);if(r<=o){o=r;c=q-1;if(c>i){e=Math.max(1,2*i-c)}else{break}}}}if(b(u+1,i)>o){break}h=p}return c};diff_match_patch.prototype.match_alphabet_=function(c){var b={};for(var a=0;a2){this.diff_cleanupSemantic(k);this.diff_cleanupEfficiency(k)}}else{if(o&&typeof o=="object"&&typeof c=="undefined"&&typeof p=="undefined"){k=(o);d=this.diff_text1(k)}else{if(typeof o=="string"&&c&&typeof c=="object"&&typeof p=="undefined"){d=(o);k=(c)}else{if(typeof o=="string"&&typeof c=="string"&&p&&typeof p=="object"){d=(o);k=(p)}else{throw new Error("Unknown call format to patch_make.")}}}}if(k.length===0){return[]}var b=[];var e=new diff_match_patch.patch_obj();var h=0;var j=0;var i=0;var g=d;var m=d;for(var n=0;n=2*this.Patch_Margin){if(h){this.patch_addContext_(e,g);b.push(e);e=new diff_match_patch.patch_obj();h=0;g=m;j=i}}}break}if(f!==DIFF_INSERT){j+=l.length}if(f!==DIFF_DELETE){i+=l.length}}if(h){this.patch_addContext_(e,g);b.push(e)}return b};diff_match_patch.prototype.patch_deepCopy=function(c){var d=[];for(var b=0;bthis.Match_MaxBits){f=this.match_main(p,e.substring(0,this.Match_MaxBits),b);if(f!=-1){k=this.match_main(p,e.substring(e.length-this.Match_MaxBits),b+e.length-this.Match_MaxBits);if(k==-1||f>=k){f=-1}}}else{f=this.match_main(p,e,b)}if(f==-1){g[n]=false;o-=a[n].length2-a[n].length1}else{g[n]=true;o=f-b;var d;if(k==-1){d=p.substring(f,f+e.length)}else{d=p.substring(f,k+this.Match_MaxBits)}if(e==d){p=p.substring(0,f)+this.diff_text2(a[n].diffs)+p.substring(f+e.length)}else{var i=this.diff_main(e,d,false);if(e.length>this.Match_MaxBits&&this.diff_levenshtein(i)/e.length>this.Patch_DeleteThreshold){g[n]=false}else{this.diff_cleanupSemanticLossless(i);var j=0;var h;for(var m=0;mf[0][1].length){var e=c-f[0][1].length;f[0][1]=b.substring(f[0][1].length)+f[0][1];g.start1-=e;g.start2-=e;g.length1+=e;g.length2+=e}}g=d[d.length-1];f=g.diffs;if(f.length==0||f[f.length-1][0]!=DIFF_EQUAL){f.push([DIFF_EQUAL,b]);g.length1+=c;g.length2+=c}else{if(c>f[f.length-1][1].length){var e=c-f[f.length-1][1].length;f[f.length-1][1]+=b.substring(0,e);g.length1+=e;g.length2+=e}}return b};diff_match_patch.prototype.patch_splitMax=function(a){var i=this.Match_MaxBits;for(var l=0;l2*i){e.length1+=k.length;c+=k.length;j=false;e.diffs.push([h,k]);f.diffs.shift()}else{k=k.substring(0,i-e.length1-this.Patch_Margin);e.length1+=k.length;c+=k.length;if(h===DIFF_EQUAL){e.length2+=k.length;b+=k.length}else{j=false}e.diffs.push([h,k]);if(k==f.diffs[0][1]){f.diffs.shift()}else{f.diffs[0][1]=f.diffs[0][1].substring(k.length)}}}}g=this.diff_text2(e.diffs);g=g.substring(g.length-this.Patch_Margin);var d=this.diff_text1(f.diffs).substring(0,this.Patch_Margin);if(d!==""){e.length1+=d.length;e.length2+=d.length;if(e.diffs.length!==0&&e.diffs[e.diffs.length-1][0]===DIFF_EQUAL){e.diffs[e.diffs.length-1][1]+=d}else{e.diffs.push([DIFF_EQUAL,d])}}if(!j){a.splice(++l,0,e)}}}};diff_match_patch.prototype.patch_toText=function(b){var c=[];for(var a=0;a=s.refresh){var E=H.loaded-this.startData;var G=E/F;s.speedUpdated(this.index,this.file,G);this.startData=H.loaded;this.currentStart=C}}}}function j(){if(e.length===0){return}var D=0,C;for(C in e){if(e.hasOwnProperty(C)){D=D+e[C]}}s.globalProgressUpdated(Math.round(D/e.length))}function w(){m=false;if(!i){s.error(f[0]);return false}if(s.allowedfiletypes.push&&s.allowedfiletypes.length){for(var G=i.length;G--;){if(!i[G].type||c.inArray(i[G].type,s.allowedfiletypes)<0){s.error(f[3],i[G]);return false}}}if(s.allowedfileextensions.push&&s.allowedfileextensions.length){for(var G=i.length;G--;){var D=false;for(I=0;Is.maxfiles&&s.queuefiles===0){s.error(f[1]);return false}var J=[];var E=[];var F=[];for(var I=0;I0&&E.length>=s.queuefiles){return M(s.queuewait)}else{Q=J[0];J.splice(0,1);E.push(Q)}try{if(g(i[Q])!==false){if(Q===r){return}var N=new FileReader(),O=1048576*s.maxfilesize;N.index=Q;if(i[Q].size>O){s.error(f[2],i[Q],Q);E.forEach(function(S,R){if(S===Q){E.splice(R,1)}});L++;return true}N.onerror=function(R){switch(R.target.error.code){case R.target.error.NOT_FOUND_ERR:s.error(f[4]);return false;case R.target.error.NOT_READABLE_ERR:s.error(f[5]);return false;case R.target.error.ABORT_ERR:s.error(f[6]);return false;default:s.error(f[7]);return false}};N.onloadend=!s.beforeSend?H:function(R){s.beforeSend(i[Q],Q,function(){H(R)})};N.readAsDataURL(i[Q])}else{L++}}catch(P){E.forEach(function(S,R){if(S===Q){E.splice(R,1)}});s.error(f[0]);return false}if(J.length>0){C()}};var H=function(V){var P=(V.srcElement||V.target).index;if(V.target.index===undefined){V.target.index=B(V.total)}var Y=new XMLHttpRequest(),Z=Y.upload,Q=i[V.target.index],U=V.target.index,T=new Date().getTime(),O="------multipartformboundary"+(new Date()).getTime(),X=e.length,S,W=l(Q.name),N=Q.type;if(s.withCredentials){Y.withCredentials=s.withCredentials}var R=atob(V.target.result.split(",")[1]);if(typeof W==="string"){S=x(W,R,N,O)}else{S=x(Q.name,R,N,O)}Z.index=U;Z.file=Q;Z.downloadStartTime=T;Z.currentStart=T;Z.currentProgress=0;Z.global_progress_index=X;Z.startData=0;Z.addEventListener("progress",k,false);if(jQuery.isFunction(s.url)){Y.open(s.requestType,s.url(),true)}else{Y.open(s.requestType,s.url,true)}Y.setRequestHeader("content-type","multipart/form-data; boundary="+O);Y.setRequestHeader("X-Requested-With","XMLHttpRequest");c.each(s.headers,function(ab,aa){Y.setRequestHeader(ab,aa)});Y.sendAsBinary(S);e[X]=0;j();s.uploadStarted(U,Q,r);Y.onload=function(){var ae=null;if(Y.responseText){try{ae=jQuery.parseJSON(Y.responseText)}catch(ac){ae=Y.responseText}}var ab=new Date().getTime(),ad=ab-T,aa=s.uploadFinished(U,Q,ae,ad,Y);K++;E.forEach(function(ag,af){if(ag===P){E.splice(af,1)}});F.push(P);e[X]=100;j();if(K===(r-L)){v()}if(aa===false){m=true}if(Y.status<200||Y.status>299){s.error(Y.statusText,Q,P,Y.status)}}};C()}function B(D){for(var C=0;C";q=("hidden" in t);e=t.childNodes.length==1||(function(){(m.createElement)("a");var v=m.createDocumentFragment();return(typeof v.cloneNode=="undefined"||typeof v.createDocumentFragment=="undefined"||typeof v.createElement=="undefined")}())}catch(u){q=true;e=true}}());function f(t,v){var w=t.createElement("p"),u=t.getElementsByTagName("head")[0]||t.documentElement;w.innerHTML="x";return u.insertBefore(w.lastChild,u.firstChild)}function l(){var t=j.elements;return typeof t=="string"?t.split(" "):t}function p(t){var u=o[t[i]];if(!u){u={};a++;t[i]=a;o[a]=u}return u}function n(w,t,v){if(!t){t=m}if(e){return t.createElement(w)}if(!v){v=p(t)}var u;if(v.cache[w]){u=v.cache[w].cloneNode()}else{if(c.test(w)){u=(v.cache[w]=v.createElem(w)).cloneNode()}else{u=v.createElem(w)}}return u.canHaveChildren&&!h.test(w)?v.frag.appendChild(u):u}function r(v,x){if(!v){v=m}if(e){return v.createDocumentFragment()}x=x||p(v);var y=x.frag.cloneNode(),w=0,u=l(),t=u.length;for(;w=0)&&d(i,!h)}});if(!b("").outerWidth(1).jquery){b.each(["Width","Height"],function(j,g){var h=g==="Width"?["Left","Right"]:["Top","Bottom"],k=g.toLowerCase(),m={innerWidth:b.fn.innerWidth,innerHeight:b.fn.innerHeight,outerWidth:b.fn.outerWidth,outerHeight:b.fn.outerHeight};function l(o,n,i,p){b.each(h,function(){n-=parseFloat(b.css(o,"padding"+this))||0;if(i){n-=parseFloat(b.css(o,"border"+this+"Width"))||0}if(p){n-=parseFloat(b.css(o,"margin"+this))||0}});return n}b.fn["inner"+g]=function(i){if(i===f){return m["inner"+g].call(this)}return this.each(function(){b(this).css(k,l(this,i)+"px")})};b.fn["outer"+g]=function(i,n){if(typeof i!=="number"){return m["outer"+g].call(this,i)}return this.each(function(){b(this).css(k,l(this,i,true,n)+"px")})}})}if(!b.fn.addBack){b.fn.addBack=function(g){return this.add(g==null?this.prevObject:this.prevObject.filter(g))}}if(b("").data("a-b","a").removeData("a-b").data("a-b")){b.fn.removeData=(function(g){return function(h){if(arguments.length){return g.call(this,b.camelCase(h))}else{return g.call(this)}}})(b.fn.removeData)}b.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());b.support.selectstart="onselectstart" in document.createElement("div");b.fn.extend({disableSelection:function(){return this.bind((b.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(g){g.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});b.extend(b.ui,{plugin:{add:function(h,j,l){var g,k=b.ui[h].prototype;for(g in l){k.plugins[g]=k.plugins[g]||[];k.plugins[g].push([j,l[g]])}},call:function(g,j,h){var k,l=g.plugins[j];if(!l||!g.element[0].parentNode||g.element[0].parentNode.nodeType===11){return}for(k=0;k0){return true}j[g]=1;i=(j[g]>0);j[g]=0;return i}})})(jQuery);(function(b,e){var a=0,d=Array.prototype.slice,c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)};b.widget=function(f,g,n){var k,l,i,m,h={},j=f.split(".")[0];f=f.split(".")[1];k=j+"-"+f;if(!n){n=g;g=b.Widget}b.expr[":"][k.toLowerCase()]=function(o){return !!b.data(o,k)};b[j]=b[j]||{};l=b[j][f];i=b[j][f]=function(o,p){if(!this._createWidget){return new i(o,p)}if(arguments.length){this._createWidget(o,p)}};b.extend(i,l,{version:n.version,_proto:b.extend({},n),_childConstructors:[]});m=new g();m.options=b.widget.extend({},m.options);b.each(n,function(p,o){if(!b.isFunction(o)){h[p]=o;return}h[p]=(function(){var q=function(){return g.prototype[p].apply(this,arguments)},r=function(s){return g.prototype[p].apply(this,s)};return function(){var u=this._super,s=this._superApply,t;this._super=q;this._superApply=r;t=o.apply(this,arguments);this._super=u;this._superApply=s;return t}})()});i.prototype=b.widget.extend(m,{widgetEventPrefix:l?m.widgetEventPrefix:f},h,{constructor:i,namespace:j,widgetName:f,widgetFullName:k});if(l){b.each(l._childConstructors,function(p,q){var o=q.prototype;b.widget(o.namespace+"."+o.widgetName,i,q._proto)});delete l._childConstructors}else{g._childConstructors.push(i)}b.widget.bridge(f,i)};b.widget.extend=function(k){var g=d.call(arguments,1),j=0,f=g.length,h,i;for(;j",options:{disabled:false,create:null},_createWidget:function(f,g){g=b(g||this.defaultElement||this)[0];this.element=b(g);this.uuid=a++;this.eventNamespace="."+this.widgetName+this.uuid;this.options=b.widget.extend({},this.options,this._getCreateOptions(),f);this.bindings=b();this.hoverable=b();this.focusable=b();if(g!==this){b.data(g,this.widgetFullName,this);this._on(true,this.element,{remove:function(h){if(h.target===g){this.destroy()}}});this.document=b(g.style?g.ownerDocument:g.document||g);this.window=b(this.document[0].defaultView||this.document[0].parentWindow)}this._create();this._trigger("create",null,this._getCreateEventData());this._init()},_getCreateOptions:b.noop,_getCreateEventData:b.noop,_create:b.noop,_init:b.noop,destroy:function(){this._destroy();this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(b.camelCase(this.widgetFullName));this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled");this.bindings.unbind(this.eventNamespace);this.hoverable.removeClass("ui-state-hover");this.focusable.removeClass("ui-state-focus")},_destroy:b.noop,widget:function(){return this.element},option:function(j,k){var f=j,l,h,g;if(arguments.length===0){return b.widget.extend({},this.options)}if(typeof j==="string"){f={};l=j.split(".");j=l.shift();if(l.length){h=f[j]=b.widget.extend({},this.options[j]);for(g=0;g=this.options.distance)},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);(function(e,g){e.extend(e.ui,{datepicker:{version:"1.10.3"}});var f="datepicker",c;function b(){this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass="ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false,disabled:false};e.extend(this._defaults,this.regional[""]);this.dpDiv=d(e("
"))}e.extend(b.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(h){a(this._defaults,h||{});return this},_attachDatepicker:function(k,h){var l,j,i;l=k.nodeName.toLowerCase();j=(l==="div"||l==="span");if(!k.id){this.uuid+=1;k.id="dp"+this.uuid}i=this._newInst(e(k),j);i.settings=e.extend({},h||{});if(l==="input"){this._connectDatepicker(k,i)}else{if(j){this._inlineDatepicker(k,i)}}},_newInst:function(i,h){var j=i[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:j,input:i,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:h,dpDiv:(!h?this.dpDiv:d(e("
")))}},_connectDatepicker:function(j,i){var h=e(j);i.append=e([]);i.trigger=e([]);if(h.hasClass(this.markerClassName)){return}this._attachments(h,i);h.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp);this._autoSize(i);e.data(j,f,i);if(i.settings.disabled){this._disableDatepicker(j)}},_attachments:function(j,m){var i,l,h,n=this._get(m,"appendText"),k=this._get(m,"isRTL");if(m.append){m.append.remove()}if(n){m.append=e(""+n+"");j[k?"before":"after"](m.append)}j.unbind("focus",this._showDatepicker);if(m.trigger){m.trigger.remove()}i=this._get(m,"showOn");if(i==="focus"||i==="both"){j.focus(this._showDatepicker)}if(i==="button"||i==="both"){l=this._get(m,"buttonText");h=this._get(m,"buttonImage");m.trigger=e(this._get(m,"buttonImageOnly")?e("").addClass(this._triggerClass).attr({src:h,alt:l,title:l}):e("").addClass(this._triggerClass).html(!h?l:e("").attr({src:h,alt:l,title:l})));j[k?"before":"after"](m.trigger);m.trigger.click(function(){if(e.datepicker._datepickerShowing&&e.datepicker._lastInput===j[0]){e.datepicker._hideDatepicker()}else{if(e.datepicker._datepickerShowing&&e.datepicker._lastInput!==j[0]){e.datepicker._hideDatepicker();e.datepicker._showDatepicker(j[0])}else{e.datepicker._showDatepicker(j[0])}}return false})}},_autoSize:function(o){if(this._get(o,"autoSize")&&!o.inline){var l,j,k,n,m=new Date(2009,12-1,20),h=this._get(o,"dateFormat");if(h.match(/[DM]/)){l=function(i){j=0;k=0;for(n=0;nj){j=i[n].length;k=n}}return k};m.setMonth(l(this._get(o,(h.match(/MM/)?"monthNames":"monthNamesShort"))));m.setDate(l(this._get(o,(h.match(/DD/)?"dayNames":"dayNamesShort")))+20-m.getDay())}o.input.attr("size",this._formatDate(o,m).length)}},_inlineDatepicker:function(i,h){var j=e(i);if(j.hasClass(this.markerClassName)){return}j.addClass(this.markerClassName).append(h.dpDiv);e.data(i,f,h);this._setDate(h,this._getDefaultDate(h),true);this._updateDatepicker(h);this._updateAlternate(h);if(h.settings.disabled){this._disableDatepicker(i)}h.dpDiv.css("display","block")},_dialogDatepicker:function(o,i,m,j,n){var h,r,l,q,p,k=this._dialogInst;if(!k){this.uuid+=1;h="dp"+this.uuid;this._dialogInput=e("");this._dialogInput.keydown(this._doKeyDown);e("body").append(this._dialogInput);k=this._dialogInst=this._newInst(this._dialogInput,false);k.settings={};e.data(this._dialogInput[0],f,k)}a(k.settings,j||{});i=(i&&i.constructor===Date?this._formatDate(k,i):i);this._dialogInput.val(i);this._pos=(n?(n.length?n:[n.pageX,n.pageY]):null);if(!this._pos){r=document.documentElement.clientWidth;l=document.documentElement.clientHeight;q=document.documentElement.scrollLeft||document.body.scrollLeft;p=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(r/2)-100+q,(l/2)-150+p]}this._dialogInput.css("left",(this._pos[0]+20)+"px").css("top",this._pos[1]+"px");k.settings.onSelect=m;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if(e.blockUI){e.blockUI(this.dpDiv)}e.data(this._dialogInput[0],f,k);return this},_destroyDatepicker:function(j){var k,h=e(j),i=e.data(j,f);if(!h.hasClass(this.markerClassName)){return}k=j.nodeName.toLowerCase();e.removeData(j,f);if(k==="input"){i.append.remove();i.trigger.remove();h.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else{if(k==="div"||k==="span"){h.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(k){var l,j,h=e(k),i=e.data(k,f);if(!h.hasClass(this.markerClassName)){return}l=k.nodeName.toLowerCase();if(l==="input"){k.disabled=false;i.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else{if(l==="div"||l==="span"){j=h.children("."+this._inlineClass);j.children().removeClass("ui-state-disabled");j.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",false)}}this._disabledInputs=e.map(this._disabledInputs,function(m){return(m===k?null:m)})},_disableDatepicker:function(k){var l,j,h=e(k),i=e.data(k,f);if(!h.hasClass(this.markerClassName)){return}l=k.nodeName.toLowerCase();if(l==="input"){k.disabled=true;i.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else{if(l==="div"||l==="span"){j=h.children("."+this._inlineClass);j.children().addClass("ui-state-disabled");j.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",true)}}this._disabledInputs=e.map(this._disabledInputs,function(m){return(m===k?null:m)});this._disabledInputs[this._disabledInputs.length]=k},_isDisabledDatepicker:function(j){if(!j){return false}for(var h=0;h-1)}},_doKeyUp:function(j){var h,k=e.datepicker._getInst(j.target);if(k.input.val()!==k.lastVal){try{h=e.datepicker.parseDate(e.datepicker._get(k,"dateFormat"),(k.input?k.input.val():null),e.datepicker._getFormatConfig(k));if(h){e.datepicker._setDateFromField(k);e.datepicker._updateAlternate(k);e.datepicker._updateDatepicker(k)}}catch(i){}}return true},_showDatepicker:function(i){i=i.target||i;if(i.nodeName.toLowerCase()!=="input"){i=e("input",i.parentNode)[0]}if(e.datepicker._isDisabledDatepicker(i)||e.datepicker._lastInput===i){return}var k,o,j,m,n,h,l;k=e.datepicker._getInst(i);if(e.datepicker._curInst&&e.datepicker._curInst!==k){e.datepicker._curInst.dpDiv.stop(true,true);if(k&&e.datepicker._datepickerShowing){e.datepicker._hideDatepicker(e.datepicker._curInst.input[0])}}o=e.datepicker._get(k,"beforeShow");j=o?o.apply(i,[i,k]):{};if(j===false){return}a(k.settings,j);k.lastVal=null;e.datepicker._lastInput=i;e.datepicker._setDateFromField(k);if(e.datepicker._inDialog){i.value=""}if(!e.datepicker._pos){e.datepicker._pos=e.datepicker._findPos(i);e.datepicker._pos[1]+=i.offsetHeight}m=false;e(i).parents().each(function(){m|=e(this).css("position")==="fixed";return !m});n={left:e.datepicker._pos[0],top:e.datepicker._pos[1]};e.datepicker._pos=null;k.dpDiv.empty();k.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});e.datepicker._updateDatepicker(k);n=e.datepicker._checkOffset(k,n,m);k.dpDiv.css({position:(e.datepicker._inDialog&&e.blockUI?"static":(m?"fixed":"absolute")),display:"none",left:n.left+"px",top:n.top+"px"});if(!k.inline){h=e.datepicker._get(k,"showAnim");l=e.datepicker._get(k,"duration");k.dpDiv.zIndex(e(i).zIndex()+1);e.datepicker._datepickerShowing=true;if(e.effects&&e.effects.effect[h]){k.dpDiv.show(h,e.datepicker._get(k,"showOptions"),l)}else{k.dpDiv[h||"show"](h?l:null)}if(e.datepicker._shouldFocusInput(k)){k.input.focus()}e.datepicker._curInst=k}},_updateDatepicker:function(j){this.maxRows=4;c=j;j.dpDiv.empty().append(this._generateHTML(j));this._attachHandlers(j);j.dpDiv.find("."+this._dayOverClass+" a").mouseover();var l,h=this._getNumberOfMonths(j),k=h[1],i=17;j.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");if(k>1){j.dpDiv.addClass("ui-datepicker-multi-"+k).css("width",(i*k)+"em")}j.dpDiv[(h[0]!==1||h[1]!==1?"add":"remove")+"Class"]("ui-datepicker-multi");j.dpDiv[(this._get(j,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(j===e.datepicker._curInst&&e.datepicker._datepickerShowing&&e.datepicker._shouldFocusInput(j)){j.input.focus()}if(j.yearshtml){l=j.yearshtml;setTimeout(function(){if(l===j.yearshtml&&j.yearshtml){j.dpDiv.find("select.ui-datepicker-year:first").replaceWith(j.yearshtml)}l=j.yearshtml=null},0)}},_shouldFocusInput:function(h){return h.input&&h.input.is(":visible")&&!h.input.is(":disabled")&&!h.input.is(":focus")},_checkOffset:function(m,k,j){var l=m.dpDiv.outerWidth(),p=m.dpDiv.outerHeight(),o=m.input?m.input.outerWidth():0,h=m.input?m.input.outerHeight():0,n=document.documentElement.clientWidth+(j?0:e(document).scrollLeft()),i=document.documentElement.clientHeight+(j?0:e(document).scrollTop());k.left-=(this._get(m,"isRTL")?(l-o):0);k.left-=(j&&k.left===m.input.offset().left)?e(document).scrollLeft():0;k.top-=(j&&k.top===(m.input.offset().top+h))?e(document).scrollTop():0;k.left-=Math.min(k.left,(k.left+l>n&&n>l)?Math.abs(k.left+l-n):0);k.top-=Math.min(k.top,(k.top+p>i&&i>p)?Math.abs(p+h):0);return k},_findPos:function(k){var h,j=this._getInst(k),i=this._get(j,"isRTL");while(k&&(k.type==="hidden"||k.nodeType!==1||e.expr.filters.hidden(k))){k=k[i?"previousSibling":"nextSibling"]}h=e(k).offset();return[h.left,h.top]},_hideDatepicker:function(j){var i,m,l,h,k=this._curInst;if(!k||(j&&k!==e.data(j,f))){return}if(this._datepickerShowing){i=this._get(k,"showAnim");m=this._get(k,"duration");l=function(){e.datepicker._tidyDialog(k)};if(e.effects&&(e.effects.effect[i]||e.effects[i])){k.dpDiv.hide(i,e.datepicker._get(k,"showOptions"),m,l)}else{k.dpDiv[(i==="slideDown"?"slideUp":(i==="fadeIn"?"fadeOut":"hide"))]((i?m:null),l)}if(!i){l()}this._datepickerShowing=false;h=this._get(k,"onClose");if(h){h.apply((k.input?k.input[0]:null),[(k.input?k.input.val():""),k])}this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(e.blockUI){e.unblockUI();e("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(h){h.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(i){if(!e.datepicker._curInst){return}var h=e(i.target),j=e.datepicker._getInst(h[0]);if(((h[0].id!==e.datepicker._mainDivId&&h.parents("#"+e.datepicker._mainDivId).length===0&&!h.hasClass(e.datepicker.markerClassName)&&!h.closest("."+e.datepicker._triggerClass).length&&e.datepicker._datepickerShowing&&!(e.datepicker._inDialog&&e.blockUI)))||(h.hasClass(e.datepicker.markerClassName)&&e.datepicker._curInst!==j)){e.datepicker._hideDatepicker()}},_adjustDate:function(l,k,j){var i=e(l),h=this._getInst(i[0]);if(this._isDisabledDatepicker(i[0])){return}this._adjustInstDate(h,k+(j==="M"?this._get(h,"showCurrentAtPos"):0),j);this._updateDatepicker(h)},_gotoToday:function(k){var h,j=e(k),i=this._getInst(j[0]);if(this._get(i,"gotoCurrent")&&i.currentDay){i.selectedDay=i.currentDay;i.drawMonth=i.selectedMonth=i.currentMonth;i.drawYear=i.selectedYear=i.currentYear}else{h=new Date();i.selectedDay=h.getDate();i.drawMonth=i.selectedMonth=h.getMonth();i.drawYear=i.selectedYear=h.getFullYear()}this._notifyChange(i);this._adjustDate(j)},_selectMonthYear:function(l,h,k){var j=e(l),i=this._getInst(j[0]);i["selected"+(k==="M"?"Month":"Year")]=i["draw"+(k==="M"?"Month":"Year")]=parseInt(h.options[h.selectedIndex].value,10);this._notifyChange(i);this._adjustDate(j)},_selectDay:function(m,k,h,l){var i,j=e(m);if(e(l).hasClass(this._unselectableClass)||this._isDisabledDatepicker(j[0])){return}i=this._getInst(j[0]);i.selectedDay=i.currentDay=e("a",l).html();i.selectedMonth=i.currentMonth=k;i.selectedYear=i.currentYear=h;this._selectDate(m,this._formatDate(i,i.currentDay,i.currentMonth,i.currentYear))},_clearDate:function(i){var h=e(i);this._selectDate(h,"")},_selectDate:function(l,h){var i,k=e(l),j=this._getInst(k[0]);h=(h!=null?h:this._formatDate(j));if(j.input){j.input.val(h)}this._updateAlternate(j);i=this._get(j,"onSelect");if(i){i.apply((j.input?j.input[0]:null),[h,j])}else{if(j.input){j.input.trigger("change")}}if(j.inline){this._updateDatepicker(j)}else{this._hideDatepicker();this._lastInput=j.input[0];if(typeof(j.input[0])!=="object"){j.input.focus()}this._lastInput=null}},_updateAlternate:function(l){var k,j,h,i=this._get(l,"altField");if(i){k=this._get(l,"altFormat")||this._get(l,"dateFormat");j=this._getDate(l);h=this.formatDate(k,j,this._getFormatConfig(l));e(i).each(function(){e(this).val(h)})}},noWeekends:function(i){var h=i.getDay();return[(h>0&&h<6),""]},iso8601Week:function(h){var i,j=new Date(h.getTime());j.setDate(j.getDate()+4-(j.getDay()||7));i=j.getTime();j.setMonth(0);j.setDate(1);return Math.floor(Math.round((i-j)/86400000)/7)+1},parseDate:function(x,s,z){if(x==null||s==null){throw"Invalid arguments"}s=(typeof s==="object"?s.toString():s+"");if(s===""){return null}var k,u,i,y=0,n=(z?z.shortYearCutoff:null)||this._defaults.shortYearCutoff,j=(typeof n!=="string"?n:new Date().getFullYear()%100+parseInt(n,10)),q=(z?z.dayNamesShort:null)||this._defaults.dayNamesShort,B=(z?z.dayNames:null)||this._defaults.dayNames,h=(z?z.monthNamesShort:null)||this._defaults.monthNamesShort,l=(z?z.monthNames:null)||this._defaults.monthNames,m=-1,C=-1,w=-1,p=-1,v=false,A,r=function(E){var F=(k+1-1){C=1;w=p;do{u=this._getDaysInMonth(m,C-1);if(w<=u){break}C++;w-=u}while(true)}A=this._daylightSavingAdjust(new Date(m,C-1,w));if(A.getFullYear()!==m||A.getMonth()+1!==C||A.getDate()!==w){throw"Invalid date"}return A},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(((1970-1)*365+Math.floor(1970/4)-Math.floor(1970/100)+Math.floor(1970/400))*24*60*60*10000000),formatDate:function(q,k,l){if(!k){return""}var s,t=(l?l.dayNamesShort:null)||this._defaults.dayNamesShort,i=(l?l.dayNames:null)||this._defaults.dayNames,o=(l?l.monthNamesShort:null)||this._defaults.monthNamesShort,m=(l?l.monthNames:null)||this._defaults.monthNames,r=function(u){var v=(s+112?h.getHours()+2:0);return h},_setDate:function(n,k,m){var h=!k,j=n.selectedMonth,l=n.selectedYear,i=this._restrictMinMax(n,this._determineDate(n,k,new Date()));n.selectedDay=n.currentDay=i.getDate();n.drawMonth=n.selectedMonth=n.currentMonth=i.getMonth();n.drawYear=n.selectedYear=n.currentYear=i.getFullYear();if((j!==n.selectedMonth||l!==n.selectedYear)&&!m){this._notifyChange(n)}this._adjustInstDate(n);if(n.input){n.input.val(h?"":this._formatDate(n))}},_getDate:function(i){var h=(!i.currentYear||(i.input&&i.input.val()==="")?null:this._daylightSavingAdjust(new Date(i.currentYear,i.currentMonth,i.currentDay)));return h},_attachHandlers:function(i){var h=this._get(i,"stepMonths"),j="#"+i.id.replace(/\\\\/g,"\\");i.dpDiv.find("[data-handler]").map(function(){var k={prev:function(){e.datepicker._adjustDate(j,-h,"M")},next:function(){e.datepicker._adjustDate(j,+h,"M")},hide:function(){e.datepicker._hideDatepicker()},today:function(){e.datepicker._gotoToday(j)},selectDay:function(){e.datepicker._selectDay(j,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this);return false},selectMonth:function(){e.datepicker._selectMonthYear(j,this,"M");return false},selectYear:function(){e.datepicker._selectMonthYear(j,this,"Y");return false}};e(this).bind(this.getAttribute("data-event"),k[this.getAttribute("data-handler")])})},_generateHTML:function(X){var A,z,S,K,l,ab,V,O,ae,I,ai,s,u,t,i,aa,q,D,ad,Q,aj,C,H,r,m,T,M,P,N,p,F,v,W,Z,k,ac,ag,L,w,Y=new Date(),B=this._daylightSavingAdjust(new Date(Y.getFullYear(),Y.getMonth(),Y.getDate())),af=this._get(X,"isRTL"),ah=this._get(X,"showButtonPanel"),R=this._get(X,"hideIfNoPrevNext"),G=this._get(X,"navigationAsDateFormat"),x=this._getNumberOfMonths(X),o=this._get(X,"showCurrentAtPos"),J=this._get(X,"stepMonths"),E=(x[0]!==1||x[1]!==1),j=this._daylightSavingAdjust((!X.currentDay?new Date(9999,9,9):new Date(X.currentYear,X.currentMonth,X.currentDay))),n=this._getMinMaxDate(X,"min"),y=this._getMinMaxDate(X,"max"),h=X.drawMonth-o,U=X.drawYear;if(h<0){h+=12;U--}if(y){A=this._daylightSavingAdjust(new Date(y.getFullYear(),y.getMonth()-(x[0]*x[1])+1,y.getDate()));A=(n&&AA){h--;if(h<0){h=11;U--}}}X.drawMonth=h;X.drawYear=U;z=this._get(X,"prevText");z=(!G?z:this.formatDate(z,this._daylightSavingAdjust(new Date(U,h-J,1)),this._getFormatConfig(X)));S=(this._canAdjustMonth(X,-1,U,h)?"
"+z+"":(R?"":""+z+""));K=this._get(X,"nextText");K=(!G?K:this.formatDate(K,this._daylightSavingAdjust(new Date(U,h+J,1)),this._getFormatConfig(X)));l=(this._canAdjustMonth(X,+1,U,h)?""+K+"":(R?"":""+K+""));ab=this._get(X,"currentText");V=(this._get(X,"gotoCurrent")&&X.currentDay?j:B);ab=(!G?ab:this.formatDate(ab,V,this._getFormatConfig(X)));O=(!X.inline?"":"");ae=(ah)?"
"+(af?O:"")+(this._isInRange(X,V)?"":"")+(af?"":O)+"
":"";I=parseInt(this._get(X,"firstDay"),10);I=(isNaN(I)?0:I);ai=this._get(X,"showWeek");s=this._get(X,"dayNames");u=this._get(X,"dayNamesMin");t=this._get(X,"monthNames");i=this._get(X,"monthNamesShort");aa=this._get(X,"beforeShowDay");q=this._get(X,"showOtherMonths");D=this._get(X,"selectOtherMonths");ad=this._getDefaultDate(X);Q="";aj;for(C=0;C1){switch(r){case 0:M+=" ui-datepicker-group-first";T=" ui-corner-"+(af?"right":"left");break;case x[1]-1:M+=" ui-datepicker-group-last";T=" ui-corner-"+(af?"left":"right");break;default:M+=" ui-datepicker-group-middle";T="";break}}M+="'>"}M+="
"+(/all|left/.test(T)&&C===0?(af?l:S):"")+(/all|right/.test(T)&&C===0?(af?S:l):"")+this._generateMonthYearHeader(X,h,U,n,y,C>0||r>0,t,i)+"
";P=(ai?"":"");for(aj=0;aj<7;aj++){N=(aj+I)%7;P+="=5?" class='ui-datepicker-week-end'":"")+">"+u[N]+""}M+=P+"";p=this._getDaysInMonth(U,h);if(U===X.selectedYear&&h===X.selectedMonth){X.selectedDay=Math.min(X.selectedDay,p)}F=(this._getFirstDayOfMonth(U,h)-I+7)%7;v=Math.ceil((F+p)/7);W=(E?this.maxRows>v?this.maxRows:v:v);this.maxRows=W;Z=this._daylightSavingAdjust(new Date(U,h,1-F));for(k=0;k";ac=(!ai?"":"");for(aj=0;aj<7;aj++){ag=(aa?aa.apply((X.input?X.input[0]:null),[Z]):[true,""]);L=(Z.getMonth()!==h);w=(L&&!D)||!ag[0]||(n&&Zy);ac+="";Z.setDate(Z.getDate()+1);Z=this._daylightSavingAdjust(Z)}M+=ac+""}h++;if(h>11){h=0;U++}M+="
"+this._get(X,"weekHeader")+"
"+this._get(X,"calculateWeek")(Z)+""+(L&&!q?" ":(w?""+Z.getDate()+"":""+Z.getDate()+""))+"
"+(E?""+((x[0]>0&&r===x[1]-1)?"
":""):"");H+=M}Q+=H}Q+=ae;X._keyEvent=false;return Q},_generateMonthYearHeader:function(l,j,t,n,r,u,p,h){var y,i,z,w,m,v,s,o,k=this._get(l,"changeMonth"),A=this._get(l,"changeYear"),B=this._get(l,"showMonthAfterYear"),q="
",x="";if(u||!k){x+=""+p[j]+""}else{y=(n&&n.getFullYear()===t);i=(r&&r.getFullYear()===t);x+=""}if(!B){q+=x+(u||!(k&&A)?" ":"")}if(!l.yearshtml){l.yearshtml="";if(u||!A){q+=""+t+""}else{w=this._get(l,"yearRange").split(":");m=new Date().getFullYear();v=function(D){var C=(D.match(/c[+\-].*/)?t+parseInt(D.substring(1),10):(D.match(/[+\-].*/)?m+parseInt(D,10):parseInt(D,10)));return(isNaN(C)?m:C)};s=v(w[0]);o=Math.max(s,v(w[1]||""));s=(n?Math.max(s,n.getFullYear()):s);o=(r?Math.min(o,r.getFullYear()):o);l.yearshtml+="";q+=l.yearshtml;l.yearshtml=null}}q+=this._get(l,"yearSuffix");if(B){q+=(u||!(k&&A)?" ":"")+x}q+="
";return q},_adjustInstDate:function(k,n,m){var j=k.drawYear+(m==="Y"?n:0),l=k.drawMonth+(m==="M"?n:0),h=Math.min(k.selectedDay,this._getDaysInMonth(j,l))+(m==="D"?n:0),i=this._restrictMinMax(k,this._daylightSavingAdjust(new Date(j,l,h)));k.selectedDay=i.getDate();k.drawMonth=k.selectedMonth=i.getMonth();k.drawYear=k.selectedYear=i.getFullYear();if(m==="M"||m==="Y"){this._notifyChange(k)}},_restrictMinMax:function(k,i){var j=this._getMinMaxDate(k,"min"),l=this._getMinMaxDate(k,"max"),h=(j&&il?l:h)},_notifyChange:function(i){var h=this._get(i,"onChangeMonthYear");if(h){h.apply((i.input?i.input[0]:null),[i.selectedYear,i.selectedMonth+1,i])}},_getNumberOfMonths:function(i){var h=this._get(i,"numberOfMonths");return(h==null?[1,1]:(typeof h==="number"?[1,h]:h))},_getMinMaxDate:function(i,h){return this._determineDate(i,this._get(i,h+"Date"),null)},_getDaysInMonth:function(h,i){return 32-this._daylightSavingAdjust(new Date(h,i,32)).getDate()},_getFirstDayOfMonth:function(h,i){return new Date(h,i,1).getDay()},_canAdjustMonth:function(k,m,j,l){var h=this._getNumberOfMonths(k),i=this._daylightSavingAdjust(new Date(j,l+(m<0?m:h[0]*h[1]),1));if(m<0){i.setDate(this._getDaysInMonth(i.getFullYear(),i.getMonth()))}return this._isInRange(k,i)},_isInRange:function(l,j){var i,o,k=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),p=null,m=null,n=this._get(l,"yearRange");if(n){i=n.split(":");o=new Date().getFullYear();p=parseInt(i[0],10);m=parseInt(i[1],10);if(i[0].match(/[+\-].*/)){p+=o}if(i[1].match(/[+\-].*/)){m+=o}}return((!k||j.getTime()>=k.getTime())&&(!h||j.getTime()<=h.getTime())&&(!p||j.getFullYear()>=p)&&(!m||j.getFullYear()<=m))},_getFormatConfig:function(h){var i=this._get(h,"shortYearCutoff");i=(typeof i!=="string"?i:new Date().getFullYear()%100+parseInt(i,10));return{shortYearCutoff:i,dayNamesShort:this._get(h,"dayNamesShort"),dayNames:this._get(h,"dayNames"),monthNamesShort:this._get(h,"monthNamesShort"),monthNames:this._get(h,"monthNames")}},_formatDate:function(k,h,l,j){if(!h){k.currentDay=k.selectedDay;k.currentMonth=k.selectedMonth;k.currentYear=k.selectedYear}var i=(h?(typeof h==="object"?h:this._daylightSavingAdjust(new Date(j,l,h))):this._daylightSavingAdjust(new Date(k.currentYear,k.currentMonth,k.currentDay)));return this.formatDate(this._get(k,"dateFormat"),i,this._getFormatConfig(k))}});function d(i){var h="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return i.delegate(h,"mouseout",function(){e(this).removeClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!==-1){e(this).removeClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!==-1){e(this).removeClass("ui-datepicker-next-hover")}}).delegate(h,"mouseover",function(){if(!e.datepicker._isDisabledDatepicker(c.inline?i.parent()[0]:c.input[0])){e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");e(this).addClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!==-1){e(this).addClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!==-1){e(this).addClass("ui-datepicker-next-hover")}}})}function a(j,i){e.extend(j,i);for(var h in i){if(i[h]==null){j[h]=i[h]}}return j}e.fn.datepicker=function(i){if(!this.length){return this}if(!e.datepicker.initialized){e(document).mousedown(e.datepicker._checkExternalClick);e.datepicker.initialized=true}if(e("#"+e.datepicker._mainDivId).length===0){e("body").append(e.datepicker.dpDiv)}var h=Array.prototype.slice.call(arguments,1);if(typeof i==="string"&&(i==="isDisabled"||i==="getDate"||i==="widget")){return e.datepicker["_"+i+"Datepicker"].apply(e.datepicker,[this[0]].concat(h))}if(i==="option"&&arguments.length===2&&typeof arguments[1]==="string"){return e.datepicker["_"+i+"Datepicker"].apply(e.datepicker,[this[0]].concat(h))}return this.each(function(){typeof i==="string"?e.datepicker["_"+i+"Datepicker"].apply(e.datepicker,[this].concat(h)):e.datepicker._attachDatepicker(this,i)})};e.datepicker=new b();e.datepicker.initialized=false;e.datepicker.uuid=new Date().getTime();e.datepicker.version="1.10.3"})(jQuery);(function(b,c){var a=5;b.widget("ui.slider",b.ui.mouse,{version:"1.10.3",widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=false;this._mouseSliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");this._refresh();this._setOption("disabled",this.options.disabled);this._animateOff=false},_refresh:function(){this._createRange();this._createHandles();this._setupEvents();this._refreshValue()},_createHandles:function(){var g,d,e=this.options,j=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),h="",f=[];d=(e.values&&e.values.length)||1;if(j.length>d){j.slice(d).remove();j=j.slice(0,d)}for(g=j.length;g").appendTo(this.element);e="ui-slider-range ui-widget-header ui-corner-all"}else{this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""})}this.range.addClass(e+((d.range==="min"||d.range==="max")?" ui-slider-range-"+d.range:""))}else{this.range=b([])}},_setupEvents:function(){var d=this.handles.add(this.range).filter("a");this._off(d);this._on(d,this._handleEvents);this._hoverable(d);this._focusable(d)},_destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all");this._mouseDestroy()},_mouseCapture:function(f){var j,m,e,h,l,n,i,d,k=this,g=this.options;if(g.disabled){return false}this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();j={x:f.pageX,y:f.pageY};m=this._normValueFromMouse(j);e=this._valueMax()-this._valueMin()+1;this.handles.each(function(o){var p=Math.abs(m-k.values(o));if((e>p)||(e===p&&(o===k._lastChangedValue||k.values(o)===g.min))){e=p;h=b(this);l=o}});n=this._start(f,l);if(n===false){return false}this._mouseSliding=true;this._handleIndex=l;h.addClass("ui-state-active").focus();i=h.offset();d=!b(f.target).parents().addBack().is(".ui-slider-handle");this._clickOffset=d?{left:0,top:0}:{left:f.pageX-i.left-(h.width()/2),top:f.pageY-i.top-(h.height()/2)-(parseInt(h.css("borderTopWidth"),10)||0)-(parseInt(h.css("borderBottomWidth"),10)||0)+(parseInt(h.css("marginTop"),10)||0)};if(!this.handles.hasClass("ui-state-hover")){this._slide(f,l,m)}this._animateOff=true;return true},_mouseStart:function(){return true},_mouseDrag:function(f){var d={x:f.pageX,y:f.pageY},e=this._normValueFromMouse(d);this._slide(f,this._handleIndex,e);return false},_mouseStop:function(d){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(d,this._handleIndex);this._change(d,this._handleIndex);this._handleIndex=null;this._clickOffset=null;this._animateOff=false;return false},_detectOrientation:function(){this.orientation=(this.options.orientation==="vertical")?"vertical":"horizontal"},_normValueFromMouse:function(e){var d,h,g,f,i;if(this.orientation==="horizontal"){d=this.elementSize.width;h=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{d=this.elementSize.height;h=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}g=(h/d);if(g>1){g=1}if(g<0){g=0}if(this.orientation==="vertical"){g=1-g}f=this._valueMax()-this._valueMin();i=this._valueMin()+g*f;return this._trimAlignValue(i)},_start:function(f,e){var d={handle:this.handles[e],value:this.value()};if(this.options.values&&this.options.values.length){d.value=this.values(e);d.values=this.values()}return this._trigger("start",f,d)},_slide:function(h,g,f){var d,e,i;if(this.options.values&&this.options.values.length){d=this.values(g?0:1);if((this.options.values.length===2&&this.options.range===true)&&((g===0&&f>d)||(g===1&&f1){this.options.values[e]=this._trimAlignValue(h);this._refreshValue();this._change(null,e);return}if(arguments.length){if(b.isArray(arguments[0])){g=this.options.values;d=arguments[0];for(f=0;f=this._valueMax()){return this._valueMax()}var d=(this.options.step>0)?this.options.step:1,f=(g-this._valueMin())%d,e=g-f;if(Math.abs(f)*2>=d){e+=(f>0)?d:(-d)}return parseFloat(e.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var i,h,l,j,m,g=this.options.range,f=this.options,k=this,e=(!this._animateOff)?f.animate:false,d={};if(this.options.values&&this.options.values.length){this.handles.each(function(n){h=(k.values(n)-k._valueMin())/(k._valueMax()-k._valueMin())*100;d[k.orientation==="horizontal"?"left":"bottom"]=h+"%";b(this).stop(1,1)[e?"animate":"css"](d,f.animate);if(k.options.range===true){if(k.orientation==="horizontal"){if(n===0){k.range.stop(1,1)[e?"animate":"css"]({left:h+"%"},f.animate)}if(n===1){k.range[e?"animate":"css"]({width:(h-i)+"%"},{queue:false,duration:f.animate})}}else{if(n===0){k.range.stop(1,1)[e?"animate":"css"]({bottom:(h)+"%"},f.animate)}if(n===1){k.range[e?"animate":"css"]({height:(h-i)+"%"},{queue:false,duration:f.animate})}}}i=h})}else{l=this.value();j=this._valueMin();m=this._valueMax();h=(m!==j)?(l-j)/(m-j)*100:0;d[this.orientation==="horizontal"?"left":"bottom"]=h+"%";this.handle.stop(1,1)[e?"animate":"css"](d,f.animate);if(g==="min"&&this.orientation==="horizontal"){this.range.stop(1,1)[e?"animate":"css"]({width:h+"%"},f.animate)}if(g==="max"&&this.orientation==="horizontal"){this.range[e?"animate":"css"]({width:(100-h)+"%"},{queue:false,duration:f.animate})}if(g==="min"&&this.orientation==="vertical"){this.range.stop(1,1)[e?"animate":"css"]({height:h+"%"},f.animate)}if(g==="max"&&this.orientation==="vertical"){this.range[e?"animate":"css"]({height:(100-h)+"%"},{queue:false,duration:f.animate})}}},_handleEvents:{keydown:function(h){var i,f,e,g,d=b(h.target).data("ui-slider-handle-index");switch(h.keyCode){case b.ui.keyCode.HOME:case b.ui.keyCode.END:case b.ui.keyCode.PAGE_UP:case b.ui.keyCode.PAGE_DOWN:case b.ui.keyCode.UP:case b.ui.keyCode.RIGHT:case b.ui.keyCode.DOWN:case b.ui.keyCode.LEFT:h.preventDefault();if(!this._keySliding){this._keySliding=true;b(h.target).addClass("ui-state-active");i=this._start(h,d);if(i===false){return}}break}g=this.options.step;if(this.options.values&&this.options.values.length){f=e=this.values(d)}else{f=e=this.value()}switch(h.keyCode){case b.ui.keyCode.HOME:e=this._valueMin();break;case b.ui.keyCode.END:e=this._valueMax();break;case b.ui.keyCode.PAGE_UP:e=this._trimAlignValue(f+((this._valueMax()-this._valueMin())/a));break;case b.ui.keyCode.PAGE_DOWN:e=this._trimAlignValue(f-((this._valueMax()-this._valueMin())/a));break;case b.ui.keyCode.UP:case b.ui.keyCode.RIGHT:if(f===this._valueMax()){return}e=this._trimAlignValue(f+g);break;case b.ui.keyCode.DOWN:case b.ui.keyCode.LEFT:if(f===this._valueMin()){return}e=this._trimAlignValue(f-g);break}this._slide(h,d,e)},click:function(d){d.preventDefault()},keyup:function(e){var d=b(e.target).data("ui-slider-handle-index");if(this._keySliding){this._keySliding=false;this._stop(e,d);this._change(e,d);b(e.target).removeClass("ui-state-active")}}}})}(jQuery));(function(a,c){var b="ui-effects-";a.effects={effect:{}}; -/* - * jQuery Color Animations v2.1.2 - * https://github.com/jquery/jquery-color - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * Date: Wed Jan 16 08:47:09 2013 -0600 - */ -(function(r,g){var n="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",k=/^([\-+])=\s*(\d+\.?\d*)/,j=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(s){return[s[1],s[2],s[3],s[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(s){return[s[1]*2.55,s[2]*2.55,s[3]*2.55,s[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(s){return[parseInt(s[1],16),parseInt(s[2],16),parseInt(s[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(s){return[parseInt(s[1]+s[1],16),parseInt(s[2]+s[2],16),parseInt(s[3]+s[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(s){return[s[1],s[2]/100,s[3]/100,s[4]]}}],h=r.Color=function(t,u,s,v){return new r.Color.fn.parse(t,u,s,v)},m={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},q={"byte":{floor:true,max:255},percent:{max:1},degrees:{mod:360,floor:true}},p=h.support={},e=r("

")[0],d,o=r.each;e.style.cssText="background-color:rgba(1,1,1,.5)";p.rgba=e.style.backgroundColor.indexOf("rgba")>-1;o(m,function(s,t){t.cache="_"+s;t.props.alpha={idx:3,type:"percent",def:1}});function l(t,v,u){var s=q[v.type]||{};if(t==null){return(u||!v.def)?null:v.def}t=s.floor?~~t:parseFloat(t);if(isNaN(t)){return v.def}if(s.mod){return(t+s.mod)%s.mod}return 0>t?0:s.maxE.mod/2){B+=E.mod}else{if(B-A>E.mod/2){B-=E.mod}}}s[C]=l((A-B)*z+B,F)}});return this[v](s)},blend:function(v){if(this._rgba[3]===1){return this}var u=this._rgba.slice(),t=u.pop(),s=h(v)._rgba;return h(r.map(u,function(w,x){return(1-t)*s[x]+t*w}))},toRgbaString:function(){var t="rgba(",s=r.map(this._rgba,function(u,w){return u==null?(w>2?1:0):u});if(s[3]===1){s.pop();t="rgb("}return t+s.join()+")"},toHslaString:function(){var t="hsla(",s=r.map(this.hsla(),function(u,w){if(u==null){u=w>2?1:0}if(w&&w<3){u=Math.round(u*100)+"%"}return u});if(s[3]===1){s.pop();t="hsl("}return t+s.join()+")"},toHexString:function(s){var t=this._rgba.slice(),u=t.pop();if(s){t.push(~~(u*255))}return"#"+r.map(t,function(w){w=(w||0).toString(16);return w.length===1?"0"+w:w}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}});h.fn.parse.prototype=h.fn;function f(u,t,s){s=(s+1)%1;if(s*6<1){return u+(t-u)*s*6}if(s*2<1){return t}if(s*3<2){return u+(t-u)*((2/3)-s)*6}return u}m.hsla.to=function(v){if(v[0]==null||v[1]==null||v[2]==null){return[null,null,null,v[3]]}var t=v[0]/255,y=v[1]/255,z=v[2]/255,B=v[3],A=Math.max(t,y,z),w=Math.min(t,y,z),C=A-w,D=A+w,u=D*0.5,x,E;if(w===A){x=0}else{if(t===A){x=(60*(y-z)/C)+360}else{if(y===A){x=(60*(z-t)/C)+120}else{x=(60*(t-y)/C)+240}}}if(C===0){E=0}else{if(u<=0.5){E=C/D}else{E=C/(2-D)}}return[Math.round(x)%360,E,u,B==null?1:B]};m.hsla.from=function(x){if(x[0]==null||x[1]==null||x[2]==null){return[null,null,null,x[3]]}var w=x[0]/360,v=x[1],u=x[2],t=x[3],y=u<=0.5?u*(1+v):u+v-u*v,z=2*u-y;return[Math.round(f(z,y,w+(1/3))*255),Math.round(f(z,y,w)*255),Math.round(f(z,y,w-(1/3))*255),t]};o(m,function(t,v){var u=v.props,s=v.cache,x=v.to,w=v.from;h.fn[t]=function(C){if(x&&!this[s]){this[s]=x(this._rgba)}if(C===g){return this[s].slice()}var z,B=r.type(C),y=(B==="array"||B==="object")?C:arguments,A=this[s].slice();o(u,function(D,F){var E=y[B==="object"?D:F.idx];if(E==null){E=A[F.idx]}A[F.idx]=l(E,F)});if(w){z=h(w(A));z[s]=A;return z}else{return h(A)}};o(u,function(y,z){if(h.fn[y]){return}h.fn[y]=function(D){var F=r.type(D),C=(y==="alpha"?(this._hsla?"hsla":"rgba"):t),B=this[C](),E=B[z.idx],A;if(F==="undefined"){return E}if(F==="function"){D=D.call(this,E);F=r.type(D)}if(D==null&&z.empty){return this}if(F==="string"){A=k.exec(D);if(A){D=E+parseFloat(A[2])*(A[1]==="+"?1:-1)}}B[z.idx]=D;return this[C](B)}})});h.hook=function(t){var s=t.split(" ");o(s,function(u,v){r.cssHooks[v]={set:function(z,A){var x,y,w="";if(A!=="transparent"&&(r.type(A)!=="string"||(x=i(A)))){A=h(x||A);if(!p.rgba&&A._rgba[3]!==1){y=v==="backgroundColor"?z.parentNode:z;while((w===""||w==="transparent")&&y&&y.style){try{w=r.css(y,"backgroundColor");y=y.parentNode}catch(B){}}A=A.blend(w&&w!=="transparent"?w:"_default")}A=A.toRgbaString()}try{z.style[v]=A}catch(B){}}};r.fx.step[v]=function(w){if(!w.colorInit){w.start=h(w.elem,v);w.end=h(w.end);w.colorInit=true}r.cssHooks[v].set(w.elem,w.start.transition(w.end,w.pos))}})};h.hook(n);r.cssHooks.borderColor={expand:function(t){var s={};o(["Top","Right","Bottom","Left"],function(v,u){s["border"+u+"Color"]=t});return s}};d=r.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery);(function(){var e=["add","remove","toggle"],f={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(h,i){a.fx.step[i]=function(j){if(j.end!=="none"&&!j.setAttr||j.pos===1&&!j.setAttr){jQuery.style(j.elem,i,j.end);j.setAttr=true}}});function g(l){var i,h,j=l.ownerDocument.defaultView?l.ownerDocument.defaultView.getComputedStyle(l,null):l.currentStyle,k={};if(j&&j.length&&j[0]&&j[j[0]]){h=j.length;while(h--){i=j[h];if(typeof j[i]==="string"){k[a.camelCase(i)]=j[i]}}}else{for(i in j){if(typeof j[i]==="string"){k[i]=j[i]}}}return k}function d(h,j){var l={},i,k;for(i in j){k=j[i];if(h[i]!==k){if(!f[i]){if(a.fx.step[i]||!isNaN(parseFloat(k))){l[i]=k}}}}return l}if(!a.fn.addBack){a.fn.addBack=function(h){return this.add(h==null?this.prevObject:this.prevObject.filter(h))}}a.effects.animateClass=function(h,i,l,k){var j=a.speed(i,l,k);return this.queue(function(){var o=a(this),m=o.attr("class")||"",n,p=j.children?o.find("*").addBack():o;p=p.map(function(){var q=a(this);return{el:q,start:g(this)}});n=function(){a.each(e,function(q,r){if(h[r]){o[r+"Class"](h[r])}})};n();p=p.map(function(){this.end=g(this.el[0]);this.diff=d(this.start,this.end);return this});o.attr("class",m);p=p.map(function(){var s=this,q=a.Deferred(),r=a.extend({},j,{queue:false,complete:function(){q.resolve(s)}});this.el.animate(this.diff,r);return q.promise()});a.when.apply(a,p.get()).done(function(){n();a.each(arguments,function(){var q=this.el;a.each(this.diff,function(r){q.css(r,"")})});j.complete.call(o[0])})})};a.fn.extend({addClass:(function(h){return function(j,i,l,k){return i?a.effects.animateClass.call(this,{add:j},i,l,k):h.apply(this,arguments)}})(a.fn.addClass),removeClass:(function(h){return function(j,i,l,k){return arguments.length>1?a.effects.animateClass.call(this,{remove:j},i,l,k):h.apply(this,arguments)}})(a.fn.removeClass),toggleClass:(function(h){return function(k,j,i,m,l){if(typeof j==="boolean"||j===c){if(!i){return h.apply(this,arguments)}else{return a.effects.animateClass.call(this,(j?{add:k}:{remove:k}),i,m,l)}}else{return a.effects.animateClass.call(this,{toggle:k},j,i,m)}}})(a.fn.toggleClass),switchClass:function(h,j,i,l,k){return a.effects.animateClass.call(this,{add:j,remove:h},i,l,k)}})})();(function(){a.extend(a.effects,{version:"1.10.3",save:function(g,h){for(var f=0;f").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),f={width:g.width(),height:g.height()},j=document.activeElement;try{j.id}catch(i){j=document.body}g.wrap(k);if(g[0]===j||a.contains(g[0],j)){a(j).focus()}k=g.parent();if(g.css("position")==="static"){k.css({position:"relative"});g.css({position:"relative"})}else{a.extend(h,{position:g.css("position"),zIndex:g.css("z-index")});a.each(["top","left","bottom","right"],function(l,m){h[m]=g.css(m);if(isNaN(parseInt(h[m],10))){h[m]="auto"}});g.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}g.css(f);return k.css(h).show()},removeWrapper:function(f){var g=document.activeElement;if(f.parent().is(".ui-effects-wrapper")){f.parent().replaceWith(f);if(f[0]===g||a.contains(f[0],g)){a(g).focus()}}return f},setTransition:function(g,i,f,h){h=h||{};a.each(i,function(k,j){var l=g.cssUnit(j);if(l[0]>0){h[j]=l[0]*f+l[1]}});return h}});function d(g,f,h,i){if(a.isPlainObject(g)){f=g;g=g.effect}g={effect:g};if(f==null){f={}}if(a.isFunction(f)){i=f;h=null;f={}}if(typeof f==="number"||a.fx.speeds[f]){i=h;h=f;f={}}if(a.isFunction(h)){i=h;h=null}if(f){a.extend(g,f)}h=h||f.duration;g.duration=a.fx.off?0:typeof h==="number"?h:h in a.fx.speeds?a.fx.speeds[h]:a.fx.speeds._default;g.complete=i||f.complete;return g}function e(f){if(!f||typeof f==="number"||a.fx.speeds[f]){return true}if(typeof f==="string"&&!a.effects.effect[f]){return true}if(a.isFunction(f)){return true}if(typeof f==="object"&&!f.effect){return true}return false}a.fn.extend({effect:function(){var h=d.apply(this,arguments),j=h.mode,f=h.queue,g=a.effects.effect[h.effect];if(a.fx.off||!g){if(j){return this[j](h.duration,h.complete)}else{return this.each(function(){if(h.complete){h.complete.call(this)}})}}function i(m){var n=a(this),l=h.complete,o=h.mode;function k(){if(a.isFunction(l)){l.call(n[0])}if(a.isFunction(m)){m()}}if(n.is(":hidden")?o==="hide":o==="show"){n[o]();k()}else{g.call(n[0],h,k)}}return f===false?this.each(i):this.queue(f||"fx",i)},show:(function(f){return function(h){if(e(h)){return f.apply(this,arguments)}else{var g=d.apply(this,arguments);g.mode="show";return this.effect.call(this,g)}}})(a.fn.show),hide:(function(f){return function(h){if(e(h)){return f.apply(this,arguments)}else{var g=d.apply(this,arguments);g.mode="hide";return this.effect.call(this,g)}}})(a.fn.hide),toggle:(function(f){return function(h){if(e(h)||typeof h==="boolean"){return f.apply(this,arguments)}else{var g=d.apply(this,arguments);g.mode="toggle";return this.effect.call(this,g)}}})(a.fn.toggle),cssUnit:function(f){var g=this.css(f),h=[];a.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}})})();(function(){var d={};a.each(["Quad","Cubic","Quart","Quint","Expo"],function(f,e){d[e]=function(g){return Math.pow(g,f+2)}});a.extend(d,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(g){var e,f=4;while(g<((e=Math.pow(2,--f))-1)/11){}return 1/Math.pow(4,3-f)-7.5625*Math.pow((e*3-2)/22-g,2)}});a.each(d,function(f,e){a.easing["easeIn"+f]=e;a.easing["easeOut"+f]=function(g){return 1-e(1-g)};a.easing["easeInOut"+f]=function(g){return g<0.5?e(g*2)/2:1-e(g*-2+2)/2}})})()})(jQuery);(function(a,b){a.effects.effect.highlight=function(h,c){var e=a(this),d=["backgroundImage","backgroundColor","opacity"],g=a.effects.setMode(e,h.mode||"show"),f={backgroundColor:e.css("backgroundColor")};if(g==="hide"){f.opacity=0}a.effects.save(e,d);e.show().css({backgroundImage:"none",backgroundColor:h.color||"#ffff99"}).animate(f,{queue:false,duration:h.duration,easing:h.easing,complete:function(){if(g==="hide"){e.hide()}a.effects.restore(e,d);c()}})}})(jQuery); \ No newline at end of file diff --git a/php/typecho09/admin/js/jquery.js b/php/typecho09/admin/js/jquery.js deleted file mode 100644 index 64af52472..000000000 --- a/php/typecho09/admin/js/jquery.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * jQuery JavaScript Library v2.0.3 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2013-07-03T13:30Z - */ -(function(window,undefined){var rootjQuery,readyList,core_strundefined=typeof undefined,location=window.location,document=window.document,docElem=document.documentElement,_jQuery=window.jQuery,_$=window.$,class2type={},core_deletedIds=[],core_version="2.0.3",core_concat=core_deletedIds.concat,core_push=core_deletedIds.push,core_slice=core_deletedIds.slice,core_indexOf=core_deletedIds.indexOf,core_toString=class2type.toString,core_hasOwn=class2type.hasOwnProperty,core_trim=core_version.trim,jQuery=function(selector,context){return new jQuery.fn.init(selector,context,rootjQuery)},core_pnum=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,core_rnotwhite=/\S+/g,rquickExpr=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,rsingleTag=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,rmsPrefix=/^-ms-/,rdashAlpha=/-([\da-z])/gi,fcamelCase=function(all,letter){return letter.toUpperCase()},completed=function(){document.removeEventListener("DOMContentLoaded",completed,false);window.removeEventListener("load",completed,false);jQuery.ready()};jQuery.fn=jQuery.prototype={jquery:core_version,constructor:jQuery,init:function(selector,context,rootjQuery){var match,elem;if(!selector){return this}if(typeof selector==="string"){if(selector.charAt(0)==="<"&&selector.charAt(selector.length-1)===">"&&selector.length>=3){match=[null,selector,null]}else{match=rquickExpr.exec(selector)}if(match&&(match[1]||!context)){if(match[1]){context=context instanceof jQuery?context[0]:context;jQuery.merge(this,jQuery.parseHTML(match[1],context&&context.nodeType?context.ownerDocument||context:document,true));if(rsingleTag.test(match[1])&&jQuery.isPlainObject(context)){for(match in context){if(jQuery.isFunction(this[match])){this[match](context[match])}else{this.attr(match,context[match])}}}return this}else{elem=document.getElementById(match[2]);if(elem&&elem.parentNode){this.length=1;this[0]=elem}this.context=document;this.selector=selector;return this}}else{if(!context||context.jquery){return(context||rootjQuery).find(selector)}else{return this.constructor(context).find(selector)}}}else{if(selector.nodeType){this.context=this[0]=selector;this.length=1;return this}else{if(jQuery.isFunction(selector)){return rootjQuery.ready(selector)}}}if(selector.selector!==undefined){this.selector=selector.selector;this.context=selector.context}return jQuery.makeArray(selector,this)},selector:"",length:0,toArray:function(){return core_slice.call(this)},get:function(num){return num==null?this.toArray():(num<0?this[this.length+num]:this[num])},pushStack:function(elems){var ret=jQuery.merge(this.constructor(),elems);ret.prevObject=this;ret.context=this.context;return ret},each:function(callback,args){return jQuery.each(this,callback,args)},ready:function(fn){jQuery.ready.promise().done(fn);return this},slice:function(){return this.pushStack(core_slice.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(i){var len=this.length,j=+i+(i<0?len:0);return this.pushStack(j>=0&&j0){return}readyList.resolveWith(document,[jQuery]);if(jQuery.fn.trigger){jQuery(document).trigger("ready").off("ready")}},isFunction:function(obj){return jQuery.type(obj)==="function"},isArray:Array.isArray,isWindow:function(obj){return obj!=null&&obj===obj.window},isNumeric:function(obj){return !isNaN(parseFloat(obj))&&isFinite(obj)},type:function(obj){if(obj==null){return String(obj)}return typeof obj==="object"||typeof obj==="function"?class2type[core_toString.call(obj)]||"object":typeof obj},isPlainObject:function(obj){if(jQuery.type(obj)!=="object"||obj.nodeType||jQuery.isWindow(obj)){return false}try{if(obj.constructor&&!core_hasOwn.call(obj.constructor.prototype,"isPrototypeOf")){return false}}catch(e){return false}return true},isEmptyObject:function(obj){var name;for(name in obj){return false}return true},error:function(msg){throw new Error(msg)},parseHTML:function(data,context,keepScripts){if(!data||typeof data!=="string"){return null}if(typeof context==="boolean"){keepScripts=context;context=false}context=context||document;var parsed=rsingleTag.exec(data),scripts=!keepScripts&&[];if(parsed){return[context.createElement(parsed[1])]}parsed=jQuery.buildFragment([data],context,scripts);if(scripts){jQuery(scripts).remove()}return jQuery.merge([],parsed.childNodes)},parseJSON:JSON.parse,parseXML:function(data){var xml,tmp;if(!data||typeof data!=="string"){return null}try{tmp=new DOMParser();xml=tmp.parseFromString(data,"text/xml")}catch(e){xml=undefined}if(!xml||xml.getElementsByTagName("parsererror").length){jQuery.error("Invalid XML: "+data)}return xml},noop:function(){},globalEval:function(code){var script,indirect=eval;code=jQuery.trim(code);if(code){if(code.indexOf("use strict")===1){script=document.createElement("script");script.text=code;document.head.appendChild(script).parentNode.removeChild(script)}else{indirect(code)}}},camelCase:function(string){return string.replace(rmsPrefix,"ms-").replace(rdashAlpha,fcamelCase)},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toLowerCase()===name.toLowerCase()},each:function(obj,callback,args){var value,i=0,length=obj.length,isArray=isArraylike(obj);if(args){if(isArray){for(;i0&&(length-1) in obj)}rootjQuery=jQuery(document); -/* - * Sizzle CSS Selector Engine v1.9.4-pre - * http://sizzlejs.com/ - * - * Copyright 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2013-06-03 - */ -(function(window,undefined){var i,support,cachedruns,Expr,getText,isXML,compile,outermostContext,sortInput,setDocument,document,docElem,documentIsHTML,rbuggyQSA,rbuggyMatches,matches,contains,expando="sizzle"+-(new Date()),preferredDoc=window.document,dirruns=0,done=0,classCache=createCache(),tokenCache=createCache(),compilerCache=createCache(),hasDuplicate=false,sortOrder=function(a,b){if(a===b){hasDuplicate=true;return 0}return 0},strundefined=typeof undefined,MAX_NEGATIVE=1<<31,hasOwn=({}).hasOwnProperty,arr=[],pop=arr.pop,push_native=arr.push,push=arr.push,slice=arr.slice,indexOf=arr.indexOf||function(elem){var i=0,len=this.length;for(;i+~]|"+whitespace+")"+whitespace+"*"),rsibling=new RegExp(whitespace+"*[+~]"),rattributeQuotes=new RegExp("="+whitespace+"*([^\\]'\"]*)"+whitespace+"*\\]","g"),rpseudo=new RegExp(pseudos),ridentifier=new RegExp("^"+identifier+"$"),matchExpr={ID:new RegExp("^#("+characterEncoding+")"),CLASS:new RegExp("^\\.("+characterEncoding+")"),TAG:new RegExp("^("+characterEncoding.replace("w","w*")+")"),ATTR:new RegExp("^"+attributes),PSEUDO:new RegExp("^"+pseudos),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+whitespace+"*(even|odd|(([+-]|)(\\d*)n|)"+whitespace+"*(?:([+-]|)"+whitespace+"*(\\d+)|))"+whitespace+"*\\)|)","i"),bool:new RegExp("^(?:"+booleans+")$","i"),needsContext:new RegExp("^"+whitespace+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+whitespace+"*((?:-\\d)?\\d*)"+whitespace+"*\\)|)(?=[^-]|$)","i")},rnative=/^[^{]+\{\s*\[native \w/,rquickExpr=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,rinputs=/^(?:input|select|textarea|button)$/i,rheader=/^h\d$/i,rescape=/'|\\/g,runescape=new RegExp("\\\\([\\da-f]{1,6}"+whitespace+"?|("+whitespace+")|.)","ig"),funescape=function(_,escaped,escapedWhitespace){var high="0x"+escaped-65536;return high!==high||escapedWhitespace?escaped:high<0?String.fromCharCode(high+65536):String.fromCharCode(high>>10|55296,high&1023|56320)};try{push.apply((arr=slice.call(preferredDoc.childNodes)),preferredDoc.childNodes);arr[preferredDoc.childNodes.length].nodeType}catch(e){push={apply:arr.length?function(target,els){push_native.apply(target,slice.call(els))}:function(target,els){var j=target.length,i=0;while((target[j++]=els[i++])){}target.length=j-1}}}function Sizzle(selector,context,results,seed){var match,elem,m,nodeType,i,groups,old,nid,newContext,newSelector;if((context?context.ownerDocument||context:preferredDoc)!==document){setDocument(context)}context=context||document;results=results||[];if(!selector||typeof selector!=="string"){return results}if((nodeType=context.nodeType)!==1&&nodeType!==9){return[]}if(documentIsHTML&&!seed){if((match=rquickExpr.exec(selector))){if((m=match[1])){if(nodeType===9){elem=context.getElementById(m);if(elem&&elem.parentNode){if(elem.id===m){results.push(elem);return results}}else{return results}}else{if(context.ownerDocument&&(elem=context.ownerDocument.getElementById(m))&&contains(context,elem)&&elem.id===m){results.push(elem);return results}}}else{if(match[2]){push.apply(results,context.getElementsByTagName(selector));return results}else{if((m=match[3])&&support.getElementsByClassName&&context.getElementsByClassName){push.apply(results,context.getElementsByClassName(m));return results}}}}if(support.qsa&&(!rbuggyQSA||!rbuggyQSA.test(selector))){nid=old=expando;newContext=context;newSelector=nodeType===9&&selector;if(nodeType===1&&context.nodeName.toLowerCase()!=="object"){groups=tokenize(selector);if((old=context.getAttribute("id"))){nid=old.replace(rescape,"\\$&")}else{context.setAttribute("id",nid)}nid="[id='"+nid+"'] ";i=groups.length;while(i--){groups[i]=nid+toSelector(groups[i])}newContext=rsibling.test(selector)&&context.parentNode||context;newSelector=groups.join(",")}if(newSelector){try{push.apply(results,newContext.querySelectorAll(newSelector));return results}catch(qsaError){}finally{if(!old){context.removeAttribute("id")}}}}}return select(selector.replace(rtrim,"$1"),context,results,seed)}function createCache(){var keys=[];function cache(key,value){if(keys.push(key+=" ")>Expr.cacheLength){delete cache[keys.shift()]}return(cache[key]=value)}return cache}function markFunction(fn){fn[expando]=true;return fn}function assert(fn){var div=document.createElement("div");try{return !!fn(div)}catch(e){return false}finally{if(div.parentNode){div.parentNode.removeChild(div)}div=null}}function addHandle(attrs,handler){var arr=attrs.split("|"),i=attrs.length;while(i--){Expr.attrHandle[arr[i]]=handler}}function siblingCheck(a,b){var cur=b&&a,diff=cur&&a.nodeType===1&&b.nodeType===1&&(~b.sourceIndex||MAX_NEGATIVE)-(~a.sourceIndex||MAX_NEGATIVE);if(diff){return diff}if(cur){while((cur=cur.nextSibling)){if(cur===b){return -1}}}return a?1:-1}function createInputPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type===type}}function createButtonPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return(name==="input"||name==="button")&&elem.type===type}}function createPositionalPseudo(fn){return markFunction(function(argument){argument=+argument;return markFunction(function(seed,matches){var j,matchIndexes=fn([],seed.length,argument),i=matchIndexes.length;while(i--){if(seed[(j=matchIndexes[i])]){seed[j]=!(matches[j]=seed[j])}}})})}isXML=Sizzle.isXML=function(elem){var documentElement=elem&&(elem.ownerDocument||elem).documentElement;return documentElement?documentElement.nodeName!=="HTML":false};support=Sizzle.support={};setDocument=Sizzle.setDocument=function(node){var doc=node?node.ownerDocument||node:preferredDoc,parent=doc.defaultView;if(doc===document||doc.nodeType!==9||!doc.documentElement){return document}document=doc;docElem=doc.documentElement;documentIsHTML=!isXML(doc);if(parent&&parent.attachEvent&&parent!==parent.top){parent.attachEvent("onbeforeunload",function(){setDocument()})}support.attributes=assert(function(div){div.className="i";return !div.getAttribute("className")});support.getElementsByTagName=assert(function(div){div.appendChild(doc.createComment(""));return !div.getElementsByTagName("*").length});support.getElementsByClassName=assert(function(div){div.innerHTML="

";div.firstChild.className="i";return div.getElementsByClassName("i").length===2});support.getById=assert(function(div){docElem.appendChild(div).id=expando;return !doc.getElementsByName||!doc.getElementsByName(expando).length});if(support.getById){Expr.find.ID=function(id,context){if(typeof context.getElementById!==strundefined&&documentIsHTML){var m=context.getElementById(id);return m&&m.parentNode?[m]:[]}};Expr.filter.ID=function(id){var attrId=id.replace(runescape,funescape);return function(elem){return elem.getAttribute("id")===attrId}}}else{delete Expr.find.ID;Expr.filter.ID=function(id){var attrId=id.replace(runescape,funescape);return function(elem){var node=typeof elem.getAttributeNode!==strundefined&&elem.getAttributeNode("id");return node&&node.value===attrId}}}Expr.find.TAG=support.getElementsByTagName?function(tag,context){if(typeof context.getElementsByTagName!==strundefined){return context.getElementsByTagName(tag)}}:function(tag,context){var elem,tmp=[],i=0,results=context.getElementsByTagName(tag);if(tag==="*"){while((elem=results[i++])){if(elem.nodeType===1){tmp.push(elem)}}return tmp}return results};Expr.find.CLASS=support.getElementsByClassName&&function(className,context){if(typeof context.getElementsByClassName!==strundefined&&documentIsHTML){return context.getElementsByClassName(className)}};rbuggyMatches=[];rbuggyQSA=[];if((support.qsa=rnative.test(doc.querySelectorAll))){assert(function(div){div.innerHTML="";if(!div.querySelectorAll("[selected]").length){rbuggyQSA.push("\\["+whitespace+"*(?:value|"+booleans+")")}if(!div.querySelectorAll(":checked").length){rbuggyQSA.push(":checked")}});assert(function(div){var input=doc.createElement("input");input.setAttribute("type","hidden");div.appendChild(input).setAttribute("t","");if(div.querySelectorAll("[t^='']").length){rbuggyQSA.push("[*^$]="+whitespace+"*(?:''|\"\")")}if(!div.querySelectorAll(":enabled").length){rbuggyQSA.push(":enabled",":disabled")}div.querySelectorAll("*,:x");rbuggyQSA.push(",.*:")})}if((support.matchesSelector=rnative.test((matches=docElem.webkitMatchesSelector||docElem.mozMatchesSelector||docElem.oMatchesSelector||docElem.msMatchesSelector)))){assert(function(div){support.disconnectedMatch=matches.call(div,"div");matches.call(div,"[s!='']:x");rbuggyMatches.push("!=",pseudos)})}rbuggyQSA=rbuggyQSA.length&&new RegExp(rbuggyQSA.join("|"));rbuggyMatches=rbuggyMatches.length&&new RegExp(rbuggyMatches.join("|"));contains=rnative.test(docElem.contains)||docElem.compareDocumentPosition?function(a,b){var adown=a.nodeType===9?a.documentElement:a,bup=b&&b.parentNode;return a===bup||!!(bup&&bup.nodeType===1&&(adown.contains?adown.contains(bup):a.compareDocumentPosition&&a.compareDocumentPosition(bup)&16))}:function(a,b){if(b){while((b=b.parentNode)){if(b===a){return true}}}return false};sortOrder=docElem.compareDocumentPosition?function(a,b){if(a===b){hasDuplicate=true;return 0}var compare=b.compareDocumentPosition&&a.compareDocumentPosition&&a.compareDocumentPosition(b);if(compare){if(compare&1||(!support.sortDetached&&b.compareDocumentPosition(a)===compare)){if(a===doc||contains(preferredDoc,a)){return -1}if(b===doc||contains(preferredDoc,b)){return 1}return sortInput?(indexOf.call(sortInput,a)-indexOf.call(sortInput,b)):0}return compare&4?-1:1}return a.compareDocumentPosition?-1:1}:function(a,b){var cur,i=0,aup=a.parentNode,bup=b.parentNode,ap=[a],bp=[b];if(a===b){hasDuplicate=true;return 0}else{if(!aup||!bup){return a===doc?-1:b===doc?1:aup?-1:bup?1:sortInput?(indexOf.call(sortInput,a)-indexOf.call(sortInput,b)):0}else{if(aup===bup){return siblingCheck(a,b)}}}cur=a;while((cur=cur.parentNode)){ap.unshift(cur)}cur=b;while((cur=cur.parentNode)){bp.unshift(cur)}while(ap[i]===bp[i]){i++}return i?siblingCheck(ap[i],bp[i]):ap[i]===preferredDoc?-1:bp[i]===preferredDoc?1:0};return doc};Sizzle.matches=function(expr,elements){return Sizzle(expr,null,null,elements)};Sizzle.matchesSelector=function(elem,expr){if((elem.ownerDocument||elem)!==document){setDocument(elem)}expr=expr.replace(rattributeQuotes,"='$1']");if(support.matchesSelector&&documentIsHTML&&(!rbuggyMatches||!rbuggyMatches.test(expr))&&(!rbuggyQSA||!rbuggyQSA.test(expr))){try{var ret=matches.call(elem,expr);if(ret||support.disconnectedMatch||elem.document&&elem.document.nodeType!==11){return ret}}catch(e){}}return Sizzle(expr,document,null,[elem]).length>0};Sizzle.contains=function(context,elem){if((context.ownerDocument||context)!==document){setDocument(context)}return contains(context,elem)};Sizzle.attr=function(elem,name){if((elem.ownerDocument||elem)!==document){setDocument(elem)}var fn=Expr.attrHandle[name.toLowerCase()],val=fn&&hasOwn.call(Expr.attrHandle,name.toLowerCase())?fn(elem,name,!documentIsHTML):undefined;return val===undefined?support.attributes||!documentIsHTML?elem.getAttribute(name):(val=elem.getAttributeNode(name))&&val.specified?val.value:null:val};Sizzle.error=function(msg){throw new Error("Syntax error, unrecognized expression: "+msg)};Sizzle.uniqueSort=function(results){var elem,duplicates=[],j=0,i=0;hasDuplicate=!support.detectDuplicates;sortInput=!support.sortStable&&results.slice(0);results.sort(sortOrder);if(hasDuplicate){while((elem=results[i++])){if(elem===results[i]){j=duplicates.push(i)}}while(j--){results.splice(duplicates[j],1)}}return results};getText=Sizzle.getText=function(elem){var node,ret="",i=0,nodeType=elem.nodeType;if(!nodeType){for(;(node=elem[i]);i++){ret+=getText(node)}}else{if(nodeType===1||nodeType===9||nodeType===11){if(typeof elem.textContent==="string"){return elem.textContent}else{for(elem=elem.firstChild;elem;elem=elem.nextSibling){ret+=getText(elem)}}}else{if(nodeType===3||nodeType===4){return elem.nodeValue}}}return ret};Expr=Sizzle.selectors={cacheLength:50,createPseudo:markFunction,match:matchExpr,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(match){match[1]=match[1].replace(runescape,funescape);match[3]=(match[4]||match[5]||"").replace(runescape,funescape);if(match[2]==="~="){match[3]=" "+match[3]+" "}return match.slice(0,4)},CHILD:function(match){match[1]=match[1].toLowerCase();if(match[1].slice(0,3)==="nth"){if(!match[3]){Sizzle.error(match[0])}match[4]=+(match[4]?match[5]+(match[6]||1):2*(match[3]==="even"||match[3]==="odd"));match[5]=+((match[7]+match[8])||match[3]==="odd")}else{if(match[3]){Sizzle.error(match[0])}}return match},PSEUDO:function(match){var excess,unquoted=!match[5]&&match[2];if(matchExpr.CHILD.test(match[0])){return null}if(match[3]&&match[4]!==undefined){match[2]=match[4]}else{if(unquoted&&rpseudo.test(unquoted)&&(excess=tokenize(unquoted,true))&&(excess=unquoted.indexOf(")",unquoted.length-excess)-unquoted.length)){match[0]=match[0].slice(0,excess);match[2]=unquoted.slice(0,excess)}}return match.slice(0,3)}},filter:{TAG:function(nodeNameSelector){var nodeName=nodeNameSelector.replace(runescape,funescape).toLowerCase();return nodeNameSelector==="*"?function(){return true}:function(elem){return elem.nodeName&&elem.nodeName.toLowerCase()===nodeName}},CLASS:function(className){var pattern=classCache[className+" "];return pattern||(pattern=new RegExp("(^|"+whitespace+")"+className+"("+whitespace+"|$)"))&&classCache(className,function(elem){return pattern.test(typeof elem.className==="string"&&elem.className||typeof elem.getAttribute!==strundefined&&elem.getAttribute("class")||"")})},ATTR:function(name,operator,check){return function(elem){var result=Sizzle.attr(elem,name);if(result==null){return operator==="!="}if(!operator){return true}result+="";return operator==="="?result===check:operator==="!="?result!==check:operator==="^="?check&&result.indexOf(check)===0:operator==="*="?check&&result.indexOf(check)>-1:operator==="$="?check&&result.slice(-check.length)===check:operator==="~="?(" "+result+" ").indexOf(check)>-1:operator==="|="?result===check||result.slice(0,check.length+1)===check+"-":false}},CHILD:function(type,what,argument,first,last){var simple=type.slice(0,3)!=="nth",forward=type.slice(-4)!=="last",ofType=what==="of-type";return first===1&&last===0?function(elem){return !!elem.parentNode}:function(elem,context,xml){var cache,outerCache,node,diff,nodeIndex,start,dir=simple!==forward?"nextSibling":"previousSibling",parent=elem.parentNode,name=ofType&&elem.nodeName.toLowerCase(),useCache=!xml&&!ofType;if(parent){if(simple){while(dir){node=elem;while((node=node[dir])){if(ofType?node.nodeName.toLowerCase()===name:node.nodeType===1){return false}}start=dir=type==="only"&&!start&&"nextSibling"}return true}start=[forward?parent.firstChild:parent.lastChild];if(forward&&useCache){outerCache=parent[expando]||(parent[expando]={});cache=outerCache[type]||[];nodeIndex=cache[0]===dirruns&&cache[1];diff=cache[0]===dirruns&&cache[2];node=nodeIndex&&parent.childNodes[nodeIndex];while((node=++nodeIndex&&node&&node[dir]||(diff=nodeIndex=0)||start.pop())){if(node.nodeType===1&&++diff&&node===elem){outerCache[type]=[dirruns,nodeIndex,diff];break}}}else{if(useCache&&(cache=(elem[expando]||(elem[expando]={}))[type])&&cache[0]===dirruns){diff=cache[1]}else{while((node=++nodeIndex&&node&&node[dir]||(diff=nodeIndex=0)||start.pop())){if((ofType?node.nodeName.toLowerCase()===name:node.nodeType===1)&&++diff){if(useCache){(node[expando]||(node[expando]={}))[type]=[dirruns,diff]}if(node===elem){break}}}}}diff-=last;return diff===first||(diff%first===0&&diff/first>=0)}}},PSEUDO:function(pseudo,argument){var args,fn=Expr.pseudos[pseudo]||Expr.setFilters[pseudo.toLowerCase()]||Sizzle.error("unsupported pseudo: "+pseudo);if(fn[expando]){return fn(argument)}if(fn.length>1){args=[pseudo,pseudo,"",argument];return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase())?markFunction(function(seed,matches){var idx,matched=fn(seed,argument),i=matched.length;while(i--){idx=indexOf.call(seed,matched[i]);seed[idx]=!(matches[idx]=matched[i])}}):function(elem){return fn(elem,0,args)}}return fn}},pseudos:{not:markFunction(function(selector){var input=[],results=[],matcher=compile(selector.replace(rtrim,"$1"));return matcher[expando]?markFunction(function(seed,matches,context,xml){var elem,unmatched=matcher(seed,null,xml,[]),i=seed.length;while(i--){if((elem=unmatched[i])){seed[i]=!(matches[i]=elem)}}}):function(elem,context,xml){input[0]=elem;matcher(input,null,xml,results);return !results.pop()}}),has:markFunction(function(selector){return function(elem){return Sizzle(selector,elem).length>0}}),contains:markFunction(function(text){return function(elem){return(elem.textContent||elem.innerText||getText(elem)).indexOf(text)>-1}}),lang:markFunction(function(lang){if(!ridentifier.test(lang||"")){Sizzle.error("unsupported lang: "+lang)}lang=lang.replace(runescape,funescape).toLowerCase();return function(elem){var elemLang;do{if((elemLang=documentIsHTML?elem.lang:elem.getAttribute("xml:lang")||elem.getAttribute("lang"))){elemLang=elemLang.toLowerCase();return elemLang===lang||elemLang.indexOf(lang+"-")===0}}while((elem=elem.parentNode)&&elem.nodeType===1);return false}}),target:function(elem){var hash=window.location&&window.location.hash;return hash&&hash.slice(1)===elem.id},root:function(elem){return elem===docElem},focus:function(elem){return elem===document.activeElement&&(!document.hasFocus||document.hasFocus())&&!!(elem.type||elem.href||~elem.tabIndex)},enabled:function(elem){return elem.disabled===false},disabled:function(elem){return elem.disabled===true},checked:function(elem){var nodeName=elem.nodeName.toLowerCase();return(nodeName==="input"&&!!elem.checked)||(nodeName==="option"&&!!elem.selected)},selected:function(elem){if(elem.parentNode){elem.parentNode.selectedIndex}return elem.selected===true},empty:function(elem){for(elem=elem.firstChild;elem;elem=elem.nextSibling){if(elem.nodeName>"@"||elem.nodeType===3||elem.nodeType===4){return false}}return true},parent:function(elem){return !Expr.pseudos.empty(elem)},header:function(elem){return rheader.test(elem.nodeName)},input:function(elem){return rinputs.test(elem.nodeName)},button:function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type==="button"||name==="button"},text:function(elem){var attr;return elem.nodeName.toLowerCase()==="input"&&elem.type==="text"&&((attr=elem.getAttribute("type"))==null||attr.toLowerCase()===elem.type)},first:createPositionalPseudo(function(){return[0]}),last:createPositionalPseudo(function(matchIndexes,length){return[length-1]}),eq:createPositionalPseudo(function(matchIndexes,length,argument){return[argument<0?argument+length:argument]}),even:createPositionalPseudo(function(matchIndexes,length){var i=0;for(;i=0;){matchIndexes.push(i)}return matchIndexes}),gt:createPositionalPseudo(function(matchIndexes,length,argument){var i=argument<0?argument+length:argument;for(;++i1?function(elem,context,xml){var i=matchers.length;while(i--){if(!matchers[i](elem,context,xml)){return false}}return true}:matchers[0]}function condense(unmatched,map,filter,context,xml){var elem,newUnmatched=[],i=0,len=unmatched.length,mapped=map!=null;for(;i-1){seed[temp]=!(results[temp]=elem)}}}}else{matcherOut=condense(matcherOut===results?matcherOut.splice(preexisting,matcherOut.length):matcherOut);if(postFinder){postFinder(null,results,matcherOut,xml)}else{push.apply(results,matcherOut)}}})}function matcherFromTokens(tokens){var checkContext,matcher,j,len=tokens.length,leadingRelative=Expr.relative[tokens[0].type],implicitRelative=leadingRelative||Expr.relative[" "],i=leadingRelative?1:0,matchContext=addCombinator(function(elem){return elem===checkContext},implicitRelative,true),matchAnyContext=addCombinator(function(elem){return indexOf.call(checkContext,elem)>-1},implicitRelative,true),matchers=[function(elem,context,xml){return(!leadingRelative&&(xml||context!==outermostContext))||((checkContext=context).nodeType?matchContext(elem,context,xml):matchAnyContext(elem,context,xml))}];for(;i1&&elementMatcher(matchers),i>1&&toSelector(tokens.slice(0,i-1).concat({value:tokens[i-2].type===" "?"*":""})).replace(rtrim,"$1"),matcher,i0,byElement=elementMatchers.length>0,superMatcher=function(seed,context,xml,results,expandContext){var elem,j,matcher,setMatched=[],matchedCount=0,i="0",unmatched=seed&&[],outermost=expandContext!=null,contextBackup=outermostContext,elems=seed||byElement&&Expr.find.TAG("*",expandContext&&context.parentNode||context),dirrunsUnique=(dirruns+=contextBackup==null?1:Math.random()||0.1);if(outermost){outermostContext=context!==document&&context;cachedruns=matcherCachedRuns}for(;(elem=elems[i])!=null;i++){if(byElement&&elem){j=0;while((matcher=elementMatchers[j++])){if(matcher(elem,context,xml)){results.push(elem);break}}if(outermost){dirruns=dirrunsUnique;cachedruns=++matcherCachedRuns}}if(bySet){if((elem=!matcher&&elem)){matchedCount--}if(seed){unmatched.push(elem)}}}matchedCount+=i;if(bySet&&i!==matchedCount){j=0;while((matcher=setMatchers[j++])){matcher(unmatched,setMatched,context,xml)}if(seed){if(matchedCount>0){while(i--){if(!(unmatched[i]||setMatched[i])){setMatched[i]=pop.call(results)}}}setMatched=condense(setMatched)}push.apply(results,setMatched);if(outermost&&!seed&&setMatched.length>0&&(matchedCount+setMatchers.length)>1){Sizzle.uniqueSort(results)}}if(outermost){dirruns=dirrunsUnique;outermostContext=contextBackup}return unmatched};return bySet?markFunction(superMatcher):superMatcher}compile=Sizzle.compile=function(selector,group){var i,setMatchers=[],elementMatchers=[],cached=compilerCache[selector+" "];if(!cached){if(!group){group=tokenize(selector)}i=group.length;while(i--){cached=matcherFromTokens(group[i]);if(cached[expando]){setMatchers.push(cached)}else{elementMatchers.push(cached)}}cached=compilerCache(selector,matcherFromGroupMatchers(elementMatchers,setMatchers))}return cached};function multipleContexts(selector,contexts,results){var i=0,len=contexts.length;for(;i2&&(token=tokens[0]).type==="ID"&&support.getById&&context.nodeType===9&&documentIsHTML&&Expr.relative[tokens[1].type]){context=(Expr.find.ID(token.matches[0].replace(runescape,funescape),context)||[])[0];if(!context){return results}selector=selector.slice(tokens.shift().value.length)}i=matchExpr.needsContext.test(selector)?0:tokens.length;while(i--){token=tokens[i];if(Expr.relative[(type=token.type)]){break}if((find=Expr.find[type])){if((seed=find(token.matches[0].replace(runescape,funescape),rsibling.test(tokens[0].type)&&context.parentNode||context))){tokens.splice(i,1);selector=seed.length&&toSelector(tokens);if(!selector){push.apply(results,seed);return results}break}}}}}compile(selector,match)(seed,context,!documentIsHTML,results,rsibling.test(selector));return results}support.sortStable=expando.split("").sort(sortOrder).join("")===expando;support.detectDuplicates=hasDuplicate;setDocument();support.sortDetached=assert(function(div1){return div1.compareDocumentPosition(document.createElement("div"))&1});if(!assert(function(div){div.innerHTML="";return div.firstChild.getAttribute("href")==="#"})){addHandle("type|href|height|width",function(elem,name,isXML){if(!isXML){return elem.getAttribute(name,name.toLowerCase()==="type"?1:2)}})}if(!support.attributes||!assert(function(div){div.innerHTML="";div.firstChild.setAttribute("value","");return div.firstChild.getAttribute("value")===""})){addHandle("value",function(elem,name,isXML){if(!isXML&&elem.nodeName.toLowerCase()==="input"){return elem.defaultValue}})}if(!assert(function(div){return div.getAttribute("disabled")==null})){addHandle(booleans,function(elem,name,isXML){var val;if(!isXML){return(val=elem.getAttributeNode(name))&&val.specified?val.value:elem[name]===true?name.toLowerCase():null}})}jQuery.find=Sizzle;jQuery.expr=Sizzle.selectors;jQuery.expr[":"]=jQuery.expr.pseudos;jQuery.unique=Sizzle.uniqueSort;jQuery.text=Sizzle.getText;jQuery.isXMLDoc=Sizzle.isXML;jQuery.contains=Sizzle.contains})(window);var optionsCache={};function createOptions(options){var object=optionsCache[options]={};jQuery.each(options.match(core_rnotwhite)||[],function(_,flag){object[flag]=true});return object}jQuery.Callbacks=function(options){options=typeof options==="string"?(optionsCache[options]||createOptions(options)):jQuery.extend({},options);var memory,fired,firing,firingStart,firingLength,firingIndex,list=[],stack=!options.once&&[],fire=function(data){memory=options.memory&&data;fired=true;firingIndex=firingStart||0;firingStart=0;firingLength=list.length;firing=true;for(;list&&firingIndex-1){list.splice(index,1);if(firing){if(index<=firingLength){firingLength--}if(index<=firingIndex){firingIndex--}}}})}return this},has:function(fn){return fn?jQuery.inArray(fn,list)>-1:!!(list&&list.length)},empty:function(){list=[];firingLength=0;return this},disable:function(){list=stack=memory=undefined;return this},disabled:function(){return !list},lock:function(){stack=undefined;if(!memory){self.disable()}return this},locked:function(){return !stack},fireWith:function(context,args){if(list&&(!fired||stack)){args=args||[];args=[context,args.slice?args.slice():args];if(firing){stack.push(args)}else{fire(args)}}return this},fire:function(){self.fireWith(this,arguments);return this},fired:function(){return !!fired}};return self};jQuery.extend({Deferred:function(func){var tuples=[["resolve","done",jQuery.Callbacks("once memory"),"resolved"],["reject","fail",jQuery.Callbacks("once memory"),"rejected"],["notify","progress",jQuery.Callbacks("memory")]],state="pending",promise={state:function(){return state},always:function(){deferred.done(arguments).fail(arguments);return this},then:function(){var fns=arguments;return jQuery.Deferred(function(newDefer){jQuery.each(tuples,function(i,tuple){var action=tuple[0],fn=jQuery.isFunction(fns[i])&&fns[i];deferred[tuple[1]](function(){var returned=fn&&fn.apply(this,arguments);if(returned&&jQuery.isFunction(returned.promise)){returned.promise().done(newDefer.resolve).fail(newDefer.reject).progress(newDefer.notify)}else{newDefer[action+"With"](this===promise?newDefer.promise():this,fn?[returned]:arguments)}})});fns=null}).promise()},promise:function(obj){return obj!=null?jQuery.extend(obj,promise):promise}},deferred={};promise.pipe=promise.then;jQuery.each(tuples,function(i,tuple){var list=tuple[2],stateString=tuple[3];promise[tuple[1]]=list.add;if(stateString){list.add(function(){state=stateString},tuples[i^1][2].disable,tuples[2][2].lock)}deferred[tuple[0]]=function(){deferred[tuple[0]+"With"](this===deferred?promise:this,arguments);return this};deferred[tuple[0]+"With"]=list.fireWith});promise.promise(deferred);if(func){func.call(deferred,deferred)}return deferred},when:function(subordinate){var i=0,resolveValues=core_slice.call(arguments),length=resolveValues.length,remaining=length!==1||(subordinate&&jQuery.isFunction(subordinate.promise))?length:0,deferred=remaining===1?subordinate:jQuery.Deferred(),updateFunc=function(i,contexts,values){return function(value){contexts[i]=this;values[i]=arguments.length>1?core_slice.call(arguments):value;if(values===progressValues){deferred.notifyWith(contexts,values)}else{if(!(--remaining)){deferred.resolveWith(contexts,values)}}}},progressValues,progressContexts,resolveContexts;if(length>1){progressValues=new Array(length);progressContexts=new Array(length);resolveContexts=new Array(length);for(;i1,null,true)},removeData:function(key){return this.each(function(){data_user.remove(this,key)})}});function dataAttr(elem,key,data){var name;if(data===undefined&&elem.nodeType===1){name="data-"+key.replace(rmultiDash,"-$1").toLowerCase();data=elem.getAttribute(name);if(typeof data==="string"){try{data=data==="true"?true:data==="false"?false:data==="null"?null:+data+""===data?+data:rbrace.test(data)?JSON.parse(data):data}catch(e){}data_user.set(elem,key,data)}else{data=undefined}}return data}jQuery.extend({queue:function(elem,type,data){var queue;if(elem){type=(type||"fx")+"queue";queue=data_priv.get(elem,type);if(data){if(!queue||jQuery.isArray(data)){queue=data_priv.access(elem,type,jQuery.makeArray(data))}else{queue.push(data)}}return queue||[]}},dequeue:function(elem,type){type=type||"fx";var queue=jQuery.queue(elem,type),startLength=queue.length,fn=queue.shift(),hooks=jQuery._queueHooks(elem,type),next=function(){jQuery.dequeue(elem,type)};if(fn==="inprogress"){fn=queue.shift();startLength--}if(fn){if(type==="fx"){queue.unshift("inprogress")}delete hooks.stop;fn.call(elem,next,hooks)}if(!startLength&&hooks){hooks.empty.fire()}},_queueHooks:function(elem,type){var key=type+"queueHooks";return data_priv.get(elem,key)||data_priv.access(elem,key,{empty:jQuery.Callbacks("once memory").add(function(){data_priv.remove(elem,[type+"queue",key])})})}});jQuery.fn.extend({queue:function(type,data){var setter=2;if(typeof type!=="string"){data=type;type="fx";setter--}if(arguments.length1)},removeAttr:function(name){return this.each(function(){jQuery.removeAttr(this,name)})},prop:function(name,value){return jQuery.access(this,jQuery.prop,name,value,arguments.length>1)},removeProp:function(name){return this.each(function(){delete this[jQuery.propFix[name]||name]})},addClass:function(value){var classes,elem,cur,clazz,j,i=0,len=this.length,proceed=typeof value==="string"&&value;if(jQuery.isFunction(value)){return this.each(function(j){jQuery(this).addClass(value.call(this,j,this.className))})}if(proceed){classes=(value||"").match(core_rnotwhite)||[];for(;i=0){cur=cur.replace(" "+clazz+" "," ")}}elem.className=value?jQuery.trim(cur):""}}}return this},toggleClass:function(value,stateVal){var type=typeof value;if(typeof stateVal==="boolean"&&type==="string"){return stateVal?this.addClass(value):this.removeClass(value)}if(jQuery.isFunction(value)){return this.each(function(i){jQuery(this).toggleClass(value.call(this,i,this.className,stateVal),stateVal)})}return this.each(function(){if(type==="string"){var className,i=0,self=jQuery(this),classNames=value.match(core_rnotwhite)||[];while((className=classNames[i++])){if(self.hasClass(className)){self.removeClass(className)}else{self.addClass(className)}}}else{if(type===core_strundefined||type==="boolean"){if(this.className){data_priv.set(this,"__className__",this.className)}this.className=this.className||value===false?"":data_priv.get(this,"__className__")||""}}})},hasClass:function(selector){var className=" "+selector+" ",i=0,l=this.length;for(;i=0){return true}}return false},val:function(value){var hooks,ret,isFunction,elem=this[0];if(!arguments.length){if(elem){hooks=jQuery.valHooks[elem.type]||jQuery.valHooks[elem.nodeName.toLowerCase()];if(hooks&&"get" in hooks&&(ret=hooks.get(elem,"value"))!==undefined){return ret}ret=elem.value;return typeof ret==="string"?ret.replace(rreturn,""):ret==null?"":ret}return}isFunction=jQuery.isFunction(value);return this.each(function(i){var val;if(this.nodeType!==1){return}if(isFunction){val=value.call(this,i,jQuery(this).val())}else{val=value}if(val==null){val=""}else{if(typeof val==="number"){val+=""}else{if(jQuery.isArray(val)){val=jQuery.map(val,function(value){return value==null?"":value+""})}}}hooks=jQuery.valHooks[this.type]||jQuery.valHooks[this.nodeName.toLowerCase()];if(!hooks||!("set" in hooks)||hooks.set(this,val,"value")===undefined){this.value=val}})}});jQuery.extend({valHooks:{option:{get:function(elem){var val=elem.attributes.value;return !val||val.specified?elem.value:elem.text}},select:{get:function(elem){var value,option,options=elem.options,index=elem.selectedIndex,one=elem.type==="select-one"||index<0,values=one?null:[],max=one?index+1:options.length,i=index<0?max:one?index:0;for(;i=0)){optionSet=true}}if(!optionSet){elem.selectedIndex=-1}return values}}},attr:function(elem,name,value){var hooks,ret,nType=elem.nodeType;if(!elem||nType===3||nType===8||nType===2){return}if(typeof elem.getAttribute===core_strundefined){return jQuery.prop(elem,name,value)}if(nType!==1||!jQuery.isXMLDoc(elem)){name=name.toLowerCase();hooks=jQuery.attrHooks[name]||(jQuery.expr.match.bool.test(name)?boolHook:nodeHook)}if(value!==undefined){if(value===null){jQuery.removeAttr(elem,name)}else{if(hooks&&"set" in hooks&&(ret=hooks.set(elem,value,name))!==undefined){return ret}else{elem.setAttribute(name,value+"");return value}}}else{if(hooks&&"get" in hooks&&(ret=hooks.get(elem,name))!==null){return ret}else{ret=jQuery.find.attr(elem,name);return ret==null?undefined:ret}}},removeAttr:function(elem,value){var name,propName,i=0,attrNames=value&&value.match(core_rnotwhite);if(attrNames&&elem.nodeType===1){while((name=attrNames[i++])){propName=jQuery.propFix[name]||name;if(jQuery.expr.match.bool.test(name)){elem[propName]=false}elem.removeAttribute(name)}}},attrHooks:{type:{set:function(elem,value){if(!jQuery.support.radioValue&&value==="radio"&&jQuery.nodeName(elem,"input")){var val=elem.value;elem.setAttribute("type",value);if(val){elem.value=val}return value}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(elem,name,value){var ret,hooks,notxml,nType=elem.nodeType;if(!elem||nType===3||nType===8||nType===2){return}notxml=nType!==1||!jQuery.isXMLDoc(elem);if(notxml){name=jQuery.propFix[name]||name;hooks=jQuery.propHooks[name]}if(value!==undefined){return hooks&&"set" in hooks&&(ret=hooks.set(elem,value,name))!==undefined?ret:(elem[name]=value)}else{return hooks&&"get" in hooks&&(ret=hooks.get(elem,name))!==null?ret:elem[name]}},propHooks:{tabIndex:{get:function(elem){return elem.hasAttribute("tabindex")||rfocusable.test(elem.nodeName)||elem.href?elem.tabIndex:-1}}}});boolHook={set:function(elem,value,name){if(value===false){jQuery.removeAttr(elem,name)}else{elem.setAttribute(name,name)}return name}};jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g),function(i,name){var getter=jQuery.expr.attrHandle[name]||jQuery.find.attr;jQuery.expr.attrHandle[name]=function(elem,name,isXML){var fn=jQuery.expr.attrHandle[name],ret=isXML?undefined:(jQuery.expr.attrHandle[name]=undefined)!=getter(elem,name,isXML)?name.toLowerCase():null;jQuery.expr.attrHandle[name]=fn;return ret}});if(!jQuery.support.optSelected){jQuery.propHooks.selected={get:function(elem){var parent=elem.parentNode;if(parent&&parent.parentNode){parent.parentNode.selectedIndex}return null}}}jQuery.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){jQuery.propFix[this.toLowerCase()]=this});jQuery.each(["radio","checkbox"],function(){jQuery.valHooks[this]={set:function(elem,value){if(jQuery.isArray(value)){return(elem.checked=jQuery.inArray(jQuery(elem).val(),value)>=0)}}};if(!jQuery.support.checkOn){jQuery.valHooks[this].get=function(elem){return elem.getAttribute("value")===null?"on":elem.value}}});var rkeyEvent=/^key/,rmouseEvent=/^(?:mouse|contextmenu)|click/,rfocusMorph=/^(?:focusinfocus|focusoutblur)$/,rtypenamespace=/^([^.]*)(?:\.(.+)|)$/;function returnTrue(){return true}function returnFalse(){return false}function safeActiveElement(){try{return document.activeElement}catch(err){}}jQuery.event={global:{},add:function(elem,types,handler,data,selector){var handleObjIn,eventHandle,tmp,events,t,handleObj,special,handlers,type,namespaces,origType,elemData=data_priv.get(elem);if(!elemData){return}if(handler.handler){handleObjIn=handler;handler=handleObjIn.handler;selector=handleObjIn.selector}if(!handler.guid){handler.guid=jQuery.guid++}if(!(events=elemData.events)){events=elemData.events={}}if(!(eventHandle=elemData.handle)){eventHandle=elemData.handle=function(e){return typeof jQuery!==core_strundefined&&(!e||jQuery.event.triggered!==e.type)?jQuery.event.dispatch.apply(eventHandle.elem,arguments):undefined};eventHandle.elem=elem}types=(types||"").match(core_rnotwhite)||[""];t=types.length;while(t--){tmp=rtypenamespace.exec(types[t])||[];type=origType=tmp[1];namespaces=(tmp[2]||"").split(".").sort();if(!type){continue}special=jQuery.event.special[type]||{};type=(selector?special.delegateType:special.bindType)||type;special=jQuery.event.special[type]||{};handleObj=jQuery.extend({type:type,origType:origType,data:data,handler:handler,guid:handler.guid,selector:selector,needsContext:selector&&jQuery.expr.match.needsContext.test(selector),namespace:namespaces.join(".")},handleObjIn);if(!(handlers=events[type])){handlers=events[type]=[];handlers.delegateCount=0;if(!special.setup||special.setup.call(elem,data,namespaces,eventHandle)===false){if(elem.addEventListener){elem.addEventListener(type,eventHandle,false)}}}if(special.add){special.add.call(elem,handleObj);if(!handleObj.handler.guid){handleObj.handler.guid=handler.guid}}if(selector){handlers.splice(handlers.delegateCount++,0,handleObj)}else{handlers.push(handleObj)}jQuery.event.global[type]=true}elem=null},remove:function(elem,types,handler,selector,mappedTypes){var j,origCount,tmp,events,t,handleObj,special,handlers,type,namespaces,origType,elemData=data_priv.hasData(elem)&&data_priv.get(elem);if(!elemData||!(events=elemData.events)){return}types=(types||"").match(core_rnotwhite)||[""];t=types.length;while(t--){tmp=rtypenamespace.exec(types[t])||[];type=origType=tmp[1];namespaces=(tmp[2]||"").split(".").sort();if(!type){for(type in events){jQuery.event.remove(elem,type+types[t],handler,selector,true)}continue}special=jQuery.event.special[type]||{};type=(selector?special.delegateType:special.bindType)||type;handlers=events[type]||[];tmp=tmp[2]&&new RegExp("(^|\\.)"+namespaces.join("\\.(?:.*\\.|)")+"(\\.|$)");origCount=j=handlers.length;while(j--){handleObj=handlers[j];if((mappedTypes||origType===handleObj.origType)&&(!handler||handler.guid===handleObj.guid)&&(!tmp||tmp.test(handleObj.namespace))&&(!selector||selector===handleObj.selector||selector==="**"&&handleObj.selector)){handlers.splice(j,1);if(handleObj.selector){handlers.delegateCount--}if(special.remove){special.remove.call(elem,handleObj)}}}if(origCount&&!handlers.length){if(!special.teardown||special.teardown.call(elem,namespaces,elemData.handle)===false){jQuery.removeEvent(elem,type,elemData.handle)}delete events[type]}}if(jQuery.isEmptyObject(events)){delete elemData.handle;data_priv.remove(elem,"events")}},trigger:function(event,data,elem,onlyHandlers){var i,cur,tmp,bubbleType,ontype,handle,special,eventPath=[elem||document],type=core_hasOwn.call(event,"type")?event.type:event,namespaces=core_hasOwn.call(event,"namespace")?event.namespace.split("."):[];cur=tmp=elem=elem||document;if(elem.nodeType===3||elem.nodeType===8){return}if(rfocusMorph.test(type+jQuery.event.triggered)){return}if(type.indexOf(".")>=0){namespaces=type.split(".");type=namespaces.shift();namespaces.sort()}ontype=type.indexOf(":")<0&&"on"+type;event=event[jQuery.expando]?event:new jQuery.Event(type,typeof event==="object"&&event);event.isTrigger=onlyHandlers?2:3;event.namespace=namespaces.join(".");event.namespace_re=event.namespace?new RegExp("(^|\\.)"+namespaces.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;event.result=undefined;if(!event.target){event.target=elem}data=data==null?[event]:jQuery.makeArray(data,[event]);special=jQuery.event.special[type]||{};if(!onlyHandlers&&special.trigger&&special.trigger.apply(elem,data)===false){return}if(!onlyHandlers&&!special.noBubble&&!jQuery.isWindow(elem)){bubbleType=special.delegateType||type;if(!rfocusMorph.test(bubbleType+type)){cur=cur.parentNode}for(;cur;cur=cur.parentNode){eventPath.push(cur);tmp=cur}if(tmp===(elem.ownerDocument||document)){eventPath.push(tmp.defaultView||tmp.parentWindow||window)}}i=0;while((cur=eventPath[i++])&&!event.isPropagationStopped()){event.type=i>1?bubbleType:special.bindType||type;handle=(data_priv.get(cur,"events")||{})[event.type]&&data_priv.get(cur,"handle");if(handle){handle.apply(cur,data)}handle=ontype&&cur[ontype];if(handle&&jQuery.acceptData(cur)&&handle.apply&&handle.apply(cur,data)===false){event.preventDefault()}}event.type=type;if(!onlyHandlers&&!event.isDefaultPrevented()){if((!special._default||special._default.apply(eventPath.pop(),data)===false)&&jQuery.acceptData(elem)){if(ontype&&jQuery.isFunction(elem[type])&&!jQuery.isWindow(elem)){tmp=elem[ontype];if(tmp){elem[ontype]=null}jQuery.event.triggered=type;elem[type]();jQuery.event.triggered=undefined;if(tmp){elem[ontype]=tmp}}}}return event.result},dispatch:function(event){event=jQuery.event.fix(event);var i,j,ret,matched,handleObj,handlerQueue=[],args=core_slice.call(arguments),handlers=(data_priv.get(this,"events")||{})[event.type]||[],special=jQuery.event.special[event.type]||{};args[0]=event;event.delegateTarget=this;if(special.preDispatch&&special.preDispatch.call(this,event)===false){return}handlerQueue=jQuery.event.handlers.call(this,event,handlers);i=0;while((matched=handlerQueue[i++])&&!event.isPropagationStopped()){event.currentTarget=matched.elem;j=0;while((handleObj=matched.handlers[j++])&&!event.isImmediatePropagationStopped()){if(!event.namespace_re||event.namespace_re.test(handleObj.namespace)){event.handleObj=handleObj;event.data=handleObj.data;ret=((jQuery.event.special[handleObj.origType]||{}).handle||handleObj.handler).apply(matched.elem,args);if(ret!==undefined){if((event.result=ret)===false){event.preventDefault();event.stopPropagation()}}}}}if(special.postDispatch){special.postDispatch.call(this,event)}return event.result},handlers:function(event,handlers){var i,matches,sel,handleObj,handlerQueue=[],delegateCount=handlers.delegateCount,cur=event.target;if(delegateCount&&cur.nodeType&&(!event.button||event.type!=="click")){for(;cur!==this;cur=cur.parentNode||this){if(cur.disabled!==true||event.type!=="click"){matches=[];for(i=0;i=0:jQuery.find(sel,this,null,[cur]).length}if(matches[sel]){matches.push(handleObj)}}if(matches.length){handlerQueue.push({elem:cur,handlers:matches})}}}}if(delegateCount1?jQuery.unique(ret):ret);ret.selector=this.selector?this.selector+" "+selector:selector;return ret},has:function(target){var targets=jQuery(target,this),l=targets.length;return this.filter(function(){var i=0;for(;i-1:cur.nodeType===1&&jQuery.find.matchesSelector(cur,selectors))){cur=matched.push(cur);break}}}return this.pushStack(matched.length>1?jQuery.unique(matched):matched)},index:function(elem){if(!elem){return(this[0]&&this[0].parentNode)?this.first().prevAll().length:-1}if(typeof elem==="string"){return core_indexOf.call(jQuery(elem),this[0])}return core_indexOf.call(this,elem.jquery?elem[0]:elem)},add:function(selector,context){var set=typeof selector==="string"?jQuery(selector,context):jQuery.makeArray(selector&&selector.nodeType?[selector]:selector),all=jQuery.merge(this.get(),set);return this.pushStack(jQuery.unique(all))},addBack:function(selector){return this.add(selector==null?this.prevObject:this.prevObject.filter(selector))}});function sibling(cur,dir){while((cur=cur[dir])&&cur.nodeType!==1){}return cur}jQuery.each({parent:function(elem){var parent=elem.parentNode;return parent&&parent.nodeType!==11?parent:null},parents:function(elem){return jQuery.dir(elem,"parentNode")},parentsUntil:function(elem,i,until){return jQuery.dir(elem,"parentNode",until)},next:function(elem){return sibling(elem,"nextSibling")},prev:function(elem){return sibling(elem,"previousSibling")},nextAll:function(elem){return jQuery.dir(elem,"nextSibling")},prevAll:function(elem){return jQuery.dir(elem,"previousSibling")},nextUntil:function(elem,i,until){return jQuery.dir(elem,"nextSibling",until)},prevUntil:function(elem,i,until){return jQuery.dir(elem,"previousSibling",until)},siblings:function(elem){return jQuery.sibling((elem.parentNode||{}).firstChild,elem)},children:function(elem){return jQuery.sibling(elem.firstChild)},contents:function(elem){return elem.contentDocument||jQuery.merge([],elem.childNodes)}},function(name,fn){jQuery.fn[name]=function(until,selector){var matched=jQuery.map(this,fn,until);if(name.slice(-5)!=="Until"){selector=until}if(selector&&typeof selector==="string"){matched=jQuery.filter(selector,matched)}if(this.length>1){if(!guaranteedUnique[name]){jQuery.unique(matched)}if(rparentsprev.test(name)){matched.reverse()}}return this.pushStack(matched)}});jQuery.extend({filter:function(expr,elems,not){var elem=elems[0];if(not){expr=":not("+expr+")"}return elems.length===1&&elem.nodeType===1?jQuery.find.matchesSelector(elem,expr)?[elem]:[]:jQuery.find.matches(expr,jQuery.grep(elems,function(elem){return elem.nodeType===1}))},dir:function(elem,dir,until){var matched=[],truncate=until!==undefined;while((elem=elem[dir])&&elem.nodeType!==9){if(elem.nodeType===1){if(truncate&&jQuery(elem).is(until)){break}matched.push(elem)}}return matched},sibling:function(n,elem){var matched=[];for(;n;n=n.nextSibling){if(n.nodeType===1&&n!==elem){matched.push(n)}}return matched}});function winnow(elements,qualifier,not){if(jQuery.isFunction(qualifier)){return jQuery.grep(elements,function(elem,i){return !!qualifier.call(elem,i,elem)!==not})}if(qualifier.nodeType){return jQuery.grep(elements,function(elem){return(elem===qualifier)!==not})}if(typeof qualifier==="string"){if(isSimple.test(qualifier)){return jQuery.filter(qualifier,elements,not)}qualifier=jQuery.filter(qualifier,elements)}return jQuery.grep(elements,function(elem){return(core_indexOf.call(qualifier,elem)>=0)!==not})}var rxhtmlTag=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,rtagName=/<([\w:]+)/,rhtml=/<|&#?\w+;/,rnoInnerhtml=/<(?:script|style|link)/i,manipulation_rcheckableType=/^(?:checkbox|radio)$/i,rchecked=/checked\s*(?:[^=]|=\s*.checked.)/i,rscriptType=/^$|\/(?:java|ecma)script/i,rscriptTypeMasked=/^true\/(.*)/,rcleanScript=/^\s*\s*$/g,wrapMap={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};wrapMap.optgroup=wrapMap.option;wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;jQuery.fn.extend({text:function(value){return jQuery.access(this,function(value){return value===undefined?jQuery.text(this):this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(value))},null,value,arguments.length)},append:function(){return this.domManip(arguments,function(elem){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var target=manipulationTarget(this,elem);target.appendChild(elem)}})},prepend:function(){return this.domManip(arguments,function(elem){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var target=manipulationTarget(this,elem);target.insertBefore(elem,target.firstChild)}})},before:function(){return this.domManip(arguments,function(elem){if(this.parentNode){this.parentNode.insertBefore(elem,this)}})},after:function(){return this.domManip(arguments,function(elem){if(this.parentNode){this.parentNode.insertBefore(elem,this.nextSibling)}})},remove:function(selector,keepData){var elem,elems=selector?jQuery.filter(selector,this):this,i=0;for(;(elem=elems[i])!=null;i++){if(!keepData&&elem.nodeType===1){jQuery.cleanData(getAll(elem))}if(elem.parentNode){if(keepData&&jQuery.contains(elem.ownerDocument,elem)){setGlobalEval(getAll(elem,"script"))}elem.parentNode.removeChild(elem)}}return this},empty:function(){var elem,i=0;for(;(elem=this[i])!=null;i++){if(elem.nodeType===1){jQuery.cleanData(getAll(elem,false));elem.textContent=""}}return this},clone:function(dataAndEvents,deepDataAndEvents){dataAndEvents=dataAndEvents==null?false:dataAndEvents;deepDataAndEvents=deepDataAndEvents==null?dataAndEvents:deepDataAndEvents;return this.map(function(){return jQuery.clone(this,dataAndEvents,deepDataAndEvents)})},html:function(value){return jQuery.access(this,function(value){var elem=this[0]||{},i=0,l=this.length;if(value===undefined&&elem.nodeType===1){return elem.innerHTML}if(typeof value==="string"&&!rnoInnerhtml.test(value)&&!wrapMap[(rtagName.exec(value)||["",""])[1].toLowerCase()]){value=value.replace(rxhtmlTag,"<$1>");try{for(;i0){setGlobalEval(destElements,!inPage&&getAll(elem,"script"))}return clone},buildFragment:function(elems,context,scripts,selection){var elem,tmp,tag,wrap,contains,j,i=0,l=elems.length,fragment=context.createDocumentFragment(),nodes=[];for(;i")+wrap[2];j=wrap[0];while(j--){tmp=tmp.lastChild}jQuery.merge(nodes,tmp.childNodes);tmp=fragment.firstChild;tmp.textContent=""}}}}fragment.textContent="";i=0;while((elem=nodes[i++])){if(selection&&jQuery.inArray(elem,selection)!==-1){continue}contains=jQuery.contains(elem.ownerDocument,elem);tmp=getAll(fragment.appendChild(elem),"script");if(contains){setGlobalEval(tmp)}if(scripts){j=0;while((elem=tmp[j++])){if(rscriptType.test(elem.type||"")){scripts.push(elem)}}}}return fragment},cleanData:function(elems){var data,elem,events,type,key,j,special=jQuery.event.special,i=0;for(;(elem=elems[i])!==undefined;i++){if(Data.accepts(elem)){key=elem[data_priv.expando];if(key&&(data=data_priv.cache[key])){events=Object.keys(data.events||{});if(events.length){for(j=0;(type=events[j])!==undefined;j++){if(special[type]){jQuery.event.remove(elem,type)}else{jQuery.removeEvent(elem,type,data.handle)}}}if(data_priv.cache[key]){delete data_priv.cache[key]}}}delete data_user.cache[elem[data_user.expando]]}},_evalUrl:function(url){return jQuery.ajax({url:url,type:"GET",dataType:"script",async:false,global:false,"throws":true})}});function manipulationTarget(elem,content){return jQuery.nodeName(elem,"table")&&jQuery.nodeName(content.nodeType===1?content:content.firstChild,"tr")?elem.getElementsByTagName("tbody")[0]||elem.appendChild(elem.ownerDocument.createElement("tbody")):elem}function disableScript(elem){elem.type=(elem.getAttribute("type")!==null)+"/"+elem.type;return elem}function restoreScript(elem){var match=rscriptTypeMasked.exec(elem.type);if(match){elem.type=match[1]}else{elem.removeAttribute("type")}return elem}function setGlobalEval(elems,refElements){var l=elems.length,i=0;for(;i1)},show:function(){return showHide(this,true)},hide:function(){return showHide(this)},toggle:function(state){if(typeof state==="boolean"){return state?this.show():this.hide()}return this.each(function(){if(isHidden(this)){jQuery(this).show()}else{jQuery(this).hide()}})}});jQuery.extend({cssHooks:{opacity:{get:function(elem,computed){if(computed){var ret=curCSS(elem,"opacity");return ret===""?"1":ret}}}},cssNumber:{columnCount:true,fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,order:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":"cssFloat"},style:function(elem,name,value,extra){if(!elem||elem.nodeType===3||elem.nodeType===8||!elem.style){return}var ret,type,hooks,origName=jQuery.camelCase(name),style=elem.style;name=jQuery.cssProps[origName]||(jQuery.cssProps[origName]=vendorPropName(style,origName));hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(value!==undefined){type=typeof value;if(type==="string"&&(ret=rrelNum.exec(value))){value=(ret[1]+1)*ret[2]+parseFloat(jQuery.css(elem,name));type="number"}if(value==null||type==="number"&&isNaN(value)){return}if(type==="number"&&!jQuery.cssNumber[origName]){value+="px"}if(!jQuery.support.clearCloneStyle&&value===""&&name.indexOf("background")===0){style[name]="inherit"}if(!hooks||!("set" in hooks)||(value=hooks.set(elem,value,extra))!==undefined){style[name]=value}}else{if(hooks&&"get" in hooks&&(ret=hooks.get(elem,false,extra))!==undefined){return ret}return style[name]}},css:function(elem,name,extra,styles){var val,num,hooks,origName=jQuery.camelCase(name);name=jQuery.cssProps[origName]||(jQuery.cssProps[origName]=vendorPropName(elem.style,origName));hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(hooks&&"get" in hooks){val=hooks.get(elem,true,extra)}if(val===undefined){val=curCSS(elem,name,styles)}if(val==="normal"&&name in cssNormalTransform){val=cssNormalTransform[name]}if(extra===""||extra){num=parseFloat(val);return extra===true||jQuery.isNumeric(num)?num||0:val}return val}});curCSS=function(elem,name,_computed){var width,minWidth,maxWidth,computed=_computed||getStyles(elem),ret=computed?computed.getPropertyValue(name)||computed[name]:undefined,style=elem.style;if(computed){if(ret===""&&!jQuery.contains(elem.ownerDocument,elem)){ret=jQuery.style(elem,name)}if(rnumnonpx.test(ret)&&rmargin.test(name)){width=style.width;minWidth=style.minWidth;maxWidth=style.maxWidth;style.minWidth=style.maxWidth=style.width=ret;ret=computed.width;style.width=width;style.minWidth=minWidth;style.maxWidth=maxWidth}}return ret};function setPositiveNumber(elem,value,subtract){var matches=rnumsplit.exec(value);return matches?Math.max(0,matches[1]-(subtract||0))+(matches[2]||"px"):value}function augmentWidthOrHeight(elem,name,extra,isBorderBox,styles){var i=extra===(isBorderBox?"border":"content")?4:name==="width"?1:0,val=0;for(;i<4;i+=2){if(extra==="margin"){val+=jQuery.css(elem,extra+cssExpand[i],true,styles)}if(isBorderBox){if(extra==="content"){val-=jQuery.css(elem,"padding"+cssExpand[i],true,styles)}if(extra!=="margin"){val-=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles)}}else{val+=jQuery.css(elem,"padding"+cssExpand[i],true,styles);if(extra!=="padding"){val+=jQuery.css(elem,"border"+cssExpand[i]+"Width",true,styles)}}}return val}function getWidthOrHeight(elem,name,extra){var valueIsBorderBox=true,val=name==="width"?elem.offsetWidth:elem.offsetHeight,styles=getStyles(elem),isBorderBox=jQuery.support.boxSizing&&jQuery.css(elem,"boxSizing",false,styles)==="border-box";if(val<=0||val==null){val=curCSS(elem,name,styles);if(val<0||val==null){val=elem.style[name]}if(rnumnonpx.test(val)){return val}valueIsBorderBox=isBorderBox&&(jQuery.support.boxSizingReliable||val===elem.style[name]);val=parseFloat(val)||0}return(val+augmentWidthOrHeight(elem,name,extra||(isBorderBox?"border":"content"),valueIsBorderBox,styles))+"px"}function css_defaultDisplay(nodeName){var doc=document,display=elemdisplay[nodeName];if(!display){display=actualDisplay(nodeName,doc);if(display==="none"||!display){iframe=(iframe||jQuery("').appendTo(document.body);if(h.onUpload){h.onUpload.call(this,k,m)}j(e[m],m)})}})($);(function(a){a.tableDnD={currentTable:null,dragObject:null,mouseOffset:null,oldY:0,build:function(b){b=b||{};this.each(function(){this.tableDnDConfig={onDragStyle:b.onDragStyle,onDropStyle:b.onDropStyle,onDragClass:b.onDragClass?b.onDragClass:"tDnD_whileDrag",onDrop:b.onDrop,onDragStart:b.onDragStart,scrollAmount:b.scrollAmount?b.scrollAmount:5};a.tableDnD.makeDraggable(this);if(0==$("tfoot",this).length&&0<$("thead",this).length){var d=$("thead",this),e=$("th",d).length,i=$('').insertAfter(d),c=$("tr:last",this);if(c.parent().prop("tagName").toLowerCase()!="tfoot"){var j=$("td",c),g=j.height();j.height(g-i.outerHeight())}}});a(document).bind("mousemove",a.tableDnD.mousemove).bind("mouseup",a.tableDnD.mouseup);return this},makeDraggable:function(e){var f=e.rows;var c=e.tableDnDConfig;for(var d=0;da.tableDnD.oldY;a.tableDnD.oldY=g;if(c.onDragClass){e.addClass(c.onDragClass)}else{e.css(c.onDragStyle)}var i=a.tableDnD.findDropTargetRow(e,g);if(i){if(f&&a.tableDnD.dragObject!=i){a.tableDnD.dragObject.parentNode.insertBefore(a.tableDnD.dragObject,i.nextSibling)}else{if(!f&&a.tableDnD.dragObject!=i){a.tableDnD.dragObject.parentNode.insertBefore(a.tableDnD.dragObject,i)}}}}return false},findDropTargetRow:function(g,h){var k=a.tableDnD.currentTable.rows;for(var f=0;fc-b)&&(h<(c+b))){if(j==g){return null}var d=a.tableDnD.currentTable.tableDnDConfig;if(d.onAllowDrop){if(d.onAllowDrop(g,j)){return j}else{return null}}else{var e=$(j).hasClass("nodrop");if(!e){return j}else{return null}}return j}}return null},mouseup:function(d){if(a.tableDnD.currentTable&&a.tableDnD.dragObject){var c=a.tableDnD.dragObject;var b=a.tableDnD.currentTable.tableDnDConfig;if(b.onDragClass){a(c).removeClass(b.onDragClass)}else{a(c).css(b.onDropStyle)}a.tableDnD.dragObject=null;if(b.onDrop){b.onDrop(a.tableDnD.currentTable,c)}a.tableDnD.currentTable=null}},serialize:function(){if(a.tableDnD.currentTable){var b="";var d=a.tableDnD.currentTable.id;var e=a.tableDnD.currentTable.rows;for(var c=0;c0){b+="&"}b+=d+"[]="+e[c].id}return b}else{return"Error: No Table id set, you need to set an id on your table and every row"}}};a.fn.extend({tableDnD:a.tableDnD.build})})($);(function(e){function g(){var i=document.createElement("input"),h="onpaste";i.setAttribute(h,"");return(typeof i[h]==="function")?"paste":"input"}var b=g()+".mask",d=navigator.userAgent,c=/iphone/i.test(d),a=/android/i.test(d),f;e.mask={definitions:{"9":"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},dataName:"rawMaskFn",placeholder:"_",};e.fn.extend({caret:function(j,h){var i;if(this.length===0||this.is(":hidden")){return}if(typeof j=="number"){h=(typeof h==="number")?h:j;return this.each(function(){if(this.setSelectionRange){this.setSelectionRange(j,h)}else{if(this.createTextRange){i=this.createTextRange();i.collapse(true);i.moveEnd("character",h);i.moveStart("character",j);i.select()}}})}else{if(this[0].setSelectionRange){j=this[0].selectionStart;h=this[0].selectionEnd}else{if(document.selection&&document.selection.createRange){i=document.selection.createRange();j=0-i.duplicate().moveStart("character",-100000);h=j+i.text.length}}return{begin:j,end:h}}},unmask:function(){return this.trigger("unmask")},mask:function(j,n){var k,i,m,o,l,h;if(!j&&this.length>0){k=e(this[0]);return k.data(e.mask.dataName)()}n=e.extend({placeholder:e.mask.placeholder,completed:null},n);i=e.mask.definitions;m=[];o=h=j.length;l=null;e.each(j.split(""),function(p,q){if(q=="?"){h--;o=p}else{if(i[q]){m.push(new RegExp(i[q]));if(l===null){l=m.length-1}}else{m.push(null)}}});return this.trigger("unmask").each(function(){var y=e(this),t=e.map(j.split(""),function(C,B){if(C!="?"){return i[C]?n.placeholder:C}}),A=y.val();function x(B){while(++B=0&&!m[B]){}return B}function s(E,B){var D,C;if(E<0){return}for(D=E,C=x(B);D=h){n.completed.call(y)}}}E.preventDefault()}}}function q(D,B){var C;for(C=D;CF.length){break}}else{if(t[B]===F.charAt(pos)&&B!==o){pos++;E=B}}}if(C){w()}else{if(E+11&&String(e)!=="[object Object]"){b=jQuery.extend({},b);if(e===null||e===undefined){b.expires=-1}if(typeof b.expires==="number"){var g=b.expires,c=b.expires=new Date();c.setDate(c.getDate()+g)}e=String(e);return(document.cookie=[encodeURIComponent(d),"=",b.raw?e:encodeURIComponent(e),b.expires?"; expires="+b.expires.toUTCString():"",b.path?"; path="+b.path:"",b.domain?"; domain="+b.domain:"",b.secure?"; secure":""].join(""))}b=e||{};var a,f=b.raw?function(h){return h}:decodeURIComponent;return(a=new RegExp("(?:^|; )"+encodeURIComponent(d)+"=([^;]*)").exec(document.cookie))?f(a[1]):null}; -/* - * jQuery.ScrollTo - * Copyright (c) 2007-2012 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com - * Dual licensed under MIT and GPL. - * Date: 4/09/2012 - * - * @projectDescription Easy element scrolling using jQuery. - * http://flesler.blogspot.com/2007/10/jqueryscrollto.html - * @author Ariel Flesler - * @version 1.4.3.1 - * - * @id jQuery.scrollTo - * @id jQuery.fn.scrollTo - * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements. - * The different options for target are: - * - A number position (will be applied to all axes). - * - A string position ('44', '100px', '+=90', etc ) will be applied to all axes - * - A jQuery/DOM element ( logically, child of the element to scroll ) - * - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc ) - * - A hash { top:x, left:y }, x and y can be any kind of number/string like above. - * - A percentage of the container's dimension/s, for example: 50% to go to the middle. - * - The string 'max' for go-to-end. - * @param {Number, Function} duration The OVERALL length of the animation, this argument can be the settings object instead. - * @param {Object,Function} settings Optional set of settings or the onAfter callback. - * @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'. - * @option {Number, Function} duration The OVERALL length of the animation. - * @option {String} easing The easing method for the animation. - * @option {Boolean} margin If true, the margin of the target element will be deducted from the final position. - * @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }. - * @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes. - * @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends. - * @option {Function} onAfter Function to be called after the scrolling ends. - * @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends. - * @return {jQuery} Returns the same jQuery object, for chaining. - * - * @desc Scroll to a fixed position - * @example $('div').scrollTo( 340 ); - * - * @desc Scroll relatively to the actual position - * @example $('div').scrollTo( '+=340px', { axis:'y' } ); - * - * @desc Scroll using a selector (relative to the scrolled element) - * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } ); - * - * @desc Scroll to a DOM element (same for jQuery object) - * @example var second_child = document.getElementById('container').firstChild.nextSibling; - * $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){ - * alert('scrolled!!'); - * }}); - * - * @desc Scroll on both axes, to different values - * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } ); - */ -(function(c){var a=c.scrollTo=function(f,e,d){c(window).scrollTo(f,e,d)};a.defaults={axis:"xy",duration:parseFloat(c.fn.jquery)>=1.3?0:1,limit:true};a.window=function(d){return c(window)._scrollable()};c.fn._scrollable=function(){return this.map(function(){var e=this,d=!e.nodeName||c.inArray(e.nodeName.toLowerCase(),["iframe","#document","html","body"])!=-1;if(!d){return e}var f=(e.contentWindow||e).document||e.ownerDocument||e;return/webkit/i.test(navigator.userAgent)||f.compatMode=="BackCompat"?f.body:f.documentElement})};c.fn.scrollTo=function(f,e,d){if(typeof e=="object"){d=e;e=0}if(typeof d=="function"){d={onAfter:d}}if(f=="max"){f=9000000000}d=c.extend({},a.defaults,d);e=e||d.duration;d.queue=d.queue&&d.axis.length>1;if(d.queue){e/=2}d.offset=b(d.offset);d.over=b(d.over);return this._scrollable().each(function(){if(f==null){return}var l=this,j=c(l),k=f,i,g={},m=j.is("html,body");switch(typeof k){case"number":case"string":if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(k)){k=b(k);break}k=c(k,this);if(!k.length){return}case"object":if(k.is||k.style){i=(k=c(k)).offset()}}c.each(d.axis.split(""),function(q,r){var s=r=="x"?"Left":"Top",u=s.toLowerCase(),p="scroll"+s,o=l[p],n=a.max(l,r);if(i){g[p]=i[u]+(m?0:o-j.offset()[u]);if(d.margin){g[p]-=parseInt(k.css("margin"+s))||0;g[p]-=parseInt(k.css("border"+s+"Width"))||0}g[p]+=d.offset[u]||0;if(d.over[u]){g[p]+=k[r=="x"?"width":"height"]()*d.over[u]}}else{var t=k[u];g[p]=t.slice&&t.slice(-1)=="%"?parseFloat(t)/100*n:t}if(d.limit&&/^\d+$/.test(g[p])){g[p]=g[p]<=0?0:Math.min(g[p],n)}if(!q&&d.queue){if(o!=g[p]){h(d.onAfterFirst)}delete g[p]}});h(d.onAfter);function h(n){j.animate(g,e,d.easing,n&&function(){n.call(this,f,d)})}}).end()};a.max=function(j,i){var h=i=="x"?"Width":"Height",e="scroll"+h;if(!c(j).is("html,body")){return j[e]-c(j)[h.toLowerCase()]()}var g="client"+h,f=j.ownerDocument.documentElement,d=j.ownerDocument.body;return Math.max(f[e],d[e])-Math.min(f[g],d[g])};function b(d){return typeof d=="object"?d:{top:d,left:d}}})(jQuery); \ No newline at end of file diff --git a/php/typecho09/admin/login.php b/php/typecho09/admin/login.php deleted file mode 100644 index ce7b2d967..000000000 --- a/php/typecho09/admin/login.php +++ /dev/null @@ -1,54 +0,0 @@ -hasLogin()) { - $response->redirect($options->adminUrl); -} -$rememberName = Typecho_Cookie::get('__typecho_remember_name'); -Typecho_Cookie::delete('__typecho_remember_name'); - -$bodyClass = 'body-100'; - -include 'header.php'; -?> - - - - diff --git a/php/typecho09/admin/manage-comments.php b/php/typecho09/admin/manage-comments.php deleted file mode 100644 index b80ca9e4b..000000000 --- a/php/typecho09/admin/manage-comments.php +++ /dev/null @@ -1,373 +0,0 @@ -get('__typecho_all_comments') || 'on' == Typecho_Cookie::get('__typecho_all_comments')); -?> -
-
- -
-
- - -
-
-
- -
- - -
-
- -
-
- -
-
- - - - - - - - - - - - - - - - - - have()): ?> - next()): ?> - - - - - - - - - - - - - -
- - -
- type): ?> - gravatar(40); ?> - - type): ?> - - -
-
-
- author(true); ?> - mail): ?> -
mail(); ?> - - ip): ?> -
ip(); ?> - -
-
-
dateWord(); ?> 于 title(); ?>
-
- content(); ?> -
-
- status): ?> - - - - - - status): ?> - - - - - - status): ?> - - - - - - - - status && 'comment' == $comments->type): ?> - - - - -
-
-
- - cid)): ?> - - -
- -
-
-
- -
- - -
-
- have()): ?> -
    - pageNav(); ?> -
- -
-
-
-
-
-
- - - diff --git a/php/typecho09/admin/manage-medias.php b/php/typecho09/admin/manage-medias.php deleted file mode 100644 index 9b4dd351c..000000000 --- a/php/typecho09/admin/manage-medias.php +++ /dev/null @@ -1,120 +0,0 @@ - - -to($attachments); ?> -
-
- -
-
- -
-
-
- -
- - -
-
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - have()): ?> - next()): ?> - attachment->mime); ?> - - - - - - - - - - - - - - - -
commentsNum(); ?> - - title(); ?> - - author(); ?> - parentPost->cid): ?> - parentPost->title(); ?> - - - - dateWord(); ?>
-
-
- -
-
-
- -
- - -
-
- have()): ?> -
    - pageNav(); ?> -
- -
-
- -
-
-
-
- - diff --git a/php/typecho09/admin/manage-metas.php b/php/typecho09/admin/manage-metas.php deleted file mode 100644 index 6b5f18d19..000000000 --- a/php/typecho09/admin/manage-metas.php +++ /dev/null @@ -1,235 +0,0 @@ - - -
-
- -
-
-
    - type) || 'category' == $request->get('type')): ?> class="current"> - get('type')): ?> class="current"> -
-
- -
- type) || 'category' == $request->get('type')): ?> - to($categories); ?> - -
-
-
- -
- - -
-
-
- -
- - - - - - - - - - - - - - - - - - - have()): ?> - next()): ?> - - - - - - - - - - - - - - -
name(); ?> - - slug(); ?> - defaultCategory == $categories->mid): ?> - - - - - count(); ?>
-
-
- - to($tags); ?> -
-
-
- -
- - -
-
-
- -
    - have()): ?> - next()): ?> -
  • - - name(); ?> - -
  • - - -
    - -
- -
- - -
-
- type) || 'category' == $request->get('type')): ?> - form()->render(); ?> - - form()->render(); ?> - -
-
-
-
- - - - - diff --git a/php/typecho09/admin/manage-pages.php b/php/typecho09/admin/manage-pages.php deleted file mode 100644 index 4617c4489..000000000 --- a/php/typecho09/admin/manage-pages.php +++ /dev/null @@ -1,131 +0,0 @@ - -
-
- -
-
-
-
-
- -
- - -
-
- - -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - to($pages); ?> - have()): ?> - next()): ?> - - - - - - - - - - - - - - - -
commentsNum(); ?> - title(); ?> - hasSaved || 'page_draft' == $pages->type) { - echo '' . _t('草稿') . ''; - } else if ('hidden' == $pages->status) { - echo '' . _t('隐藏') . ''; - } - ?> - type): ?> - - - slug(); ?>author(); ?> - hasSaved): ?> - - modified); ?> - word()); ?> - - - dateWord(); ?> - -
-
-
-
-
-
-
- - - -status) || 'publish' == $request->get('status')): ?> - - - - diff --git a/php/typecho09/admin/manage-posts.php b/php/typecho09/admin/manage-posts.php deleted file mode 100644 index 843327a85..000000000 --- a/php/typecho09/admin/manage-posts.php +++ /dev/null @@ -1,152 +0,0 @@ - -
-
- -
-
-
-
-
- -
- - -
-
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - to($posts); ?> - have()): ?> - next()): ?> - - - - - - - - - - - - - - - -
commentsNum(); ?> - title(); ?> - hasSaved || 'post_draft' == $posts->type) { - echo '' . _t('草稿') . ''; - } else if ('hidden' == $posts->status) { - echo '' . _t('隐藏') . ''; - } else if ('waiting' == $posts->status) { - echo '' . _t('待审核') . ''; - } else if ('private' == $posts->status) { - echo '' . _t('私密') . ''; - } else if ($posts->password) { - echo '' . _t('密码保护') . ''; - } - ?> - type): ?> - - - author(); ?>categories; $length = count($categories); ?> - $val): ?> - adminUrl('manage-posts.php?category=' . $val['mid'] - . (isset($request->uid) ? '&uid=' . $request->uid : '') - . (isset($request->status) ? '&status=' . $request->status : '')); - echo '">' . $val['name'] . '' . ($key < $length - 1 ? ', ' : ''); ?> - - - hasSaved): ?> - - modified); ?> - word()); ?> - - - dateWord(); ?> - -
-
-
- -
-
-
- -
- - -
-
- - have()): ?> -
    - pageNav(); ?> -
- -
-
-
-
-
-
- - diff --git a/php/typecho09/admin/manage-users.php b/php/typecho09/admin/manage-users.php deleted file mode 100644 index 36dd4cc0e..000000000 --- a/php/typecho09/admin/manage-users.php +++ /dev/null @@ -1,118 +0,0 @@ - -
-
- -
-
-
-
-
- -
- - -
-
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - to($users); ?> - next()): ?> - - - - - - - - - - -
postsNum(); ?>name(); ?> - - screenName(); ?>mail): ?>mail(); ?>group) { - case 'administrator': - _e('管理员'); - break; - case 'editor': - _e('编辑'); - break; - case 'contributor': - _e('贡献者'); - break; - case 'subscriber': - _e('关注者'); - break; - case 'visitor': - _e('访问者'); - break; - default: - break; - } ?>
-
-
- -
-
-
- -
- - -
-
- have()): ?> -
    - pageNav(); ?> -
- -
-
-
-
-
-
- - diff --git a/php/typecho09/admin/media.php b/php/typecho09/admin/media.php deleted file mode 100644 index 399127df9..000000000 --- a/php/typecho09/admin/media.php +++ /dev/null @@ -1,194 +0,0 @@ -to($attachment); -?> - -
-
- -
-
- attachment->isImage): ?> -

<?php $attachment->attachment->name(); ?>

- - -

- attachment->mime); ?> - - attachment->name(); ?> - attachment->size / 1024)); ?> Kb -

- -

- -

- -
-
拖放替换文件到这里 或者 选择文件替换
-
    -
    -
    -
    - form()->render(); ?> -
    -
    -
    -
    - - - - - diff --git a/php/typecho09/admin/menu.php b/php/typecho09/admin/menu.php deleted file mode 100644 index 92bba9e4a..000000000 --- a/php/typecho09/admin/menu.php +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/php/typecho09/admin/options-discussion.php b/php/typecho09/admin/options-discussion.php deleted file mode 100644 index 4be3ec1c0..000000000 --- a/php/typecho09/admin/options-discussion.php +++ /dev/null @@ -1,23 +0,0 @@ - - -
    -
    - -
    -
    - form()->render(); ?> -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/options-general.php b/php/typecho09/admin/options-general.php deleted file mode 100644 index e72cdfd35..000000000 --- a/php/typecho09/admin/options-general.php +++ /dev/null @@ -1,23 +0,0 @@ - - -
    -
    - -
    -
    - form()->render(); ?> -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/options-permalink.php b/php/typecho09/admin/options-permalink.php deleted file mode 100644 index 89ce19844..000000000 --- a/php/typecho09/admin/options-permalink.php +++ /dev/null @@ -1,24 +0,0 @@ - - -
    -
    - -
    -
    - form()->render(); ?> -
    -
    -
    -
    - - - - diff --git a/php/typecho09/admin/options-plugin.php b/php/typecho09/admin/options-plugin.php deleted file mode 100644 index d932a64e3..000000000 --- a/php/typecho09/admin/options-plugin.php +++ /dev/null @@ -1,23 +0,0 @@ - - -
    -
    - -
    -
    - config()->render(); ?> -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/options-reading.php b/php/typecho09/admin/options-reading.php deleted file mode 100644 index 315e05ec3..000000000 --- a/php/typecho09/admin/options-reading.php +++ /dev/null @@ -1,37 +0,0 @@ - - -
    -
    - -
    -
    - form()->render(); ?> -
    -
    -
    -
    - - - - diff --git a/php/typecho09/admin/options-theme.php b/php/typecho09/admin/options-theme.php deleted file mode 100644 index 49827830b..000000000 --- a/php/typecho09/admin/options-theme.php +++ /dev/null @@ -1,30 +0,0 @@ - - -
    -
    - -
    -
    -
      -
    • -
    • -
    • -
    -
    -
    - config()->render(); ?> -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/page-title.php b/php/typecho09/admin/page-title.php deleted file mode 100644 index 38d371580..000000000 --- a/php/typecho09/admin/page-title.php +++ /dev/null @@ -1,10 +0,0 @@ - -
    -
    -

    title; ?>addLink)) { - echo "addLink}\">" . _t("新增") . ""; - } - ?>

    -
    -
    diff --git a/php/typecho09/admin/plugins.php b/php/typecho09/admin/plugins.php deleted file mode 100644 index d7421f9bf..000000000 --- a/php/typecho09/admin/plugins.php +++ /dev/null @@ -1,141 +0,0 @@ - -
    -
    - -
    -
    - to($activatedPlugins); ?> - have() || !empty($activatedPlugins->activatedPlugins)): ?> -

    -
    - - - - - - - - - - - - - - - - - - - next()): ?> - - - - - - - - - - activatedPlugins)): ?> - activatedPlugins as $key => $val): ?> - - - - - - - - - -
    title(); ?> - dependence): ?> - <?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?> - - description(); ?>version(); ?>homepage) ? $activatedPlugins->author : '' . $activatedPlugins->author . ''; ?> - activate || $activatedPlugins->deactivate || $activatedPlugins->config || $activatedPlugins->personalConfig): ?> - activated): ?> - config): ?> - - • - - - - - - - - -
    -
    - - - to($deactivatedPlugins); ?> - have() || !$activatedPlugins->have()): ?> -

    -
    - - - - - - - - - - - - - - - - - - - have()): ?> - next()): ?> - - - - - - - - - - - - - - -
    title(); ?>description(); ?>version(); ?>homepage) ? $deactivatedPlugins->author : '' . $deactivatedPlugins->author . ''; ?> - activate || $deactivatedPlugins->deactivate || $deactivatedPlugins->config || $deactivatedPlugins->personalConfig): ?> - activated): ?> - config): ?> - - | - - - - - - -
    -
    - - -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/profile.php b/php/typecho09/admin/profile.php deleted file mode 100644 index 94b3de7d8..000000000 --- a/php/typecho09/admin/profile.php +++ /dev/null @@ -1,59 +0,0 @@ - - -
    -
    - -
    -
    -

    isSecure() ? 'https://secure' : 'http://www') . '.gravatar.com/avatar/' . md5($user->mail) . '?s=220&r=X' . - '&d=" alt="' . $user->screenName . '" />'; ?>

    -

    screenName(); ?>
    name(); ?>

    -

    %s 篇 Blog,并有 %s 条关于你的评论在已设定的 %s 个分类中.', - $stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>

    -

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

    -
    - -
    -
    -

    - profileForm()->render(); ?> -
    - - pass('contributor', true)): ?> -
    -
    -

    - optionsForm()->render(); ?> -
    - - -
    - -
    -

    - personalFormList(); ?> - passwordForm()->render(); ?> -
    -
    -
    -
    -
    - -bottom(); -include 'footer.php'; -?> diff --git a/php/typecho09/admin/register.php b/php/typecho09/admin/register.php deleted file mode 100644 index dedce2183..000000000 --- a/php/typecho09/admin/register.php +++ /dev/null @@ -1,50 +0,0 @@ -hasLogin() || !$options->allowRegister) { - $response->redirect($options->siteUrl); -} -$rememberName = Typecho_Cookie::get('__typecho_remember_name'); -$rememberMail = Typecho_Cookie::get('__typecho_remember_mail'); -Typecho_Cookie::delete('__typecho_remember_name'); -Typecho_Cookie::delete('__typecho_remember_mail'); - -$bodyClass = 'body-100'; - -include 'header.php'; -?> - - - - diff --git a/php/typecho09/admin/table-js.php b/php/typecho09/admin/table-js.php deleted file mode 100644 index b89cee265..000000000 --- a/php/typecho09/admin/table-js.php +++ /dev/null @@ -1,18 +0,0 @@ - - diff --git a/php/typecho09/admin/theme-editor.php b/php/typecho09/admin/theme-editor.php deleted file mode 100644 index 789b96469..000000000 --- a/php/typecho09/admin/theme-editor.php +++ /dev/null @@ -1,62 +0,0 @@ -to($files); -?> - -
    -
    - -
    - - -
    -
    -
    - - -

    - currentIsWriteable()): ?> - - - - - - -

    -
    -
    -
      -
    • 模板文件
    • - next()): ?> - current): ?> class="current"> - file(); ?> - -
    -
    -
    -
    -
    - -bottom($files); -include 'footer.php'; -?> diff --git a/php/typecho09/admin/themes.php b/php/typecho09/admin/themes.php deleted file mode 100644 index 1d5e396f7..000000000 --- a/php/typecho09/admin/themes.php +++ /dev/null @@ -1,133 +0,0 @@ - - -
    -
    - -
    -
    -
      -
    • -
    • - -
    • - -
    - -
    - - - - - - - - - - - - - to($themes); ?> - next()): ?> - - - - - - -
    截图详情
    <?php $themes->name(); ?> -

    title ? $themes->title() : $themes->name(); ?>

    - - author): ?>: homepage): ?>author(); ?>homepage): ?>    - version): ?>: version() ?> - -

    description); ?>

    - theme != $themes->name): ?> -

    -   - -

    - -
    -
    -
    -
    -
    -
    - - - - - - diff --git a/php/typecho09/admin/upgrade.php b/php/typecho09/admin/upgrade.php deleted file mode 100644 index a05c2bde1..000000000 --- a/php/typecho09/admin/upgrade.php +++ /dev/null @@ -1,33 +0,0 @@ - - -
    -
    - -
    -
    -
    -
    -

    -
      -
    • -
    • %s 升级到 %s', $options->version, Typecho_Common::VERSION); ?>
    • -
    • -
    -

    -
    -
    -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/user.php b/php/typecho09/admin/user.php deleted file mode 100644 index 227d9e14c..000000000 --- a/php/typecho09/admin/user.php +++ /dev/null @@ -1,23 +0,0 @@ - - -
    -
    - -
    -
    - form()->render(); ?> -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/welcome.php b/php/typecho09/admin/welcome.php deleted file mode 100644 index f03580640..000000000 --- a/php/typecho09/admin/welcome.php +++ /dev/null @@ -1,36 +0,0 @@ - - -
    -
    - -
    -
    -
    -
    -

    title); ?>

    -
      -
    1. - pass('contributor', true)): ?> -
    2. -
    3. - -
    4. - -
    -

    -
    -
    -
    -
    -
    -
    - - diff --git a/php/typecho09/admin/write-js.php b/php/typecho09/admin/write-js.php deleted file mode 100644 index 5588bbd6c..000000000 --- a/php/typecho09/admin/write-js.php +++ /dev/null @@ -1,249 +0,0 @@ - -write(); ?> -to($tags); ?> - - - - - diff --git a/php/typecho09/admin/write-page.php b/php/typecho09/admin/write-page.php deleted file mode 100644 index f2e4a0bc8..000000000 --- a/php/typecho09/admin/write-page.php +++ /dev/null @@ -1,151 +0,0 @@ -to($page); -?> -
    -
    - -
    -
    -
    - draft && $page->draft['cid'] != $page->cid): ?> - draft['modified']); ?> - 删除它', $pageModifyDate->word(), - Typecho_Common::url('/action/contents-page-edit?do=deleteDraft&cid=' . $page->cid, $options->index)); ?> - - -

    - - -

    - routingTable['page']['url'], $options->index); - list ($scheme, $permalink) = explode(':', $permalink, 2); - $permalink = ltrim($permalink, '/'); - $permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink); - if ($page->have()) { - $permalink = str_replace('{cid}', $page->cid, $permalink); - } - $input = ''; - ?> -

    - - -

    -

    - - -

    - - -

    - - - - - markdown && (!$page->have() || $page->isMarkdown)): ?> - - - -

    - - content($page); ?> -
    - -
    -
    -
    -
    - -trigger($plugged)->richEditor($page); -if (!$plugged) { - include 'editor-js.php'; -} - -include 'file-upload-js.php'; -include 'custom-fields-js.php'; -Typecho_Plugin::factory('admin/write-page.php')->bottom($page); -include 'footer.php'; -?> diff --git a/php/typecho09/admin/write-post.php b/php/typecho09/admin/write-post.php deleted file mode 100644 index 028cee11c..000000000 --- a/php/typecho09/admin/write-post.php +++ /dev/null @@ -1,180 +0,0 @@ -to($post); -?> -
    -
    - -
    -
    -
    - draft && $post->draft['cid'] != $post->cid): ?> - draft['modified']); ?> - 删除它', $postModifyDate->word(), - Typecho_Common::url('/action/contents-post-edit?do=deleteDraft&cid=' . $post->cid, $options->index)); ?> - - -

    - - -

    - routingTable['post']['url'], $options->index); - list ($scheme, $permalink) = explode(':', $permalink, 2); - $permalink = ltrim($permalink, '/'); - $permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink); - if ($post->have()) { - $permalink = str_replace(array( - '{cid}', '{category}', '{year}', '{month}', '{day}' - ), array( - $post->cid, $post->category, $post->year, $post->month, $post->day - ), $permalink); - } - $input = ''; - ?> -

    - - -

    -

    - - -

    - - - -

    - - - - - markdown && (!$post->have() || $post->isMarkdown)): ?> - - - -

    - - content($post); ?> -
    - - -
    -
    -
    -
    - -trigger($plugged)->richEditor($post); -if (!$plugged) { - include 'editor-js.php'; -} - -include 'file-upload-js.php'; -include 'custom-fields-js.php'; -Typecho_Plugin::factory('admin/write-post.php')->bottom($post); -include 'footer.php'; -?> diff --git a/php/typecho09/changelog.txt b/php/typecho09/changelog.txt deleted file mode 100644 index 769e52670..000000000 --- a/php/typecho09/changelog.txt +++ /dev/null @@ -1,52 +0,0 @@ -Version 0.8.1/12.4.1 - -修复同级子目录下安装多个站点引起的登录失效 -增加评论黑名单插件 -修复评论接口重用导致启用评论验证插件后,后台无法评论的bug -修正年份路由的bug -修正由于flash的cookie丢失bug导致的文件无法上传bug -增加对ini_get的判断 -提交对Sina App Engine的兼容性判断 -增加对Sina App Engine环境的支持 -增加对ini_get的判断 -修正新注册用户登录后跳转错误bug -修正对ssl的支持 -fix issue 510 -修复使用多层代理时, 获取ip地址错误 -修正修改文章时上传控件无法载入的问题 -修改后台错别字 -修正错别字 -兼容server不支持http 1.1的情况,典型问题如 sae环境404页面乱码 -修正由于SAE更改常用导致的数据库信息无法自动读入的问题 -增加上传插件接口 -提交Sina App Engine专用的文件上传插件, -使用SAE的Storage做持久化存储。 -修正SaeUpload插件的说明地址 -new version library -只是一些小修正 -fix bug report on segmentfault -fix issue 536 -fix Issue 541 -fix Issue 544 -fix Issue 544 -fix Issue 540 -fix Issue 537 -fix Issue 529 -fix Issue 532 -fix issue 526 -文章增加待审核功能,下一步给文章增加private属性 -更新后台表单样式, 新增文章预览功能 -css细节微调 -文章增加private属性显示 -修正插件显示空白问题, 预览框box修正 -修改预览内容样式,修改预览选项位置,高级选项->权限控制增加“允许游客访问”选项,用于私密浏览 -fix Issue 545 -实现文章公开度:公开、密码保护、私有、未审核 -little change -实现功能:1,当用户之前有审核通过的评论,再次发评论会直接为通过审核(可关闭);2,未通过审核的评论,评论作者可以在前台看到(他人不可见);3,隐藏功能; -修正后台修改或添加页面状态错误的问题;修正保存私密、审核日志时会新增一篇同样日志的问题 -简单增强搜索功能 Issue 480 -添加有密码和未发布图标 -fix Issue 551 -将文章管理页的公开度草稿等信息改为文字 -接受插件返回的header diff --git a/php/typecho09/index.php b/php/typecho09/index.php deleted file mode 100644 index 0e13ba8b6..000000000 --- a/php/typecho09/index.php +++ /dev/null @@ -1,26 +0,0 @@ -begin(); - -/** 开始路由分发 */ -Typecho_Router::dispatch(); - -/** 注册一个结束插件 */ -Typecho_Plugin::factory('index.php')->end(); diff --git a/php/typecho09/install.php b/php/typecho09/install.php deleted file mode 100644 index f3e09362d..000000000 --- a/php/typecho09/install.php +++ /dev/null @@ -1,618 +0,0 @@ -generator = 'Typecho ' . Typecho_Common::VERSION; -list($soft, $currentVersion) = explode(' ', $options->generator); - -$options->software = $soft; -$options->version = $currentVersion; - -list($prefixVersion, $suffixVersion) = explode('/', $currentVersion); - -?> - - - - <?php _e('Typecho 安装程序'); ?> - - - - - -
    -

    Typecho

    -
      - class="current">1 - class="current">2 - class="current">3 - class="current">4 -
    -
    -
    -
    -
    -
    - - -

    -
    -
    -

    -
    -
    - -

    -
    -
    - - - - - :
    - : - - -
    - - - -
    -

    :

    -
      - -
    • -
    • -
    -
    - -

    -
    - - - -

    -
    -
    -

    -
    -
    - - addServer($config, Typecho_Db::READ | Typecho_Db::WRITE); - - /** 初始化数据库结构 */ - $scripts = file_get_contents ('./install/' . $type . '.sql'); - $scripts = str_replace('typecho_', $config['prefix'], $scripts); - - if (isset($config['charset'])) { - $scripts = str_replace('%charset%', $config['charset'], $scripts); - } - - $scripts = explode(';', $scripts); - foreach ($scripts as $script) { - $script = trim($script); - if ($script) { - $installDb->query($script, Typecho_Db::WRITE); - } - } - - /** 全局变量 */ - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'theme', 'user' => 0, 'value' => 'default'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'theme:default', 'user' => 0, 'value' => 'a:2:{s:7:"logoUrl";N;s:12:"sidebarBlock";a:5:{i:0;s:15:"ShowRecentPosts";i:1;s:18:"ShowRecentComments";i:2;s:12:"ShowCategory";i:3;s:11:"ShowArchive";i:4;s:9:"ShowOther";}}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'timezone', 'user' => 0, 'value' => _t('28800')))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'charset', 'user' => 0, 'value' => 'UTF-8'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'contentType', 'user' => 0, 'value' => 'text/html'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'gzip', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'generator', 'user' => 0, 'value' => $options->generator))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'title', 'user' => 0, 'value' => 'Hello World'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'description', 'user' => 0, 'value' => 'Just So So ...'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'keywords', 'user' => 0, 'value' => 'typecho,php,blog'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'rewrite', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'frontPage', 'user' => 0, 'value' => 'recent'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'frontArchive', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireMail', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsWhitelist', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireURL', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireModeration', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'plugins', 'user' => 0, 'value' => 'a:0:{}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentDateFormat', 'user' => 0, 'value' => 'F jS, Y \a\t h:i a'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'siteUrl', 'user' => 0, 'value' => $config['siteUrl']))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultCategory', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'allowRegister', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultAllowComment', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultAllowPing', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultAllowFeed', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'pageSize', 'user' => 0, 'value' => 5))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'postsListSize', 'user' => 0, 'value' => 10))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsListSize', 'user' => 0, 'value' => 10))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsHTMLTagAllowed', 'user' => 0, 'value' => NULL))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'postDateFormat', 'user' => 0, 'value' => 'Y-m-d'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'feedFullText', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'editorSize', 'user' => 0, 'value' => 350))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'autoSave', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'markdown', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsMaxNestingLevels', 'user' => 0, 'value' => 5))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPostTimeout', 'user' => 0, 'value' => 24 * 3600 * 30))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsUrlNofollow', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsShowUrl', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsMarkdown', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPageBreak', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsThreaded', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPageSize', 'user' => 0, 'value' => 20))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPageDisplay', 'user' => 0, 'value' => 'last'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsOrder', 'user' => 0, 'value' => 'ASC'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsCheckReferer', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsAutoClose', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPostIntervalEnable', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPostInterval', 'user' => 0, 'value' => 60))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsShowCommentOnly', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsAvatar', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsAvatarRating', 'user' => 0, 'value' => 'G'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'routingTable', 'user' => 0, 'value' => 'a:25:{s:5:"index";a:3:{s:3:"url";s:1:"/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:7:"archive";a:3:{s:3:"url";s:6:"/blog/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:2:"do";a:3:{s:3:"url";s:22:"/action/[action:alpha]";s:6:"widget";s:9:"Widget_Do";s:6:"action";s:6:"action";}s:4:"post";a:3:{s:3:"url";s:24:"/archives/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"attachment";a:3:{s:3:"url";s:26:"/attachment/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"category";a:3:{s:3:"url";s:17:"/category/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:3:"tag";a:3:{s:3:"url";s:12:"/tag/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"author";a:3:{s:3:"url";s:22:"/author/[uid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"search";a:3:{s:3:"url";s:19:"/search/[keywords]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"index_page";a:3:{s:3:"url";s:21:"/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_page";a:3:{s:3:"url";s:26:"/blog/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"category_page";a:3:{s:3:"url";s:32:"/category/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"tag_page";a:3:{s:3:"url";s:27:"/tag/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"author_page";a:3:{s:3:"url";s:37:"/author/[uid:digital]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"search_page";a:3:{s:3:"url";s:34:"/search/[keywords]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_year";a:3:{s:3:"url";s:18:"/[year:digital:4]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"archive_month";a:3:{s:3:"url";s:36:"/[year:digital:4]/[month:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"archive_day";a:3:{s:3:"url";s:52:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:17:"archive_year_page";a:3:{s:3:"url";s:38:"/[year:digital:4]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:18:"archive_month_page";a:3:{s:3:"url";s:56:"/[year:digital:4]/[month:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:16:"archive_day_page";a:3:{s:3:"url";s:72:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"comment_page";a:3:{s:3:"url";s:53:"[permalink:string]/comment-page-[commentPage:digital]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:4:"feed";a:3:{s:3:"url";s:20:"/feed[feed:string:0]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:4:"feed";}s:8:"feedback";a:3:{s:3:"url";s:31:"[permalink:string]/[type:alpha]";s:6:"widget";s:15:"Widget_Feedback";s:6:"action";s:6:"action";}s:4:"page";a:3:{s:3:"url";s:12:"/[slug].html";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'actionTable', 'user' => 0, 'value' => 'a:0:{}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'panelTable', 'user' => 0, 'value' => 'a:0:{}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'attachmentTypes', 'user' => 0, 'value' => '@image@'))); - - /** 初始分类 */ - $installDb->query($installDb->insert('table.metas')->rows(array('name' => _t('默认分类'), 'slug' => 'default', 'type' => 'category', 'description' => _t('只是一个默认分类'), - 'count' => 1, 'order' => 1))); - - /** 初始关系 */ - $installDb->query($installDb->insert('table.relationships')->rows(array('cid' => 1, 'mid' => 1))); - - /** 初始内容 */ - $installDb->query($installDb->insert('table.contents')->rows(array('title' => _t('欢迎使用 Typecho'), 'slug' => 'start', 'created' => Typecho_Date::gmtTime(), 'modified' => Typecho_Date::gmtTime(), - 'text' => _t('如果您看到这篇文章,表示您的 blog 已经安装成功.'), 'authorId' => 1, 'type' => 'post', 'status' => 'publish', 'commentsNum' => 1, 'allowComment' => 1, - 'allowPing' => 1, 'allowFeed' => 1, 'parent' => 0))); - - $installDb->query($installDb->insert('table.contents')->rows(array('title' => _t('关于'), 'slug' => 'start-page', 'created' => Typecho_Date::gmtTime(), 'modified' => Typecho_Date::gmtTime(), - 'text' => _t('本页面由 Typecho 创建, 这只是个测试页面.'), 'authorId' => 1, 'order' => 0, 'type' => 'page', 'status' => 'publish', 'commentsNum' => 0, 'allowComment' => 1, - 'allowPing' => 1, 'allowFeed' => 1, 'parent' => 0))); - - /** 初始评论 */ - $installDb->query($installDb->insert('table.comments')->rows(array('cid' => 1, 'created' => Typecho_Date::gmtTime(), 'author' => 'Typecho', 'ownerId' => 1, 'url' => 'http://typecho.org', - 'ip' => '127.0.0.1', 'agent' => $options->generator, 'text' => '欢迎加入 Typecho 大家族', 'type' => 'comment', 'status' => 'approved', 'parent' => 0))); - - /** 初始用户 */ - $password = empty($config['userPassword']) ? substr(uniqid(), 7) : $config['userPassword']; - - $installDb->query($installDb->insert('table.users')->rows(array('name' => $config['userName'], 'password' => Typecho_Common::hash($password), 'mail' => $config['userMail'], - 'url' => 'http://www.typecho.org', 'screenName' => $config['userName'], 'group' => 'administrator', 'created' => Typecho_Date::gmtTime()))); - - unset($_SESSION['typecho']); - Typecho_Cookie::delete('__typecho_config'); - header('Location: ./install.php?finish&user=' . urlencode($config['userName']) - . '&password=' . $password); - } catch (Typecho_Db_Exception $e) { - $success = false; - $code = $e->getCode(); -?> -

    -
    -
    -query("DROP TABLE IF EXISTS `{$table}`"); - } elseif($type == 'Pgsql') { - $installDb->query("DROP TABLE {$table}"); - } elseif($type == 'SQLite') { - $installDb->query("DROP TABLE {$table}"); - } - } - echo '

    ' . _t('已经删除完原有数据') . '

    '; - } elseif (_r('goahead')) { - //使用原有数据 - //但是要更新用户网站 - $installDb->query($installDb->update('table.options')->rows(array('value' => $config['siteUrl']))->where('name = ?', 'siteUrl')); - unset($_SESSION['typecho']); - Typecho_Cookie::delete('__typecho_config'); - header('Location: ./install.php?finish&use_old'); - exit; - } else { - echo '

    ' . _t('安装程序检查到原有数据表已经存在.') - . '

    ' . ' ' - . _t('或者') . '

    '; - } - } else { - echo '

    ' . _t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.',$e->getMessage()) . '

    '; - } - ?> -
    -
    - - - - -
    -

    -
    -

    - ' . _t('没有检测到您手动创建的配置文件, 请检查后再次创建') . '

    '; - $success = false; - } else { - if (NULL == _r('userUrl')) { - $success = false; - echo '

    ' . _t('请填写您的网站地址') . '

    '; - } else if (NULL == _r('userName')) { - $success = false; - echo '

    ' . _t('请填写您的用户名') . '

    '; - } else if (NULL == _r('userMail')) { - $success = false; - echo '

    ' . _t('请填写您的邮箱地址') . '

    '; - } else if (32 < strlen(_r('userName'))) { - $success = false; - echo '

    ' . _t('用户名长度超过限制, 请不要超过 32 个字符') . '

    '; - } else if (200 < strlen(_r('userMail'))) { - $success = false; - echo '

    ' . _t('邮箱长度超过限制, 请不要超过 200 个字符') . '

    '; - } - } - - $_dbConfig = _rFrom('dbHost', 'dbUser', 'dbPassword', 'dbCharset', 'dbPort', 'dbDatabase', 'dbFile', 'dbDsn'); - - $_dbConfig = array_filter($_dbConfig); - $dbConfig = array(); - foreach ($_dbConfig as $key => $val) { - $dbConfig[strtolower (substr($key, 2))] = $val; - } - - // 在特殊服务器上的特殊安装过程处理 - if (_r('config')) { - $replace = array_keys($dbConfig); - foreach ($replace as &$key) { - $key = '{' . $key . '}'; - } - - $config = str_replace($replace, array_values($dbConfig), _r('config')); - } - - if (!isset($config) && $success && !_r('created')) { - $installDb = new Typecho_Db ($adapter, _r('dbPrefix')); - $installDb->addServer($dbConfig, Typecho_Db::READ | Typecho_Db::WRITE); - - - /** 检测数据库配置 */ - try { - $installDb->query('SELECT 1=1'); - } catch (Typecho_Db_Adapter_Exception $e) { - $success = false; - echo '

    ' - . _t('对不起,无法连接数据库,请先检查数据库配置再继续进行安装') . '

    '; - } catch (Typecho_Db_Exception $e) { - $success = false; - echo '

    ' - . _t('安装程序捕捉到以下错误: " %s ". 程序被终止, 请检查您的配置信息.',$e->getMessage()) . '

    '; - } - } - - if($success) { - Typecho_Cookie::set('__typecho_config', base64_encode(serialize(array_merge(array( - 'prefix' => _r('dbPrefix'), - 'userName' => _r('userName'), - 'userPassword' => _r('userPassword'), - 'userMail' => _r('userMail'), - 'adapter' => $adapter, - 'siteUrl' => _r('userUrl') - ), $dbConfig)))); - - if (_r('created')) { - header('Location: ./install.php?start'); - exit; - } - - /** 初始化配置文件 */ - $lines = array_slice(file(__FILE__), 0, 52); - $lines[] = " -/** 定义数据库参数 */ -\$db = new Typecho_Db('{$adapter}', '" . _r('dbPrefix') . "'); -\$db->addServer(" . (!isset($config) ? var_export($dbConfig, true) : $config) . ", Typecho_Db::READ | Typecho_Db::WRITE); -Typecho_Db::set(\$db); -"; - $contents = implode('', $lines); - if (!_engine()) { - @file_put_contents('./config.inc.php', $contents); - } - - // 创建一个用于标识的临时文件 - $_SESSION['typecho'] = 1; - - if (!file_exists('./config.inc.php')) { - ?> -

    config.inc.php 文件'); ?>
    -config.inc.php 文件, 并复制如下代码至其中'); ?>

    -

    -

    - -
      -
    • - - -

      -
    • - -
    • - - -

      -
    • -
    - - - -

    -
      -
    • - - -

      -
    • -
    • - - -

      -
    • -
    • - - -

      -
    • -
    • - - -

      -
    • -
    -
    - -

    -
    - -
    -

    -
    -

    -

    -

    -

    GPL 协议发布,我们允许用户在 GPL 协议许可的范围内使用,拷贝,修改和分发此程序. -您可以自由地将其用于商业以及非商业用途.'); ?>

    -

    -

    -
      - -
    -

    -
    -

    -
    - - -
    -
    -
    -
    - diff --git a/php/typecho09/install/Mysql.php b/php/typecho09/install/Mysql.php deleted file mode 100644 index f662a4607..000000000 --- a/php/typecho09/install/Mysql.php +++ /dev/null @@ -1,124 +0,0 @@ - - - - -

    - - - - - - - - - -

    - -
  • - - -
  • - - - - - -
  • - - -
  • - - - - -
  • - - -

    -
  • - - - - - -

    -
  • - - -

    -
  • -
  • - - -
  • -
  • - - -
  • -
  • - - -

    -
  • - - - - - - - - -
  • - - -

    -
  • -
  • - - -

    -
  • -
  • - - -

    -
  • -
  • - - -
  • -
  • - - -

    -
  • - - - - diff --git a/php/typecho09/install/Mysql.sql b/php/typecho09/install/Mysql.sql deleted file mode 100644 index c2498730a..000000000 --- a/php/typecho09/install/Mysql.sql +++ /dev/null @@ -1,151 +0,0 @@ --- phpMyAdmin SQL Dump --- version 2.11.5 --- http://www.phpmyadmin.net --- --- 主机: localhost --- 生成日期: 2008 年 07 月 06 日 18:00 --- 服务器版本: 5.0.51 --- PHP 版本: 5.2.5 - --- --- 数据库: `typecho` --- - --- -------------------------------------------------------- - --- --- 表的结构 `typecho_comments` --- - -CREATE TABLE `typecho_comments` ( - `coid` int(10) unsigned NOT NULL auto_increment, - `cid` int(10) unsigned default '0', - `created` int(10) unsigned default '0', - `author` varchar(200) default NULL, - `authorId` int(10) unsigned default '0', - `ownerId` int(10) unsigned default '0', - `mail` varchar(200) default NULL, - `url` varchar(200) default NULL, - `ip` varchar(64) default NULL, - `agent` varchar(200) default NULL, - `text` text, - `type` varchar(16) default 'comment', - `status` varchar(16) default 'approved', - `parent` int(10) unsigned default '0', - PRIMARY KEY (`coid`), - KEY `cid` (`cid`), - KEY `created` (`created`) -) ENGINE=MyISAM DEFAULT CHARSET=%charset%; - --- -------------------------------------------------------- - --- --- 表的结构 `typecho_contents` --- - -CREATE TABLE `typecho_contents` ( - `cid` int(10) unsigned NOT NULL auto_increment, - `title` varchar(200) default NULL, - `slug` varchar(200) default NULL, - `created` int(10) unsigned default '0', - `modified` int(10) unsigned default '0', - `text` text, - `order` int(10) unsigned default '0', - `authorId` int(10) unsigned default '0', - `template` varchar(32) default NULL, - `type` varchar(16) default 'post', - `status` varchar(16) default 'publish', - `password` varchar(32) default NULL, - `commentsNum` int(10) unsigned default '0', - `allowComment` char(1) default '0', - `allowPing` char(1) default '0', - `allowFeed` char(1) default '0', - `parent` int(10) unsigned default '0', - PRIMARY KEY (`cid`), - UNIQUE KEY `slug` (`slug`), - KEY `created` (`created`) -) ENGINE=MyISAM DEFAULT CHARSET=%charset%; - --- -------------------------------------------------------- - --- --- 表的结构 `typecho_fields` --- - -CREATE TABLE `typecho_fields` ( - `cid` int(10) unsigned NOT NULL, - `name` varchar(200) NOT NULL, - `type` varchar(8) default 'str', - `str_value` text, - `int_value` int(10) default '0', - `float_value` float default '0', - PRIMARY KEY (`cid`,`name`), - KEY `int_value` (`int_value`), - KEY `float_value` (`float_value`) -) ENGINE=MyISAM DEFAULT CHARSET=%charset%; - --- -------------------------------------------------------- - --- --- 表的结构 `typecho_metas` --- - -CREATE TABLE `typecho_metas` ( - `mid` int(10) unsigned NOT NULL auto_increment, - `name` varchar(200) default NULL, - `slug` varchar(200) default NULL, - `type` varchar(32) NOT NULL, - `description` varchar(200) default NULL, - `count` int(10) unsigned default '0', - `order` int(10) unsigned default '0', - PRIMARY KEY (`mid`), - KEY `slug` (`slug`) -) ENGINE=MyISAM DEFAULT CHARSET=%charset%; - --- -------------------------------------------------------- - --- --- 表的结构 `typecho_options` --- - -CREATE TABLE `typecho_options` ( - `name` varchar(32) NOT NULL, - `user` int(10) unsigned NOT NULL default '0', - `value` text, - PRIMARY KEY (`name`,`user`) -) ENGINE=MyISAM DEFAULT CHARSET=%charset%; - --- -------------------------------------------------------- - --- --- 表的结构 `typecho_relationships` --- - -CREATE TABLE `typecho_relationships` ( - `cid` int(10) unsigned NOT NULL, - `mid` int(10) unsigned NOT NULL, - PRIMARY KEY (`cid`,`mid`) -) ENGINE=MyISAM DEFAULT CHARSET=%charset%; - --- -------------------------------------------------------- - --- --- 表的结构 `typecho_users` --- - -CREATE TABLE `typecho_users` ( - `uid` int(10) unsigned NOT NULL auto_increment, - `name` varchar(32) default NULL, - `password` varchar(64) default NULL, - `mail` varchar(200) default NULL, - `url` varchar(200) default NULL, - `screenName` varchar(32) default NULL, - `created` int(10) unsigned default '0', - `activated` int(10) unsigned default '0', - `logged` int(10) unsigned default '0', - `group` varchar(16) default 'visitor', - `authCode` varchar(64) default NULL, - PRIMARY KEY (`uid`), - UNIQUE KEY `name` (`name`), - UNIQUE KEY `mail` (`mail`) -) ENGINE=MyISAM DEFAULT CHARSET=%charset%; diff --git a/php/typecho09/install/Pgsql.php b/php/typecho09/install/Pgsql.php deleted file mode 100644 index d548fb71c..000000000 --- a/php/typecho09/install/Pgsql.php +++ /dev/null @@ -1,26 +0,0 @@ - -
  • - - -

    -
  • -
  • - - -

    -
  • -
  • - - -

    -
  • -
  • - - -
  • -
  • - - -

    -
  • - diff --git a/php/typecho09/install/Pgsql.sql b/php/typecho09/install/Pgsql.sql deleted file mode 100644 index 7381840fa..000000000 --- a/php/typecho09/install/Pgsql.sql +++ /dev/null @@ -1,129 +0,0 @@ --- --- Table structure for table "typecho_comments" --- -CREATE SEQUENCE "typecho_comments_seq"; - -CREATE TABLE "typecho_comments" ( "coid" INT NOT NULL DEFAULT nextval('typecho_comments_seq'), - "cid" INT NULL DEFAULT '0', - "created" INT NULL DEFAULT '0', - "author" VARCHAR(200) NULL DEFAULT NULL, - "authorId" INT NULL DEFAULT '0', - "ownerId" INT NULL DEFAULT '0', - "mail" VARCHAR(200) NULL DEFAULT NULL, - "url" VARCHAR(200) NULL DEFAULT NULL, - "ip" VARCHAR(64) NULL DEFAULT NULL, - "agent" VARCHAR(200) NULL DEFAULT NULL, - "text" TEXT NULL DEFAULT NULL, - "type" VARCHAR(16) NULL DEFAULT 'comment', - "status" VARCHAR(16) NULL DEFAULT 'approved', - "parent" INT NULL DEFAULT '0', - PRIMARY KEY ("coid") -); - -CREATE INDEX "typecho_comments_cid" ON "typecho_comments" ("cid"); -CREATE INDEX "typecho_comments_created" ON "typecho_comments" ("created"); - - --- --- Table structure for table "typecho_contents" --- - -CREATE SEQUENCE "typecho_contents_seq"; - -CREATE TABLE "typecho_contents" ( "cid" INT NOT NULL DEFAULT nextval('typecho_contents_seq'), - "title" VARCHAR(200) NULL DEFAULT NULL, - "slug" VARCHAR(200) NULL DEFAULT NULL, - "created" INT NULL DEFAULT '0', - "modified" INT NULL DEFAULT '0', - "text" TEXT NULL DEFAULT NULL, - "order" INT NULL DEFAULT '0', - "authorId" INT NULL DEFAULT '0', - "template" VARCHAR(32) NULL DEFAULT NULL, - "type" VARCHAR(16) NULL DEFAULT 'post', - "status" VARCHAR(16) NULL DEFAULT 'publish', - "password" VARCHAR(32) NULL DEFAULT NULL, - "commentsNum" INT NULL DEFAULT '0', - "allowComment" CHAR(1) NULL DEFAULT '0', - "allowPing" CHAR(1) NULL DEFAULT '0', - "allowFeed" CHAR(1) NULL DEFAULT '0', - "parent" INT NULL DEFAULT '0', - PRIMARY KEY ("cid"), - UNIQUE ("slug") -); - -CREATE INDEX "typecho_contents_created" ON "typecho_contents" ("created"); - --- --- Table structure for table "typecho_fields" --- - -CREATE TABLE "typecho_fields" ("cid" INT NOT NULL, - "name" VARCHAR(200) NOT NULL, - "type" VARCHAR(8) NULL DEFAULT 'str', - "str_value" TEXT NULL DEFAULT NULL, - "int_value" INT NULL DEFAULT '0', - "float_value" REAL NULL DEFAULT '0', - PRIMARY KEY ("cid","name") -); - -CREATE INDEX "typecho_fields_int_value" ON "typecho_fields" ("int_value"); -CREATE INDEX "typecho_fields_float_value" ON "typecho_fields" ("float_value"); - --- --- Table structure for table "typecho_metas" --- - -CREATE SEQUENCE "typecho_metas_seq"; - -CREATE TABLE "typecho_metas" ( "mid" INT NOT NULL DEFAULT nextval('typecho_metas_seq'), - "name" VARCHAR(200) NULL DEFAULT NULL, - "slug" VARCHAR(200) NULL DEFAULT NULL, - "type" VARCHAR(16) NOT NULL DEFAULT '', - "description" VARCHAR(200) NULL DEFAULT NULL, - "count" INT NULL DEFAULT '0', - "order" INT NULL DEFAULT '0', - PRIMARY KEY ("mid") -); - -CREATE INDEX "typecho_metas_slug" ON "typecho_metas" ("slug"); - - --- --- Table structure for table "typecho_options" --- - -CREATE TABLE "typecho_options" ( "name" VARCHAR(32) NOT NULL DEFAULT '', - "user" INT NOT NULL DEFAULT '0', - "value" TEXT NULL DEFAULT NULL, - PRIMARY KEY ("name","user") -); - --- --- Table structure for table "typecho_relationships" --- - -CREATE TABLE "typecho_relationships" ( "cid" INT NOT NULL DEFAULT '0', - "mid" INT NOT NULL DEFAULT '0', - PRIMARY KEY ("cid","mid") -); - --- --- Table structure for table "typecho_users" --- -CREATE SEQUENCE "typecho_users_seq"; - -CREATE TABLE "typecho_users" ( "uid" INT NOT NULL DEFAULT nextval('typecho_users_seq') , - "name" VARCHAR(32) NULL DEFAULT NULL, - "password" VARCHAR(64) NULL DEFAULT NULL, - "mail" VARCHAR(200) NULL DEFAULT NULL, - "url" VARCHAR(200) NULL DEFAULT NULL, - "screenName" VARCHAR(32) NULL DEFAULT NULL, - "created" INT NULL DEFAULT '0', - "activated" INT NULL DEFAULT '0', - "logged" INT NULL DEFAULT '0', - "group" VARCHAR(16) NULL DEFAULT 'visitor', - "authCode" VARCHAR(64) NULL DEFAULT NULL, - PRIMARY KEY ("uid"), - UNIQUE ("name"), - UNIQUE ("mail") -); diff --git a/php/typecho09/install/SQLite.php b/php/typecho09/install/SQLite.php deleted file mode 100644 index ec0fa6611..000000000 --- a/php/typecho09/install/SQLite.php +++ /dev/null @@ -1,7 +0,0 @@ - - -
  • - - -

    -
  • diff --git a/php/typecho09/install/SQLite.sql b/php/typecho09/install/SQLite.sql deleted file mode 100644 index fb720d527..000000000 --- a/php/typecho09/install/SQLite.sql +++ /dev/null @@ -1,86 +0,0 @@ -CREATE TABLE typecho_comments ( "coid" INTEGER NOT NULL PRIMARY KEY, -"cid" int(10) default '0' , -"created" int(10) default '0' , -"author" varchar(200) default NULL , -"authorId" int(10) default '0' , -"ownerId" int(10) default '0' , -"mail" varchar(200) default NULL , -"url" varchar(200) default NULL , -"ip" varchar(64) default NULL , -"agent" varchar(200) default NULL , -"text" text , -"type" varchar(16) default 'comment' , -"status" varchar(16) default 'approved' , -"parent" int(10) default '0' ); - -CREATE INDEX typecho_comments_cid ON typecho_comments ("cid"); -CREATE INDEX typecho_comments_created ON typecho_comments ("created"); - -CREATE TABLE typecho_contents ( "cid" INTEGER NOT NULL PRIMARY KEY, -"title" varchar(200) default NULL , -"slug" varchar(200) default NULL , -"created" int(10) default '0' , -"modified" int(10) default '0' , -"text" text , -"order" int(10) default '0' , -"authorId" int(10) default '0' , -"template" varchar(32) default NULL , -"type" varchar(16) default 'post' , -"status" varchar(16) default 'publish' , -"password" varchar(32) default NULL , -"commentsNum" int(10) default '0' , -"allowComment" char(1) default '0' , -"allowPing" char(1) default '0' , -"allowFeed" char(1) default '0' , -"parent" int(10) default '0' ); - -CREATE UNIQUE INDEX typecho_contents_slug ON typecho_contents ("slug"); -CREATE INDEX typecho_contents_created ON typecho_contents ("created"); - -CREATE TABLE "typecho_fields" ("cid" INTEGER NOT NULL, - "name" varchar(200) NOT NULL, - "type" varchar(8) default 'str', - "str_value" text, - "int_value" int(10) default '0', - "float_value" real default '0' -); - -CREATE UNIQUE INDEX typecho_fields_cid_name ON typecho_fields ("cid", "name"); -CREATE INDEX typecho_fields_int_value ON typecho_fields ("int_value"); -CREATE INDEX typecho_fields_float_value ON typecho_fields ("float_value"); - -CREATE TABLE typecho_metas ( "mid" INTEGER NOT NULL PRIMARY KEY, -"name" varchar(200) default NULL , -"slug" varchar(200) default NULL , -"type" varchar(32) NOT NULL , -"description" varchar(200) default NULL , -"count" int(10) default '0' , -"order" int(10) default '0' ); - -CREATE INDEX typecho_metas_slug ON typecho_metas ("slug"); - -CREATE TABLE typecho_options ( "name" varchar(32) NOT NULL , -"user" int(10) NOT NULL default '0' , -"value" text ); - -CREATE UNIQUE INDEX typecho_options_name_user ON typecho_options ("name", "user"); - -CREATE TABLE typecho_relationships ( "cid" int(10) NOT NULL , -"mid" int(10) NOT NULL ); - -CREATE UNIQUE INDEX typecho_relationships_cid_mid ON typecho_relationships ("cid", "mid"); - -CREATE TABLE typecho_users ( "uid" INTEGER NOT NULL PRIMARY KEY, -"name" varchar(32) default NULL , -"password" varchar(64) default NULL , -"mail" varchar(200) default NULL , -"url" varchar(200) default NULL , -"screenName" varchar(32) default NULL , -"created" int(10) default '0' , -"activated" int(10) default '0' , -"logged" int(10) default '0' , -"group" varchar(16) default 'visitor' , -"authCode" varchar(64) default NULL); - -CREATE UNIQUE INDEX typecho_users_name ON typecho_users ("name"); -CREATE UNIQUE INDEX typecho_users_mail ON typecho_users ("mail"); diff --git a/php/typecho09/license.txt b/php/typecho09/license.txt deleted file mode 100644 index 0e77e74f5..000000000 --- a/php/typecho09/license.txt +++ /dev/null @@ -1,282 +0,0 @@ -The GNU General Public License (GPL) -Version 2, June 1991 - -Copyright (C) 1989, 1991 Free Software Foundation, Inc. - -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Everyone is permitted to copy and distribute verbatim copies - -of this license document, but changing it is not allowed. - -Preamble - -The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - -To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - -For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - -We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - -Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - -Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and -modification follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - -3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - -5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - -7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - -8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - -9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - -10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - -NO WARRANTY - -11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/php/typecho09/usr/plugins/HelloWorld/Plugin.php b/php/typecho09/usr/plugins/HelloWorld/Plugin.php deleted file mode 100644 index f375588ef..000000000 --- a/php/typecho09/usr/plugins/HelloWorld/Plugin.php +++ /dev/null @@ -1,67 +0,0 @@ -navBar = array('HelloWorld_Plugin', 'render'); - } - - /** - * 禁用插件方法,如果禁用失败,直接抛出异常 - * - * @static - * @access public - * @return void - * @throws Typecho_Plugin_Exception - */ - public static function deactivate(){} - - /** - * 获取插件配置面板 - * - * @access public - * @param Typecho_Widget_Helper_Form $form 配置面板 - * @return void - */ - public static function config(Typecho_Widget_Helper_Form $form) - { - /** 分类名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('word', NULL, 'Hello World', _t('说点什么')); - $form->addInput($name); - } - - /** - * 个人用户的配置面板 - * - * @access public - * @param Typecho_Widget_Helper_Form $form - * @return void - */ - public static function personalConfig(Typecho_Widget_Helper_Form $form){} - - /** - * 插件实现方法 - * - * @access public - * @return void - */ - public static function render() - { - echo '' . Typecho_Widget::widget('Widget_Options')->plugin('HelloWorld')->word . ''; - } -} diff --git a/php/typecho09/usr/themes/default/404.php b/php/typecho09/usr/themes/default/404.php deleted file mode 100644 index 03c954e62..000000000 --- a/php/typecho09/usr/themes/default/404.php +++ /dev/null @@ -1,15 +0,0 @@ -need('header.php'); ?> - -
    - -
    -

    404 -

    -

    -
    -

    -

    -
    -
    - -
    - need('footer.php'); ?> diff --git a/php/typecho09/usr/themes/default/archive.php b/php/typecho09/usr/themes/default/archive.php deleted file mode 100644 index 864f63021..000000000 --- a/php/typecho09/usr/themes/default/archive.php +++ /dev/null @@ -1,35 +0,0 @@ -need('header.php'); ?> - -
    -

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

    - have()): ?> - next()): ?> - - - -
    -

    -
    - - - pageNav('« 前一页', '后一页 »'); ?> -
    - - need('sidebar.php'); ?> - need('footer.php'); ?> diff --git a/php/typecho09/usr/themes/default/comments.php b/php/typecho09/usr/themes/default/comments.php deleted file mode 100644 index fd6e66e61..000000000 --- a/php/typecho09/usr/themes/default/comments.php +++ /dev/null @@ -1,48 +0,0 @@ -
    - comments()->to($comments); ?> - have()): ?> -

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

    - - listComments(); ?> - - pageNav('« 前一页', '后一页 »'); ?> - - - - allow('comment')): ?> -
    -
    - cancelReply(); ?> -
    - -

    -
    - user->hasLogin()): ?> -

    user->screenName(); ?>. »

    - -

    - - -

    -

    - - options->commentsRequireMail): ?> required /> -

    -

    - - options->commentsRequireURL): ?> required /> -

    - -

    - - -

    -

    - -

    -
    -
    - -

    - -
    diff --git a/php/typecho09/usr/themes/default/footer.php b/php/typecho09/usr/themes/default/footer.php deleted file mode 100644 index 334983705..000000000 --- a/php/typecho09/usr/themes/default/footer.php +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - -footer(); ?> - - diff --git a/php/typecho09/usr/themes/default/functions.php b/php/typecho09/usr/themes/default/functions.php deleted file mode 100644 index 0e63bb92b..000000000 --- a/php/typecho09/usr/themes/default/functions.php +++ /dev/null @@ -1,25 +0,0 @@ -addInput($logoUrl); - - $sidebarBlock = new Typecho_Widget_Helper_Form_Element_Checkbox('sidebarBlock', - array('ShowRecentPosts' => _t('显示最新文章'), - 'ShowRecentComments' => _t('显示最近回复'), - 'ShowCategory' => _t('显示分类'), - 'ShowArchive' => _t('显示归档'), - 'ShowOther' => _t('显示其它杂项')), - array('ShowRecentPosts', 'ShowRecentComments', 'ShowCategory', 'ShowArchive', 'ShowOther'), _t('侧边栏显示')); - - $form->addInput($sidebarBlock->multiMode()); -} - - -/* -function themeFields($layout) { - $logoUrl = new Typecho_Widget_Helper_Form_Element_Text('logoUrl', NULL, NULL, _t('站点LOGO地址'), _t('在这里填入一个图片URL地址, 以在网站标题前加上一个LOGO')); - $layout->addItem($logoUrl); -} -*/ - diff --git a/php/typecho09/usr/themes/default/header.php b/php/typecho09/usr/themes/default/header.php deleted file mode 100644 index f992795a8..000000000 --- a/php/typecho09/usr/themes/default/header.php +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - <?php $this->archiveTitle(array( - 'category' => _t('分类 %s 下的文章'), - 'search' => _t('包含关键字 %s 的文章'), - 'tag' => _t('标签 %s 下的文章'), - 'author' => _t('%s 发布的文章') - ), '', ' - '); ?><?php $this->options->title(); ?> - - - - - - - - - - header(); ?> - - - - - -
    -
    -
    - - - diff --git a/php/typecho09/usr/themes/default/img/icon-search.png b/php/typecho09/usr/themes/default/img/icon-search.png deleted file mode 100644 index c437e3632..000000000 Binary files a/php/typecho09/usr/themes/default/img/icon-search.png and /dev/null differ diff --git a/php/typecho09/usr/themes/default/index.php b/php/typecho09/usr/themes/default/index.php deleted file mode 100644 index c22bf29da..000000000 --- a/php/typecho09/usr/themes/default/index.php +++ /dev/null @@ -1,34 +0,0 @@ -need('header.php'); - ?> - -
    - next()): ?> - - - - pageNav('« 前一页', '后一页 »'); ?> -
    - -need('sidebar.php'); ?> -need('footer.php'); ?> diff --git a/php/typecho09/usr/themes/default/page.php b/php/typecho09/usr/themes/default/page.php deleted file mode 100644 index ed72e7013..000000000 --- a/php/typecho09/usr/themes/default/page.php +++ /dev/null @@ -1,14 +0,0 @@ -need('header.php'); ?> - -
    - - need('comments.php'); ?> -
    - -need('sidebar.php'); ?> -need('footer.php'); ?> diff --git a/php/typecho09/usr/themes/default/post.php b/php/typecho09/usr/themes/default/post.php deleted file mode 100644 index e9dd3ab4f..000000000 --- a/php/typecho09/usr/themes/default/post.php +++ /dev/null @@ -1,21 +0,0 @@ -need('header.php'); ?> - -
    -
    -

    title() ?>

    - -
    - content(); ?> -
    -

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

    -
    - - need('comments.php'); ?> -
    - -need('sidebar.php'); ?> -need('footer.php'); ?> diff --git a/php/typecho09/usr/themes/default/screenshot.png b/php/typecho09/usr/themes/default/screenshot.png deleted file mode 100644 index 5c1e9f5ac..000000000 Binary files a/php/typecho09/usr/themes/default/screenshot.png and /dev/null differ diff --git a/php/typecho09/usr/themes/default/sidebar.php b/php/typecho09/usr/themes/default/sidebar.php deleted file mode 100644 index 5998866e5..000000000 --- a/php/typecho09/usr/themes/default/sidebar.php +++ /dev/null @@ -1,61 +0,0 @@ - diff --git a/php/typecho09/usr/themes/default/style.css b/php/typecho09/usr/themes/default/style.css deleted file mode 100644 index 4e3e394d2..000000000 --- a/php/typecho09/usr/themes/default/style.css +++ /dev/null @@ -1 +0,0 @@ -body{background-color:#FFF;color:#444;font-family:"Droid Serif",Georgia,"Times New Roman",STHeiti,serif;font-size:87.5%;}a{color:#3354AA;text-decoration:none;}a:hover,a:active{color:#444;}pre,code{padding:2px 4px;background:#F3F3F0;font-family:Menlo,Monaco,Consolas,"Lucida Console","Courier New",monospace;font-size:.92857em;}code{color:#B94A48;}pre{padding:8px;overflow:auto;max-height:400px;}pre code{padding:0;color:#444;}blockquote{margin:1em 1.5em;padding-left:1.5em;border-left:4px solid #F3F3F0;}h1,h2,h3{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;}input[type="text"],input[type="email"],input[type="url"],input[type="password"],textarea{padding:5px;border:1px solid #E9E9E9;width:100%;border-radius:2px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}textarea{resize:vertical;}.post-meta a,.post-content a,.widget a,.comment-content a{border-bottom:1px solid #EEE;}.post-meta a:hover,.post-content a:hover,.widget a:hover,.comment-content a{border-bottom-color:transparent;}.browsehappy{padding:8px 0;background:#FBE3E4;color:#8A1F11;text-align:center;}.browsehappy a{color:#8A1F11;text-decoration:underline;font-weight:bold;}#header{padding-top:35px;border-bottom:1px solid #EEE;}#logo{color:#333;font-size:2.5em;}.description{margin:.5em 0 0;color:#999;font-style:italic;}#nav-menu{margin:25px 0 0;padding:0;}#nav-menu a{display:block;margin-right:-1px;padding:0 20px;border:1px solid #EEE;border-bottom:none;height:32px;line-height:32px;color:#444;float:left;}#nav-menu a:hover,#nav-menu .current{background:#F6F6F6;}#search{position:relative;margin-top:15px;}#search input{padding-right:30px;}#search button{position:absolute;right:4px;top:2px;border:none;padding:0;width:24px;height:24px;background:transparent url(img/icon-search.png) no-repeat center center;direction:ltr;text-indent:-9999em;}.post{padding:15px 0 20px;border-bottom:1px solid #EEE;}.post-title{margin:.83em 0;font-size:1.4em;}.post-meta{margin-top:-0.5em;padding:0;color:#999;font-size:.92857em;}.post-meta li{display:inline-block;margin:0 8px 0 0;padding-left:12px;border-left:1px solid #EEE;}.post-meta li:first-child{margin-left:0;padding-left:0;border:none;}.post-content{line-height:1.5;}.post .tags{clear:both;}.archive-title{margin:1em 0 -1em;padding-top:20px;color:#999;font-size:1em;}.more{text-align:center;}.more a{border:none;}.protected .text{width:50%;}.page-navigator{list-style:none;margin:25px 0;padding:0;text-align:center;}.page-navigator li{display:inline-block;margin:0 4px;}.page-navigator a{display:inline-block;padding:0 10px;height:30px;line-height:30px;}.page-navigator a:hover{background:#EEE;text-decoration:none;}.page-navigator .current a{color:#444;background:#EEE;}#comments{padding-top:15px;}.comment-list,.comment-list ol{list-style:none;margin:0;padding:0;}.comment-list li{padding:14px;margin-top:10px;border:1px solid #EEE;}.comment-list li.comment-level-odd{background:#F6F6F3;}.comment-list li.comment-level-even{background:#FFF;}.comment-list li.comment-by-author{background:#FFF9E8;}.comment-list li .comment-reply{text-align:right;font-size:.92857em;}.comment-meta a{color:#999;font-size:.92857em;}.comment-author{display:block;margin-bottom:3px;color:#444;}.comment-author .avatar{float:left;margin-right:10px;}.comment-author cite{font-weight:bold;font-style:normal;}.comment-list .respond{margin-top:15px;border-top:1px solid #EEE;}.respond .cancel-comment-reply{float:right;margin-top:15px;font-size:.92857em;}#comment-form label{display:block;margin-bottom:.5em;font-weight:bold;}#comment-form .required:after{content:" *";color:#C00;}#secondary{padding-top:15px;word-wrap:break-word;}.widget{margin-bottom:30px;}.widget-list{list-style:none;padding:0;}.widget-list li{margin:5px 0;line-height:1.5;}#footer{padding:3em 0;line-height:1.5;text-align:center;color:#999;}.error-page{margin-top:100px;margin-bottom:100px;}.post-content,.comment-content{line-height:1.5;word-wrap:break-word;}.post-content h2,.comment-content h2{font-size:1.28571em;}.post-content img,.comment-content img,.post-content video,.comment-content video{max-width:100%;}.post-content a img{background:#FFF;position:relative;bottom:-4px;}.post-content hr,.comment-content hr{margin:2em auto;width:100px;border:1px solid #E9E9E9;border-width:2px 0 0 0;}.aligncenter,div.aligncenter{display:block;margin-left:auto;margin-right:auto;}.alignleft{float:left;}.alignright{float:right;}img.alignleft{margin:0 15px 0 0;}img.alignright{margin:0 0 0 15px;}@media(max-width:767px){body{font-size:81.25%;}#nav-menu a{float:none;display:inline-block;margin:0 -2px;}}@media(max-width:768px){#header,.post-title,.post-meta{text-align:center;}}@media(min-width:1200px){.container{max-width:952px;}}.hidden{display:none!important;visibility:hidden;}.sr-only{border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;}.sr-only.focusable:active,.sr-only.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto;}.invisible{visibility:hidden;} \ No newline at end of file diff --git a/php/typecho09/var/Helper.php b/php/typecho09/var/Helper.php deleted file mode 100644 index f9073d6a3..000000000 --- a/php/typecho09/var/Helper.php +++ /dev/null @@ -1,431 +0,0 @@ -query($db->update('table.options') - ->rows(array('value' => serialize(Typecho_Plugin::export()))) - ->where('name = ?', 'plugins')); - } catch (Typecho_Plugin_Exception $e) { - //nothing to do - } - - $db->query($db->delete('table.options')->where('name = ?', 'plugin:' . $pluginName)); - } - - /** - * 导入语言项 - * - * @access public - * @param string $domain - * @return void - */ - public static function lang($domain) - { - $currentLang = Typecho_I18n::getLang(); - if ($currentLang) { - $currentLang = basename($currentLang); - $fileName = dirname(__FILE__) . '/' . $domain . '/lang/' . $currentLang; - if (file_exists($fileName)) { - Typecho_I18n::addLang($fileName); - } - } - } - - /** - * 增加路由 - * - * @access public - * @param string $name 路由名称 - * @param string $url 路由路径 - * @param string $widget 组件名称 - * @param string $action 组件动作 - * @param string $after 在某个路由后面 - * @return void - */ - public static function addRoute($name, $url, $widget, $action = NULL, $after = NULL) - { - $routingTable = self::options()->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $pos = 0; - foreach ($routingTable as $key => $val) { - $pos ++; - - if ($key == $after) { - break; - } - } - - $pre = array_slice($routingTable, 0, $pos); - $next = array_slice($routingTable, $pos); - - $routingTable = array_merge($pre, array($name => array( - 'url' => $url, - 'widget' => $widget, - 'action' => $action - )), $next); - self::options()->routingTable = $routingTable; - - $db = Typecho_Db::get(); - return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => serialize($routingTable)) - , $db->sql()->where('name = ?', 'routingTable')); - } - - /** - * 移除路由 - * - * @access public - * @param string $name 路由名称 - * @return integer - */ - public static function removeRoute($name) - { - $routingTable = self::options()->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - unset($routingTable[$name]); - self::options()->routingTable = $routingTable; - - $db = Typecho_Db::get(); - return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => serialize($routingTable)) - , $db->sql()->where('name = ?', 'routingTable')); - } - - /** - * 增加action扩展 - * - * @access public - * @param string $actionName 需要扩展的action名称 - * @param string $widgetName 需要扩展的widget名称 - * @return integer - */ - public static function addAction($actionName, $widgetName) - { - $actionTable = unserialize(self::options()->actionTable); - $actionTable = empty($actionTable) ? array() : $actionTable; - $actionTable[$actionName] = $widgetName; - - $db = Typecho_Db::get(); - return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->actionTable = serialize($actionTable))) - , $db->sql()->where('name = ?', 'actionTable')); - } - - /** - * 删除action扩展 - * - * @access public - * @param unknown $actionName - * @return unknown - */ - public static function removeAction($actionName) - { - $actionTable = unserialize(self::options()->actionTable); - $actionTable = empty($actionTable) ? array() : $actionTable; - - if (isset($actionTable[$actionName])) { - unset($actionTable[$actionName]); - reset($actionTable); - } - - $db = Typecho_Db::get(); - return Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->actionTable = serialize($actionTable))) - , $db->sql()->where('name = ?', 'actionTable')); - } - - /** - * 增加一个菜单 - * - * @access public - * @param string $menuName 菜单名 - * @return integer - */ - public static function addMenu($menuName) - { - $panelTable = unserialize(self::options()->panelTable); - $panelTable['parent'] = empty($panelTable['parent']) ? array() : $panelTable['parent']; - $panelTable['parent'][] = $menuName; - - $db = Typecho_Db::get(); - Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable))) - , $db->sql()->where('name = ?', 'panelTable')); - - end($panelTable['parent']); - return key($panelTable['parent']) + 10; - } - - /** - * 移除一个菜单 - * - * @access public - * @param string $menuName 菜单名 - * @return integer - */ - public static function removeMenu($menuName) - { - $panelTable = unserialize(self::options()->panelTable); - $panelTable['parent'] = empty($panelTable['parent']) ? array() : $panelTable['parent']; - - if (false !== ($index = array_search($menuName, $panelTable['parent']))) { - unset($panelTable['parent'][$index]); - } - - $db = Typecho_Db::get(); - Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable))) - , $db->sql()->where('name = ?', 'panelTable')); - - return $index + 10; - } - - /** - * 增加一个面板 - * - * @access public - * @param integer $index 菜单索引 - * @param string $fileName 文件名称 - * @param string $title 面板标题 - * @param string $subTitle 面板副标题 - * @param string $level 进入权限 - * @param boolean $hidden 是否隐藏 - * @param boolean $addLink 新增项目链接, 会显示在页面标题之后 - * @return integer - */ - public static function addPanel($index, $fileName, $title, $subTitle, $level, $hidden = false, $addLink = '') - { - $panelTable = unserialize(self::options()->panelTable); - $panelTable['child'] = empty($panelTable['child']) ? array() : $panelTable['child']; - $panelTable['child'][$index] = empty($panelTable['child'][$index]) ? array() : $panelTable['child'][$index]; - $fileName = urlencode(trim($fileName, '/')); - $panelTable['child'][$index][] = array($title, $subTitle, 'extending.php?panel=' . $fileName, $level, $hidden, $addLink); - - $panelTable['file'] = empty($panelTable['file']) ? array() : $panelTable['file']; - $panelTable['file'][] = $fileName; - $panelTable['file'] = array_unique($panelTable['file']); - - $db = Typecho_Db::get(); - Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable))) - , $db->sql()->where('name = ?', 'panelTable')); - - end($panelTable['child'][$index]); - return key($panelTable['child'][$index]); - } - - /** - * 移除一个面板 - * - * @access public - * @param integer $index 菜单索引 - * @param string $fileName 文件名称 - * @return integer - */ - public static function removePanel($index, $fileName) - { - $panelTable = unserialize(self::options()->panelTable); - $panelTable['child'] = empty($panelTable['child']) ? array() : $panelTable['child']; - $panelTable['child'][$index] = empty($panelTable['child'][$index]) ? array() : $panelTable['child'][$index]; - $panelTable['file'] = empty($panelTable['file']) ? array() : $panelTable['file']; - $fileName = urlencode(trim($fileName, '/')); - - if (false !== ($key = array_search($fileName, $panelTable['file']))) { - unset($panelTable['file'][$key]); - } - - $return = 0; - foreach ($panelTable['child'][$index] as $key => $val) { - if ($val[2] == 'extending.php?panel=' . $fileName) { - unset($panelTable['child'][$index][$key]); - $return = $key; - } - } - - $db = Typecho_Db::get(); - Typecho_Widget::widget('Widget_Abstract_Options')->update(array('value' => (self::options()->panelTable = serialize($panelTable))) - , $db->sql()->where('name = ?', 'panelTable')); - return $return; - } - - /** - * 获取面板url - * - * @access public - * @return unknown - */ - public static function url($fileName) - { - return Typecho_Common::url('extending.php?panel=' . (trim($fileName, '/')), self::options()->adminUrl); - } - - /** - * 手动配置插件变量 - * - * @access public - * @static - * @param mixed $pluginName 插件名称 - * @param mixed array $settings 变量键值对 - * @param bool $isPersonal. (default: false) 是否为私人变量 - * @return void - */ - public static function configPlugin($pluginName, array $settings, $isPersonal = false) - { - if (empty($settings)) { - return; - } - - Widget_Plugins_Edit::configPlugin($pluginName, $settings, $isPersonal); - } - - /** - * 评论回复按钮 - * - * @access public - * @param string $theId 评论元素id - * @param integer $coid 评论id - * @param string $word 按钮文字 - * @param string $formId 表单id - * @param integer $style 样式类型 - * @return void - */ - public static function replyLink($theId, $coid, $word = 'Reply', $formId = 'respond', $style = 2) - { - if (self::options()->commentsThreaded) { - echo '' . $word . ''; - } - } - - /** - * 评论取消按钮 - * - * @access public - * @param string $word 按钮文字 - * @param string $formId 表单id - * @return void - */ - public static function cancleCommentReplyLink($word = 'Cancle', $formId = 'respond') - { - if (self::options()->commentsThreaded) { - echo '' . $word . ''; - } - } - - /** - * 评论回复js脚本 - * - * @access public - * @return void - */ - public static function threadedCommentsScript() - { - if (self::options()->commentsThreaded) { - echo -<< -var typechoAddCommentReply = function (cid, coid, cfid, style) { - var _ce = document.getElementById(cid), _cp = _ce.parentNode; - var _cf = document.getElementById(cfid); - - var _pi = document.getElementById('comment-parent'); - if (null == _pi) { - _pi = document.createElement('input'); - _pi.setAttribute('type', 'hidden'); - _pi.setAttribute('name', 'parent'); - _pi.setAttribute('id', 'comment-parent'); - - var _form = 'form' == _cf.tagName ? _cf : _cf.getElementsByTagName('form')[0]; - - _form.appendChild(_pi); - } - _pi.setAttribute('value', coid); - - if (null == document.getElementById('comment-form-place-holder')) { - var _cfh = document.createElement('div'); - _cfh.setAttribute('id', 'comment-form-place-holder'); - _cf.parentNode.insertBefore(_cfh, _cf); - } - - 1 == style ? (null == _ce.nextSibling ? _cp.appendChild(_cf) - : _cp.insertBefore(_cf, _ce.nextSibling)) : _ce.appendChild(_cf); - - return false; -}; - -var typechoCancleCommentReply = function (cfid) { - var _cf = document.getElementById(cfid), - _cfh = document.getElementById('comment-form-place-holder'); - - var _pi = document.getElementById('comment-parent'); - if (null != _pi) { - _pi.parentNode.removeChild(_pi); - } - - if (null == _cfh) { - return true; - } - - _cfh.parentNode.insertBefore(_cf, _cfh); - return false; -}; - -EOF; - } - } -} diff --git a/php/typecho09/var/IXR/Base64.php b/php/typecho09/var/IXR/Base64.php deleted file mode 100644 index 0afe16eae..000000000 --- a/php/typecho09/var/IXR/Base64.php +++ /dev/null @@ -1,43 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** - * IXR Base64编码 - * - * @package IXR - */ -class IXR_Base64 -{ - /** - * 编码数据 - * - * @var string - */ - private $data; - - /** - * 初始化数据 - * - * @param string $data - */ - public function __construct($data) - { - $this->data = $data; - } - - /** - * 获取XML数据 - * - * @return string - */ - public function getXml() - { - return '' . base64_encode($this->data) . ''; - } -} diff --git a/php/typecho09/var/IXR/Client.php b/php/typecho09/var/IXR/Client.php deleted file mode 100644 index 89f1cc15b..000000000 --- a/php/typecho09/var/IXR/Client.php +++ /dev/null @@ -1,300 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** IXR值 */ -require_once 'IXR/Value.php'; - -/** IXR消息 */ -require_once 'IXR/Message.php'; - -/** IXR请求体 */ -require_once 'IXR/Request.php'; - -/** IXR错误 */ -require_once 'IXR/Error.php'; - -/** IXR日期 */ -require_once 'IXR/Date.php'; - -/** IXR Base64编码 */ -require_once 'IXR/Base64.php'; - -/** Typecho_Http_Client */ -require_once 'Typecho/Http/Client.php'; - -/** - * IXR客户端 - * reload by typecho team(http://www.typecho.org) - * - * @package IXR - */ -class IXR_Client -{ - /** 默认客户端 */ - const DEFAULT_USERAGENT = 'The Incutio XML-RPC PHP Library(Reload By Typecho)'; - - /** - * 服务端地址 - * - * @access private - * @var string - */ - private $server; - - /** - * 端口名称 - * - * @access private - * @var integer - */ - private $port; - - /** - * 路径名称 - * - * @access private - * @var string - */ - private $path; - - /** - * 地址 - * - * @access private - * @var string - */ - private $url; - - /** - * 客户端 - * - * @access private - * @var string - */ - private $useragent; - - /** - * 回执结构体 - * - * @access private - * @var string - */ - private $response; - - /** - * 消息体 - * - * @access private - * @var string - */ - private $message = false; - - /** - * 调试开关 - * - * @access private - * @var boolean - */ - private $debug = false; - - /** - * 请求前缀 - * - * @access private - * @var string - */ - private $prefix = NULL; - - // Storage place for an error message - private $error = false; - - /** - * 客户端构造函数 - * - * @access public - * @param string $server 服务端地址 - * @param string $path 路径名称 - * @param integer $port 端口名称 - * @param string $useragent 客户端 - * @return void - */ - public function __construct($server, $path = false, $port = 80, $useragent = self::DEFAULT_USERAGENT, $prefix = NULL) - { - if (!$path) { - $this->url = $server; - - // Assume we have been given a Url instead - $bits = parse_url($server); - $this->server = $bits['host']; - $this->port = isset($bits['port']) ? $bits['port'] : 80; - $this->path = isset($bits['path']) ? $bits['path'] : '/'; - - // Make absolutely sure we have a path - if (isset($bits['query'])) { - $this->path .= '?' . $bits['query']; - } - } else { - /** Typecho_Common */ - require_once 'Typecho/Common.php'; - - $this->url = Typecho_Common::buildUrl(array( - 'scheme' => 'http', - 'host' => $server, - 'path' => $path, - 'port' => $port - )); - - $this->server = $server; - $this->path = $path; - $this->port = $port; - } - - $this->prefix = $prefix; - $this->useragent = $useragent; - } - - /** - * 设置调试模式 - * - * @access public - * @return void - */ - public function __setDebug() - { - $this->debug = true; - } - - /** - * 执行请求 - * - * @access public - * @return void - */ - public function __rpcCall() - { - $args = func_get_args(); - $method = array_shift($args); - $request = new IXR_Request($method, $args); - $xml = $request->getXml(); - - $client = Typecho_Http_Client::get(); - if (!$client) { - $this->error = new IXR_Error(-32300, 'transport error - could not open socket'); - return false; - } - - $client->setHeader('Content-Type', 'text/xml') - ->setHeader('User-Agent', $this->useragent) - ->setData($xml) - ->send($this->url); - - $contents = $client->getResponseBody(); - - if ($this->debug) { - echo '
    '.htmlspecialchars($contents)."\n
    \n\n"; - } - - // Now parse what we've got back - $this->message = new IXR_Message($contents); - if (!$this->message->parse()) { - // XML error - $this->error = new IXR_Error(-32700, 'parse error. not well formed'); - return false; - } - - // Is the message a fault? - if ($this->message->messageType == 'fault') { - $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); - return false; - } - - // Message must be OK - return true; - } - - /** - * 增加前缀 - * - * $rpc->metaWeblog->newPost(); - * - * - * @access public - * @param string $prefix 前缀 - * @return void - */ - public function __get($prefix) - { - return new IXR_Client($this->server, $this->path, $this->port, $this->useragent, $this->prefix . $prefix . '.'); - } - - /** - * 增加魔术特性 - * by 70 - * - * @access public - * @return mixed - */ - public function __call($method, $args) - { - array_unshift($args, $this->prefix . $method); - $return = call_user_func_array(array($this, '__rpcCall'), $args); - - if ($return) { - return $this->__getResponse(); - } else { - require_once 'IXR/Exception.php'; - throw new IXR_Exception($this->__getErrorMessage(), $this->__getErrorCode()); - } - } - - /** - * 获得返回值 - * - * @access public - * @return void - */ - public function __getResponse() - { - // methodResponses can only have one param - return that - return $this->message->params[0]; - } - - /** - * 是否为错误 - * - * @access public - * @return void - */ - public function __isError() - { - return (is_object($this->error)); - } - - /** - * 获取错误代码 - * - * @access public - * @return void - */ - public function __getErrorCode() - { - return $this->error->code; - } - - /** - * 获取错误消息 - * - * @access public - * @return void - */ - public function __getErrorMessage() - { - return $this->error->message; - } -} diff --git a/php/typecho09/var/IXR/ClientMulticall.php b/php/typecho09/var/IXR/ClientMulticall.php deleted file mode 100644 index 24f91148a..000000000 --- a/php/typecho09/var/IXR/ClientMulticall.php +++ /dev/null @@ -1,37 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** IXR_Clinet */ -require_once 'IXR/Clinet.php'; - -/** - * IXR客户端 - * - * @package IXR - */ -class IXR_ClientMulticall extends IXR_Client { - var $calls = array(); - function IXR_ClientMulticall($server, $path = false, $port = 80) { - parent::IXR_Client($server, $path, $port); - $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)'; - } - function addCall() { - $args = func_get_args(); - $methodName = array_shift($args); - $struct = array( - 'methodName' => $methodName, - 'params' => $args - ); - $this->calls[] = $struct; - } - function query() { - // Prepare multicall, then call the parent::query() method - return parent::query('system.multicall', $this->calls); - } -} diff --git a/php/typecho09/var/IXR/Date.php b/php/typecho09/var/IXR/Date.php deleted file mode 100644 index 048caae22..000000000 --- a/php/typecho09/var/IXR/Date.php +++ /dev/null @@ -1,55 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** - * IXR日期 - * - * @package IXR - */ -class IXR_Date { - var $year; - var $month; - var $day; - var $hour; - var $minute; - var $second; - function IXR_Date($time) { - // $time can be a PHP timestamp or an ISO one - if (is_numeric($time)) { - $this->parseTimestamp($time); - } else { - $this->parseIso($time); - } - } - function parseTimestamp($timestamp) { - $this->year = date('Y', $timestamp); - $this->month = date('m', $timestamp); - $this->day = date('d', $timestamp); - $this->hour = date('H', $timestamp); - $this->minute = date('i', $timestamp); - $this->second = date('s', $timestamp); - } - function parseIso($iso) { - $this->year = substr($iso, 0, 4); - $this->month = substr($iso, 4, 2); - $this->day = substr($iso, 6, 2); - $this->hour = substr($iso, 9, 2); - $this->minute = substr($iso, 12, 2); - $this->second = substr($iso, 15, 2); - } - function getIso() { - return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; - } - function getXml() { - return ''.$this->getIso().''; - } - function getTimestamp() { - return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); - } -} diff --git a/php/typecho09/var/IXR/Error.php b/php/typecho09/var/IXR/Error.php deleted file mode 100644 index cfc7aaad5..000000000 --- a/php/typecho09/var/IXR/Error.php +++ /dev/null @@ -1,76 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** - * IXR错误 - * - * @package IXR - */ -class IXR_Error -{ - /** - * 错误代码 - * - * @access public - * @var integer - */ - public $code; - - /** - * 错误消息 - * - * @access public - * @var string - */ - public $message; - - /** - * 构造函数 - * - * @access public - * @param integer $code 错误代码 - * @param string $message 错误消息 - * @return void - */ - public function __construct($code, $message) - { - $this->code = $code; - $this->message = $message; - } - - /** - * 获取xml - * - * @access public - * @return string - */ - public function getXml() - { - $xml = << - - - - - faultCode - {$this->code} - - - faultString - {$this->message} - - - - - - -EOD; - return $xml; - } -} diff --git a/php/typecho09/var/IXR/Exception.php b/php/typecho09/var/IXR/Exception.php deleted file mode 100644 index 9fad44739..000000000 --- a/php/typecho09/var/IXR/Exception.php +++ /dev/null @@ -1,16 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** - * IXR异常类 - * - * @package IXR - */ -class IXR_Exception extends Exception -{} diff --git a/php/typecho09/var/IXR/IntrospectionServer.php b/php/typecho09/var/IXR/IntrospectionServer.php deleted file mode 100644 index b8664c970..000000000 --- a/php/typecho09/var/IXR/IntrospectionServer.php +++ /dev/null @@ -1,160 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** IXR_Server */ -require_once 'IXR/Server.php'; - -/** - * IXR服务器 - * - * @package IXR - */ -class IXR_IntrospectionServer extends IXR_Server { - var $signatures; - var $help; - function IXR_IntrospectionServer() { - $this->setCallbacks(); - $this->setCapabilities(); - $this->capabilities['introspection'] = array( - 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html', - 'specVersion' => 1 - ); - $this->addCallback( - 'system.methodSignature', - 'this:methodSignature', - array('array', 'string'), - 'Returns an array describing the return type and required parameters of a method' - ); - $this->addCallback( - 'system.getCapabilities', - 'this:getCapabilities', - array('struct'), - 'Returns a struct describing the XML-RPC specifications supported by this server' - ); - $this->addCallback( - 'system.listMethods', - 'this:listMethods', - array('array'), - 'Returns an array of available methods on this server' - ); - $this->addCallback( - 'system.methodHelp', - 'this:methodHelp', - array('string', 'string'), - 'Returns a documentation string for the specified method' - ); - } - function addCallback($method, $callback, $args, $help) { - $this->callbacks[$method] = $callback; - $this->signatures[$method] = $args; - $this->help[$method] = $help; - } - function call($methodname, $args) { - // Make sure it's in an array - if ($args && !is_array($args)) { - $args = array($args); - } - // Over-rides default call method, adds signature check - if (!$this->hasMethod($methodname)) { - return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.'); - } - $method = $this->callbacks[$methodname]; - $signature = $this->signatures[$methodname]; - $returnType = array_shift($signature); - // Check the number of arguments - if (count($args) != count($signature)) { - // print 'Num of args: '.count($args).' Num in signature: '.count($signature); - return new IXR_Error(-32602, 'server error. wrong number of method parameters'); - } - // Check the argument types - $ok = true; - $argsbackup = $args; - for ($i = 0, $j = count($args); $i < $j; $i++) { - $arg = array_shift($args); - $type = array_shift($signature); - switch ($type) { - case 'int': - case 'i4': - if (is_array($arg) || !is_int($arg)) { - $ok = false; - } - break; - case 'base64': - case 'string': - if (!is_string($arg)) { - $ok = false; - } - break; - case 'boolean': - if ($arg !== false && $arg !== true) { - $ok = false; - } - break; - case 'float': - case 'double': - if (!is_float($arg)) { - $ok = false; - } - break; - case 'date': - case 'dateTime.iso8601': - if (!is_a($arg, 'IXR_Date')) { - $ok = false; - } - break; - } - if (!$ok) { - return new IXR_Error(-32602, 'server error. invalid method parameters'); - } - } - // It passed the test - run the "real" method call - return parent::call($methodname, $argsbackup); - } - function methodSignature($method) { - if (!$this->hasMethod($method)) { - return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.'); - } - // We should be returning an array of types - $types = $this->signatures[$method]; - $return = array(); - foreach ($types as $type) { - switch ($type) { - case 'string': - $return[] = 'string'; - break; - case 'int': - case 'i4': - $return[] = 42; - break; - case 'double': - $return[] = 3.1415; - break; - case 'dateTime.iso8601': - $return[] = new IXR_Date(time()); - break; - case 'boolean': - $return[] = true; - break; - case 'base64': - $return[] = new IXR_Base64('base64'); - break; - case 'array': - $return[] = array('array'); - break; - case 'struct': - $return[] = array('struct' => 'struct'); - break; - } - } - return $return; - } - function methodHelp($method) { - return $this->help[$method]; - } -} diff --git a/php/typecho09/var/IXR/Message.php b/php/typecho09/var/IXR/Message.php deleted file mode 100644 index 78cb703d8..000000000 --- a/php/typecho09/var/IXR/Message.php +++ /dev/null @@ -1,167 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** - * IXR消息 - * - * @package IXR - */ -class IXR_Message { - var $message; - var $messageType; // methodCall / methodResponse / fault - var $faultCode; - var $faultString; - var $methodName; - var $params; - // Current variable stacks - var $_arraystructs = array(); // The stack used to keep track of the current array/struct - var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array - var $_currentStructName = array(); // A stack as well - var $_param; - var $_value; - var $_currentTag; - var $_currentTagContents; - // The XML parser - var $_parser; - function IXR_Message ($message) { - $this->message = $message; - } - function parse() { - // first remove the XML declaration - $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); - if (trim($this->message) == '') { - return false; - } - $this->_parser = xml_parser_create(); - // Set XML parser to take the case of tags in to account - xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); - // Set XML parser callback functions - xml_set_object($this->_parser, $this); - xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); - xml_set_character_data_handler($this->_parser, 'cdata'); - if (!xml_parse($this->_parser, $this->message)) { - /* die(sprintf('XML error: %s at line %d', - xml_error_string(xml_get_error_code($this->_parser)), - xml_get_current_line_number($this->_parser))); */ - return false; - } - xml_parser_free($this->_parser); - // Grab the error messages, if any - if ($this->messageType == 'fault') { - $this->faultCode = $this->params[0]['faultCode']; - $this->faultString = $this->params[0]['faultString']; - } - return true; - } - function tag_open($parser, $tag, $attr) { - $this->currentTag = $tag; - switch($tag) { - case 'methodCall': - case 'methodResponse': - case 'fault': - $this->messageType = $tag; - break; - /* Deal with stacks of arrays and structs */ - case 'data': // data is to all intents and puposes more interesting than array - $this->_arraystructstypes[] = 'array'; - $this->_arraystructs[] = array(); - break; - case 'struct': - $this->_arraystructstypes[] = 'struct'; - $this->_arraystructs[] = array(); - break; - } - } - function cdata($parser, $cdata) { - $this->_currentTagContents .= $cdata; - } - function tag_close($parser, $tag) { - $valueFlag = false; - switch($tag) { - case 'int': - case 'i4': - $value = (int)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'double': - $value = (double)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'string': - $value = (string)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'dateTime.iso8601': - $value = new IXR_Date(trim($this->_currentTagContents)); - // $value = $iso->getTimestamp(); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'value': - // "If no type is indicated, the type is string." - if (trim($this->_currentTagContents) != '') { - $value = (string)$this->_currentTagContents; - $this->_currentTagContents = ''; - $valueFlag = true; - } - break; - case 'boolean': - $value = (boolean)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'base64': - $value = base64_decode($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - /* Deal with stacks of arrays and structs */ - case 'data': - case 'struct': - $value = array_pop($this->_arraystructs); - array_pop($this->_arraystructstypes); - $valueFlag = true; - break; - case 'member': - array_pop($this->_currentStructName); - break; - case 'name': - $this->_currentStructName[] = trim($this->_currentTagContents); - $this->_currentTagContents = ''; - break; - case 'methodName': - $this->methodName = trim($this->_currentTagContents); - $this->_currentTagContents = ''; - break; - } - if ($valueFlag) { - /* - if (!is_array($value) && !is_object($value)) { - $value = trim($value); - } - */ - if (count($this->_arraystructs) > 0) { - // Add value to struct or array - if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { - // Add to struct - $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; - } else { - // Add to array - $this->_arraystructs[count($this->_arraystructs)-1][] = $value; - } - } else { - // Just add as a paramater - $this->params[] = $value; - } - } - } -} diff --git a/php/typecho09/var/IXR/Request.php b/php/typecho09/var/IXR/Request.php deleted file mode 100644 index ef2df6cae..000000000 --- a/php/typecho09/var/IXR/Request.php +++ /dev/null @@ -1,43 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** - * IXR请求体 - * - * @package IXR - */ -class IXR_Request { - var $method; - var $args; - var $xml; - function IXR_Request($method, $args) { - $this->method = $method; - $this->args = $args; - $this->xml = << - -{$this->method} - - -EOD; - foreach ($this->args as $arg) { - $this->xml .= ''; - $v = new IXR_Value($arg); - $this->xml .= $v->getXml(); - $this->xml .= "\n"; - } - $this->xml .= ''; - } - function getLength() { - return strlen($this->xml); - } - function getXml() { - return $this->xml; - } -} diff --git a/php/typecho09/var/IXR/Server.php b/php/typecho09/var/IXR/Server.php deleted file mode 100644 index a7fce2b34..000000000 --- a/php/typecho09/var/IXR/Server.php +++ /dev/null @@ -1,346 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** IXR值 */ -require_once 'IXR/Value.php'; - -/** IXR消息 */ -require_once 'IXR/Message.php'; - -/** IXR请求体 */ -require_once 'IXR/Request.php'; - -/** IXR错误 */ -require_once 'IXR/Error.php'; - -/** IXR日期 */ -require_once 'IXR/Date.php'; - -/** IXR Base64编码 */ -require_once 'IXR/Base64.php'; - -/** - * IXR服务器 - * - * @package IXR - */ -class IXR_Server -{ - /** - * 输入参数 - * - * @access private - * @var array - */ - private $data; - - /** - * 回调函数 - * - * @access private - * @var array - */ - private $callbacks = array(); - - /** - * 消息体 - * - * @access private - * @var IXR_Message - */ - private $message; - - /** - * 默认参数 - * - * @access private - * @var array - */ - private $capabilities; - - /** - * 构造函数 - * - * @access public - * @param mixed $callbacks 回调函数 - * @param mixed $data 输入参数 - * @return void - */ - public function __construct($callbacks = false, $data = false) - { - $this->setCapabilities(); - if ($callbacks) { - $this->callbacks = $callbacks; - } - $this->setCallbacks(); - $this->serve($data); - } - - /** - * 呼叫内部方法 - * - * @access private - * @param string $methodname 方法名 - * @param mixed $args 参数 - * @return mixed - */ - private function call($methodname, $args) - { - // hook - if (0 !== strpos($methodname, 'hook.') && $this->hasMethod('hook.beforeCall')) { - $this->call('hook.beforeCall', array($methodname)); - } - - if (!$this->hasMethod($methodname)) { - return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.'); - } - $method = $this->callbacks[$methodname]; - - // Are we dealing with a function or a method? - if (is_string($method) && substr($method, 0, 5) == 'this:') { - // It's a class method - check it exists - $method = substr($method, 5); - if (!method_exists($this, $method)) { - return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.'); - } - // Call the method - $result = $this->$method($args); - } else { - if (is_array($method)) { - list($object, $func) = $method; - if (!is_callable($method)) { - return new IXR_Error(-32601, 'server error. requested class method "'.$object . '.' . $func.'" does not exist.'); - } - - $result = call_user_func_array(array($object, $func), $args); - } elseif (!function_exists($method)) { - // It's a function - does it exist? - return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.'); - } else { - // Call the function - $result = $method($args); - } - } - - // hook - if (0 !== strpos($methodname, 'hook.') && $this->hasMethod('hook.afterCall')) { - $this->call('hook.afterCall', array($methodname)); - } - - return $result; - } - - /** - * 抛出错误 - * - * @access private - * @param integer $error 错误代码 - * @param string $message 错误消息 - * @return void - */ - private function error($error, $message = false) - { - // Accepts either an error object or an error code and message - if ($message && !is_object($error)) { - $error = new IXR_Error($error, $message); - } - $this->output($error->getXml()); - } - - /** - * 输出xml - * - * @access private - * @param string $xml 输出xml - * @return 输出xml - */ - private function output($xml) - { - $xml = ''."\n".$xml; - $length = strlen($xml); - header('Connection: close'); - header('Content-Length: '.$length); - header('Content-Type: text/xml'); - header('Date: '.date('r')); - echo $xml; - exit; - } - - /** - * 是否存在方法 - * - * @access private - * @param string $method 方法名 - * @return mixed - */ - private function hasMethod($method) - { - return in_array($method, array_keys($this->callbacks)); - } - - /** - * 设置默认参数 - * - * @access public - * @return void - */ - private function setCapabilities() - { - // Initialises capabilities array - $this->capabilities = array( - 'xmlrpc' => array( - 'specUrl' => 'http://www.xmlrpc.com/spec', - 'specVersion' => 1 - ), - 'faults_interop' => array( - 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php', - 'specVersion' => 20010516 - ), - 'system.multicall' => array( - 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', - 'specVersion' => 1 - ), - ); - } - - /** - * 设置默认方法 - * - * @access private - * @return void - */ - private function setCallbacks() - { - $this->callbacks['system.getCapabilities'] = 'this:getCapabilities'; - $this->callbacks['system.listMethods'] = 'this:listMethods'; - $this->callbacks['system.multicall'] = 'this:multiCall'; - } - - /** - * 服务入口 - * - * @access private - * @param mixed $data 输入参数 - * @return void - */ - private function serve($data = false) - { - if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) { - $GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents("php://input"); - } - if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) { - $GLOBALS['HTTP_RAW_POST_DATA'] = trim($GLOBALS['HTTP_RAW_POST_DATA']); - } - - if (!$data) { - global $HTTP_RAW_POST_DATA; - if (!$HTTP_RAW_POST_DATA) { - die('XML-RPC server accepts POST requests only.'); - } - $data = $HTTP_RAW_POST_DATA; - } - $this->message = new IXR_Message($data); - if (!$this->message->parse()) { - $this->error(-32700, 'parse error. not well formed'); - } - if ($this->message->messageType != 'methodCall') { - $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall'); - } - - if (0 === strpos($this->message->methodName, 'hook.')) { - die('THIS METHOD MUST BE CALLED INSIDE.'); - } - - $result = $this->call($this->message->methodName, $this->message->params); - // Is the result an error? - if (is_a($result, 'IXR_Error')) { - $this->error($result); - } - // Encode the result - $r = new IXR_Value($result); - $resultxml = $r->getXml(); - // Create the XML - $xml = << - - - - $resultxml - - - - - -EOD; - // hook - if ($this->hasMethod('hook.beforeOutput')) { - $this->call('hook.beforeOutput', array()); - } - - // Send it - $this->output($xml); - } - - /** - * 获取默认参数 - * - * @access public - * @param mixed $args 输入参数 - * @return array - */ - public function getCapabilities($args) - { - return $this->capabilities; - } - - /** - * 列出所有方法 - * - * @access public - * @param mixed $args 输入参数 - * @return mixed - */ - public function listMethods($args) - { - // Returns a list of methods - uses array_reverse to ensure user defined - // methods are listed before server defined methods - return array_reverse(array_keys($this->callbacks)); - } - - /** - * 一次处理多个请求 - * - * @access public - * @param void $methodcalls - * @return array - */ - public function multiCall($methodcalls) - { - // See http://www.xmlrpc.com/discuss/msgReader$1208 - $return = array(); - foreach ($methodcalls as $call) { - $method = $call['methodName']; - $params = $call['params']; - if ($method == 'system.multicall') { - $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden'); - } else { - $result = $this->call($method, $params); - } - if (is_a($result, 'IXR_Error')) { - $return[] = array( - 'faultCode' => $result->code, - 'faultString' => $result->message - ); - } else { - $return[] = array($result); - } - } - return $return; - } -} diff --git a/php/typecho09/var/IXR/Value.php b/php/typecho09/var/IXR/Value.php deleted file mode 100644 index 4e8424d16..000000000 --- a/php/typecho09/var/IXR/Value.php +++ /dev/null @@ -1,119 +0,0 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php -*/ - -/** - * IXR值 - * - * @package IXR - */ -class IXR_Value { - var $data; - var $type; - function IXR_Value ($data, $type = false) { - $this->data = $data; - if (!$type) { - $type = $this->calculateType(); - } - $this->type = $type; - if ($type == 'struct') { - /* Turn all the values in the array in to new IXR_Value objects */ - foreach ($this->data as $key => $value) { - $this->data[$key] = new IXR_Value($value); - } - } - if ($type == 'array') { - for ($i = 0, $j = count($this->data); $i < $j; $i++) { - $this->data[$i] = new IXR_Value($this->data[$i]); - } - } - } - function calculateType() { - if ($this->data === true || $this->data === false) { - return 'boolean'; - } - if (is_integer($this->data)) { - return 'int'; - } - if (is_double($this->data)) { - return 'double'; - } - // Deal with IXR object types base64 and date - if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { - return 'date'; - } - if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { - return 'base64'; - } - // If it is a normal PHP object convert it in to a struct - if (is_object($this->data)) { - - $this->data = get_object_vars($this->data); - return 'struct'; - } - if (!is_array($this->data)) { - return 'string'; - } - /* We have an array - is it an array or a struct ? */ - if ($this->isStruct($this->data)) { - return 'struct'; - } else { - return 'array'; - } - } - function getXml() { - /* Return XML for this value */ - switch ($this->type) { - case 'boolean': - return ''.(($this->data) ? '1' : '0').''; - break; - case 'int': - return ''.$this->data.''; - break; - case 'double': - return ''.$this->data.''; - break; - case 'string': - return ''.htmlspecialchars($this->data).''; - break; - case 'array': - $return = ''."\n"; - foreach ($this->data as $item) { - $return .= ' '.$item->getXml()."\n"; - } - $return .= ''; - return $return; - break; - case 'struct': - $return = ''."\n"; - foreach ($this->data as $name => $value) { - $return .= " $name"; - $return .= $value->getXml()."\n"; - } - $return .= ''; - return $return; - break; - case 'date': - case 'base64': - return $this->data->getXml(); - break; - } - return false; - } - function isStruct($array) { - /* Nasty function to check if an array is a struct or not */ - $expected = 0; - foreach ($array as $key => $value) { - if ((string)$key != (string)$expected) { - return true; - } - $expected++; - } - return false; - } -} diff --git a/php/typecho09/var/MarkdownExtraExtended.php b/php/typecho09/var/MarkdownExtraExtended.php deleted file mode 100644 index 674d089aa..000000000 --- a/php/typecho09/var/MarkdownExtraExtended.php +++ /dev/null @@ -1,3305 +0,0 @@ - -# -# Original Markdown -# Copyright (c) 2004-2006 John Gruber -# -# - -# -# Markdown Parser Class -# - -class Markdown { - - ### Version ### - - const MARKDOWNLIB_VERSION = "1.3"; - - ### Configuration Variables ### - - # Change to ">" for HTML output. - public $empty_element_suffix = " />"; - public $tab_width = 4; - - # Change to `true` to disallow markup or entities. - public $no_markup = false; - public $no_entities = false; - - # Predefined urls and titles for reference links and images. - public $predef_urls = array(); - public $predef_titles = array(); - - - ### Parser Implementation ### - - # Regex to match balanced [brackets]. - # Needed to insert a maximum bracked depth while converting to PHP. - protected $nested_brackets_depth = 6; - protected $nested_brackets_re; - - protected $nested_url_parenthesis_depth = 4; - protected $nested_url_parenthesis_re; - - # Table of hash values for escaped characters: - protected $escape_chars = '\`*_{}[]()>#+-.!'; - protected $escape_chars_re; - - - public function __construct() { - # - # Constructor function. Initialize appropriate member variables. - # - $this->_initDetab(); - $this->prepareItalicsAndBold(); - - $this->nested_brackets_re = - str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). - str_repeat('\])*', $this->nested_brackets_depth); - - $this->nested_url_parenthesis_re = - str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). - str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); - - $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; - - # Sort document, block, and span gamut in ascendent priority order. - asort($this->document_gamut); - asort($this->block_gamut); - asort($this->span_gamut); - } - - - # Internal hashes used during transformation. - protected $urls = array(); - protected $titles = array(); - protected $html_hashes = array(); - - # Status flag to avoid invalid nesting. - protected $in_anchor = false; - - - protected function setup() { - # - # Called before the transformation process starts to setup parser - # states. - # - # Clear global hashes. - $this->urls = $this->predef_urls; - $this->titles = $this->predef_titles; - $this->html_hashes = array(); - - $this->in_anchor = false; - } - - protected function teardown() { - # - # Called after the transformation process to clear any variable - # which may be taking up memory unnecessarly. - # - $this->urls = array(); - $this->titles = array(); - $this->html_hashes = array(); - } - - - public function transform($text) { - # - # Main function. Performs some preprocessing on the input text - # and pass it through the document gamut. - # - $this->setup(); - - # Remove UTF-8 BOM and marker character in input, if present. - $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); - - # Standardize line endings: - # DOS to Unix and Mac to Unix - $text = preg_replace('{\r\n?}', "\n", $text); - - # Make sure $text ends with a couple of newlines: - $text .= "\n\n"; - - # Convert all tabs to spaces. - $text = $this->detab($text); - - # Turn block-level HTML blocks into hash entries - $text = $this->hashHTMLBlocks($text); - - # Strip any lines consisting only of spaces and tabs. - # This makes subsequent regexen easier to write, because we can - # match consecutive blank lines with /\n+/ instead of something - # contorted like /[ ]*\n+/ . - $text = preg_replace('/^[ ]+$/m', '', $text); - - # Run document gamut methods. - foreach ($this->document_gamut as $method => $priority) { - $text = $this->$method($text); - } - - $this->teardown(); - - $text = preg_replace_callback("/<\/?(\!doctype|html|head|body|link|title|input|select|button|textarea|style|noscript)[^>]*>/is", - array($this, '_doEscape_callback'), $text); - - return $text . "\n"; - } - - /** - * _doEscape_callback - * - * @param array $matches - * @access protected - * @return string - */ - protected function _doEscape_callback($matches) { - return htmlspecialchars($matches[0], ENT_NOQUOTES); - } - - protected $document_gamut = array( - # Strip link definitions, store in hashes. - "stripLinkDefinitions" => 20, - - "runBasicBlockGamut" => 30, - ); - - - protected function stripLinkDefinitions($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # - $less_than_tab = $this->tab_width - 1; - - # Link defs are in the form: ^[id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 - [ ]* - \n? # maybe *one* newline - [ ]* - (?: - <(.+?)> # url = $2 - | - (\S+?) # url = $3 - ) - [ ]* - \n? # maybe one newline - [ ]* - (?: - (?<=\s) # lookbehind for whitespace - ["(] - (.*?) # title = $4 - [")] - [ ]* - )? # title is optional - (?:\n+|\Z) - }xm', - array($this, '_stripLinkDefinitions_callback'), - $text); - return $text; - } - protected function _stripLinkDefinitions_callback($matches) { - $link_id = strtolower($matches[1]); - $url = $matches[2] == '' ? $matches[3] : $matches[2]; - $this->urls[$link_id] = $url; - $this->titles[$link_id] =& $matches[4]; - return ''; # String that will replace the block - } - - - protected function hashHTMLBlocks($text) { - if ($this->no_markup) return $text; - - $less_than_tab = $this->tab_width - 1; - - # Hashify HTML blocks: - # We only want to do this for block-level HTML tags, such as headers, - # lists, and tables. That's because we still want to wrap

    s around - # "paragraphs" that are wrapped in non-block-level tags, such as anchors, - # phrase emphasis, and spans. The list of tags we're looking for is - # hard-coded: - # - # * List "a" is made of tags which can be both inline or block-level. - # These will be treated block-level when the start tag is alone on - # its line, otherwise they're not matched here and will be taken as - # inline later. - # * List "b" is made of tags which are always block-level; - # - $block_tags_a_re = 'ins|del'; - $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. - 'script|noscript|form|fieldset|iframe|math|svg|'. - 'article|section|nav|aside|hgroup|header|footer|'. - 'figure'; - - # Regular expression for the content of a block tag. - $nested_tags_level = 4; - $attr = ' - (?> # optional tag attributes - \s # starts with whitespace - (?> - [^>"/]+ # text outside quotes - | - /+(?!>) # slash not followed by ">" - | - "[^"]*" # text inside double quotes (tolerate ">") - | - \'[^\']*\' # text inside single quotes (tolerate ">") - )* - )? - '; - $content = - str_repeat(' - (?> - [^<]+ # content without tag - | - <\2 # nested opening tag - '.$attr.' # attributes - (?> - /> - | - >', $nested_tags_level). # end of opening tag - '.*?'. # last level nested tag content - str_repeat(' - # closing nested tag - ) - | - <(?!/\2\s*> # other tags with a different name - ) - )*', - $nested_tags_level); - $content2 = str_replace('\2', '\3', $content); - - # First, look for nested blocks, e.g.: - #

    - #
    - # tags for inner block must be indented. - #
    - #
    - # - # The outermost tags must start at the left margin for this to match, and - # the inner nested divs must be indented. - # We need to do this before the next, more liberal match, because the next - # match will start at the first `
    ` and stop at the first `
    `. - $text = preg_replace_callback('{(?> - (?> - (?<=\n\n) # Starting after a blank line - | # or - \A\n? # the beginning of the doc - ) - ( # save in $1 - - # Match from `\n` to `\n`, handling nested tags - # in between. - - [ ]{0,'.$less_than_tab.'} - <('.$block_tags_b_re.')# start tag = $2 - '.$attr.'> # attributes followed by > and \n - '.$content.' # content, support nesting - # the matching end tag - [ ]* # trailing spaces/tabs - (?=\n+|\Z) # followed by a newline or end of document - - | # Special version for tags of group a. - - [ ]{0,'.$less_than_tab.'} - <('.$block_tags_a_re.')# start tag = $3 - '.$attr.'>[ ]*\n # attributes followed by > - '.$content2.' # content, support nesting - # the matching end tag - [ ]* # trailing spaces/tabs - (?=\n+|\Z) # followed by a newline or end of document - - | # Special case just for
    . It was easier to make a special - # case than to make the other regex more complicated. - - [ ]{0,'.$less_than_tab.'} - <(hr) # start tag = $2 - '.$attr.' # attributes - /?> # the matching end tag - [ ]* - (?=\n{2,}|\Z) # followed by a blank line or end of document - - | # Special case for standalone HTML comments: - - [ ]{0,'.$less_than_tab.'} - (?s: - - ) - [ ]* - (?=\n{2,}|\Z) # followed by a blank line or end of document - - | # PHP and ASP-style processor instructions ( - ) - [ ]* - (?=\n{2,}|\Z) # followed by a blank line or end of document - - ) - )}Sxmi', - array($this, '_hashHTMLBlocks_callback'), - $text); - - return $text; - } - protected function _hashHTMLBlocks_callback($matches) { - $text = $matches[1]; - $key = $this->hashBlock($text); - return "\n\n$key\n\n"; - } - - - protected function hashPart($text, $boundary = 'X') { - # - # Called whenever a tag must be hashed when a function insert an atomic - # element in the text stream. Passing $text to through this function gives - # a unique text-token which will be reverted back when calling unhash. - # - # The $boundary argument specify what character should be used to surround - # the token. By convension, "B" is used for block elements that needs not - # to be wrapped into paragraph tags at the end, ":" is used for elements - # that are word separators and "X" is used in the general case. - # - # Swap back any tag hash found in $text so we do not have to `unhash` - # multiple times at the end. - $text = $this->unhash($text); - - # Then hash the block. - static $i = 0; - $key = "$boundary\x1A" . ++$i . $boundary; - $this->html_hashes[$key] = $text; - return $key; # String that will replace the tag. - } - - - protected function hashBlock($text) { - # - # Shortcut function for hashPart with block-level boundaries. - # - return $this->hashPart($text, 'B'); - } - - - protected $block_gamut = array( - # - # These are all the transformations that form block-level - # tags like paragraphs, headers, and list items. - # - "doHeaders" => 10, - "doHorizontalRules" => 20, - - "doLists" => 40, - "doCodeBlocks" => 50, - "doBlockQuotes" => 60, - ); - - protected function runBlockGamut($text) { - # - # Run block gamut tranformations. - # - # We need to escape raw HTML in Markdown source before doing anything - # else. This need to be done for each block, and not only at the - # begining in the Markdown function since hashed blocks can be part of - # list items and could have been indented. Indented blocks would have - # been seen as a code block in a previous pass of hashHTMLBlocks. - $text = $this->hashHTMLBlocks($text); - - return $this->runBasicBlockGamut($text); - } - - protected function runBasicBlockGamut($text) { - # - # Run block gamut tranformations, without hashing HTML blocks. This is - # useful when HTML blocks are known to be already hashed, like in the first - # whole-document pass. - # - foreach ($this->block_gamut as $method => $priority) { - $text = $this->$method($text); - } - - # Finally form paragraph and restore hashed blocks. - $text = $this->formParagraphs($text); - - return $text; - } - - - protected function doHorizontalRules($text) { - # Do Horizontal Rules: - return preg_replace( - '{ - ^[ ]{0,3} # Leading space - ([-*_]) # $1: First marker - (?> # Repeated marker group - [ ]{0,2} # Zero, one, or two spaces. - \1 # Marker character - ){2,} # Group repeated at least twice - [ ]* # Tailing spaces - $ # End of line. - }mx', - "\n".$this->hashBlock("empty_element_suffix")."\n", - $text); - } - - - protected $span_gamut = array( - # - # These are all the transformations that occur *within* block-level - # tags like paragraphs, headers, and list items. - # - # Process character escapes, code spans, and inline HTML - # in one shot. - "parseSpan" => -30, - - # Process anchor and image tags. Images must come first, - # because ![foo][f] looks like an anchor. - "doImages" => 10, - "doAnchors" => 20, - - # Make links out of things like `` - # Must come after doAnchors, because you can use < and > - # delimiters in inline links like [this](). - "doAutoLinks" => 30, - "encodeAmpsAndAngles" => 40, - - "doItalicsAndBold" => 50, - "doHardBreaks" => 60, - ); - - protected function runSpanGamut($text) { - # - # Run span gamut tranformations. - # - foreach ($this->span_gamut as $method => $priority) { - $text = $this->$method($text); - } - - return $text; - } - - - protected function doHardBreaks($text) { - # Do hard breaks: - return preg_replace_callback('/ {2,}\n/', - array($this, '_doHardBreaks_callback'), $text); - } - protected function _doHardBreaks_callback($matches) { - return $this->hashPart("empty_element_suffix\n"); - } - - - protected function doAnchors($text) { - # - # Turn Markdown link shortcuts into XHTML tags. - # - if ($this->in_anchor) return $text; - $this->in_anchor = true; - - # - # First, handle reference-style links: [link text] [id] - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - # - # Next, inline-style links: [link text](url "optional title") - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - \( # literal paren - [ \n]* - (?: - <(.+?)> # href = $3 - | - ('.$this->nested_url_parenthesis_re.') # href = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # Title = $7 - \6 # matching quote - [ \n]* # ignore any spaces/tabs between closing quote and ) - )? # title is optional - \) - ) - }xs', - array($this, '_doAnchors_inline_callback'), $text); - - # - # Last, handle reference-style shortcuts: [link text] - # These must come last in case you've also got [link text][1] - # or [link text](/foo) - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ([^\[\]]+) # link text = $2; can\'t contain [ or ] - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - $this->in_anchor = false; - return $text; - } - protected function _doAnchors_reference_callback($matches) { - $whole_match = $matches[1]; - $link_text = $matches[2]; - $link_id =& $matches[3]; - - if ($link_id == "") { - # for shortcut links like [this][] or [this]. - $link_id = $link_text; - } - - # lower-case and turn embedded newlines into spaces - $link_id = strtolower($link_id); - $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); - - if (isset($this->urls[$link_id])) { - $url = $this->urls[$link_id]; - $url = $this->encodeAttribute($url); - - $result = "titles[$link_id] ) ) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - $result = $this->hashPart($result); - } - else { - $result = $whole_match; - } - return $result; - } - protected function _doAnchors_inline_callback($matches) { - $whole_match = $matches[1]; - $link_text = $this->runSpanGamut($matches[2]); - $url = $matches[3] == '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - - $url = $this->encodeAttribute($url); - - $result = "encodeAttribute($title); - $result .= " title=\"$title\""; - } - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - - return $this->hashPart($result); - } - - - protected function doImages($text) { - # - # Turn Markdown image shortcuts into tags. - # - # - # First, handle reference-style labeled images: ![alt text][id] - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - - ) - }xs', - array($this, '_doImages_reference_callback'), $text); - - # - # Next, handle inline images: ![alt text](url "optional title") - # Don't forget: encode * and _ - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - \s? # One optional whitespace character - \( # literal paren - [ \n]* - (?: - <(\S*)> # src url = $3 - | - ('.$this->nested_url_parenthesis_re.') # src url = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # title = $7 - \6 # matching quote - [ \n]* - )? # title is optional - \) - ) - }xs', - array($this, '_doImages_inline_callback'), $text); - - return $text; - } - protected function _doImages_reference_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $link_id = strtolower($matches[3]); - - if ($link_id == "") { - $link_id = strtolower($alt_text); # for shortcut links like ![this][]. - } - - $alt_text = $this->encodeAttribute($alt_text); - if (isset($this->urls[$link_id])) { - $url = $this->encodeAttribute($this->urls[$link_id]); - $result = "\"$alt_text\"";titles[$link_id])) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - $result .= $this->empty_element_suffix; - $result = $this->hashPart($result); - } - else { - # If there's no such link ID, leave intact: - $result = $whole_match; - } - - return $result; - } - protected function _doImages_inline_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $url = $matches[3] == '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - - $alt_text = $this->encodeAttribute($alt_text); - $url = $this->encodeAttribute($url); - $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; # $title already quoted - } - $result .= $this->empty_element_suffix; - - return $this->hashPart($result); - } - - - protected function doHeaders($text) { - # Setext-style headers: - # Header 1 - # ======== - # - # Header 2 - # -------- - # - $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', - array($this, '_doHeaders_callback_setext'), $text); - - # atx-style headers: - # # Header 1 - # ## Header 2 - # ## Header 2 with closing hashes ## - # ... - # ###### Header 6 - # - $text = preg_replace_callback('{ - ^(\#{1,6}) # $1 = string of #\'s - [ ]* - (.+?) # $2 = Header text - [ ]* - \#* # optional closing #\'s (not counted) - \n+ - }xm', - array($this, '_doHeaders_callback_atx'), $text); - - return $text; - } - protected function _doHeaders_callback_setext($matches) { - # Terrible hack to check we haven't found an empty list item. - if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) - return $matches[0]; - - $level = $matches[2]{0} == '=' ? 1 : 2; - $block = "".$this->runSpanGamut($matches[1]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - protected function _doHeaders_callback_atx($matches) { - $level = strlen($matches[1]); - $block = "".$this->runSpanGamut($matches[2]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - - - protected function doLists($text) { - # - # Form HTML ordered (numbered) and unordered (bulleted) lists. - # - $less_than_tab = $this->tab_width - 1; - - # Re-usable patterns to match list item bullets and number markers: - $marker_ul_re = '[*+-]'; - $marker_ol_re = '\d+[\.]'; - $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; - - $markers_relist = array( - $marker_ul_re => $marker_ol_re, - $marker_ol_re => $marker_ul_re, - ); - - foreach ($markers_relist as $marker_re => $other_marker_re) { - # Re-usable pattern to match any entirel ul or ol list: - $whole_list_re = ' - ( # $1 = whole list - ( # $2 - ([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces - ('.$marker_re.') # $4 = first list item marker - [ ]+ - ) - (?s:.+?) - ( # $5 - \z - | - \n{2,} - (?=\S) - (?! # Negative lookahead for another list item marker - [ ]* - '.$marker_re.'[ ]+ - ) - | - (?= # Lookahead for another kind of list - \n - \3 # Must have the same indentation - '.$other_marker_re.'[ ]+ - ) - ) - ) - '; // mx - - # We use a different prefix before nested lists than top-level lists. - # See extended comment in _ProcessListItems(). - - if ($this->list_level) { - $text = preg_replace_callback('{ - ^ - '.$whole_list_re.' - }mx', - array($this, '_doLists_callback'), $text); - } - else { - $text = preg_replace_callback('{ - (?:(?<=\n)\n?|\A\n?) # Must eat the newline - '.$whole_list_re.' - }mx', - array($this, '_doLists_callback'), $text); - } - } - - return $text; - } - protected function _doLists_callback($matches) { - # Re-usable patterns to match list item bullets and number markers: - $marker_ul_re = '[*+-]'; - $marker_ol_re = '\d+[\.]'; - $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; - - $list = $matches[1]; - $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol"; - - $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); - - $list .= "\n"; - $result = $this->processListItems($list, $marker_any_re); - - $result = $this->hashBlock("<$list_type>\n" . $result . ""); - return "\n". $result ."\n\n"; - } - - protected $list_level = 0; - - protected function processListItems($list_str, $marker_any_re) { - # - # Process the contents of a single ordered or unordered list, splitting it - # into individual list items. - # - # The $this->list_level global keeps track of when we're inside a list. - # Each time we enter a list, we increment it; when we leave a list, - # we decrement. If it's zero, we're not in a list anymore. - # - # We do this because when we're not inside a list, we want to treat - # something like this: - # - # I recommend upgrading to version - # 8. Oops, now this line is treated - # as a sub-list. - # - # As a single paragraph, despite the fact that the second line starts - # with a digit-period-space sequence. - # - # Whereas when we're inside a list (or sub-list), that line will be - # treated as the start of a sub-list. What a kludge, huh? This is - # an aspect of Markdown's syntax that's hard to parse perfectly - # without resorting to mind-reading. Perhaps the solution is to - # change the syntax rules such that sub-lists must start with a - # starting cardinal number; e.g. "1." or "a.". - - $this->list_level++; - - # trim trailing blank lines: - $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); - - $list_str = preg_replace_callback('{ - (\n)? # leading line = $1 - (^[ ]*) # leading whitespace = $2 - ('.$marker_any_re.' # list marker and space = $3 - (?:[ ]+|(?=\n)) # space only required if item is not empty - ) - ((?s:.*?)) # list item text = $4 - (?:(\n+(?=\n))|\n) # tailing blank line = $5 - (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) - }xm', - array($this, '_processListItems_callback'), $list_str); - - $this->list_level--; - return $list_str; - } - protected function _processListItems_callback($matches) { - $item = $matches[4]; - $leading_line =& $matches[1]; - $leading_space =& $matches[2]; - $marker_space = $matches[3]; - $tailing_blank_line =& $matches[5]; - - if ($leading_line || $tailing_blank_line || - preg_match('/\n{2,}/', $item)) - { - # Replace marker with the appropriate whitespace indentation - $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; - $item = $this->runBlockGamut($this->outdent($item)."\n"); - } - else { - # Recursion for sub-lists: - $item = $this->doLists($this->outdent($item)); - $item = preg_replace('/\n+$/', '', $item); - $item = $this->runSpanGamut($item); - } - - return "
  • " . $item . "
  • \n"; - } - - - protected function doCodeBlocks($text) { - # - # Process Markdown `
    ` blocks.
    -	#
    -		$text = preg_replace_callback('{
    -				(?:\n\n|\A\n?)
    -				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    -				  (?>
    -					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
    -					.*\n+
    -				  )+
    -				)
    -				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
    -			}xm',
    -			array($this, '_doCodeBlocks_callback'), $text);
    -
    -		return $text;
    -	}
    -	protected function _doCodeBlocks_callback($matches) {
    -		$codeblock = $this->unhashHTMLBlocks($matches[1]);
    -
    -		$codeblock = $this->outdent($codeblock);
    -		$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    -
    -		# trim leading newlines and trailing newlines
    -		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
    -
    -		$codeblock = "
    $codeblock\n
    "; - return "\n\n".$this->hashBlock($codeblock)."\n\n"; - } - - - protected function makeCodeSpan($code) { - # - # Create a code span markup for $code. Called from handleSpanToken. - # - $code = htmlspecialchars(trim($code), ENT_NOQUOTES); - return $this->hashPart("$code"); - } - - - protected $em_relist = array( - '' => '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(?em_relist as $em => $em_re) { - foreach ($this->strong_relist as $strong => $strong_re) { - # Construct list of allowed token expressions. - $token_relist = array(); - if (isset($this->em_strong_relist["$em$strong"])) { - $token_relist[] = $this->em_strong_relist["$em$strong"]; - } - $token_relist[] = $em_re; - $token_relist[] = $strong_re; - - # Construct master expression from list. - $token_re = '{('. implode('|', $token_relist) .')}'; - $this->em_strong_prepared_relist["$em$strong"] = $token_re; - } - } - } - - protected function doItalicsAndBold($text) { - $token_stack = array(''); - $text_stack = array(''); - $em = ''; - $strong = ''; - $tree_char_em = false; - - while (1) { - # - # Get prepared regular expression for seraching emphasis tokens - # in current context. - # - $token_re = $this->em_strong_prepared_relist["$em$strong"]; - - # - # Each loop iteration search for the next emphasis token. - # Each token is then passed to handleSpanToken. - # - $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); - $text_stack[0] .= $parts[0]; - $token =& $parts[1]; - $text =& $parts[2]; - - if (empty($token)) { - # Reached end of text span: empty stack without emitting. - # any more emphasis. - while ($token_stack[0]) { - $text_stack[1] .= array_shift($token_stack); - $text_stack[0] .= array_shift($text_stack); - } - break; - } - - $token_len = strlen($token); - if ($tree_char_em) { - # Reached closing marker while inside a three-char emphasis. - if ($token_len == 3) { - # Three-char closing marker, close em and strong. - array_shift($token_stack); - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "$span"; - $text_stack[0] .= $this->hashPart($span); - $em = ''; - $strong = ''; - } else { - # Other closing marker: close one em or strong and - # change current token state to match the other - $token_stack[0] = str_repeat($token{0}, 3-$token_len); - $tag = $token_len == 2 ? "strong" : "em"; - $span = $text_stack[0]; - $span = $this->runSpanGamut($span); - $span = "<$tag>$span"; - $text_stack[0] = $this->hashPart($span); - $$tag = ''; # $$tag stands for $em or $strong - } - $tree_char_em = false; - } else if ($token_len == 3) { - if ($em) { - # Reached closing marker for both em and strong. - # Closing strong marker: - for ($i = 0; $i < 2; ++$i) { - $shifted_token = array_shift($token_stack); - $tag = strlen($shifted_token) == 2 ? "strong" : "em"; - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "<$tag>$span"; - $text_stack[0] .= $this->hashPart($span); - $$tag = ''; # $$tag stands for $em or $strong - } - } else { - # Reached opening three-char emphasis marker. Push on token - # stack; will be handled by the special condition above. - $em = $token{0}; - $strong = "$em$em"; - array_unshift($token_stack, $token); - array_unshift($text_stack, ''); - $tree_char_em = true; - } - } else if ($token_len == 2) { - if ($strong) { - # Unwind any dangling emphasis marker: - if (strlen($token_stack[0]) == 1) { - $text_stack[1] .= array_shift($token_stack); - $text_stack[0] .= array_shift($text_stack); - } - # Closing strong marker: - array_shift($token_stack); - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "$span"; - $text_stack[0] .= $this->hashPart($span); - $strong = ''; - } else { - array_unshift($token_stack, $token); - array_unshift($text_stack, ''); - $strong = $token; - } - } else { - # Here $token_len == 1 - if ($em) { - if (strlen($token_stack[0]) == 1) { - # Closing emphasis marker: - array_shift($token_stack); - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "$span"; - $text_stack[0] .= $this->hashPart($span); - $em = ''; - } else { - $text_stack[0] .= $token; - } - } else { - array_unshift($token_stack, $token); - array_unshift($text_stack, ''); - $em = $token; - } - } - } - return $text_stack[0]; - } - - - protected function doBlockQuotes($text) { - $text = preg_replace_callback('/ - ( # Wrap whole match in $1 - (?> - ^[ ]*>[ ]? # ">" at the start of a line - .+\n # rest of the first line - (.+\n)* # subsequent consecutive lines - \n* # blanks - )+ - ) - /xm', - array($this, '_doBlockQuotes_callback'), $text); - - return $text; - } - protected function _doBlockQuotes_callback($matches) { - $bq = $matches[1]; - # trim one level of quoting - trim whitespace-only lines - $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); - $bq = $this->runBlockGamut($bq); # recurse - - $bq = preg_replace('/^/m', " ", $bq); - # These leading spaces cause problem with
     content, 
    -		# so we need to fix that:
    -		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', - array($this, '_doBlockQuotes_callback2'), $bq); - - return "\n". $this->hashBlock("
    \n$bq\n
    ")."\n\n"; - } - protected function _doBlockQuotes_callback2($matches) { - $pre = $matches[1]; - $pre = preg_replace('/^ /m', '', $pre); - return $pre; - } - - - protected function formParagraphs($text) { - # - # Params: - # $text - string to process with html

    tags - # - # Strip leading and trailing lines: - $text = preg_replace('/\A\n+|\n+\z/', '', $text); - - $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - - # - # Wrap

    tags and unhashify HTML blocks - # - foreach ($grafs as $key => $value) { - if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { - # Is a paragraph. - $value = $this->runSpanGamut($value); - $value = preg_replace('/^([ ]*)/', "

    ", $value); - $value .= "

    "; - $grafs[$key] = $this->unhash($value); - } - else { - # Is a block. - # Modify elements of @grafs in-place... - $graf = $value; - $block = $this->html_hashes[$graf]; - $graf = $block; -// if (preg_match('{ -// \A -// ( # $1 =
    tag -//
    ]* -// \b -// markdown\s*=\s* ([\'"]) # $2 = attr quote char -// 1 -// \2 -// [^>]* -// > -// ) -// ( # $3 = contents -// .* -// ) -// (
    ) # $4 = closing tag -// \z -// }xs', $block, $matches)) -// { -// list(, $div_open, , $div_content, $div_close) = $matches; -// -// # We can't call Markdown(), because that resets the hash; -// # that initialization code should be pulled into its own sub, though. -// $div_content = $this->hashHTMLBlocks($div_content); -// -// # Run document gamut methods on the content. -// foreach ($this->document_gamut as $method => $priority) { -// $div_content = $this->$method($div_content); -// } -// -// $div_open = preg_replace( -// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); -// -// $graf = $div_open . "\n" . $div_content . "\n" . $div_close; -// } - $grafs[$key] = $graf; - } - } - - return implode("\n\n", $grafs); - } - - - protected function encodeAttribute($text) { - # - # Encode text for a double-quoted HTML attribute. This function - # is *not* suitable for attributes enclosed in single quotes. - # - $text = $this->encodeAmpsAndAngles($text); - $text = str_replace('"', '"', $text); - return $text; - } - - - protected function encodeAmpsAndAngles($text) { - # - # Smart processing for ampersands and angle brackets that need to - # be encoded. Valid character entities are left alone unless the - # no-entities mode is set. - # - if ($this->no_entities) { - $text = str_replace('&', '&', $text); - } else { - # Ampersand-encoding based entirely on Nat Irons's Amputator - # MT plugin: - $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', - '&', $text);; - } - # Encode remaining <'s - $text = str_replace('<', '<', $text); - - return $text; - } - - - protected function doAutoLinks($text) { - $text = preg_replace_callback('/(="|<)?\b(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\])])(?=$|\W)/i', - array($this, '_doAutoLinks_url_callback'), $text); - $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', - array($this, '_doAutoLinks_url_callback_replace'), $text); - - # Email addresses: - $text = preg_replace_callback('{ - < - (?:mailto:)? - ( - (?: - [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+ - | - ".*?" - ) - \@ - (?: - [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ - | - \[[\d.a-fA-F:]+\] # IPv4 & IPv6 - ) - ) - > - }xi', - array($this, '_doAutoLinks_email_callback'), $text); - - return $text; - } - protected function _doAutoLinks_url_callback_replace($matches) { - $url = $this->encodeAttribute($matches[1]); - $link = "$url"; - return $this->hashPart($link); - } - - private $tail; - - protected function _doAutoLinks_url_callback($matches) { - list ($wholeMatch, $lookbehind, $protocol, $link) = $matches; - - if ($lookbehind) { - return $wholeMatch; - } - - if ($link[strlen($link) - 1] != ')') { - return '<' . $protocol . $link . '>'; - } - - $level = 0; - if (preg_match_all("/[()]/", $link, $matches)) { - foreach ($matches[0] as $op) { - if ('(' == $op) { - if ($level <= 0) { - $level = 1; - } else { - $level ++; - } - } else { - $level --; - } - } - } - - $this->tail = ''; - if ($level < 0) { - $link = preg_replace_callback("/\){1," . (- $level) . "}$/", - array($this, '_doAutoLinks_url_callback_callback'), $link); - } - - $url = $this->encodeAttribute($protocol . $link); - $link = "$url"; - return $this->hashPart($link) . $this->tail; - } - - protected function _doAutoLinks_email_callback($matches) { - $address = $matches[1]; - $link = $this->encodeEmailAddress($address); - return $this->hashPart($link); - } - - protected function _doAutoLinks_url_callback_callback($matches) { - $this->tail = $matches[0]; - return ''; - } - - protected function encodeEmailAddress($addr) { - # - # Input: an email address, e.g. "foo@example.com" - # - # Output: the email address as a mailto link, with each character - # of the address encoded as either a decimal or hex entity, in - # the hopes of foiling most address harvesting spam bots. E.g.: - # - #

    foo@exampl - # e.com

    - # - # Based by a filter by Matthew Wickline, posted to BBEdit-Talk. - # With some optimizations by Milian Wolff. - # - $addr = "mailto:" . $addr; - $chars = preg_split('/(? $char) { - $ord = ord($char); - # Ignore non-ascii chars. - if ($ord < 128) { - $r = ($seed * (1 + $key)) % 100; # Pseudo-random function. - # roughly 10% raw, 45% hex, 45% dec - # '@' *must* be encoded. I insist. - if ($r > 90 && $char != '@') /* do nothing */; - else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';'; - else $chars[$key] = '&#'.$ord.';'; - } - } - - $addr = implode('', $chars); - $text = implode('', array_slice($chars, 7)); # text without `mailto:` - $addr = "$text"; - - return $addr; - } - - - protected function parseSpan($str) { - # - # Take the string $str and parse it into tokens, hashing embeded HTML, - # escaped characters and handling code spans. - # - $output = ''; - - $span_re = '{ - ( - \\\\'.$this->escape_chars_re.' - | - (?no_markup ? '' : ' - | - # comment - | - <\?.*?\?> | <%.*?%> # processing instruction - | - <[!$]?[-a-zA-Z0-9:_]+ # regular tags - (?> - \s - (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* - )? - > - | - <[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag - | - # closing tag - ').' - ) - }xs'; - - while (1) { - # - # Each loop iteration seach for either the next tag, the next - # openning code span marker, or the next escaped character. - # Each token is then passed to handleSpanToken. - # - $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); - - # Create token from text preceding tag. - if ($parts[0] != "") { - $output .= $parts[0]; - } - - # Check if we reach the end. - if (isset($parts[1])) { - $output .= $this->handleSpanToken($parts[1], $parts[2]); - $str = $parts[2]; - } - else { - break; - } - } - - return $output; - } - - - protected function handleSpanToken($token, &$str) { - # - # Handle $token provided by parseSpan by determining its nature and - # returning the corresponding value that should replace it. - # - switch ($token{0}) { - case "\\": - return $this->hashPart("&#". ord($token{1}). ";"); - case "`": - # Search for end marker in remaining text. - if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', - $str, $matches)) - { - $str = $matches[2]; - $codespan = $this->makeCodeSpan($matches[1]); - return $this->hashPart($codespan); - } - return $token; // return as text since no ending marker found. - default: - return $this->hashPart($token); - } - } - - - protected function outdent($text) { - # - # Remove one level of line-leading tabs or spaces - # - return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text); - } - - - # String length function for detab. `_initDetab` will create a function to - # hanlde UTF-8 if the default function does not exist. - protected $utf8_strlen = 'mb_strlen'; - - protected function detab($text) { - # - # Replace tabs with the appropriate amount of space. - # - # For each line we separate the line in blocks delemited by - # tab characters. Then we reconstruct every line by adding the - # appropriate number of space between each blocks. - - $text = preg_replace_callback('/^.*\t.*$/m', - array($this, '_detab_callback'), $text); - - return $text; - } - protected function _detab_callback($matches) { - $line = $matches[0]; - $strlen = $this->utf8_strlen; # strlen function for UTF-8. - - # Split in blocks. - $blocks = explode("\t", $line); - # Add each blocks to the line. - $line = $blocks[0]; - unset($blocks[0]); # Do not add first block twice. - foreach ($blocks as $block) { - # Calculate amount of space, insert spaces, insert block. - $amount = $this->tab_width - - call_user_func($strlen, $line, 'UTF-8') % $this->tab_width; - $line .= str_repeat(" ", $amount) . $block; - } - return $line; - } - protected function _initDetab() { - # - # Check for the availability of the function in the `utf8_strlen` property - # (initially `mb_strlen`). If the function is not available, create a - # function that will loosely count the number of UTF-8 characters with a - # regular expression. - # - if (function_exists($this->utf8_strlen)) return; - $this->utf8_strlen = array($this, '_utf8_strlen'); - } - - protected function _utf8_strlen($text) { - return preg_match_all( - "/[\\x00-\\xBF]|[\\xC0-\\xFF][\\x80-\\xBF]*/", - $text, $m); - } - - - protected function unhash($text) { - # - # Swap back in all the tags hashed by _HashHTMLBlocks. - # - return preg_replace_callback('/(.)\x1A[0-9]+\1/', - array($this, '_unhash_callback'), $text); - } - protected function _unhash_callback($matches) { - return $this->html_hashes[trim($matches[0])]; - } - - protected function unhashHTMLBlocks($text) { - return preg_replace_callback("/\n\n(.)\\x1A[0-9]+\\1\n\n/", - array($this, '_unhash_callback'), $text); - } -} - -# -# Temporary Markdown Extra Parser Implementation Class -# -# NOTE: DON'T USE THIS CLASS -# Currently the implementation of of Extra resides here in this temporary class. -# This makes it easier to propagate the changes between the three different -# packaging styles of PHP Markdown. When this issue is resolved, this -# MarkdownExtra_TmpImpl class here will disappear and \Michelf\MarkdownExtra -# will contain the code. So please use \Michelf\MarkdownExtra and ignore this -# one. -# - -class MarkdownExtra extends Markdown { - - ### Configuration Variables ### - - # Prefix for footnote ids. - public $fn_id_prefix = ""; - - # Optional title attribute for footnote links and backlinks. - public $fn_link_title = ""; - public $fn_backlink_title = ""; - - # Optional class attribute for footnote links and backlinks. - public $fn_link_class = "footnote-ref"; - public $fn_backlink_class = "footnote-backref"; - - # Class name for table cell alignment (%% replaced left/center/right) - # For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' - # If empty, the align attribute is used instead of a class name. - public $table_align_class_tmpl = ''; - - # Optional class prefix for fenced code block. - public $code_class_prefix = ""; - # Class attribute for code blocks goes on the `code` tag; - # setting this to true will put attributes on the `pre` tag instead. - public $code_attr_on_pre = false; - - # Predefined abbreviations. - public $predef_abbr = array(); - - - ### Parser Implementation ### - - public function __construct() { - # - # Constructor function. Initialize the parser object. - # - # Add extra escapable characters before parent constructor - # initialize the table. - $this->escape_chars .= ':|'; - - # Insert extra document, block, and span transformations. - # Parent constructor will do the sorting. - $this->document_gamut += array( - "doFencedCodeBlocks" => 5, - "stripFootnotes" => 15, - "stripAbbreviations" => 25, - "appendFootnotes" => 50, - ); - $this->block_gamut += array( - "doFencedCodeBlocks" => 5, - "doTables" => 15, - "doDefLists" => 45, - ); - $this->span_gamut += array( - "doFootnotes" => 5, - "doAbbreviations" => 70, - ); - - parent::__construct(); - } - - - # Extra variables used during extra transformations. - protected $footnotes = array(); - protected $footnotes_ordered = array(); - protected $footnotes_ref_count = array(); - protected $footnotes_numbers = array(); - protected $abbr_desciptions = array(); - protected $abbr_word_re = ''; - - # Give the current footnote number. - protected $footnote_counter = 1; - - - protected function setup() { - # - # Setting up Extra-specific variables. - # - parent::setup(); - - $this->footnotes = array(); - $this->footnotes_ordered = array(); - $this->footnotes_ref_count = array(); - $this->footnotes_numbers = array(); - $this->abbr_desciptions = array(); - $this->abbr_word_re = ''; - $this->footnote_counter = 1; - - foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { - if ($this->abbr_word_re) - $this->abbr_word_re .= '|'; - $this->abbr_word_re .= preg_quote($abbr_word); - $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); - } - } - - protected function teardown() { - # - # Clearing Extra-specific variables. - # - $this->footnotes = array(); - $this->footnotes_ordered = array(); - $this->footnotes_ref_count = array(); - $this->footnotes_numbers = array(); - $this->abbr_desciptions = array(); - $this->abbr_word_re = ''; - - parent::teardown(); - } - - - ### Extra Attribute Parser ### - - # Expression to use to catch attributes (includes the braces) - protected $id_class_attr_catch_re = '\{((?:[ ]*[#.][-_:a-zA-Z0-9]+){1,})[ ]*\}'; - # Expression to use when parsing in a context when no capture is desired - protected $id_class_attr_nocatch_re = '\{(?:[ ]*[#.][-_:a-zA-Z0-9]+){1,}[ ]*\}'; - - protected function doExtraAttributes($tag_name, $attr) { - # - # Parse attributes caught by the $this->id_class_attr_catch_re expression - # and return the HTML-formatted list of attributes. - # - # Currently supported attributes are .class and #id. - # - if (empty($attr)) return ""; - - # Split on components - preg_match_all('/[#.][-_:a-zA-Z0-9]+/', $attr, $matches); - $elements = $matches[0]; - - # handle classes and ids (only first id taken into account) - $classes = array(); - $id = false; - foreach ($elements as $element) { - if ($element{0} == '.') { - $classes[] = substr($element, 1); - } else if ($element{0} == '#') { - if ($id === false) $id = substr($element, 1); - } - } - - # compose attributes as string - $attr_str = ""; - if (!empty($id)) { - $attr_str .= ' id="'.$id.'"'; - } - if (!empty($classes)) { - $attr_str .= ' class="'.implode(" ", $classes).'"'; - } - return $attr_str; - } - - - protected function stripLinkDefinitions($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # - $less_than_tab = $this->tab_width - 1; - - # Link defs are in the form: ^[id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 - [ ]* - \n? # maybe *one* newline - [ ]* - (?: - <(.+?)> # url = $2 - | - (\S+?) # url = $3 - ) - [ ]* - \n? # maybe one newline - [ ]* - (?: - (?<=\s) # lookbehind for whitespace - ["(] - (.*?) # title = $4 - [")] - [ ]* - )? # title is optional - (?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr - (?:\n+|\Z) - }xm', - array($this, '_stripLinkDefinitions_callback'), - $text); - return $text; - } - protected function _stripLinkDefinitions_callback($matches) { - $link_id = strtolower($matches[1]); - $url = $matches[2] == '' ? $matches[3] : $matches[2]; - $this->urls[$link_id] = $url; - $this->titles[$link_id] =& $matches[4]; - $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]); - return ''; # String that will replace the block - } - - - ### HTML Block Parser ### - - # Tags that are always treated as block tags: - protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption'; - - # Tags treated as block tags only if the opening tag is alone on its line: - protected $context_block_tags_re = 'script|noscript|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; - - # Tags where markdown="1" default to span mode: - protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; - - # Tags which must not have their contents modified, no matter where - # they appear: - protected $clean_tags_re = 'script|math|svg'; - - # Tags that do not need to be closed. - protected $auto_close_tags_re = 'hr|img|param|source|track'; - - - protected function hashHTMLBlocks($text) { - # - # Hashify HTML Blocks and "clean tags". - # - # We only want to do this for block-level HTML tags, such as headers, - # lists, and tables. That's because we still want to wrap

    s around - # "paragraphs" that are wrapped in non-block-level tags, such as anchors, - # phrase emphasis, and spans. The list of tags we're looking for is - # hard-coded. - # - # This works by calling _HashHTMLBlocks_InMarkdown, which then calls - # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" - # attribute is found within a tag, _HashHTMLBlocks_InHTML calls back - # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. - # These two functions are calling each other. It's recursive! - # - if ($this->no_markup) return $text; - - # - # Call the HTML-in-Markdown hasher. - # - list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); - - return $text; - } - protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0, - $enclosing_tag_re = '', $span = false) - { - # - # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. - # - # * $indent is the number of space to be ignored when checking for code - # blocks. This is important because if we don't take the indent into - # account, something like this (which looks right) won't work as expected: - # - #

    - #
    - # Hello World. <-- Is this a Markdown code block or text? - #
    <-- Is this a Markdown code block or a real tag? - #
    - # - # If you don't like this, just don't indent the tag on which - # you apply the markdown="1" attribute. - # - # * If $enclosing_tag_re is not empty, stops at the first unmatched closing - # tag with that name. Nested tags supported. - # - # * If $span is true, text inside must treated as span. So any double - # newline will be replaced by a single newline so that it does not create - # paragraphs. - # - # Returns an array of that form: ( processed text , remaining text ) - # - if ($text === '') return array('', ''); - - # Regex to check for the presense of newlines around a block tag. - $newline_before_re = '/(?:^\n?|\n\n)*$/'; - $newline_after_re = - '{ - ^ # Start of text following the tag. - (?>[ ]*)? # Optional comment. - [ ]*\n # Must be followed by newline. - }xs'; - - # Regex to match any tag. - $block_tag_re = - '{ - ( # $2: Capture whole tag. - # Tag name. - '.$this->block_tags_re.' | - '.$this->context_block_tags_re.' | - '.$this->clean_tags_re.' | - (?!\s)'.$enclosing_tag_re.' - ) - (?: - (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. - (?> - ".*?" | # Double quotes (can contain `>`) - \'.*?\' | # Single quotes (can contain `>`) - .+? # Anything but quotes and `>`. - )*? - )? - > # End of tag. - | - # HTML Comment - | - <\?.*?\?> | <%.*?%> # Processing instruction - | - # CData Block - | - # Code span marker - `+ - '. ( !$span ? ' # If not in span. - | - # Indented code block - (?: ^[ ]*\n | ^ | \n[ ]*\n ) - [ ]{'.($indent+4).'}[^\n]* \n - (?> - (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n - )* - | - # Fenced code block marker - (?<= ^ | \n ) - [ ]{0,'.($indent+3).'}~{3,} - [ ]* - (?: - \.?[-_:a-zA-Z0-9]+ # standalone class name - | - '.$this->id_class_attr_nocatch_re.' # extra attributes - )? - [ ]* - \n - ' : '' ). ' # End (if not is span). - ) - }xs'; - - - $depth = 0; # Current depth inside the tag tree. - $parsed = ""; # Parsed text that will be returned. - - # - # Loop through every tag until we find the closing tag of the parent - # or loop until reaching the end of text if no parent tag specified. - # - do { - # - # Split the text using the first $tag_match pattern found. - # Text before pattern will be first in the array, text after - # pattern will be at the end, and between will be any catches made - # by the pattern. - # - $parts = preg_split($block_tag_re, $text, 2, - PREG_SPLIT_DELIM_CAPTURE); - - # If in Markdown span mode, add a empty-string span-level hash - # after each newline to prevent triggering any block element. - if ($span) { - $void = $this->hashPart("", ':'); - $newline = "$void\n"; - $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; - } - - $parsed .= $parts[0]; # Text before current tag. - - # If end of $text has been reached. Stop loop. - if (count($parts) < 3) { - $text = ""; - break; - } - - $tag = $parts[1]; # Tag to handle. - $text = $parts[2]; # Remaining text after current tag. - $tag_re = preg_quote($tag); # For use in a regular expression. - - # - # Check for: Code span marker - # - if ($tag{0} == "`") { - # Find corresponding end marker. - $tag_re = preg_quote($tag); - if (preg_match('{^(?>.+?|\n(?!\n))*?(?.*\n)*?[ ]{'.($fence_indent).'}'.$fence_re.'[ ]*(?:\n|$)}', $text, - $matches)) - { - # End marker found: pass text unchanged until marker. - $parsed .= $tag . $matches[0]; - $text = substr($text, strlen($matches[0])); - } - else { - # No end marker: just skip it. - $parsed .= $tag; - } - } - # - # Check for: Indented code block. - # - else if ($tag{0} == "\n" || $tag{0} == " ") { - # Indented code block: pass it unchanged, will be handled - # later. - $parsed .= $tag; - } - # - # Check for: Opening Block level tag or - # Opening Context Block tag (like ins and del) - # used as a block tag (tag is alone on it's line). - # - else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) || - ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) && - preg_match($newline_before_re, $parsed) && - preg_match($newline_after_re, $text) ) - ) - { - # Need to parse tag and following text using the HTML parser. - list($block_text, $text) = - $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); - - # Make sure it stays outside of any paragraph by adding newlines. - $parsed .= "\n\n$block_text\n\n"; - } - # - # Check for: Clean tag (like script, math) - # HTML Comments, processing instructions. - # - else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) || - $tag{1} == '!' || $tag{1} == '?') - { - # Need to parse tag and following text using the HTML parser. - # (don't check for markdown attribute) - list($block_text, $text) = - $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); - - $parsed .= $block_text; - } - # - # Check for: Tag with same name as enclosing tag. - # - else if ($enclosing_tag_re !== '' && - # Same name as enclosing tag. - preg_match('{^= 0); - - return array($parsed, $text); - } - protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { - # - # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. - # - # * Calls $hash_method to convert any blocks. - # * Stops when the first opening tag closes. - # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. - # (it is not inside clean tags) - # - # Returns an array of that form: ( processed text , remaining text ) - # - if ($text === '') return array('', ''); - - # Regex to match `markdown` attribute inside of a tag. - $markdown_attr_re = ' - { - \s* # Eat whitespace before the `markdown` attribute - markdown - \s*=\s* - (?> - (["\']) # $1: quote delimiter - (.*?) # $2: attribute value - \1 # matching delimiter - | - ([^\s>]*) # $3: unquoted attribute value - ) - () # $4: make $3 always defined (avoid warnings) - }xs'; - - # Regex to match any tag. - $tag_re = '{ - ( # $2: Capture whole tag. - - ".*?" | # Double quotes (can contain `>`) - \'.*?\' | # Single quotes (can contain `>`) - .+? # Anything but quotes and `>`. - )*? - )? - > # End of tag. - | - # HTML Comment - | - <\?.*?\?> | <%.*?%> # Processing instruction - | - # CData Block - ) - }xs'; - - $original_text = $text; # Save original text in case of faliure. - - $depth = 0; # Current depth inside the tag tree. - $block_text = ""; # Temporary text holder for current text. - $parsed = ""; # Parsed text that will be returned. - - # - # Get the name of the starting tag. - # (This pattern makes $base_tag_name_re safe without quoting.) - # - if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) - $base_tag_name_re = $matches[1]; - - # - # Loop through every tag until we find the corresponding closing tag. - # - do { - # - # Split the text using the first $tag_match pattern found. - # Text before pattern will be first in the array, text after - # pattern will be at the end, and between will be any catches made - # by the pattern. - # - $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); - - if (count($parts) < 3) { - # - # End of $text reached with unbalenced tag(s). - # In that case, we return original text unchanged and pass the - # first character as filtered to prevent an infinite loop in the - # parent function. - # - return array($original_text{0}, substr($original_text, 1)); - } - - $block_text .= $parts[0]; # Text before current tag. - $tag = $parts[1]; # Tag to handle. - $text = $parts[2]; # Remaining text after current tag. - - # - # Check for: Auto-close tag (like
    ) - # Comments and Processing Instructions. - # - if (preg_match('{^auto_close_tags_re.')\b}', $tag) || - $tag{1} == '!' || $tag{1} == '?') - { - # Just add the tag to the block as if it was text. - $block_text .= $tag; - } - else { - # - # Increase/decrease nested tag count. Only do so if - # the tag's name match base tag's. - # - if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; - $span_mode = $this->mode == 'span' || $this->mode != 'block' && - preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag); - - # Calculate indent before tag. - if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { - $strlen = $this->utf8_strlen; - $indent = call_user_func($strlen, $matches[1], 'UTF-8'); - } else { - $indent = 0; - } - - # End preceding block with this tag. - $block_text .= $tag; - $parsed .= $this->$hash_method($block_text); - - # Get enclosing tag name for the ParseMarkdown function. - # (This pattern makes $tag_name_re safe without quoting.) - preg_match('/^<([\w:$]*)\b/', $tag, $matches); - $tag_name_re = $matches[1]; - - # Parse the content using the HTML-in-Markdown parser. - list ($block_text, $text) - = $this->_hashHTMLBlocks_inMarkdown($text, $indent, - $tag_name_re, $span_mode); - - # Outdent markdown text. - if ($indent > 0) { - $block_text = preg_replace("/^[ ]{1,$indent}/m", "", - $block_text); - } - - # Append tag content to parsed text. - if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; - else $parsed .= "$block_text"; - - # Start over with a new block. - $block_text = ""; - } - else $block_text .= $tag; - } - - } while ($depth > 0); - - # - # Hash last block text that wasn't processed inside the loop. - # - $parsed .= $this->$hash_method($block_text); - - return array($parsed, $text); - } - - - protected function hashClean($text) { - # - # Called whenever a tag must be hashed when a function inserts a "clean" tag - # in $text, it passes through this function and is automaticaly escaped, - # blocking invalid nested overlap. - # - return $this->hashPart($text, 'C'); - } - - - protected function doAnchors($text) { - # - # Turn Markdown link shortcuts into XHTML tags. - # - if ($this->in_anchor) return $text; - $this->in_anchor = true; - - # - # First, handle reference-style links: [link text] [id] - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - # - # Next, inline-style links: [link text](url "optional title") - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - \( # literal paren - [ \n]* - (?: - <(.+?)> # href = $3 - | - ('.$this->nested_url_parenthesis_re.') # href = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # Title = $7 - \6 # matching quote - [ \n]* # ignore any spaces/tabs between closing quote and ) - )? # title is optional - \) - (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes - ) - }xs', - array($this, '_doAnchors_inline_callback'), $text); - - # - # Last, handle reference-style shortcuts: [link text] - # These must come last in case you've also got [link text][1] - # or [link text](/foo) - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ([^\[\]]+) # link text = $2; can\'t contain [ or ] - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - $this->in_anchor = false; - return $text; - } - protected function _doAnchors_reference_callback($matches) { - $whole_match = $matches[1]; - $link_text = $matches[2]; - $link_id =& $matches[3]; - - if ($link_id == "") { - # for shortcut links like [this][] or [this]. - $link_id = $link_text; - } - - # lower-case and turn embedded newlines into spaces - $link_id = strtolower($link_id); - $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); - - if (isset($this->urls[$link_id])) { - $url = $this->urls[$link_id]; - $url = $this->encodeAttribute($url); - - $result = "titles[$link_id] ) ) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - if (isset($this->ref_attr[$link_id])) - $result .= $this->ref_attr[$link_id]; - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - $result = $this->hashPart($result); - } - else { - $result = $whole_match; - } - return $result; - } - protected function _doAnchors_inline_callback($matches) { - $whole_match = $matches[1]; - $link_text = $this->runSpanGamut($matches[2]); - $url = $matches[3] == '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - $attr = $this->doExtraAttributes("a", $dummy =& $matches[8]); - - - $url = $this->encodeAttribute($url); - - $result = "encodeAttribute($title); - $result .= " title=\"$title\""; - } - $result .= $attr; - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - - return $this->hashPart($result); - } - - - protected function doImages($text) { - # - # Turn Markdown image shortcuts into tags. - # - # - # First, handle reference-style labeled images: ![alt text][id] - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - - ) - }xs', - array($this, '_doImages_reference_callback'), $text); - - # - # Next, handle inline images: ![alt text](url "optional title") - # Don't forget: encode * and _ - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - \s? # One optional whitespace character - \( # literal paren - [ \n]* - (?: - <(\S*)> # src url = $3 - | - ('.$this->nested_url_parenthesis_re.') # src url = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # title = $7 - \6 # matching quote - [ \n]* - )? # title is optional - \) - (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes - ) - }xs', - array($this, '_doImages_inline_callback'), $text); - - return $text; - } - protected function _doImages_reference_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $link_id = strtolower($matches[3]); - - if ($link_id == "") { - $link_id = strtolower($alt_text); # for shortcut links like ![this][]. - } - - $alt_text = $this->encodeAttribute($alt_text); - if (isset($this->urls[$link_id])) { - $url = $this->encodeAttribute($this->urls[$link_id]); - $result = "\"$alt_text\"";titles[$link_id])) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - if (isset($this->ref_attr[$link_id])) - $result .= $this->ref_attr[$link_id]; - $result .= $this->empty_element_suffix; - $result = $this->hashPart($result); - } - else { - # If there's no such link ID, leave intact: - $result = $whole_match; - } - - return $result; - } - protected function _doImages_inline_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $url = $matches[3] == '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); - - $alt_text = $this->encodeAttribute($alt_text); - $url = $this->encodeAttribute($url); - $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; # $title already quoted - } - $result .= $attr; - $result .= $this->empty_element_suffix; - - return $this->hashPart($result); - } - - - protected function doHeaders($text) { - # - # Redefined to add id and class attribute support. - # - # Setext-style headers: - # Header 1 {#header1} - # ======== - # - # Header 2 {#header2 .class1 .class2} - # -------- - # - $text = preg_replace_callback( - '{ - (^.+?) # $1: Header text - (?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes - [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer - }mx', - array($this, '_doHeaders_callback_setext'), $text); - - # atx-style headers: - # # Header 1 {#header1} - # ## Header 2 {#header2} - # ## Header 2 with closing hashes ## {#header3.class1.class2} - # ... - # ###### Header 6 {.class2} - # - $text = preg_replace_callback('{ - ^(\#{1,6}) # $1 = string of #\'s - [ ]* - (.+?) # $2 = Header text - [ ]* - \#* # optional closing #\'s (not counted) - (?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes - [ ]* - \n+ - }xm', - array($this, '_doHeaders_callback_atx'), $text); - - return $text; - } - protected function _doHeaders_callback_setext($matches) { - if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) - return $matches[0]; - $level = $matches[3]{0} == '=' ? 1 : 2; - $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2]); - $block = "".$this->runSpanGamut($matches[1]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - protected function _doHeaders_callback_atx($matches) { - $level = strlen($matches[1]); - $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3]); - $block = "".$this->runSpanGamut($matches[2]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - - - protected function doTables($text) { - # - # Form HTML tables. - # - $less_than_tab = $this->tab_width - 1; - # - # Find tables with leading pipe. - # - # | Header 1 | Header 2 - # | -------- | -------- - # | Cell 1 | Cell 2 - # | Cell 3 | Cell 4 - # - $text = preg_replace_callback(' - { - ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - [|] # Optional leading pipe (present) - (.+) \n # $1: Header row (at least one pipe) - - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline - - ( # $3: Cells - (?> - [ ]* # Allowed whitespace. - [|] .* \n # Row content. - )* - ) - (?=\n|\Z) # Stop at final double newline. - }xm', - array($this, '_doTable_leadingPipe_callback'), $text); - - # - # Find tables without leading pipe. - # - # Header 1 | Header 2 - # -------- | -------- - # Cell 1 | Cell 2 - # Cell 3 | Cell 4 - # - $text = preg_replace_callback(' - { - ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - (\S.*[|].*) \n # $1: Header row (at least one pipe) - - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline - - ( # $3: Cells - (?> - .* [|] .* \n # Row content - )* - ) - (?=\n|\Z) # Stop at final double newline. - }xm', - array($this, '_DoTable_callback'), $text); - - return $text; - } - protected function _doTable_leadingPipe_callback($matches) { - $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; - - # Remove leading pipe for each row. - $content = preg_replace('/^ *[|]/m', '', $content); - - return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); - } - protected function _doTable_makeAlignAttr($alignname) - { - if (empty($this->table_align_class_tmpl)) - return " align=\"$alignname\""; - - $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl); - return " class=\"$classname\""; - } - protected function _doTable_callback($matches) { - $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; - - # Remove any tailing pipes for each line. - $head = preg_replace('/[|] *$/m', '', $head); - $underline = preg_replace('/[|] *$/m', '', $underline); - $content = preg_replace('/[|] *$/m', '', $content); - - # Reading alignement from header underline. - $separators = preg_split('/ *[|] */', $underline); - foreach ($separators as $n => $s) { - if (preg_match('/^ *-+: *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('right'); - else if (preg_match('/^ *:-+: *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('center'); - else if (preg_match('/^ *:-+ *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('left'); - else - $attr[$n] = ''; - } - - # Parsing span elements, including code spans, character escapes, - # and inline HTML tags, so that pipes inside those gets ignored. - $head = $this->parseSpan($head); - $headers = preg_split('/ *[|] */', $head); - $col_count = count($headers); - $attr = array_pad($attr, $col_count, ''); - - # Write column headers. - $text = "\n"; - $text .= "\n"; - $text .= "\n"; - foreach ($headers as $n => $header) - $text .= " ".$this->runSpanGamut(trim($header))."\n"; - $text .= "\n"; - $text .= "\n"; - - # Split content by row. - $rows = explode("\n", trim($content, "\n")); - - $text .= "\n"; - foreach ($rows as $row) { - # Parsing span elements, including code spans, character escapes, - # and inline HTML tags, so that pipes inside those gets ignored. - $row = $this->parseSpan($row); - - # Split row by cell. - $row_cells = preg_split('/ *[|] */', $row, $col_count); - $row_cells = array_pad($row_cells, $col_count, ''); - - $text .= "\n"; - foreach ($row_cells as $n => $cell) - $text .= " ".$this->runSpanGamut(trim($cell))."\n"; - $text .= "\n"; - } - $text .= "\n"; - $text .= "
    "; - - return $this->hashBlock($text) . "\n"; - } - - - protected function doDefLists($text) { - # - # Form HTML definition lists. - # - $less_than_tab = $this->tab_width - 1; - - # Re-usable pattern to match any entire dl list: - $whole_list_re = '(?> - ( # $1 = whole list - ( # $2 - [ ]{0,'.$less_than_tab.'} - ((?>.*\S.*\n)+) # $3 = defined term - \n? - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition - ) - (?s:.+?) - ( # $4 - \z - | - \n{2,} - (?=\S) - (?! # Negative lookahead for another term - [ ]{0,'.$less_than_tab.'} - (?: \S.*\n )+? # defined term - \n? - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition - ) - (?! # Negative lookahead for another definition - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition - ) - ) - ) - )'; // mx - - $text = preg_replace_callback('{ - (?>\A\n?|(?<=\n\n)) - '.$whole_list_re.' - }mx', - array($this, '_doDefLists_callback'), $text); - - return $text; - } - protected function _doDefLists_callback($matches) { - # Re-usable patterns to match list item bullets and number markers: - $list = $matches[1]; - - # Turn double returns into triple returns, so that we can make a - # paragraph for the last item in a list, if necessary: - $result = trim($this->processDefListItems($list)); - $result = "
    \n" . $result . "\n
    "; - return $this->hashBlock($result) . "\n\n"; - } - - - protected function processDefListItems($list_str) { - # - # Process the contents of a single definition list, splitting it - # into individual term and definition list items. - # - $less_than_tab = $this->tab_width - 1; - - # trim trailing blank lines: - $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); - - # Process definition terms. - $list_str = preg_replace_callback('{ - (?>\A\n?|\n\n+) # leading line - ( # definition terms = $1 - [ ]{0,'.$less_than_tab.'} # leading whitespace - (?!\:[ ]|[ ]) # negative lookahead for a definition - # mark (colon) or more whitespace. - (?> \S.* \n)+? # actual term (not whitespace). - ) - (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed - # with a definition mark. - }xm', - array($this, '_processDefListItems_callback_dt'), $list_str); - - # Process actual definitions. - $list_str = preg_replace_callback('{ - \n(\n+)? # leading line = $1 - ( # marker space = $2 - [ ]{0,'.$less_than_tab.'} # whitespace before colon - \:[ ]+ # definition mark (colon) - ) - ((?s:.+?)) # definition text = $3 - (?= \n+ # stop at next definition mark, - (?: # next term or end of text - [ ]{0,'.$less_than_tab.'} \:[ ] | -
    | \z - ) - ) - }xm', - array($this, '_processDefListItems_callback_dd'), $list_str); - - return $list_str; - } - protected function _processDefListItems_callback_dt($matches) { - $terms = explode("\n", trim($matches[1])); - $text = ''; - foreach ($terms as $term) { - $term = $this->runSpanGamut(trim($term)); - $text .= "\n
    " . $term . "
    "; - } - return $text . "\n"; - } - protected function _processDefListItems_callback_dd($matches) { - $leading_line = $matches[1]; - $marker_space = $matches[2]; - $def = $matches[3]; - - if ($leading_line || preg_match('/\n{2,}/', $def)) { - # Replace marker with the appropriate whitespace indentation - $def = str_repeat(' ', strlen($marker_space)) . $def; - $def = $this->runBlockGamut($this->outdent($def . "\n\n")); - $def = "\n". $def ."\n"; - } - else { - $def = rtrim($def); - $def = $this->runSpanGamut($this->outdent($def)); - } - - return "\n
    " . $def . "
    \n"; - } - - - protected function doFencedCodeBlocks($text) { - # - # Adding the fenced code block syntax to regular Markdown: - # - # ~~~ - # Code block - # ~~~ - # - $less_than_tab = $this->tab_width; - - $text = preg_replace_callback('{ - (?:\n|\A) - # 1: Opening marker - ( - ~{3,} # Marker: three tilde or more. - ) - [ ]* - (?: - \.?([-_:a-zA-Z0-9]+) # 2: standalone class name - | - '.$this->id_class_attr_catch_re.' # 3: Extra attributes - )? - [ ]* \n # Whitespace and newline following marker. - - # 4: Content - ( - (?> - (?!\1 [ ]* \n) # Not a closing marker. - .*\n+ - )+ - ) - - # Closing marker. - \1 [ ]* \n - }xm', - array($this, '_doFencedCodeBlocks_callback'), $text); - - return $text; - } - protected function _doFencedCodeBlocks_callback($matches) { - $classname =& $matches[2]; - $attrs =& $matches[3]; - $codeblock = $matches[4]; - $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); - $codeblock = preg_replace_callback('/^\n+/', - array($this, '_doFencedCodeBlocks_newlines'), $codeblock); - - if ($classname != "") { - if ($classname{0} == '.') - $classname = substr($classname, 1); - $attr_str = ' class="'.$this->code_class_prefix.$classname.'"'; - } else { - $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs); - } - $pre_attr_str = $this->code_attr_on_pre ? $attr_str : ''; - $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str; - $codeblock = "$codeblock
    "; - - return "\n\n".$this->hashBlock($codeblock)."\n\n"; - } - protected function _doFencedCodeBlocks_newlines($matches) { - return str_repeat("empty_element_suffix", - strlen($matches[0])); - } - - - # - # Redefining emphasis markers so that emphasis by underscore does not - # work in the middle of a word. - # - protected $em_relist = array( - '' => '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? tags - # - # Strip leading and trailing lines: - $text = preg_replace('/\A\n+|\n+\z/', '', $text); - - $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - - # - # Wrap

    tags and unhashify HTML blocks - # - foreach ($grafs as $key => $value) { - $value = trim($this->runSpanGamut($value)); - - # Check if this should be enclosed in a paragraph. - # Clean tag hashes & block tag hashes are left alone. - $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); - - if ($is_p) { - $value = "

    $value

    "; - } - $grafs[$key] = $value; - } - - # Join grafs in one text, then unhash HTML tags. - $text = implode("\n\n", $grafs); - - # Finish by removing any tag hashes still present in $text. - $text = $this->unhash($text); - - return $text; - } - - - ### Footnotes - - protected function stripFootnotes($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # - $less_than_tab = $this->tab_width - 1; - - # Link defs are in the form: [^id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1 - [ ]* - \n? # maybe *one* newline - ( # text = $2 (no blank lines allowed) - (?: - .+ # actual text - | - \n # newlines but - (?!\[\^.+?\]:\s)# negative lookahead for footnote marker. - (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed - # by non-indented content - )* - ) - }xm', - array($this, '_stripFootnotes_callback'), - $text); - return $text; - } - protected function _stripFootnotes_callback($matches) { - $note_id = $this->fn_id_prefix . $matches[1]; - $this->footnotes[$note_id] = $this->outdent($matches[2]); - return ''; # String that will replace the block - } - - - protected function doFootnotes($text) { - # - # Replace footnote references in $text [^id] with a special text-token - # which will be replaced by the actual footnote marker in appendFootnotes. - # - if (!$this->in_anchor) { - $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); - } - return $text; - } - - - protected function appendFootnotes($text) { - # - # Append footnote list to text. - # - $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array($this, '_appendFootnotes_callback'), $text); - - if (!empty($this->footnotes_ordered)) { - $text .= "\n\n"; - $text .= "
    \n"; - $text .= "empty_element_suffix ."\n"; - $text .= "
      \n\n"; - - $attr = " rev=\"footnote\""; - if ($this->fn_backlink_class != "") { - $class = $this->fn_backlink_class; - $class = $this->encodeAttribute($class); - $attr .= " class=\"$class\""; - } - if ($this->fn_backlink_title != "") { - $title = $this->fn_backlink_title; - $title = $this->encodeAttribute($title); - $attr .= " title=\"$title\""; - } - $num = 0; - - while (!empty($this->footnotes_ordered)) { - $footnote = reset($this->footnotes_ordered); - $note_id = key($this->footnotes_ordered); - unset($this->footnotes_ordered[$note_id]); - $ref_count = $this->footnotes_ref_count[$note_id]; - unset($this->footnotes_ref_count[$note_id]); - unset($this->footnotes[$note_id]); - - $footnote .= "\n"; # Need to append newline before parsing. - $footnote = $this->runBlockGamut("$footnote\n"); - $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array($this, '_appendFootnotes_callback'), $footnote); - - $attr = str_replace("%%", ++$num, $attr); - $note_id = $this->encodeAttribute($note_id); - - # Prepare backlink, multiple backlinks if multiple references - $backlink = ""; - for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) { - $backlink .= " "; - } - # Add backlink to last paragraph; create new paragraph if needed. - if (preg_match('{

      $}', $footnote)) { - $footnote = substr($footnote, 0, -4) . " $backlink

      "; - } else { - $footnote .= "\n\n

      $backlink

      "; - } - - $text .= "
    1. \n"; - $text .= $footnote . "\n"; - $text .= "
    2. \n\n"; - } - - $text .= "
    \n"; - $text .= "
    "; - } - return $text; - } - protected function _appendFootnotes_callback($matches) { - $node_id = $this->fn_id_prefix . $matches[1]; - - # Create footnote marker only if it has a corresponding footnote *and* - # the footnote hasn't been used by another marker. - if (isset($this->footnotes[$node_id])) { - $num =& $this->footnotes_numbers[$node_id]; - if (!isset($num)) { - # Transfer footnote content to the ordered list and give it its - # number - $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; - $this->footnotes_ref_count[$node_id] = 1; - $num = $this->footnote_counter++; - $ref_count_mark = ''; - } else { - $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1; - } - - $attr = ""; - if ($this->fn_link_class != "") { - $class = $this->fn_link_class; - $class = $this->encodeAttribute($class); - $attr .= " class=\"$class\""; - } - if ($this->fn_link_title != "") { - $title = $this->fn_link_title; - $title = $this->encodeAttribute($title); - $attr .= " title=\"$title\""; - } - - $attr = str_replace("%%", $num, $attr); - $node_id = $this->encodeAttribute($node_id); - - return - "". - "$num". - ""; - } - - return "[^".$matches[1]."]"; - } - - - ### Abbreviations ### - - protected function stripAbbreviations($text) { - # - # Strips abbreviations from text, stores titles in hash references. - # - $less_than_tab = $this->tab_width - 1; - - # Link defs are in the form: [id]*: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1 - (.*) # text = $2 (no blank lines allowed) - }xm', - array($this, '_stripAbbreviations_callback'), - $text); - return $text; - } - protected function _stripAbbreviations_callback($matches) { - $abbr_word = $matches[1]; - $abbr_desc = $matches[2]; - if ($this->abbr_word_re) - $this->abbr_word_re .= '|'; - $this->abbr_word_re .= preg_quote($abbr_word); - $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); - return ''; # String that will replace the block - } - - - protected function doAbbreviations($text) { - # - # Find defined abbreviations in text and wrap them in elements. - # - if ($this->abbr_word_re) { - // cannot use the /x modifier because abbr_word_re may - // contain significant spaces: - $text = preg_replace_callback('{'. - '(?abbr_word_re.')'. - '(?![\w\x1A])'. - '}', - array($this, '_doAbbreviations_callback'), $text); - } - return $text; - } - protected function _doAbbreviations_callback($matches) { - $abbr = $matches[0]; - if (isset($this->abbr_desciptions[$abbr])) { - $desc = $this->abbr_desciptions[$abbr]; - if (empty($desc)) { - return $this->hashPart("$abbr"); - } else { - $desc = $this->encodeAttribute($desc); - return $this->hashPart("$abbr"); - } - } else { - return $matches[0]; - } - } - -} - -// https://github.com/egil/php-markdown-extra-extended -class MarkdownExtraExtended extends MarkdownExtra { - # Tags that are always treated as block tags: - protected $block_tags_re = 'figure|figcaption|p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend'; - - public function __construct() { - $this->block_gamut += array( - "doFencedFigures" => 7 - ); - - $this->document_gamut += array( - "doClearBreaks" => 100 - ); - - parent::__construct(); - } - - public static function defaultTransform($text) { - # try to take parser from the static parser list - static $parser; - - # create the parser it not already set - if (!$parser) { - $parser = new MarkdownExtraExtended(); - } - - # Transform text using parser. - return $parser->transform($text); - } - - public function doHardBreaks($text) { - # Do hard breaks: - # EXTENDED: changed to allow breaks without two spaces and just one new line - # original code /* return preg_replace_callback('/ {2,}\n/', */ - return preg_replace_callback('/ *\n/', - array($this, '_doHardBreaks_callback'), $text); - } - - public function doClearBreaks($text) { - return preg_replace("/\s*((?:
    \n)+)\s*(<\/?(?:$this->block_tags_re|li|dd|dt)[^\d])/is", - "\\2", $text); - } - - - public function doBlockQuotes($text) { - $text = preg_replace_callback('/ - (?>^[ ]*>[ ]? - (?:\((.+?)\))? - [ ]*(.+\n(?:.+\n)*) - )+ - /xm', - array($this, '_doBlockQuotes_callback'), $text); - - return $text; - } - - public function _doBlockQuotes_callback($matches) { - $cite = $matches[1]; - $bq = '> ' . $matches[2]; - # trim one level of quoting - trim whitespace-only lines - $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); - $bq = $this->runBlockGamut($bq); # recurse - - $bq = preg_replace('/^/m', " ", $bq); - # These leading spaces cause problem with
     content, 
    -		# so we need to fix that:
    -		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', - array($this, '_doBlockQuotes_callback2'), $bq); - - $res = "" : " cite=\"$cite\">"; - $res .= "\n$bq\n"; - return "\n". $this->hashBlock($res)."\n\n"; - } - - public function doFencedCodeBlocks($text) { - $less_than_tab = $this->tab_width; - - $text = preg_replace_callback('{ - (?:\n|\A) - # 1: Opening marker - ( - ~{3,}|`{3,} # Marker: three tilde or more. - ) - - [ ]?(\w+)?(?:,[ ]?(\d+))?[ ]* \n # Whitespace and newline following marker. - - # 3: Content - ( - (?> - (?!\1 [ ]* \n) # Not a closing marker. - .*\n+ - )+ - ) - - # Closing marker. - \1 [ ]* \n - }xm', - array($this, '_doFencedCodeBlocks_callback'), $text); - - return $text; - } - - public function _doFencedCodeBlocks_callback($matches) { - $codeblock = $this->unhashHTMLBlocks($matches[4]); - $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); - $codeblock = preg_replace_callback('/^\n+/', - array($this, '_doFencedCodeBlocks_newlines'), $codeblock); - //$codeblock = "
    $codeblock
    "; - //$cb = "
    " : " class=\"lang-$matches[2]\">";
    -		$cb .= "$codeblock
    "; - return "\n\n".$this->hashBlock($cb)."\n\n"; - } - - public function doFencedFigures($text){ - $text = preg_replace_callback('{ - (?:\n|\A) - # 1: Opening marker - ( - ={3,} # Marker: equal sign. - ) - - [ ]?(?:\[([^\]]+)\])?[ ]* \n # Whitespace and newline following marker. - - # 3: Content - ( - (?> - (?!\1 [ ]?(?:\[([^\]]+)\])?[ ]* \n) # Not a closing marker. - .*\n+ - )+ - ) - - # Closing marker. - \1 [ ]?(?:\[([^\]]+)\])?[ ]* \n - }xm', array($this, '_doFencedFigures_callback'), $text); - - return $text; - } - - public function _doFencedFigures_callback($matches) { - # get figcaption - $topcaption = empty($matches[2]) ? null : $this->runBlockGamut($matches[2]); - $bottomcaption = empty($matches[5]) ? null : $this->runBlockGamut($matches[5]); - $figure = $matches[3]; - $figure = $this->runBlockGamut($figure); # recurse - - $figure = preg_replace('/^/m', " ", $figure); - # These leading spaces cause problem with
     content, 
    -		# so we need to fix that - reuse blockqoute code to handle this:
    -		$figure = preg_replace_callback('{(\s*
    .+?
    )}sx', - array($this, '_doBlockQuotes_callback2'), $figure); - - $res = "
    "; - if(!empty($topcaption)){ - $res .= "\n
    $topcaption
    "; - } - $res .= "\n$figure\n"; - if(!empty($bottomcaption) && empty($topcaption)){ - $res .= "
    $bottomcaption
    "; - } - $res .= "
    "; - return "\n". $this->hashBlock($res)."\n\n"; - } -} - diff --git a/php/typecho09/var/Typecho/Common.php b/php/typecho09/var/Typecho/Common.php deleted file mode 100644 index 4e00fea32..000000000 --- a/php/typecho09/var/Typecho/Common.php +++ /dev/null @@ -1,1345 +0,0 @@ -

    ' => ''); - - /** - * 允许的标签 - * - * @access private - * @var array - */ - private static $_allowableTags = ''; - - /** - * 允许的属性 - * - * @access private - * @var array - */ - private static $_allowableAttributes = array(); - - /** - * 默认编码 - * - * @access public - * @var string - */ - public static $charset = 'UTF-8'; - - /** - * 异常处理类 - * - * @access public - * @var string - */ - public static $exceptionHandle; - - /** - * 锁定标签回调函数 - * - * @access private - * @param array $matches 匹配的值 - * @return string - */ - public static function __lockHTML(array $matches) - { - $guid = '' . uniqid(time()) . ''; - self::$_lockedBlocks[$guid] = $matches[0]; - return $guid; - } - - /** - * 将url中的非法xss去掉时的数组回调过滤函数 - * - * @access private - * @param string $string 需要过滤的字符串 - * @return string - */ - public static function __removeUrlXss($string) - { - $string = str_replace(array('%0d', '%0a'), '', strip_tags($string)); - return preg_replace(array( - "/\(\s*(\"|')/i", //函数开头 - "/(\"|')\s*\)/i", //函数结尾 - ), '', $string); - } - - /** - * 检查是否为安全路径 - * - * @access public - * @param string $path 检查是否为安全路径 - * @return boolean - */ - public static function __safePath($path) - { - $safePath = rtrim(__TYPECHO_ROOT_DIR__, '/'); - return 0 === strpos($path, $safePath); - } - - /** - * __filterAttrs - * - * @param mixed $matches - * @static - * @access public - * @return void - */ - public static function __filterAttrs($matches) - { - if (!isset($matches[2])) { - return $matches[0]; - } - - $str = trim($matches[2]); - - if (empty($str)) { - return $matches[0]; - } - - $attrs = self::__parseAttrs($str); - $parsedAttrs = array(); - $tag = strtolower($matches[1]); - - foreach ($attrs as $key => $val) { - if (in_array($key, self::$_allowableAttributes[$tag])) { - $parsedAttrs[] = " {$key}" . (empty($val) ? '' : "={$val}"); - } - } - - return '<' . $tag . implode('', $parsedAttrs) . '>'; - } - - /** - * 解析属性 - * - * @access public - * @param string $attrs 属性字符串 - * @return array - */ - public static function __parseAttrs($attrs) - { - $attrs = trim($attrs); - $len = strlen($attrs); - $pos = -1; - $result = array(); - $quote = ''; - $key = ''; - $value = ''; - - for ($i = 0; $i < $len; $i ++) { - if ('=' != $attrs[$i] && !ctype_space($attrs[$i]) && -1 == $pos) { - $key .= $attrs[$i]; - - /** 最后一个 */ - if ($i == $len - 1) { - if ('' != ($key = trim($key))) { - $result[$key] = ''; - $key = ''; - $value = ''; - } - } - - } else if (ctype_space($attrs[$i]) && -1 == $pos) { - $pos = -2; - } else if ('=' == $attrs[$i] && 0 > $pos) { - $pos = 0; - } else if (('"' == $attrs[$i] || "'" == $attrs[$i]) && 0 == $pos) { - $quote = $attrs[$i]; - $value .= $attrs[$i]; - $pos = 1; - } else if ($quote != $attrs[$i] && 1 == $pos) { - $value .= $attrs[$i]; - } else if ($quote == $attrs[$i] && 1 == $pos) { - $pos = -1; - $value .= $attrs[$i]; - $result[trim($key)] = $value; - $key = ''; - $value = ''; - } else if ('=' != $attrs[$i] && !ctype_space($attrs[$i]) && -2 == $pos) { - if ('' != ($key = trim($key))) { - $result[$key] = ''; - } - - $key = ''; - $value = ''; - $pos = -1; - $key .= $attrs[$i]; - } - } - - return $result; - } - - /** - * 程序初始化方法 - * - * @access public - * @return void - */ - public static function init() - { - /** 设置自动载入函数 */ - function __autoLoad($className) - { - /** - * 自动载入函数并不判断此类的文件是否存在, 我们认为当你显式的调用它时, 你已经确认它存在了 - * 如果真的无法被加载, 那么系统将出现一个严重错误(Fetal Error) - * 如果你需要判断一个类能否被加载, 请使用 Typecho_Common::isAvailableClass 方法 - */ - @include_once str_replace('_', '/', $className) . '.php'; - } - - /** 兼容php6 */ - if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { - $_GET = self::stripslashesDeep($_GET); - $_POST = self::stripslashesDeep($_POST); - $_COOKIE = self::stripslashesDeep($_COOKIE); - - reset($_GET); - reset($_POST); - reset($_COOKIE); - } - - /** 设置异常截获函数 */ - set_exception_handler(array('Typecho_Common', 'exceptionHandle')); - } - - /** - * 异常截获函数 - * - * @access public - * @param Exception $exception 截获的异常 - * @return void - */ - public static function exceptionHandle(Exception $exception) - { - //$obHandles = ob_list_handlers(); - - @ob_end_clean(); - - /* - if (in_array('ob_gzhandler', $obHandles)) { - ob_start('ob_gzhandler'); - } else { - ob_start(); - } - */ - - if (defined('__TYPECHO_DEBUG__')) { - //@ob_clean(); - echo nl2br($exception->__toString()); - } else { - if (404 == $exception->getCode() && !empty(self::$exceptionHandle)) { - $handleClass = self::$exceptionHandle; - new $handleClass($exception); - } else { - self::error($exception); - } - } - - exit; - } - - /** - * 输出错误页面 - * - * @access public - * @param mixed $exception 错误信息 - * @return void - */ - public static function error($exception) - { - $isException = is_object($exception); - - if ($isException) { - $code = $exception->getCode(); - $message = $exception->getMessage(); - } else { - $code = $exception; - } - - require_once 'Typecho/Response.php'; - $charset = self::$charset; - - if ($isException && $exception instanceof Typecho_Db_Exception) { - $code = 500; - @error_log($message); - - //覆盖原始错误信息 - $message = 'Database Server Error'; - - if ($exception instanceof Typecho_Db_Adapter_Exception) { - $code = 503; - $message = 'Error establishing a database connection'; - } else if ($exception instanceof Typecho_Db_Query_Exception) { - $message = 'Database Query Error'; - } - } else { - switch ($code) { - case 500: - $message = 'Server Error'; - break; - - case 404: - $message = 'Page Not Found'; - break; - - default: - $code = 'Error'; - break; - } - } - - - /** 设置http code */ - if (is_numeric($code) && $code > 200) { - require_once 'Typecho/Response.php'; - Typecho_Response::setStatus($code); - } - - $message = nl2br($message); - - if (defined('__TYPECHO_EXCEPTION_FILE__')) { - require_once __TYPECHO_EXCEPTION_FILE__; - } else { - echo -<< - - - - {$code} - - - -
    -

    {$code}

    - {$message} -
    - - -EOF; - } - - exit; - } - - /** - * 判断类是否能被加载 - * 此函数会遍历所有的include目录, 所以会有一定的性能消耗, 但是不会很大 - * 可是我们依然建议你在必须检测一个类能否被加载时使用它, 它通常表现为以下两种情况 - * 1. 当需要被加载的类不存在时, 系统不会停止运行 (如果你不判断, 系统会因抛出严重错误而停止) - * 2. 你需要知道哪些类无法被加载, 以提示使用者 - * 除了以上情况, 你无需关注那些类无法被加载, 因为当它们不存在时系统会自动停止并报错 - * - * @access public - * @param string $className 类名 - * @param string $path 指定的路径名称 - * @return boolean - */ - public static function isAvailableClass($className, $path = NULL) - { - /** 获取所有include目录 */ - //增加安全目录检测 fix issue 106 - $dirs = array_map('realpath', array_filter(explode(PATH_SEPARATOR, get_include_path()), - array('Typecho_Common', '__safePath'))); - - $file = str_replace('_', '/', $className) . '.php'; - - if (!empty($path)) { - $path = realpath($path); - if (in_array($path, $dirs)) { - $dirs = array($path); - } else { - return false; - } - } - - foreach ($dirs as $dir) { - if (!empty($dir)) { - if (file_exists($dir . '/' . $file)) { - return true; - } - } - } - - return false; - } - - /** - * 递归去掉数组反斜线 - * - * @access public - * @param mixed $value - * @return mixed - */ - public static function stripslashesDeep($value) - { - return is_array($value) ? array_map(array('Typecho_Common', 'stripslashesDeep'), $value) : stripslashes($value); - } - - /** - * 抽取多维数组的某个元素,组成一个新数组,使这个数组变成一个扁平数组 - * 使用方法: - * - * 2, 'banana' => 3), array('apple' => 10, 'banana' => 12)); - * $banana = Typecho_Common::arrayFlatten($fruit, 'banana'); - * print_r($banana); - * //outputs: array(0 => 3, 1 => 12); - * ?> - * - * - * @access public - * @param array $value 被处理的数组 - * @param string $key 需要抽取的键值 - * @return array - */ - public static function arrayFlatten(array $value, $key) - { - $result = array(); - - if ($value) { - foreach ($value as $inval) { - if (is_array($inval) && isset($inval[$key])) { - $result[] = $inval[$key]; - } else { - break; - } - } - } - - return $result; - } - - /** - * 根据parse_url的结果重新组合url - * - * @access public - * @param array $params 解析后的参数 - * @return string - */ - public static function buildUrl($params) - { - return (isset($params['scheme']) ? $params['scheme'] . '://' : NULL) - . (isset($params['user']) ? $params['user'] . (isset($params['pass']) ? ':' . $params['pass'] : NULL) . '@' : NULL) - . (isset($params['host']) ? $params['host'] : NULL) - . (isset($params['port']) ? ':' . $params['port'] : NULL) - . (isset($params['path']) ? $params['path'] : NULL) - . (isset($params['query']) ? '?' . $params['query'] : NULL) - . (isset($params['fragment']) ? '#' . $params['fragment'] : NULL); - } - - /** - * 根据count数目来输出字符 - * - * echo splitByCount(20, 10, 20, 30, 40, 50); - * - * - * @access public - * @return string - */ - public static function splitByCount($count) - { - $sizes = func_get_args(); - array_shift($sizes); - - foreach ($sizes as $size) { - if ($count < $size) { - return $size; - } - } - - return 0; - } - - /** - * 自闭合html修复函数 - * 使用方法: - * - * $input = '这是一段被截断的html文本 - * - * @access public - * @param string $string 需要修复处理的字符串 - * @return string - */ - public static function fixHtml($string) - { - //关闭自闭合标签 - $startPos = strrpos($string, "<"); - - if (false == $startPos) { - return $string; - } - - $trimString = substr($string, $startPos); - - if (false === strpos($trimString, ">")) { - $string = substr($string, 0, $startPos); - } - - //非自闭合html标签列表 - preg_match_all("/<([_0-9a-zA-Z-\:]+)\s*([^>]*)>/is", $string, $startTags); - preg_match_all("/<\/([_0-9a-zA-Z-\:]+)>/is", $string, $closeTags); - - if (!empty($startTags[1]) && is_array($startTags[1])) { - krsort($startTags[1]); - $closeTagsIsArray = is_array($closeTags[1]); - foreach ($startTags[1] as $key => $tag) { - $attrLength = strlen($startTags[2][$key]); - if ($attrLength > 0 && "/" == trim($startTags[2][$key][$attrLength - 1])) { - continue; - } - if (!empty($closeTags[1]) && $closeTagsIsArray) { - if (false !== ($index = array_search($tag, $closeTags[1]))) { - unset($closeTags[1][$index]); - continue; - } - } - $string .= ""; - } - } - - return preg_replace("/\\s*\<\/p\>/is", '

    ', $string); - } - - /** - * 去掉字符串中的html标签 - * 使用方法: - * - * $input = '
    hello'; - * $output = Typecho_Common::stripTags($input, ); - * echo $output; - * //display: 'hello' - * - * - * @access public - * @param string $string 需要处理的字符串 - * @param string $allowableTags 需要忽略的html标签 - * @return string - */ - public static function stripTags($html, $allowableTags = NULL) - { - static $dom; - - $normalizeTags = ''; - $allowableAttributes = array(); - - if (!empty($allowableTags) && preg_match_all("/\<([_a-z0-9-]+)([^>]*)\>/is", $allowableTags, $tags)) { - $normalizeTags = '<' . implode('><', array_map('strtolower', $tags[1])) . '>'; - $attributes = array_map('trim', $tags[2]); - foreach ($attributes as $key => $val) { - $allowableAttributes[strtolower($tags[1][$key])] = - array_map('strtolower', array_keys(self::__parseAttrs($val))); - } - } - - self::$_allowableAttributes = $allowableAttributes; - $html = strip_tags($html, $normalizeTags); - $html = preg_replace_callback("/<([_a-z0-9-]+)(\s+[^>]+)?>/is", - array('Typecho_Common', '__filterAttrs'), $html); - - return $html; - } - - /** - * 过滤用于搜索的字符串 - * - * @access public - * @param string $query 搜索字符串 - * @return string - */ - public static function filterSearchQuery($query) - { - return str_replace('-', ' ', self::slugName($query)); - } - - /** - * 将url中的非法字符串 - * - * @access private - * @param string $string 需要过滤的url - * @return string - */ - public static function safeUrl($url) - { - //~ 针对location的xss过滤, 因为其特殊性无法使用removeXSS函数 - //~ fix issue 66 - $params = parse_url(str_replace(array("\r", "\n"), '', $url)); - - /** 禁止非法的协议跳转 */ - if (isset($params['scheme'])) { - if (!in_array($params['scheme'], array('http', 'https'))) { - return; - } - } - - /** 过滤解析串 */ - $params = array_map(array('Typecho_Common', '__removeUrlXss'), $params); - return self::buildUrl($params); - } - - /** - * 处理XSS跨站攻击的过滤函数 - * - * @author kallahar@kallahar.com - * @link http://kallahar.com/smallprojects/php_xss_filter_function.php - * @access public - * @param string $val 需要处理的字符串 - * @return string - */ - public static function removeXSS($val) - { - // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed - // this prevents some character re-spacing such as - // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs - $val = preg_replace('/([\x00-\x08]|[\x0b-\x0c]|[\x0e-\x19])/', '', $val); - - // straight replacements, the user should never need these since they're normal characters - // this prevents like - $search = 'abcdefghijklmnopqrstuvwxyz'; - $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $search .= '1234567890!@#$%^&*()'; - $search .= '~`";:?+/={}[]-_|\'\\'; - - for ($i = 0; $i < strlen($search); $i++) { - // ;? matches the ;, which is optional - // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars - - // @ @ search for the hex values - $val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ; - // @ @ 0{0,7} matches '0' zero to seven times - $val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; - } - - // now the only remaining whitespace attacks are \t, \n, and \r - $ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base'); - $ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload'); - $ra = array_merge($ra1, $ra2); - - $found = true; // keep replacing as long as the previous round replaced something - while ($found == true) { - $val_before = $val; - for ($i = 0; $i < sizeof($ra); $i++) { - $pattern = '/'; - for ($j = 0; $j < strlen($ra[$i]); $j++) { - if ($j > 0) { - $pattern .= '('; - $pattern .= '(&#[xX]0{0,8}([9ab]);)'; - $pattern .= '|'; - $pattern .= '|(�{0,8}([9|10|13]);)'; - $pattern .= ')*'; - } - $pattern .= $ra[$i][$j]; - } - $pattern .= '/i'; - $replacement = substr($ra[$i], 0, 2).''.substr($ra[$i], 2); // add in <> to nerf the tag - $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags - - if ($val_before == $val) { - // no replacements were made, so exit the loop - $found = false; - } - } - } - - return $val; - } - - /** - * 宽字符串截字函数 - * - * @access public - * @param string $str 需要截取的字符串 - * @param integer $start 开始截取的位置 - * @param integer $length 需要截取的长度 - * @param string $trim 截取后的截断标示符 - * @return string - */ - public static function subStr($str, $start, $length, $trim = "...") - { - if (function_exists('mb_get_info')) { - $iLength = mb_strlen($str, self::$charset); - $str = mb_substr($str, $start, $length, self::$charset); - return ($length < $iLength - $start) ? $str . $trim : $str; - } else { - preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $str, $info); - $str = join("", array_slice($info[0], $start, $length)); - return ($length < (sizeof($info[0]) - $start)) ? $str . $trim : $str; - } - } - - /** - * 获取宽字符串长度函数 - * - * @access public - * @param string $str 需要获取长度的字符串 - * @return integer - */ - public static function strLen($str) - { - if (function_exists('mb_get_info')) { - return mb_strlen($str, self::$charset); - } else { - preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $str, $info); - return sizeof($info[0]); - } - } - - /** - * 生成缩略名 - * - * @access public - * @param string $str 需要生成缩略名的字符串 - * @param string $default 默认的缩略名 - * @param integer $maxLength 缩略名最大长度 - * @return string - */ - public static function slugName($str, $default = NULL, $maxLength = 128) - { - $str = trim($str); - - if (!strlen($str)) { - return $default; - } - - if (function_exists('mb_regex_encoding')) { - mb_regex_encoding(self::$charset); - mb_ereg_search_init($str, "[\w" . preg_quote('_-') . "]+"); - $result = mb_ereg_search(); - $return = ''; - - if ($result) { - $regs = mb_ereg_search_getregs(); - $pos = 0; - do { - $return .= ($pos > 0 ? '-' : '') . $regs[0]; - $pos ++; - } while ($regs = mb_ereg_search_regs()); - } - - $str = $return; - } else { - $str = str_replace(array("'", ":", "\\", "/", '"'), "", $str); - $str = str_replace(array("+", ",", ' ', ',', ' ', ".", "?", "=", "&", "!", "<", ">", "(", ")", "[", "]", "{", "}"), "-", $str); - $str = trim($str, '-'); - } - - $str = !strlen($str) ? $default : $str; - return substr($str, 0, $maxLength); - } - - /** - * 去掉html中的分段 - * - * @access public - * @param string $html 输入串 - * @return string - */ - public static function removeParagraph($html) - { - /** 锁定标签 */ - $html = self::lockHTML($html); - $html = str_replace(array("\r", "\n"), '', $html); - - $html = trim(preg_replace( - array("/\s*

    (.*?)<\/p>\s*/is", "/\s*\s*/is", - "/\s*<(div|blockquote|pre|code|script|table|fieldset|ol|ul|dl|h[1-6])([^>]*)>/is", - "/<\/(div|blockquote|pre|code|script|table|fieldset|ol|ul|dl|h[1-6])>\s*/is", "/\s*<\!--more-->\s*/is"), - array("\n\\1\n", "\n", "\n\n<\\1\\2>", "\n\n", "\n\n\n\n"), - $html)); - - return trim(self::releaseHTML($html)); - } - - /** - * 锁定标签 - * - * @access public - * @param string $html 输入串 - * @return string - */ - public static function lockHTML($html) - { - return preg_replace_callback("/<(code|pre|script)[^>]*>.*?<\/\\1>/is", array('Typecho_Common', '__lockHTML'), $html); - } - - /** - * 释放标签 - * - * @access public - * @param string $html 输入串 - * @return string - */ - public static function releaseHTML($html) - { - $html = trim(str_replace(array_keys(self::$_lockedBlocks), array_values(self::$_lockedBlocks), $html)); - self::$_lockedBlocks = array('

    ' => ''); - return $html; - } - - /** - * 文本分段函数 - * - * @param string $string 需要分段的字符串 - * @return string - */ - public static function cutParagraph($string) - { - static $loaded; - if (!$loaded) { - require_once 'Typecho/Common/Paragraph.php'; - $loaded = true; - } - - return Typecho_Common_Paragraph::process($string); - } - - /** - * 生成随机字符串 - * - * @access public - * @param integer $length 字符串长度 - * @param string $specialChars 是否有特殊字符 - * @return string - */ - public static function randString($length, $specialChars = false) - { - $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - if ($specialChars) { - $chars .= '!@#$%^&*()'; - } - - $result = ''; - $max = strlen($chars) - 1; - for ($i = 0; $i < $length; $i++) { - $result .= $chars[rand(0, $max)]; - } - return $result; - } - - /** - * 对字符串进行hash加密 - * - * @access public - * @param string $string 需要hash的字符串 - * @param string $salt 扰码 - * @return string - */ - public static function hash($string, $salt = NULL) - { - /** 生成随机字符串 */ - $salt = empty($salt) ? self::randString(9) : $salt; - $length = strlen($string); - $hash = ''; - $last = ord($string[$length - 1]); - $pos = 0; - - /** 判断扰码长度 */ - if (strlen($salt) != 9) { - /** 如果不是9直接返回 */ - return; - } - - while ($pos < $length) { - $asc = ord($string[$pos]); - $last = ($last * ord($salt[($last % $asc) % 9]) + $asc) % 95 + 32; - $hash .= chr($last); - $pos ++; - } - - return '$T$' . $salt . md5($hash); - } - - /** - * 判断hash值是否相等 - * - * @access public - * @param string $from 源字符串 - * @param string $to 目标字符串 - * @return boolean - */ - public static function hashValidate($from, $to) - { - if ('$T$' == substr($to, 0, 3)) { - $salt = substr($to, 3, 9); - return self::hash($from, $salt) == $to; - } else { - return md5($from) == $to; - } - } - - /** - * 将路径转化为链接 - * - * @access public - * @param string $path 路径 - * @param string $prefix 前缀 - * @return string - */ - public static function url($path, $prefix) - { - $path = (0 === strpos($path, './')) ? substr($path, 2) : $path; - return rtrim($prefix, '/') . '/' . str_replace('//', '/', ltrim($path, '/')); - } - - /** - * 获取图片 - * - * @access public - * @param string $fileName 文件名 - * @return string - */ - public static function mimeContentType($fileName) - { - //改为并列判断 - if (function_exists('mime_content_type')) { - return mime_content_type($fileName); - } - - if (function_exists('finfo_open')) { - $fInfo = @finfo_open(FILEINFO_MIME); - - if (false !== $fInfo) { - $mimeType = finfo_file($fInfo, $fileName); - finfo_close($fInfo); - return $mimeType; - } - } - - $mimeTypes = array( - 'ez' => 'application/andrew-inset', - 'csm' => 'application/cu-seeme', - 'cu' => 'application/cu-seeme', - 'tsp' => 'application/dsptype', - 'spl' => 'application/x-futuresplash', - 'hta' => 'application/hta', - 'cpt' => 'image/x-corelphotopaint', - 'hqx' => 'application/mac-binhex40', - 'nb' => 'application/mathematica', - 'mdb' => 'application/msaccess', - 'doc' => 'application/msword', - 'dot' => 'application/msword', - 'bin' => 'application/octet-stream', - 'oda' => 'application/oda', - 'ogg' => 'application/ogg', - 'prf' => 'application/pics-rules', - 'key' => 'application/pgp-keys', - 'pdf' => 'application/pdf', - 'pgp' => 'application/pgp-signature', - 'ps' => 'application/postscript', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'rss' => 'application/rss+xml', - 'rtf' => 'text/rtf', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'wp5' => 'application/wordperfect5.1', - 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - 'zip' => 'application/zip', - 'cdy' => 'application/vnd.cinderella', - 'mif' => 'application/x-mif', - 'xls' => 'application/vnd.ms-excel', - 'xlb' => 'application/vnd.ms-excel', - 'cat' => 'application/vnd.ms-pki.seccat', - 'stl' => 'application/vnd.ms-pki.stl', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pps' => 'application/vnd.ms-powerpoint', - 'pot' => 'application/vnd.ms-powerpoint', - 'sdc' => 'application/vnd.stardivision.calc', - 'sda' => 'application/vnd.stardivision.draw', - 'sdd' => 'application/vnd.stardivision.impress', - 'sdp' => 'application/vnd.stardivision.impress', - 'smf' => 'application/vnd.stardivision.math', - 'sdw' => 'application/vnd.stardivision.writer', - 'vor' => 'application/vnd.stardivision.writer', - 'sgl' => 'application/vnd.stardivision.writer-global', - 'sxc' => 'application/vnd.sun.xml.calc', - 'stc' => 'application/vnd.sun.xml.calc.template', - 'sxd' => 'application/vnd.sun.xml.draw', - 'std' => 'application/vnd.sun.xml.draw.template', - 'sxi' => 'application/vnd.sun.xml.impress', - 'sti' => 'application/vnd.sun.xml.impress.template', - 'sxm' => 'application/vnd.sun.xml.math', - 'sxw' => 'application/vnd.sun.xml.writer', - 'sxg' => 'application/vnd.sun.xml.writer.global', - 'stw' => 'application/vnd.sun.xml.writer.template', - 'sis' => 'application/vnd.symbian.install', - 'wbxml' => 'application/vnd.wap.wbxml', - 'wmlc' => 'application/vnd.wap.wmlc', - 'wmlsc' => 'application/vnd.wap.wmlscriptc', - 'wk' => 'application/x-123', - 'dmg' => 'application/x-apple-diskimage', - 'bcpio' => 'application/x-bcpio', - 'torrent' => 'application/x-bittorrent', - 'cdf' => 'application/x-cdf', - 'vcd' => 'application/x-cdlink', - 'pgn' => 'application/x-chess-pgn', - 'cpio' => 'application/x-cpio', - 'csh' => 'text/x-csh', - 'deb' => 'application/x-debian-package', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'wad' => 'application/x-doom', - 'dms' => 'application/x-dms', - 'dvi' => 'application/x-dvi', - 'pfa' => 'application/x-font', - 'pfb' => 'application/x-font', - 'gsf' => 'application/x-font', - 'pcf' => 'application/x-font', - 'pcf.Z' => 'application/x-font', - 'gnumeric' => 'application/x-gnumeric', - 'sgf' => 'application/x-go-sgf', - 'gcf' => 'application/x-graphing-calculator', - 'gtar' => 'application/x-gtar', - 'tgz' => 'application/x-gtar', - 'taz' => 'application/x-gtar', - 'gz' => 'application/x-gtar', - 'hdf' => 'application/x-hdf', - 'phtml' => 'application/x-httpd-php', - 'pht' => 'application/x-httpd-php', - 'php' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'php3' => 'application/x-httpd-php3', - 'php3p' => 'application/x-httpd-php3-preprocessed', - 'php4' => 'application/x-httpd-php4', - 'ica' => 'application/x-ica', - 'ins' => 'application/x-internet-signup', - 'isp' => 'application/x-internet-signup', - 'iii' => 'application/x-iphone', - 'jar' => 'application/x-java-archive', - 'jnlp' => 'application/x-java-jnlp-file', - 'ser' => 'application/x-java-serialized-object', - 'class' => 'application/x-java-vm', - 'js' => 'application/x-javascript', - 'chrt' => 'application/x-kchart', - 'kil' => 'application/x-killustrator', - 'kpr' => 'application/x-kpresenter', - 'kpt' => 'application/x-kpresenter', - 'skp' => 'application/x-koan', - 'skd' => 'application/x-koan', - 'skt' => 'application/x-koan', - 'skm' => 'application/x-koan', - 'ksp' => 'application/x-kspread', - 'kwd' => 'application/x-kword', - 'kwt' => 'application/x-kword', - 'latex' => 'application/x-latex', - 'lha' => 'application/x-lha', - 'lzh' => 'application/x-lzh', - 'lzx' => 'application/x-lzx', - 'frm' => 'application/x-maker', - 'maker' => 'application/x-maker', - 'frame' => 'application/x-maker', - 'fm' => 'application/x-maker', - 'fb' => 'application/x-maker', - 'book' => 'application/x-maker', - 'fbdoc' => 'application/x-maker', - 'wmz' => 'application/x-ms-wmz', - 'wmd' => 'application/x-ms-wmd', - 'com' => 'application/x-msdos-program', - 'exe' => 'application/x-msdos-program', - 'bat' => 'application/x-msdos-program', - 'dll' => 'application/x-msdos-program', - 'msi' => 'application/x-msi', - 'nc' => 'application/x-netcdf', - 'pac' => 'application/x-ns-proxy-autoconfig', - 'nwc' => 'application/x-nwc', - 'o' => 'application/x-object', - 'oza' => 'application/x-oz-application', - 'pl' => 'application/x-perl', - 'pm' => 'application/x-perl', - 'p7r' => 'application/x-pkcs7-certreqresp', - 'crl' => 'application/x-pkcs7-crl', - 'qtl' => 'application/x-quicktimeplayer', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'shar' => 'application/x-shar', - 'swf' => 'application/x-shockwave-flash', - 'swfl' => 'application/x-shockwave-flash', - 'sh' => 'text/x-sh', - 'sit' => 'application/x-stuffit', - 'sv4cpio' => 'application/x-sv4cpio', - 'sv4crc' => 'application/x-sv4crc', - 'tar' => 'application/x-tar', - 'tcl' => 'text/x-tcl', - 'tex' => 'text/x-tex', - 'gf' => 'application/x-tex-gf', - 'pk' => 'application/x-tex-pk', - 'texinfo' => 'application/x-texinfo', - 'texi' => 'application/x-texinfo', - '~' => 'application/x-trash', - '%' => 'application/x-trash', - 'bak' => 'application/x-trash', - 'old' => 'application/x-trash', - 'sik' => 'application/x-trash', - 't' => 'application/x-troff', - 'tr' => 'application/x-troff', - 'roff' => 'application/x-troff', - 'man' => 'application/x-troff-man', - 'me' => 'application/x-troff-me', - 'ms' => 'application/x-troff-ms', - 'ustar' => 'application/x-ustar', - 'src' => 'application/x-wais-source', - 'wz' => 'application/x-wingz', - 'crt' => 'application/x-x509-ca-cert', - 'fig' => 'application/x-xfig', - 'au' => 'audio/basic', - 'snd' => 'audio/basic', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'kar' => 'audio/midi', - 'mpga' => 'audio/mpeg', - 'mpega' => 'audio/mpeg', - 'mp2' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', - 'm3u' => 'audio/x-mpegurl', - 'sid' => 'audio/prs.sid', - 'aif' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'gsm' => 'audio/x-gsm', - 'wma' => 'audio/x-ms-wma', - 'wax' => 'audio/x-ms-wax', - 'ra' => 'audio/x-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'ram' => 'audio/x-pn-realaudio', - 'pls' => 'audio/x-scpls', - 'sd2' => 'audio/x-sd2', - 'wav' => 'audio/x-wav', - 'pdb' => 'chemical/x-pdb', - 'xyz' => 'chemical/x-xyz', - 'bmp' => 'image/x-ms-bmp', - 'gif' => 'image/gif', - 'ief' => 'image/ief', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'jpe' => 'image/jpeg', - 'pcx' => 'image/pcx', - 'png' => 'image/png', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'wbmp' => 'image/vnd.wap.wbmp', - 'ras' => 'image/x-cmu-raster', - 'cdr' => 'image/x-coreldraw', - 'pat' => 'image/x-coreldrawpattern', - 'cdt' => 'image/x-coreldrawtemplate', - 'djvu' => 'image/x-djvu', - 'djv' => 'image/x-djvu', - 'ico' => 'image/x-icon', - 'art' => 'image/x-jg', - 'jng' => 'image/x-jng', - 'psd' => 'image/x-photoshop', - 'pnm' => 'image/x-portable-anymap', - 'pbm' => 'image/x-portable-bitmap', - 'pgm' => 'image/x-portable-graymap', - 'ppm' => 'image/x-portable-pixmap', - 'rgb' => 'image/x-rgb', - 'xbm' => 'image/x-xbitmap', - 'xpm' => 'image/x-xpixmap', - 'xwd' => 'image/x-xwindowdump', - 'igs' => 'model/iges', - 'iges' => 'model/iges', - 'msh' => 'model/mesh', - 'mesh' => 'model/mesh', - 'silo' => 'model/mesh', - 'wrl' => 'x-world/x-vrml', - 'vrml' => 'x-world/x-vrml', - 'csv' => 'text/comma-separated-values', - 'css' => 'text/css', - '323' => 'text/h323', - 'htm' => 'text/html', - 'html' => 'text/html', - 'uls' => 'text/iuls', - 'mml' => 'text/mathml', - 'asc' => 'text/plain', - 'txt' => 'text/plain', - 'text' => 'text/plain', - 'diff' => 'text/plain', - 'rtx' => 'text/richtext', - 'sct' => 'text/scriptlet', - 'wsc' => 'text/scriptlet', - 'tm' => 'text/texmacs', - 'ts' => 'text/texmacs', - 'tsv' => 'text/tab-separated-values', - 'jad' => 'text/vnd.sun.j2me.app-descriptor', - 'wml' => 'text/vnd.wap.wml', - 'wmls' => 'text/vnd.wap.wmlscript', - 'xml' => 'text/xml', - 'xsl' => 'text/xml', - 'h++' => 'text/x-c++hdr', - 'hpp' => 'text/x-c++hdr', - 'hxx' => 'text/x-c++hdr', - 'hh' => 'text/x-c++hdr', - 'c++' => 'text/x-c++src', - 'cpp' => 'text/x-c++src', - 'cxx' => 'text/x-c++src', - 'cc' => 'text/x-c++src', - 'h' => 'text/x-chdr', - 'c' => 'text/x-csrc', - 'java' => 'text/x-java', - 'moc' => 'text/x-moc', - 'p' => 'text/x-pascal', - 'pas' => 'text/x-pascal', - '***' => 'text/x-pcs-***', - 'shtml' => 'text/x-server-parsed-html', - 'etx' => 'text/x-setext', - 'tk' => 'text/x-tcl', - 'ltx' => 'text/x-tex', - 'sty' => 'text/x-tex', - 'cls' => 'text/x-tex', - 'vcs' => 'text/x-vcalendar', - 'vcf' => 'text/x-vcard', - 'dl' => 'video/dl', - 'fli' => 'video/fli', - 'gl' => 'video/gl', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'mxu' => 'video/vnd.mpegurl', - 'dif' => 'video/x-dv', - 'dv' => 'video/x-dv', - 'lsf' => 'video/x-la-asf', - 'lsx' => 'video/x-la-asf', - 'mng' => 'video/x-mng', - 'asf' => 'video/x-ms-asf', - 'asx' => 'video/x-ms-asf', - 'wm' => 'video/x-ms-wm', - 'wmv' => 'video/x-ms-wmv', - 'wmx' => 'video/x-ms-wmx', - 'wvx' => 'video/x-ms-wvx', - 'avi' => 'video/x-msvideo', - 'movie' => 'video/x-sgi-movie', - 'ice' => 'x-conference/x-cooltalk', - 'vrm' => 'x-world/x-vrml', - 'rar' => 'application/x-rar-compressed', - 'cab' => 'application/vnd.ms-cab-compressed' - ); - - $part = explode('.', $fileName); - $size = count($part); - - if ($size > 1) { - $ext = $part[$size - 1]; - if (isset($mimeTypes[$ext])) { - return $mimeTypes[$ext]; - } - } - - return 'application/octet-stream'; - } - - /** - * 寻找匹配的mime图标 - * - * @access public - * @param string $mime mime类型 - * @return string - */ - public static function mimeIconType($mime) - { - $parts = explode('/', $mime); - - if (count($parts) < 2) { - return 'unknown'; - } - - list ($type, $stream) = $parts; - - if (in_array($type, array('image', 'video', 'audio', 'text', 'application'))) { - switch (true) { - case in_array($stream, array('msword', 'msaccess', 'ms-powerpoint', 'ms-powerpoint')): - case 0 === strpos($stream, 'vnd.'): - return 'office'; - case false !== strpos($stream, 'html') || false !== strpos($stream, 'xml') || false !== strpos($stream, 'wml'): - return 'html'; - case false !== strpos($stream, 'compressed') || false !== strpos($stream, 'zip') || - in_array($stream, array('application/x-gtar', 'application/x-tar')): - return 'archive'; - case 'text' == $type && 0 === strpos($stream, 'x-'): - return 'script'; - default: - return $type; - } - } else { - return 'unknown'; - } - } -} diff --git a/php/typecho09/var/Typecho/Common/Paragraph.php b/php/typecho09/var/Typecho/Common/Paragraph.php deleted file mode 100644 index f1094c9fb..000000000 --- a/php/typecho09/var/Typecho/Common/Paragraph.php +++ /dev/null @@ -1,218 +0,0 @@ -

    ", $text); - $text = nl2br($text); - $text = preg_replace("/(

    )?\s*\s*(<\/p>)?/s", "", $text); - $text = preg_replace("/

    {$space}*<\/p>/is", '', $text); - return $text; - } - - /** - * 修复段落开头和结尾 - * - * @access private - * @param string $text - * @return string - */ - private static function fixPragraph($text) - { - $text = trim($text); - if (!preg_match("/^<(" . self::$_blockTag . ")(\s|>)/i", $text)) { - $text = '

    ' . $text; - } - - if (!preg_match("/<\/(" . self::$_blockTag . ")>$/i", $text)) { - $text = $text . '

    '; - } - - return $text; - } - - /** - * 替换段落的回调函数 - * - * @access public - * @param array $matches 匹配值 - * @return string - */ - public static function replaceBlockCallback($matches) - { - $tagMatch = '|' . $matches[1] . '|'; - $text = $matches[4]; - - switch (true) { - /** 用br处理换行 */ - case false !== strpos('|li|dd|dt|td|p|a|span|cite|strong|sup|sub|small|del|u|i|b|h1|h2|h3|h4|h5|h6|', $tagMatch): - $text = nl2br(trim($text)); - break; - /** 用段落处理换行 */ - case false !== strpos('|div|blockquote|form|', $tagMatch): - $text = self::cutByBlock($text); - if (false !== strpos($text, '

    ')) { - $text = self::fixPragraph($text); - } - break; - default: - break; - } - - /** 没有段落能力的标签 */ - if (false !== strpos('|a|span|cite|strong|sup|sub|small|del|u|i|b|', $tagMatch)) { - $key = ''; - } else { - $key = ''; - } - - self::$_blocks[$key] = "<{$matches[1]}{$matches[3]}>{$text}"; - return $key; - } - - /** - * 处理文本 - * - * @access public - * @param string $text 文本 - * @return string - */ - public static function process($text) - { - /** 锁定标签 */ - $text = Typecho_Common::lockHTML($text); - - /** 重置计数器 */ - self::$_uniqueId = 0; - self::$_blocks = array(); - - /** 将已有的段落后面的换行处理掉 */ - $text = preg_replace(array("/<\/p>\s+\s*/is"), array("

    "), trim($text)); - - /** 将所有非自闭合标签解析为唯一的字符串 */ - $foundTagCount = 0; - $textLength = strlen($text); - $uniqueIdList = array(); - - if (preg_match_all("/<\/\s*([a-z0-9]+)>/is", $text, $matches, PREG_OFFSET_CAPTURE)) { - foreach ($matches[0] as $key => $match) { - $tag = $matches[1][$key][0]; - - $leftOffset = $match[1] - $textLength; - $posSingle = strrpos($text, '<' . $tag . '>', $leftOffset); - $posFix = strrpos($text, '<' . $tag . ' ', $leftOffset); - $pos = false; - - switch (true) { - case (false !== $posSingle && false !== $posFix): - $pos = max($posSingle, $posFix); - break; - case false === $posSingle && false !== $posFix: - $pos = $posFix; - break; - case false !== $posSingle && false === $posFix: - $pos = $posSingle; - break; - default: - break; - } - - if (false !== $pos) { - $uniqueId = self::makeUniqueId(); - $uniqueIdList[$uniqueId] = $tag; - $tagLength = strlen($tag); - - $text = substr_replace($text, $uniqueId, $pos + 1 + $tagLength, 0); - $text = substr_replace($text, $uniqueId, $match[1] + 7 + $foundTagCount * 10 + $tagLength, 0); // 7 = 5 + 2 - $foundTagCount ++; - } - } - } - - foreach ($uniqueIdList as $uniqueId => $tag) { - $text = preg_replace_callback("/<({$tag})({$uniqueId})([^>]*)>(.*)<\/\\1\\2>/is", - array('Typecho_Common_Paragraph', 'replaceBlockCallback'), $text, 1); - } - - $text = self::cutByBlock($text); - $blocks = array_reverse(self::$_blocks); - - foreach ($blocks as $blockKey => $blockValue) { - $text = str_replace($blockKey, $blockValue, $text); - } - - $text = self::fixPragraph($text); - - /** 释放标签 */ - return Typecho_Common::releaseHTML($text); - } -} diff --git a/php/typecho09/var/Typecho/Config.php b/php/typecho09/var/Typecho/Config.php deleted file mode 100644 index 7f7eb31a8..000000000 --- a/php/typecho09/var/Typecho/Config.php +++ /dev/null @@ -1,199 +0,0 @@ -setDefault($config); - } - - /** - * 工厂模式实例化一个当前配置 - * - * @access public - * @param array $config 配置列表 - * @return void - */ - public static function factory($config = array()) - { - return new Typecho_Config($config); - } - - /** - * 设置默认的配置 - * - * @access public - * @param mixed $config 配置信息 - * @param boolean $replace 是否替换已经存在的信息 - * @return void - */ - public function setDefault($config, $replace = false) - { - if (empty($config)) { - return; - } - - /** 初始化参数 */ - if (is_string($config)) { - parse_str($config, $params); - } else { - $params = $config; - } - - /** 设置默认参数 */ - foreach ($params as $name => $value) { - if ($replace || !array_key_exists($name, $this->_currentConfig)) { - $this->_currentConfig[$name] = $value; - } - } - } - - /** - * 重设指针 - * - * @access public - * @return void - */ - public function rewind() - { - reset($this->_currentConfig); - } - - /** - * 返回当前值 - * - * @access public - * @return mixed - */ - public function current() - { - return current($this->_currentConfig); - } - - /** - * 指针后移一位 - * - * @access public - * @return void - */ - public function next() - { - next($this->_currentConfig); - } - - /** - * 获取当前指针 - * - * @access public - * @return void - */ - public function key() - { - return key($this->_currentConfig); - } - - /** - * 验证当前值是否到达最后 - * - * @access public - * @return boolean - */ - public function valid() - { - return false !== $this->current(); - } - - /** - * 魔术函数获取一个配置值 - * - * @access public - * @param string $name 配置名称 - * @return mixed - */ - public function __get($name) - { - return isset($this->_currentConfig[$name]) ? $this->_currentConfig[$name] : NULL; - } - - /** - * 魔术函数设置一个配置值 - * - * @access public - * @param string $name 配置名称 - * @param mixed $value 配置值 - * @return void - */ - public function __set($name, $value) - { - $this->_currentConfig[$name] = $value; - } - - /** - * 直接输出默认配置值 - * - * @access public - * @param string $name 配置名称 - * @param array $args 参数 - * @return void - */ - public function __call($name, $args) - { - echo $this->_currentConfig[$name]; - } - - /** - * 判断当前配置值是否存在 - * - * @access public - * @param string $name 配置名称 - * @return boolean - */ - public function __isSet($name) - { - return isset($this->_currentConfig[$name]); - } - - /** - * 魔术方法,打印当前配置数组 - * - * @access public - * @return string - */ - public function __toString() - { - return serialize($this->_currentConfig); - } -} diff --git a/php/typecho09/var/Typecho/Cookie.php b/php/typecho09/var/Typecho/Cookie.php deleted file mode 100644 index 6eadcc39f..000000000 --- a/php/typecho09/var/Typecho/Cookie.php +++ /dev/null @@ -1,137 +0,0 @@ - $val) { - setrawcookie("{$key}[{$name}]", rawurlencode($val), $expire, $path); - } - } else { - setrawcookie($key, rawurlencode($value), $expire, $path); - } - - $_COOKIE[$key] = $value; - } - - /** - * 删除指定的COOKIE值 - * - * @access public - * @param string $key 指定的参数 - * @return void - */ - public static function delete($key, $url = NULL) - { - $key = self::$_prefix . $key; - if (!isset($_COOKIE[$key])) { - return; - } - - $path = '/'; - if (!empty($url)) { - $parsed = parse_url($url); - - /** 在路径后面强制加上斜杠 */ - $path = empty($parsed['path']) ? '/' : Typecho_Common::url(NULL, $parsed['path']); - } - - /** 对数组型COOKIE的删除支持 */ - if (is_array($_COOKIE[$key])) { - foreach ($_COOKIE[$key] as $name => $val) { - setcookie("{$key}[{$name}]", '', time() - 2592000, $path); - } - } else { - setcookie($key, '', time() - 2592000, $path); - } - - unset($_COOKIE[$key]); - } -} - diff --git a/php/typecho09/var/Typecho/Date.php b/php/typecho09/var/Typecho/Date.php deleted file mode 100644 index fd36c1f9a..000000000 --- a/php/typecho09/var/Typecho/Date.php +++ /dev/null @@ -1,126 +0,0 @@ -timeStamp = $gmtTime + (self::$timezoneOffset - self::$serverTimezoneOffset); - } - - /** - * 设置当前期望的时区偏移 - * - * @access public - * @param integer $offset - * @return void - */ - public static function setTimezoneOffset($offset) - { - self::$timezoneOffset = $offset; - self::$serverTimezoneOffset = idate('Z'); - } - - /** - * 获取格式化时间 - * - * @access public - * @param string $format 时间格式 - * @return string - */ - public function format($format) - { - return date($format, $this->timeStamp); - } - - /** - * 获取国际化偏移时间 - * - * @access public - * @return string - */ - public function word() - { - return Typecho_I18n::dateWord($this->timeStamp, self::gmtTime() + (self::$timezoneOffset - self::$serverTimezoneOffset)); - } - - /** - * 获取单项数据 - * - * @access public - * @param string $name 名称 - * @return integer - */ - public function __get($name) - { - switch ($name) { - case 'year': - return date('Y', $this->timeStamp); - case 'month': - return date('m', $this->timeStamp); - case 'day': - return date('d', $this->timeStamp); - default: - return; - } - } - - /** - * 获取GMT时间 - * - * @access public - * @return integer - */ - public static function gmtTime() - { - return self::$gmtTimeStamp ? self::$gmtTimeStamp : (self::$gmtTimeStamp = @gmmktime()); - } -} diff --git a/php/typecho09/var/Typecho/Db.php b/php/typecho09/var/Typecho/Db.php deleted file mode 100644 index 61c2286fb..000000000 --- a/php/typecho09/var/Typecho/Db.php +++ /dev/null @@ -1,418 +0,0 @@ -_adapterName = $adapterName; - - /** 数据库适配器 */ - require_once 'Typecho/Db/Adapter/' . str_replace('_', '/', $adapterName) . '.php'; - $adapterName = 'Typecho_Db_Adapter_' . $adapterName; - - if (!call_user_func(array($adapterName, 'isAvailable'))) { - throw new Typecho_Db_Exception("Adapter {$adapterName} is not available"); - } - - $this->_prefix = $prefix; - - /** 初始化内部变量 */ - $this->_pool = array(); - $this->_connectedPool = array(); - $this->_config = array(); - - //实例化适配器对象 - $this->_adapter = new $adapterName(); - } - - /** - * 获取适配器名称 - * - * @access public - * @return string - */ - public function getAdapterName() - { - return $this->_adapterName; - } - - /** - * 获取表前缀 - * - * @access public - * @return string - */ - public function getPrefix() - { - return $this->_prefix; - } - - /** - * getConfig - * - * @access public - * @return void - */ - public function getConfig() - { - return $this->_config; - } - - /** - * 获取SQL词法构建器实例化对象 - * - * @return Typecho_Db_Query - */ - public function sql() - { - return new Typecho_Db_Query($this->_adapter, $this->_prefix); - } - - /** - * 为多数据库提供支持 - * - * @access public - * @param Typecho_Db $db 数据库实例 - * @param integer $op 数据库操作 - * @return void - */ - public function addServer($config, $op) - { - $this->_config[] = Typecho_Config::factory($config); - $key = key($this->_config); - - /** 将连接放入池中 */ - switch ($op) { - case self::READ: - case self::WRITE: - $this->_pool[$op][] = $key; - break; - default: - $this->_pool[self::READ][] = $key; - $this->_pool[self::WRITE][] = $key; - break; - } - } - - /** - * 设置默认数据库对象 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @return void - */ - public static function set(Typecho_Db $db) - { - self::$_instance = $db; - } - - /** - * 获取数据库实例化对象 - * 用静态变量存储实例化的数据库对象,可以保证数据连接仅进行一次 - * - * @return Typecho_Db - * @throws Typecho_Db_Exception - */ - public static function get() - { - if (empty(self::$_instance)) { - /** Typecho_Db_Exception */ - require_once 'Typecho/Db/Exception.php'; - throw new Typecho_Db_Exception('Missing Database Object'); - } - - return self::$_instance; - } - - /** - * 选择查询字段 - * - * @access public - * @param mixed $field 查询字段 - * @return Typecho_Db_Query - */ - public function select() - { - $args = func_get_args(); - return call_user_func_array(array($this->sql(), 'select'), $args ? $args : array('*')); - } - - /** - * 更新记录操作(UPDATE) - * - * @param string $table 需要更新记录的表 - * @return Typecho_Db_Query - */ - public function update($table) - { - return $this->sql()->update($table); - } - - /** - * 删除记录操作(DELETE) - * - * @param string $table 需要删除记录的表 - * @return Typecho_Db_Query - */ - public function delete($table) - { - return $this->sql()->delete($table); - } - - /** - * 插入记录操作(INSERT) - * - * @param string $table 需要插入记录的表 - * @return Typecho_Db_Query - */ - public function insert($table) - { - return $this->sql()->insert($table); - } - - /** - * 执行查询语句 - * - * @param mixed $query 查询语句或者查询对象 - * @param boolean $op 数据库读写状态 - * @param string $action 操作动作 - * @return mixed - */ - public function query($query, $op = self::READ, $action = self::SELECT) - { - /** 在适配器中执行查询 */ - if ($query instanceof Typecho_Db_Query) { - $action = $query->getAttribute('action'); - $op = (self::UPDATE == $action || self::DELETE == $action - || self::INSERT == $action) ? self::WRITE : self::READ; - } else if (!is_string($query)) { - /** 如果query不是对象也不是字符串,那么将其判断为查询资源句柄,直接返回 */ - return $query; - } - - /** 选择连接池 */ - if (!isset($this->_connectedPool[$op])) { - if (empty($this->_pool[$op])) { - /** Typecho_Db_Exception */ - require_once 'Typecho/Db/Exception.php'; - throw new Typecho_Db_Exception('Missing Database Connection'); - } - - $selectConnection = rand(0, count($this->_pool[$op]) - 1); - $selectConnectionConfig = $this->_config[$selectConnection]; - $selectConnectionHandle = $this->_adapter->connect($selectConnectionConfig); - $other = (self::READ == $op) ? self::WRITE : self::READ; - - if (!empty($this->_pool[$other]) && in_array($selectConnection, $this->_pool[$other])) { - $this->_connectedPool[$other] = &$selectConnectionHandle; - } - $this->_connectedPool[$op] = &$selectConnectionHandle; - } - $handle = $this->_connectedPool[$op]; - - /** 提交查询 */ - $resource = $this->_adapter->query($query, $handle, $op, $action); - - if ($action) { - //根据查询动作返回相应资源 - switch ($action) { - case self::UPDATE: - case self::DELETE: - return $this->_adapter->affectedRows($resource, $handle); - case self::INSERT: - return $this->_adapter->lastInsertId($resource, $handle); - case self::SELECT: - default: - return $resource; - } - } else { - //如果直接执行查询语句则返回资源 - return $resource; - } - } - - /** - * 一次取出所有行 - * - * @param mixed $query 查询对象 - * @param array $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中 - * @return array - */ - public function fetchAll($query, array $filter = NULL) - { - //执行查询 - $resource = $this->query($query, self::READ); - $result = array(); - - /** 取出过滤器 */ - if (!empty($filter)) { - list($object, $method) = $filter; - } - - //取出每一行 - while ($rows = $this->_adapter->fetch($resource)) { - //判断是否有过滤器 - $result[] = $filter ? call_user_func(array(&$object, $method), $rows) : $rows; - } - - return $result; - } - - /** - * 一次取出一行 - * - * @param mixed $query 查询对象 - * @param array $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中 - * @return stdClass - */ - public function fetchRow($query, array $filter = NULL) - { - $resource = $this->query($query, self::READ); - - /** 取出过滤器 */ - if ($filter) { - list($object, $method) = $filter; - } - - return ($rows = $this->_adapter->fetch($resource)) ? - ($filter ? $object->$method($rows) : $rows) : - array(); - } - - /** - * 一次取出一个对象 - * - * @param mixed $query 查询对象 - * @param array $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中 - * @return array - */ - public function fetchObject($query, array $filter = NULL) - { - $resource = $this->query($query, self::READ); - - /** 取出过滤器 */ - if ($filter) { - list($object, $method) = $filter; - } - - return ($rows = $this->_adapter->fetchObject($resource)) ? - ($filter ? $object->$method($rows) : $rows) : - new stdClass(); - } -} diff --git a/php/typecho09/var/Typecho/Db/Adapter.php b/php/typecho09/var/Typecho/Db/Adapter.php deleted file mode 100644 index 63170c8c4..000000000 --- a/php/typecho09/var/Typecho/Db/Adapter.php +++ /dev/null @@ -1,104 +0,0 @@ -_dbLink = @mysql_connect($config->host . (empty($config->port) ? '' : ':' . $config->port), - $config->user, $config->password, true)) { - if (@mysql_select_db($config->database, $this->_dbLink)) { - if ($config->charset) { - mysql_query("SET NAMES '{$config->charset}'", $this->_dbLink); - } - return $this->_dbLink; - } - } - - /** 数据库异常 */ - require_once 'Typecho/Db/Adapter/Exception.php'; - throw new Typecho_Db_Adapter_Exception(@mysql_error($this->_dbLink)); - } - - /** - * 执行数据库查询 - * - * @param string $query 数据库查询SQL字符串 - * @param mixed $handle 连接对象 - * @param integer $op 数据库读写状态 - * @param string $action 数据库动作 - * @throws Typecho_Db_Exception - * @return resource - */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL) - { - if ($resource = @mysql_query($query instanceof Typecho_Db_Query ? $query->__toString() : $query, $handle)) { - return $resource; - } - - /** 数据库异常 */ - require_once 'Typecho/Db/Query/Exception.php'; - throw new Typecho_Db_Query_Exception(@mysql_error($this->_dbLink), mysql_errno($this->_dbLink)); - } - - /** - * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 - * - * @param resource $resource 查询返回资源标识 - * @return array - */ - public function fetch($resource) - { - return mysql_fetch_assoc($resource); - } - - /** - * 将数据查询的其中一行作为对象取出,其中字段名对应对象属性 - * - * @param resource $resource 查询的资源数据 - * @return object - */ - public function fetchObject($resource) - { - return mysql_fetch_object($resource); - } - - /** - * 引号转义函数 - * - * @param string $string 需要转义的字符串 - * @return string - */ - public function quoteValue($string) - { - return '\'' . str_replace(array('\'', '\\'), array('\'\'', '\\\\'), $string) . '\''; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '`' . $string . '`'; - } - - /** - * 合成查询语句 - * - * @access public - * @param array $sql 查询对象词法数组 - * @return string - */ - public function parseSelect(array $sql) - { - if (!empty($sql['join'])) { - foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; - $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; - } - } - - $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; - $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset']; - } - - /** - * 取出最后一次查询影响的行数 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function affectedRows($resource, $handle) - { - return mysql_affected_rows($handle); - } - - /** - * 取出最后一次插入返回的主键值 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function lastInsertId($resource, $handle) - { - return mysql_insert_id($handle); - } -} diff --git a/php/typecho09/var/Typecho/Db/Adapter/Pdo.php b/php/typecho09/var/Typecho/Db/Adapter/Pdo.php deleted file mode 100644 index 3bdcd2f6f..000000000 --- a/php/typecho09/var/Typecho/Db/Adapter/Pdo.php +++ /dev/null @@ -1,177 +0,0 @@ -_object = $this->init($config); - $this->_object->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - return $this->_object; - } catch (PDOException $e) { - /** 数据库异常 */ - require_once 'Typecho/Db/Adapter/Exception.php'; - throw new Typecho_Db_Adapter_Exception($e->getMessage()); - } - } - - /** - * 初始化数据库 - * - * @param Typecho_Config $config 数据库配置 - * @abstract - * @access public - * @return PDO - */ - abstract public function init(Typecho_Config $config); - - /** - * 执行数据库查询 - * - * @param string $query 数据库查询SQL字符串 - * @param mixed $handle 连接对象 - * @param integer $op 数据库读写状态 - * @param string $action 数据库动作 - * @throws Typecho_Db_Exception - * @return resource - */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL) - { - try { - $isQueryObject = $query instanceof Typecho_Db_Query; - $this->_lastTable = $isQueryObject ? $query->getAttribute('table') : NULL; - $resource = $handle->prepare($isQueryObject ? $query->__toString() : $query); - $resource->execute(); - } catch (PDOException $e) { - /** 数据库异常 */ - require_once 'Typecho/Db/Query/Exception.php'; - throw new Typecho_Db_Query_Exception($e->getMessage(), $e->getCode()); - } - - return $resource; - } - - /** - * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 - * - * @param resource $resource 查询返回资源标识 - * @return array - */ - public function fetch($resource) - { - return $resource->fetch(PDO::FETCH_ASSOC); - } - - /** - * 将数据查询的其中一行作为对象取出,其中字段名对应对象属性 - * - * @param resource $resource 查询的资源数据 - * @return object - */ - public function fetchObject($resource) - { - return $resource->fetchObject(); - } - - /** - * 引号转义函数 - * - * @param string $string 需要转义的字符串 - * @return string - */ - public function quoteValue($string) - { - return $this->_object->quote($string); - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string){} - - /** - * 合成查询语句 - * - * @access public - * @param array $sql 查询对象词法数组 - * @return string - */ - public function parseSelect(array $sql){} - - /** - * 取出最后一次查询影响的行数 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function affectedRows($resource, $handle) - { - return $resource->rowCount(); - } - - /** - * 取出最后一次插入返回的主键值 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function lastInsertId($resource, $handle) - { - return $handle->lastInsertId(); - } -} diff --git a/php/typecho09/var/Typecho/Db/Adapter/Pdo/Mysql.php b/php/typecho09/var/Typecho/Db/Adapter/Pdo/Mysql.php deleted file mode 100644 index d2528956b..000000000 --- a/php/typecho09/var/Typecho/Db/Adapter/Pdo/Mysql.php +++ /dev/null @@ -1,92 +0,0 @@ -dsn) ? $config->dsn : - "mysql:dbname={$config->database};host={$config->host};port={$config->port}", $config->user, $config->password); - $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); - $pdo->exec("SET NAMES '{$config->charset}'"); - return $pdo; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '`' . $string . '`'; - } - - /** - * 引号转义函数 - * - * @param string $string 需要转义的字符串 - * @return string - */ - public function quoteValue($string) - { - return '\'' . str_replace(array('\'', '\\'), array('\'\'', '\\\\'), $string) . '\''; - } - - /** - * 合成查询语句 - * - * @access public - * @param array $sql 查询对象词法数组 - * @return string - */ - public function parseSelect(array $sql) - { - if (!empty($sql['join'])) { - foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; - $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; - } - } - - $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; - $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset']; - } -} diff --git a/php/typecho09/var/Typecho/Db/Adapter/Pdo/Pgsql.php b/php/typecho09/var/Typecho/Db/Adapter/Pdo/Pgsql.php deleted file mode 100644 index 48e4e258b..000000000 --- a/php/typecho09/var/Typecho/Db/Adapter/Pdo/Pgsql.php +++ /dev/null @@ -1,96 +0,0 @@ -database};host={$config->host};port={$config->port}", $config->user, $config->password); - $pdo->exec("SET NAMES '{$config->charset}'"); - return $pdo; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '"' . $string . '"'; - } - - /** - * 合成查询语句 - * - * @access public - * @param array $sql 查询对象词法数组 - * @return string - */ - public function parseSelect(array $sql) - { - if (!empty($sql['join'])) { - foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; - $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; - } - } - - $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; - $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset']; - } - - /** - * 取出最后一次插入返回的主键值 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function lastInsertId($resource, $handle) - { - /** 查看是否存在序列,可能需要更严格的检查 */ - if ($handle->query('SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq'))->fetchAll()) { - return $handle->lastInsertId($this->_lastTable . '_seq'); - } - - return 0; - } -} diff --git a/php/typecho09/var/Typecho/Db/Adapter/Pdo/SQLite.php b/php/typecho09/var/Typecho/Db/Adapter/Pdo/SQLite.php deleted file mode 100644 index a7b3584c9..000000000 --- a/php/typecho09/var/Typecho/Db/Adapter/Pdo/SQLite.php +++ /dev/null @@ -1,78 +0,0 @@ -file}"); - return $pdo; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '"' . $string . '"'; - } - - /** - * 合成查询语句 - * - * @access public - * @param array $sql 查询对象词法数组 - * @return string - */ - public function parseSelect(array $sql) - { - if (!empty($sql['join'])) { - foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; - $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; - } - } - - $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; - $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset']; - } -} diff --git a/php/typecho09/var/Typecho/Db/Adapter/Pgsql.php b/php/typecho09/var/Typecho/Db/Adapter/Pgsql.php deleted file mode 100644 index 750fc6f9a..000000000 --- a/php/typecho09/var/Typecho/Db/Adapter/Pgsql.php +++ /dev/null @@ -1,188 +0,0 @@ -_dbLink = @pg_connect("host={$config->host} port={$config->port} dbname={$config->database} user={$config->user} password={$config->password}")) { - if ($config->charset) { - pg_query($this->_dbLink, "SET NAMES '{$config->charset}'"); - } - return $this->_dbLink; - } - - /** 数据库异常 */ - require_once 'Typecho/Db/Adapter/Exception.php'; - throw new Typecho_Db_Adapter_Exception(@pg_last_error($this->_dbLink)); - } - - /** - * 执行数据库查询 - * - * @param string $query 数据库查询SQL字符串 - * @param mixed $handle 连接对象 - * @param integer $op 数据库读写状态 - * @param string $action 数据库动作 - * @throws Typecho_Db_Exception - * @return resource - */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL) - { - $isQueryObject = $query instanceof Typecho_Db_Query; - $this->_lastTable = $isQueryObject ? $query->getAttribute('table') : NULL; - if ($resource = @pg_query($handle, $isQueryObject ? $query->__toString() : $query)) { - return $resource; - } - - /** 数据库异常 */ - require_once 'Typecho/Db/Query/Exception.php'; - throw new Typecho_Db_Query_Exception(@pg_last_error($this->_dbLink), - pg_result_error_field(pg_get_result($this->_dbLink), PGSQL_DIAG_SQLSTATE)); - } - - /** - * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 - * - * @param resource $resource 查询返回资源标识 - * @return array - */ - public function fetch($resource) - { - return pg_fetch_assoc($resource); - } - - /** - * 将数据查询的其中一行作为对象取出,其中字段名对应对象属性 - * - * @param resource $resource 查询的资源数据 - * @return object - */ - public function fetchObject($resource) - { - return pg_fetch_object($resource); - } - - /** - * 引号转义函数 - * - * @param string $string 需要转义的字符串 - * @return string - */ - public function quoteValue($string) - { - return '\'' . pg_escape_string($string) . '\''; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '"' . $string . '"'; - } - - /** - * 合成查询语句 - * - * @access public - * @param array $sql 查询对象词法数组 - * @return string - */ - public function parseSelect(array $sql) - { - if (!empty($sql['join'])) { - foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; - $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; - } - } - - $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; - $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset']; - } - - /** - * 取出最后一次查询影响的行数 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function affectedRows($resource, $handle) - { - return pg_affected_rows($resource); - } - - /** - * 取出最后一次插入返回的主键值 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function lastInsertId($resource, $handle) - { - /** 查看是否存在序列,可能需要更严格的检查 */ - if (pg_fetch_assoc(pg_query($handle, 'SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq')))) { - return pg_fetch_result(pg_query($handle, 'SELECT CURRVAL(' . $this->quoteValue($this->_lastTable . '_seq') . ')'), 0, 0); - } - - return 0; - } -} diff --git a/php/typecho09/var/Typecho/Db/Adapter/SQLite.php b/php/typecho09/var/Typecho/Db/Adapter/SQLite.php deleted file mode 100644 index 9142c1d85..000000000 --- a/php/typecho09/var/Typecho/Db/Adapter/SQLite.php +++ /dev/null @@ -1,203 +0,0 @@ - $val) { - /** 按点分隔 */ - if (false !== ($pos = strpos($key, '.'))) { - $key = substr($key, $pos + 1); - } - - /** 按引号分割 */ - if (false === ($pos = strpos($key, '"'))) { - $tResult[$key] = $val; - } else { - $tResult[substr($key, $pos + 1, -1)] = $val; - } - } - - return $tResult; - } - - /** - * 数据库连接函数 - * - * @param Typecho_Config $config 数据库配置 - * @throws Typecho_Db_Exception - * @return resource - */ - public function connect(Typecho_Config $config) - { - if ($this->_dbHandle = sqlite_open($config->file, 0666, $error)) { - return $this->_dbHandle; - } - - /** 数据库异常 */ - require_once 'Typecho/Db/Adapter/Exception.php'; - throw new Typecho_Db_Adapter_Exception($error); - } - - /** - * 执行数据库查询 - * - * @param string $sql 查询字符串 - * @param mixed $handle 连接对象 - * @param boolean $op 查询读写开关 - * @throws Typecho_Db_Exception - * @return resource - */ - public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL) - { - if ($resource = @sqlite_query($query instanceof Typecho_Db_Query ? $query->__toString() : $query, $handle)) { - return $resource; - } - - /** 数据库异常 */ - require_once 'Typecho/Db/Query/Exception.php'; - $errorCode = sqlite_last_error($this->_dbHandle); - throw new Typecho_Db_Query_Exception(sqlite_error_string($errorCode), $errorCode); - } - - /** - * 将数据查询的其中一行作为数组取出,其中字段名对应数组键值 - * - * @param resource $resource 查询返回资源标识 - * @return array - */ - public function fetch($resource) - { - return $this->filterColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC)); - } - - /** - * 将数据查询的其中一行作为对象取出,其中字段名对应对象属性 - * - * @param resource $resource 查询的资源数据 - * @return object - */ - public function fetchObject($resource) - { - return (object) $this->filterColumnName(sqlite_fetch_array($resource, SQLITE_ASSOC)); - } - - /** - * 引号转义函数 - * - * @param string $string 需要转义的字符串 - * @return string - */ - public function quoteValue($string) - { - return '\'' . str_replace('\'', '\'\'', $string) . '\''; - } - - /** - * 对象引号过滤 - * - * @access public - * @param string $string - * @return string - */ - public function quoteColumn($string) - { - return '"' . $string . '"'; - } - - /** - * 合成查询语句 - * - * @access public - * @param array $sql 查询对象词法数组 - * @return string - */ - public function parseSelect(array $sql) - { - if (!empty($sql['join'])) { - foreach ($sql['join'] as $val) { - list($table, $condition, $op) = $val; - $sql['table'] = "{$sql['table']} {$op} JOIN {$table} ON {$condition}"; - } - } - - $sql['limit'] = (0 == strlen($sql['limit'])) ? NULL : ' LIMIT ' . $sql['limit']; - $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset']; - - return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] . - $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset']; - } - - /** - * 取出最后一次查询影响的行数 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function affectedRows($resource, $handle) - { - return sqlite_changes($handle); - } - - /** - * 取出最后一次插入返回的主键值 - * - * @param resource $resource 查询的资源数据 - * @param mixed $handle 连接对象 - * @return integer - */ - public function lastInsertId($resource, $handle) - { - return sqlite_last_insert_rowid($handle); - } -} diff --git a/php/typecho09/var/Typecho/Db/Exception.php b/php/typecho09/var/Typecho/Db/Exception.php deleted file mode 100644 index 8899ea2f5..000000000 --- a/php/typecho09/var/Typecho/Db/Exception.php +++ /dev/null @@ -1,19 +0,0 @@ -select('posts', 'post_id, post_title') - * ->where('post_id = %d', 1) - * ->limit(1); - * echo $query; - * 打印的结果将是 - * SELECT post_id, post_title FROM posts WHERE 1=1 AND post_id = 1 LIMIT 1 - * - * - * @package Db - */ -class Typecho_Db_Query -{ - /** 数据库关键字 */ - const KEYWORDS = '*PRIMARY|AND|OR|LIKE|BINARY|BY|DISTINCT|AS|IN|IS|NULL'; - - /** - * 数据库适配器 - * - * @var Typecho_Db_Adapter - */ - private $_adapter; - - /** - * 查询语句预结构,由数组构成,方便组合为SQL查询字符串 - * - * @var array - */ - private $_sqlPreBuild; - - /** - * 前缀 - * - * @access private - * @var string - */ - private $_prefix; - - /** - * 构造函数,引用数据库适配器作为内部数据 - * - * @param Typecho_Db_Adapter $adapter 数据库适配器 - * @param string $prefix 前缀 - * @return void - */ - public function __construct(Typecho_Db_Adapter $adapter, $prefix) - { - $this->_adapter = &$adapter; - $this->_prefix = $prefix; - - $this->_sqlPreBuild = array( - 'action' => NULL, - 'table' => NULL, - 'fields' => '*', - 'join' => array(), - 'where' => NULL, - 'limit' => NULL, - 'offset' => NULL, - 'order' => NULL, - 'group' => NULL, - 'rows' => array(), - ); - } - - /** - * 过滤表前缀,表前缀由table.构成 - * - * @param string $string 需要解析的字符串 - * @return string - */ - private function filterPrefix($string) - { - return (0 === strpos($string, 'table.')) ? substr_replace($string, $this->_prefix, 0, 6) : $string; - } - - /** - * 过滤数组键值 - * - * @access private - * @param string $str 待处理字段值 - * @return string - */ - private function filterColumn($str) - { - $str = $str . ' 0'; - $length = strlen($str); - $lastIsAlnum = false; - $result = ''; - $word = ''; - $split = ''; - $quotes = 0; - - for ($i = 0; $i < $length; $i ++) { - $cha = $str[$i]; - - if (ctype_alnum($cha) || false !== strpos('_*', $cha)) { - if (!$lastIsAlnum) { - if ($quotes > 0 && !ctype_digit($word) && '.' != $split - && false === strpos(self::KEYWORDS, strtoupper($word))) { - $word = $this->_adapter->quoteColumn($word); - } else if ('.' == $split && 'table' == $word) { - $word = $this->_prefix; - $split = ''; - } - - $result .= $word . $split; - $word = ''; - $quotes = 0; - } - - $word .= $cha; - $lastIsAlnum = true; - } else { - - if ($lastIsAlnum) { - - if (0 == $quotes) { - if (false !== strpos(' ,)=<>.+-*/', $cha)) { - $quotes = 1; - } else if ('(' == $cha) { - $quotes = -1; - } - } - - $split = ''; - } - - $split .= $cha; - $lastIsAlnum = false; - } - - } - - return $result; - } - - /** - * 从参数中合成查询字段 - * - * @access private - * @param array $parameters - * @return string - */ - private function getColumnFromParameters(array $parameters) - { - $fields = array(); - - foreach ($parameters as $value) { - if (is_array($value)) { - foreach ($value as $key => $val) { - $fields[] = $key . ' AS ' . $val; - } - } else { - $fields[] = $value; - } - } - - return $this->filterColumn(implode(' , ', $fields)); - } - - /** - * 获取查询字串属性值 - * - * @access public - * @param string $attributeName 属性名称 - * @return string - */ - public function getAttribute($attributeName) - { - return isset($this->_sqlPreBuild[$attributeName]) ? $this->_sqlPreBuild[$attributeName] : NULL; - } - - /** - * 连接表 - * - * @param string $table 需要连接的表 - * @param string $condition 连接条件 - * @param string $op 连接方法(LEFT, RIGHT, INNER) - * @return Typecho_Db_Query - */ - public function join($table, $condition, $op = Typecho_Db::INNER_JOIN) - { - $this->_sqlPreBuild['join'][] = array($this->filterPrefix($table), $this->filterColumn($condition), $op); - return $this; - } - - /** - * AND条件查询语句 - * - * @param string $condition 查询条件 - * @param mixed $param 条件值 - * @return Typecho_Db_Query - */ - public function where() - { - $condition = func_get_arg(0); - $condition = str_replace('?', "%s", $this->filterColumn($condition)); - $operator = empty($this->_sqlPreBuild['where']) ? ' WHERE ' : ' AND'; - - if (func_num_args() <= 1) { - $this->_sqlPreBuild['where'] .= $operator . ' (' . $condition . ')'; - } else { - $args = func_get_args(); - array_shift($args); - $this->_sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, array_map(array($this->_adapter, 'quoteValue'), $args)) . ')'; - } - - return $this; - } - - /** - * OR条件查询语句 - * - * @param string $condition 查询条件 - * @param mixed $param 条件值 - * @return Typecho_Db_Query - */ - public function orWhere() - { - $condition = func_get_arg(0); - $condition = str_replace('?', "%s", $this->filterColumn($condition)); - $operator = empty($this->_sqlPreBuild['where']) ? ' WHERE ' : ' OR'; - - if (func_num_args() <= 1) { - $this->_sqlPreBuild['where'] .= $operator . ' (' . $condition . ')'; - } else { - $args = func_get_args(); - array_shift($args); - $this->_sqlPreBuild['where'] .= $operator . ' (' . vsprintf($condition, array_map(array($this->_adapter, 'quoteValue'), $args)) . ')'; - } - - return $this; - } - - /** - * 查询行数限制 - * - * @param integer $limit 需要查询的行数 - * @return Typecho_Db_Query - */ - public function limit($limit) - { - $this->_sqlPreBuild['limit'] = intval($limit); - return $this; - } - - /** - * 查询行数偏移量 - * - * @param integer $offset 需要偏移的行数 - * @return Typecho_Db_Query - */ - public function offset($offset) - { - $this->_sqlPreBuild['offset'] = intval($offset); - return $this; - } - - /** - * 分页查询 - * - * @param integer $page 页数 - * @param integer $pageSize 每页行数 - * @return Typecho_Db_Query - */ - public function page($page, $pageSize) - { - $pageSize = intval($pageSize); - $this->_sqlPreBuild['limit'] = $pageSize; - $this->_sqlPreBuild['offset'] = (max(intval($page), 1) - 1) * $pageSize; - return $this; - } - - /** - * 指定需要写入的栏目及其值 - * - * @param array $rows - * @return Typecho_Db_Query - */ - public function rows(array $rows) - { - foreach ($rows as $key => $row) { - $this->_sqlPreBuild['rows'][$this->filterColumn($key)] = is_null($row) ? 'NULL' : $this->_adapter->quoteValue($row); - } - return $this; - } - - /** - * 指定需要写入栏目及其值 - * 单行且不会转义引号 - * - * @param string $key 栏目名称 - * @param mixed $value 指定的值 - * @return Typecho_Db_Query - */ - public function expression($key, $value) - { - $this->_sqlPreBuild['rows'][$this->filterColumn($key)] = $this->filterColumn($value); - return $this; - } - - /** - * 排序顺序(ORDER BY) - * - * @param string $orderby 排序的索引 - * @param string $sort 排序的方式(ASC, DESC) - * @return Typecho_Db_Query - */ - public function order($orderby, $sort = Typecho_Db::SORT_ASC) - { - $this->_sqlPreBuild['order'] = ' ORDER BY ' . $this->filterColumn($orderby) . (empty($sort) ? NULL : ' ' . $sort); - return $this; - } - - /** - * 集合聚集(GROUP BY) - * - * @param string $key 聚集的键值 - * @return Typecho_Db_Query - */ - public function group($key) - { - $this->_sqlPreBuild['group'] = ' GROUP BY ' . $this->filterColumn($key); - return $this; - } - - /** - * 选择查询字段 - * - * @access public - * @param mixed $field 查询字段 - * @return Typecho_Db_Query - */ - public function select($field = '*') - { - $this->_sqlPreBuild['action'] = Typecho_Db::SELECT; - $args = func_get_args(); - - $this->_sqlPreBuild['fields'] = $this->getColumnFromParameters($args); - return $this; - } - - /** - * 查询记录操作(SELECT) - * - * @param string $table 查询的表 - * @return Typecho_Db_Query - */ - public function from($table) - { - $this->_sqlPreBuild['table'] = $this->filterPrefix($table); - return $this; - } - - /** - * 更新记录操作(UPDATE) - * - * @param string $table 需要更新记录的表 - * @return Typecho_Db_Query - */ - public function update($table) - { - $this->_sqlPreBuild['action'] = Typecho_Db::UPDATE; - $this->_sqlPreBuild['table'] = $this->filterPrefix($table); - return $this; - } - - /** - * 删除记录操作(DELETE) - * - * @param string $table 需要删除记录的表 - * @return Typecho_Db_Query - */ - public function delete($table) - { - $this->_sqlPreBuild['action'] = Typecho_Db::DELETE; - $this->_sqlPreBuild['table'] = $this->filterPrefix($table); - return $this; - } - - /** - * 插入记录操作(INSERT) - * - * @param string $table 需要插入记录的表 - * @return Typecho_Db_Query - */ - public function insert($table) - { - $this->_sqlPreBuild['action'] = Typecho_Db::INSERT; - $this->_sqlPreBuild['table'] = $this->filterPrefix($table); - return $this; - } - - /** - * 构造最终查询语句 - * - * @return string - */ - public function __toString() - { - switch ($this->_sqlPreBuild['action']) { - case Typecho_Db::SELECT: - return $this->_adapter->parseSelect($this->_sqlPreBuild); - case Typecho_Db::INSERT: - return 'INSERT INTO ' - . $this->_sqlPreBuild['table'] - . '(' . implode(' , ', array_keys($this->_sqlPreBuild['rows'])) . ')' - . ' VALUES ' - . '(' . implode(' , ', array_values($this->_sqlPreBuild['rows'])) . ')' - . $this->_sqlPreBuild['limit']; - case Typecho_Db::DELETE: - return 'DELETE FROM ' - . $this->_sqlPreBuild['table'] - . $this->_sqlPreBuild['where']; - case Typecho_Db::UPDATE: - $columns = array(); - if (isset($this->_sqlPreBuild['rows'])) { - foreach ($this->_sqlPreBuild['rows'] as $key => $val) { - $columns[] = "$key = $val"; - } - } - - return 'UPDATE ' - . $this->_sqlPreBuild['table'] - . ' SET ' . implode(' , ', $columns) - . $this->_sqlPreBuild['where']; - default: - return NULL; - } - } -} diff --git a/php/typecho09/var/Typecho/Db/Query/Exception.php b/php/typecho09/var/Typecho/Db/Query/Exception.php deleted file mode 100644 index 5336367cf..000000000 --- a/php/typecho09/var/Typecho/Db/Query/Exception.php +++ /dev/null @@ -1,19 +0,0 @@ -message = $message; - $this->code = $code; - } -} diff --git a/php/typecho09/var/Typecho/Feed.php b/php/typecho09/var/Typecho/Feed.php deleted file mode 100644 index 42d0701c5..000000000 --- a/php/typecho09/var/Typecho/Feed.php +++ /dev/null @@ -1,411 +0,0 @@ - - * @category typecho - * @package Feed - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id: Feed.php 219 2008-05-27 09:06:15Z magike.net $ - */ - -/** - * Typecho_Feed - * - * @author qining - * @category typecho - * @package Feed - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Typecho_Feed -{ - /** 定义RSS 1.0类型 */ - const RSS1 = 'RSS 1.0'; - - /** 定义RSS 2.0类型 */ - const RSS2 = 'RSS 2.0'; - - /** 定义ATOM 1.0类型 */ - const ATOM1 = 'ATOM 1.0'; - - /** 定义RSS时间格式 */ - const DATE_RFC822 = 'r'; - - /** 定义ATOM时间格式 */ - const DATE_W3CDTF = 'c'; - - /** 定义行结束符 */ - const EOL = "\n"; - - /** - * feed状态 - * - * @access private - * @var string - */ - private $_type; - - /** - * 字符集编码 - * - * @access private - * @var string - */ - private $_charset; - - /** - * 语言状态 - * - * @access private - * @var string - */ - private $_lang; - - /** - * 聚合地址 - * - * @access private - * @var string - */ - private $_feedUrl; - - /** - * 基本地址 - * - * @access private - * @var unknown - */ - private $_baseUrl; - - /** - * 聚合标题 - * - * @access private - * @var string - */ - private $_title; - - /** - * 聚合副标题 - * - * @access private - * @var string - */ - private $_subTitle; - - /** - * 版本信息 - * - * @access private - * @var string - */ - private $_version; - - /** - * 所有的items - * - * @access private - * @var array - */ - private $_items = array(); - - /** - * 创建Feed对象 - * - * @access public - * @return void - */ - public function __construct($version, $type = self::RSS2, $charset = 'UTF-8', $lang = 'en') - { - $this->_version = $version; - $this->_type = $type; - $this->_charset = $charset; - $this->_lang = $lang; - } - - /** - * 设置标题 - * - * @access public - * @param string $title 标题 - * @return void - */ - public function setTitle($title) - { - $this->_title = $title; - } - - /** - * 设置副标题 - * - * @access public - * @param string $subTitle 副标题 - * @return void - */ - public function setSubTitle($subTitle) - { - $this->_subTitle = $subTitle; - } - - /** - * 设置聚合地址 - * - * @access public - * @param string $feedUrl 聚合地址 - * @return void - */ - public function setFeedUrl($feedUrl) - { - $this->_feedUrl = $feedUrl; - } - - /** - * 设置主页 - * - * @access public - * @param string $baseUrl 主页地址 - * @return void - */ - public function setBaseUrl($baseUrl) - { - $this->_baseUrl = $baseUrl; - } - - /** - * 获取Feed时间格式 - * - * @access public - * @param integer $stamp 时间戳 - * @return string - */ - public function dateFormat($stamp) - { - if (self::RSS2 == $this->_type) { - return date(self::DATE_RFC822, $stamp); - } else if (self::RSS1 == $this->_type || self::ATOM1 == $this->_type) { - return date(self::DATE_W3CDTF, $stamp); - } - } - - /** - * $item的格式为 - * - * array ( - * 'title' => 'xxx', - * 'content' => 'xxx', - * 'excerpt' => 'xxx', - * 'date' => 'xxx', - * 'link' => 'xxx', - * 'author' => 'xxx', - * 'comments' => 'xxx', - * 'commentsUrl'=> 'xxx', - * 'commentsFeedUrl' => 'xxx', - * ) - * - * - * @access public - * @param array $item - * @return unknown - */ - public function addItem(array $item) - { - $this->_items[] = $item; - } - - /** - * 输出字符串 - * - * @access public - * @return string - */ - public function __toString() - { - $result = '_charset . '"?>' . self::EOL; - - if (self::RSS1 == $this->_type) { - $result .= '' . self::EOL; - - $content = ''; - $links = array(); - $lastUpdate = 0; - - foreach ($this->_items as $item) { - $content .= '' . self::EOL; - $content .= '' . htmlspecialchars($item['title']) . '' . self::EOL; - $content .= '' . $item['link'] . '' . self::EOL; - $content .= '' . $this->dateFormat($item['date']) . '' . self::EOL; - $content .= '' . strip_tags($item['content']) . '' . self::EOL; - if (!empty($item['suffix'])) { - $content .= $item['suffix']; - } - $content .= '' . self::EOL; - - $links[] = $item['link']; - - if ($item['date'] > $lastUpdate) { - $lastUpdate = $item['date']; - } - } - - $result .= ' -' . htmlspecialchars($this->_title) . ' -' . $this->_baseUrl . ' -' . htmlspecialchars($this->_subTitle) . ' - -' . self::EOL; - - foreach ($links as $link) { - $result .= '' . self::EOL; - } - - $result .= ' - -' . self::EOL; - - $result .= $content . ''; - - } else if (self::RSS2 == $this->_type) { - $result .= ' -' . self::EOL; - - $content = ''; - $lastUpdate = 0; - - foreach ($this->_items as $item) { - $content .= '' . self::EOL; - $content .= '' . htmlspecialchars($item['title']) . '' . self::EOL; - $content .= '' . $item['link'] . '' . self::EOL; - $content .= '' . $item['link'] . '' . self::EOL; - $content .= '' . $this->dateFormat($item['date']) . '' . self::EOL; - $content .= '' . htmlspecialchars($item['author']->screenName) . '' . self::EOL; - - if (!empty($item['category']) && is_array($item['category'])) { - foreach ($item['category'] as $category) { - $content .= '' . self::EOL; - } - } - - if (!empty($item['excerpt'])) { - $content .= '' . self::EOL; - } - - if (!empty($item['content'])) { - $content .= '' . self::EOL; - } - - if (isset($item['comments']) && strlen($item['comments']) > 0) { - $content .= '' . $item['comments'] . '' . self::EOL; - } - - $content .= '' . $item['link'] . '#comments' . self::EOL; - if (!empty($item['commentsFeedUrl'])) { - $content .= '' . $item['commentsFeedUrl'] . '' . self::EOL; - } - - if (!empty($item['suffix'])) { - $content .= $item['suffix']; - } - - $content .= '' . self::EOL; - - if ($item['date'] > $lastUpdate) { - $lastUpdate = $item['date']; - } - } - - $result .= '' . htmlspecialchars($this->_title) . ' -' . $this->_baseUrl . ' - -' . $this->_lang . ' -' . htmlspecialchars($this->_subTitle) . ' -' . $this->dateFormat($lastUpdate) . ' -' . $this->dateFormat($lastUpdate) . '' . self::EOL; - - $result .= $content . ' -'; - - } else if (self::ATOM1 == $this->_type) { - $result .= '' . self::EOL; - - $content = ''; - $lastUpdate = 0; - - foreach ($this->_items as $item) { - $content .= '' . self::EOL; - $content .= '<![CDATA[' . $item['title'] . ']]>' . self::EOL; - $content .= '' . self::EOL; - $content .= '' . $item['link'] . '' . self::EOL; - $content .= '' . $this->dateFormat($item['date']) . '' . self::EOL; - $content .= '' . $this->dateFormat($item['date']) . '' . self::EOL; - $content .= ' - ' . $item['author']->screenName . ' - ' . $item['author']->url . ' -' . self::EOL; - - if (!empty($item['category']) && is_array($item['category'])) { - foreach ($item['category'] as $category) { - $content .= '' . self::EOL; - } - } - - if (!empty($item['excerpt'])) { - $content .= '' . self::EOL; - } - - if (!empty($item['content'])) { - $content .= '' . self::EOL; - } - - if (isset($item['comments']) && strlen($item['comments']) > 0) { - $content .= '' . self::EOL; - - if (!empty($item['commentsFeedUrl'])) { - $content .= '' . self::EOL; - } - } - - if (!empty($item['suffix'])) { - $content .= $item['suffix']; - } - - $content .= '' . self::EOL; - - if ($item['date'] > $lastUpdate) { - $lastUpdate = $item['date']; - } - } - - $result .= '' . htmlspecialchars($this->_title) . ' -' . htmlspecialchars($this->_subTitle) . ' -' . $this->dateFormat($lastUpdate) . ' -Typecho - -' . $this->_feedUrl . ' - -'; - $result .= $content . ''; - } - - return $result; - } -} diff --git a/php/typecho09/var/Typecho/Http/Client.php b/php/typecho09/var/Typecho/Http/Client.php deleted file mode 100644 index 827f9f7e6..000000000 --- a/php/typecho09/var/Typecho/Http/Client.php +++ /dev/null @@ -1,62 +0,0 @@ -method = $method; - return $this; - } - - /** - * 设置指定的COOKIE值 - * - * @access public - * @param string $key 指定的参数 - * @param mixed $value 设置的值 - * @return Typecho_Http_Client_Adapter - */ - public function setCookie($key, $value) - { - $this->cookies[$key] = $value; - return $this; - } - - /** - * 设置传递参数 - * - * @access public - * @param mixed $query 传递参数 - * @return Typecho_Http_Client_Adapter - */ - public function setQuery($query) - { - $query = is_array($query) ? http_build_query($query) : $query; - $this->query = empty($this->query) ? $query : $this->query . '&' . $query; - return $this; - } - - /** - * 设置需要POST的数据 - * - * @access public - * @param array $data 需要POST的数据 - * @return Typecho_Http_Client_Adapter - */ - public function setData($data) - { - $this->data = $data; - $this->setMethod(Typecho_Http_Client::METHOD_POST); - return $this; - } - - /** - * 设置需要POST的文件 - * - * @access public - * @param array $files 需要POST的文件 - * @return Typecho_Http_Client_Adapter - */ - public function setFiles(array $files) - { - $this->files = empty($this->files) ? $files : array_merge($this->files, $files); - $this->setMethod(Typecho_Http_Client::METHOD_POST); - return $this; - } - - /** - * 设置超时时间 - * - * @access public - * @param integer $timeout 超时时间 - * @return Typecho_Http_Client_Adapter - */ - public function setTimeout($timeout) - { - $this->timeout = $timeout; - return $this; - } - - /** - * 设置http协议 - * - * @access public - * @param string $rfc http协议 - * @return Typecho_Http_Client_Adapter - */ - public function setRfc($rfc) - { - $this->rfc = $rfc; - return $this; - } - - /** - * 设置ip地址 - * - * @access public - * @param string $ip ip地址 - * @return Typecho_Http_Client_Adapter - */ - public function setIp($ip) - { - $this->ip = $ip; - return $this; - } - - /** - * 设置头信息参数 - * - * @access public - * @param string $key 参数名称 - * @param string $value 参数值 - * @return Typecho_Http_Client_Adapter - */ - public function setHeader($key, $value) - { - $key = str_replace(' ', '-', ucwords(str_replace('-', ' ', $key))); - $this->headers[$key] = $value; - return $this; - } - - /** - * 发送请求 - * - * @access public - * @param string $url 请求地址 - * @param string $rfc 请求协议 - * @return string - */ - public function send($url) - { - $params = parse_url($url); - - if (!empty($params['host'])) { - $this->host = $params['host']; - } else { - /** Typecho_Http_Client_Exception */ - require_once 'Typecho/Http/Client/Exception.php'; - throw new Typecho_Http_Client_Exception('Unknown Host', 500); - } - - if (!empty($params['path'])) { - $this->path = $params['path']; - } - - if (!empty($params['query'])) { - $this->path .= '?' . $params['query'] . (empty($this->query) ? NULL : '&' . $this->query); - $url .= (empty($this->query) ? NULL : '&' . $this->query); - } else { - $url .= (empty($this->query) ? NULL : '?' . $this->query); - } - - $this->scheme = $params['scheme']; - $this->port = ('https' == $params['scheme']) ? 443 : 80; - - if (!empty($params['port'])) { - $this->port = $params['port']; - } - - /** 整理cookie */ - if (!empty($this->cookies)) { - $this->setHeader('Cookie', str_replace('&', '; ', http_build_query($this->cookies))); - } - - $response = $this->httpSend($url); - - if (!$response) { - return; - } - - str_replace("\r", '', $response); - $rows = explode("\n", $response); - - $foundStatus = false; - $foundInfo = false; - $lines = array(); - - foreach ($rows as $key => $line) { - if (!$foundStatus) { - if (0 === strpos($line, "HTTP/")) { - if ('' == trim($rows[$key + 1])) { - continue; - } else { - $status = explode(' ', str_replace(' ', ' ', $line)); - $this->responseStatus = intval($status[1]); - $foundStatus = true; - } - } - } else { - if (!$foundInfo) { - if ('' != trim($line)) { - $status = explode(':', $line); - $name = strtolower(array_shift($status)); - $data = implode(':', $status); - $this->responseHeader[trim($name)] = trim($data); - } else { - $foundInfo = true; - } - } else { - $lines[] = $line; - } - } - } - - $this->reponseBody = implode("\n", $lines); - return $this->reponseBody; - } - - /** - * 获取回执的头部信息 - * - * @access public - * @param string $key 头信息名称 - * @return string - */ - public function getResponseHeader($key) - { - $key = strtolower($key); - return isset($this->responseHeader[$key]) ? $this->responseHeader[$key] : NULL; - } - - /** - * 获取回执代码 - * - * @access public - * @return integer - */ - public function getResponseStatus() - { - return $this->responseStatus; - } - - /** - * 获取回执身体 - * - * @access public - * @return string - */ - public function getResponseBody() - { - return $this->reponseBody; - } - - /** - * 需要实现的请求方法 - * - * @access public - * @param string $url 请求地址 - * @return string - */ - abstract public function httpSend($url); -} diff --git a/php/typecho09/var/Typecho/Http/Client/Adapter/Curl.php b/php/typecho09/var/Typecho/Http/Client/Adapter/Curl.php deleted file mode 100644 index 40b943276..000000000 --- a/php/typecho09/var/Typecho/Http/Client/Adapter/Curl.php +++ /dev/null @@ -1,122 +0,0 @@ -ip) { - $url = $this->scheme . '://' . $this->ip . $this->path; - $this->headers['Rfc'] = $this->method . ' ' . $this->path . ' ' . $this->rfc; - $this->headers['Host'] = $this->host; - } - - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_PORT, $this->port); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); - curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); - - /** 设置HTTP版本 */ - switch ($this->rfc) { - case 'HTTP/1.0': - curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); - break; - case 'HTTP/1.1': - curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); - break; - default: - curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE); - break; - } - - /** 设置header信息 */ - if (!empty($this->headers)) { - if (isset($this->headers['User-Agent'])) { - curl_setopt($ch, CURLOPT_USERAGENT, $this->headers['User-Agent']); - unset($this->headers['User-Agent']); - } - - $headers = array(); - - if (isset($this->headers['Rfc'])) { - $headers[] = $this->headers['Rfc']; - unset($this->headers['Rfc']); - } - - foreach ($this->headers as $key => $val) { - $headers[] = $key . ': ' . $val; - } - - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - } - - /** POST模式 */ - if (Typecho_Http_Client::METHOD_POST == $this->method) { - if (!isset($this->headers['content-type'])) { - curl_setopt($ch, CURLOPT_POST, true); - } - - if (!empty($this->data)) { - curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($this->data) ? http_build_query($this->data) : $this->data); - } - - if (!empty($this->files)) { - foreach ($this->files as $key => &$file) { - $file = '@' . $file; - } - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->files); - } - } - - $response = curl_exec($ch); - if (false === $response) { - /** Typecho_Http_Client_Exception */ - require_once 'Typecho/Http/Client/Exception.php'; - throw new Typecho_Http_Client_Exception(curl_error($ch), 500); - } - - curl_close($ch); - return $response; - } -} diff --git a/php/typecho09/var/Typecho/Http/Client/Adapter/Socket.php b/php/typecho09/var/Typecho/Http/Client/Adapter/Socket.php deleted file mode 100644 index ff5ba5009..000000000 --- a/php/typecho09/var/Typecho/Http/Client/Adapter/Socket.php +++ /dev/null @@ -1,156 +0,0 @@ -method . ' ' . $this->path . ' ' . $this->rfc . $eol; - $request .= 'Host: ' . $this->host . $eol; - $request .= 'Accept: */*' . $eol; - $request .= 'Cache-Control: no-cache' . $eol; - $request .= 'Connection: Close' . $eol; - - /** 设置header信息 */ - if (!empty($this->headers)) { - foreach ($this->headers as $key => $val) { - $request .= $key . ': ' . $val . $eol; - } - } - - /** 发送POST信息 */ - if (Typecho_Http_Client::METHOD_POST == $this->method) { - if (empty($this->files)) { - $content = is_array($this->data) ? http_build_query($this->data) : $this->data; - $request .= 'Content-Length: ' . strlen($content) . $eol; - - if (!isset($this->headers['content-type'])) { - $request .= 'Content-Type: application/x-www-form-urlencoded' . $eol; - } - - $request .= $eol; - $request .= $content; - } else { - $boundary = '---------------------------' . substr(md5(uniqid()), 0, 16); - $content .= $eol . $boundary; - - if (!empty($this->data)) { - foreach ($this->data as $key => $val) { - $content .= $eol . 'Content-Disposition: form-data; name="' . $key . '"' . $eol . $eol; - $content .= $val . $eol; - $content .= $boundary; - } - } - - foreach ($this->files as $key => $file) { - $content .= $eol . 'Content-Disposition: form-data; name="' . $key . '"; filename="' . $file . '"' . $eol; - $content .= 'Content-Type: ' . mime_content_type($file) . $eol . $eol; - $content .= file_get_contents($file) . $eol; - $content .= $boundary; - } - - $content .= '--' . $eol; - $request .= 'Content-Length: ' . strlen($content) . $eol; - $request .= 'Content-Type: multipart/form-data; boundary=' . $boundary; - $request .= $eol; - $request .= $content; - } - } else { - $request .= $eol; - } - - /** 打开连接 */ - $socket = @fsockopen($this->ip ? $this->ip : $this->host, $this->port, $errno, $errstr, $this->timeout); - if (false === $socket) { - throw new Typecho_Http_Client_Exception($errno . ':' . $errstr, 500); - } - - /** 发送数据 */ - fwrite($socket, $request); - stream_set_timeout($socket, $this->timeout); - $response = ''; - - //facebook code - while (!feof($socket)) { - $buf = fgets($socket, 4096); - - if (false === $buf || '' === $buf) { - $info = stream_get_meta_data($socket); - - //超时判断 - if ($info['timed_out']) { - throw new Typecho_Http_Client_Exception(__CLASS__ . ': timeout reading from ' . $this->host . ':' . $this->port, 500); - } else { - throw new Typecho_Http_Client_Exception(__CLASS__ . ': could not read from ' . $this->host . ':' . $this->port, 500); - } - } else if (strlen($buf) < 4096) { - $info = stream_get_meta_data($socket); - - if ($info['timed_out']) { - throw new Typecho_Http_Client_Exception(__CLASS__ . ': timeout reading from ' . $this->host . ':' . $this->port, 500); - } - } - - $response .= $buf; - } - - fclose($socket); - return $response; - } - - /** - * 获取回执身体 - * - * @access public - * @return string - */ - public function getResponseBody() - { - /** 支持chunked编码 */ - if ('chunked' == $this->getResponseHeader('Transfer-Encoding')) { - $parts = explode("\r\n", $this->reponseBody, 2); - $counter = hexdec($parts[0]); - $this->reponseBody = substr($parts[1], 0, $counter); - } - - return $this->reponseBody; - } -} diff --git a/php/typecho09/var/Typecho/Http/Client/Exception.php b/php/typecho09/var/Typecho/Http/Client/Exception.php deleted file mode 100644 index 984fdd504..000000000 --- a/php/typecho09/var/Typecho/Http/Client/Exception.php +++ /dev/null @@ -1,19 +0,0 @@ -translate($string) : $string; - } - - /** - * 针对复数形式的翻译函数 - * - * @param string $single 单数形式的翻译 - * @param string $plural 复数形式的翻译 - * @param integer $number 数字 - * @return string - */ - public static function ngettext($single, $plural, $number) - { - self::$_lang && empty(self::$_loaded) && self::init(); - return self::$_lang ? self::$_loaded->ngettext($single, $plural, $number) : ($number > 1 ? $plural : $single); - } - - /** - * 词义化时间 - * - * @access public - * @param string $from 起始时间 - * @param string $now 终止时间 - * @return string - */ - public static function dateWord($from, $now) - { - $between = $now - $from; - - /** 如果是一天 */ - if ($between > 0 && $between < 86400 && idate('d', $from) == idate('d', $now)) { - /** 如果是一小时 */ - if ($between < 3600 && idate('H', $from) == idate('H', $now)) { - /** 如果是一分钟 */ - if ($between < 60 && idate('i', $from) == idate('i', $now)) { - $second = idate('s', $now) - idate('s', $from); - if (0 == $second) { - return _t('刚刚'); - } else { - return sprintf(_n('%d秒前', '%d秒前', $second), $second); - } - } - - $min = idate('i', $now) - idate('i', $from); - return sprintf(_n('%d分钟前', '%d分钟前', $min), $min); - } - - $hour = idate('H', $now) - idate('H', $from); - return sprintf(_n('%d小时前', '%d小时前', $hour), $hour); - } - - /** 如果是昨天 */ - if ($between > 0 && $between < 172800 && (idate('z', $from) + 1 == idate('z', $now) || idate('z', $from) > 2 + idate('z', $now))) { - return _t('昨天 %s', date('H:i', $from)); - } - - /** 如果是一个星期 */ - if ($between > 0 && $between < 604800 && idate('W', $from) == idate('W', $now)) { - $day = intval($between / (3600 * 24)); - return sprintf(_n('%d天前', '%d天前', $day), $day); - } - - /** 如果是 */ - if ($between > 0 && $between < 31622400 && idate('Y', $from) == idate('Y', $now)) { - return date(_t('n月j日'), $from); - } - - return date(_t('Y年m月d日'), $from); - } - - /** - * 设置语言项 - * - * @access public - * @param string $lang 配置信息 - * @return void - */ - public static function setLang($lang) - { - self::$_lang = $lang; - } - - /** - * 增加语言项 - * - * @access public - * @param string $lang 语言名称 - * @return void - */ - public static function addLang($lang) - { - self::$_loaded->addFile($lang); - } - - /** - * 获取语言项 - * - * @access public - * @return void - */ - public static function getLang() - { - return self::$_lang; - } -} diff --git a/php/typecho09/var/Typecho/I18n/GetText.php b/php/typecho09/var/Typecho/I18n/GetText.php deleted file mode 100644 index 81b858d2e..000000000 --- a/php/typecho09/var/Typecho/I18n/GetText.php +++ /dev/null @@ -1,378 +0,0 @@ -. - Copyright (c) 2005 Nico Kaiser - - This file is part of PHP-gettext. - - PHP-gettext is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - PHP-gettext is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with PHP-gettext; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - */ - -/** - * Provides a simple gettext replacement that works independently from - * the system's gettext abilities. - * It can read MO files and use them for translating strings. - * The files are passed to gettext_reader as a Stream (see streams.php) - * - * This version has the ability to cache all strings and translations to - * speed up the string lookup. - * While the cache is enabled by default, it can be switched off with the - * second parameter in the constructor (e.g. whenusing very large MO files - * that you don't want to keep in memory) - */ - -//reload by 70 (typecho group) -/** - * This file is part of PHP-gettext - * - * @author Danilo Segan , Nico Kaiser - * @category typecho - * @package I18n - */ -class Typecho_I18n_GetText -{ - //public: - public $error = 0; // public variable that holds error code (0 if no error) - - //private: - private $BYTEORDER = 0; // 0: low endian, 1: big endian - private $STREAM = NULL; - private $short_circuit = false; - private $enable_cache = false; - private $originals = NULL; // offset of original table - private $translations = NULL; // offset of translation table - private $pluralheader = NULL; // cache header field for plural forms - private $total = 0; // total string count - private $table_originals = NULL; // table for original strings (offsets) - private $table_translations = NULL; // table for translated strings (offsets) - private $cache_translations = NULL; // original -> translation mapping - - - /* Methods */ - /** - * Constructor - * - * @param string $file file name - * @param boolean enable_cache Enable or disable caching of strings (default on) - */ - public function __construct($file, $enable_cache = true) - { - // If there isn't a StreamReader, turn on short circuit mode. - if (!file_exists($file)) { - $this->short_circuit = true; - return; - } - - // Caching can be turned off - $this->enable_cache = $enable_cache; - - // $MAGIC1 = (int)0x950412de; //bug in PHP 5 - $MAGIC1 = (int) - 1794895138; - // $MAGIC2 = (int)0xde120495; //bug - $MAGIC2 = (int) - 569244523; - - $this->STREAM = @fopen($file, 'rb'); - $magic = $this->readint(); - if ($magic == $MAGIC1) { - $this->BYTEORDER = 0; - } elseif ($magic == $MAGIC2) { - $this->BYTEORDER = 1; - } else { - $this->error = 1; // not MO file - return false; - } - - // FIXME: Do we care about revision? We should. - $revision = $this->readint(); - - $this->total = $this->readint(); - $this->originals = $this->readint(); - $this->translations = $this->readint(); - } - - /** - * Reads a 32bit Integer from the Stream - * - * @access private - * @return Integer from the Stream - */ - private function readint() - { - $end = unpack($this->BYTEORDER == 0 ? 'V' : 'N', fread($this->STREAM, 4)); - return array_shift($end); - } - - /** - * Reads an array of Integers from the Stream - * - * @param int count How many elements should be read - * @return Array of Integers - */ - private function readintarray($count) - { - return unpack(($this->BYTEORDER == 0 ? 'V' : 'N') . $count, fread($this->STREAM, 4 * $count)); - } - - /** - * Loads the translation tables from the MO file into the cache - * If caching is enabled, also loads all strings into a cache - * to speed up translation lookups - * - * @access private - */ - private function load_tables() - { - if (is_array($this->cache_translations) && - is_array($this->table_originals) && - is_array($this->table_translations)) - return; - - /* get original and translations tables */ - fseek($this->STREAM, $this->originals); - $this->table_originals = $this->readintarray($this->total * 2); - fseek($this->STREAM, $this->translations); - $this->table_translations = $this->readintarray($this->total * 2); - - if ($this->enable_cache) { - $this->cache_translations = array (); - /* read all strings in the cache */ - for ($i = 0; $i < $this->total; $i++) { - if ($this->table_originals[$i * 2 + 1] > 0) { - fseek($this->STREAM, $this->table_originals[$i * 2 + 2]); - $original = fread($this->STREAM, $this->table_originals[$i * 2 + 1]); - fseek($this->STREAM, $this->table_translations[$i * 2 + 2]); - $translation = fread($this->STREAM, $this->table_translations[$i * 2 + 1]); - $this->cache_translations[$original] = $translation; - } - } - } - } - - /** - * Returns a string from the "originals" table - * - * @access private - * @param int num Offset number of original string - * @return string Requested string if found, otherwise '' - */ - private function get_original_string($num) - { - $length = $this->table_originals[$num * 2 + 1]; - $offset = $this->table_originals[$num * 2 + 2]; - if (! $length) - return ''; - fseek($this->STREAM, $offset); - $data = fread($this->STREAM, $length); - return (string)$data; - } - - /** - * Returns a string from the "translations" table - * - * @access private - * @param int num Offset number of original string - * @return string Requested string if found, otherwise '' - */ - private function get_translation_string($num) - { - $length = $this->table_translations[$num * 2 + 1]; - $offset = $this->table_translations[$num * 2 + 2]; - if (! $length) - return ''; - fseek($this->STREAM, $offset); - $data = fread($this->STREAM, $length); - return (string)$data; - } - - /** - * Binary search for string - * - * @access private - * @param string string - * @param int start (internally used in recursive function) - * @param int end (internally used in recursive function) - * @return int string number (offset in originals table) - */ - private function find_string($string, $start = -1, $end = -1) - { - if (($start == -1) or ($end == -1)) { - // find_string is called with only one parameter, set start end end - $start = 0; - $end = $this->total; - } - if (abs($start - $end) <= 1) { - // We're done, now we either found the string, or it doesn't exist - $txt = $this->get_original_string($start); - if ($string == $txt) - return $start; - else - return -1; - } else if ($start > $end) { - // start > end -> turn around and start over - return $this->find_string($string, $end, $start); - } else { - // Divide table in two parts - $half = (int)(($start + $end) / 2); - $cmp = strcmp($string, $this->get_original_string($half)); - if ($cmp == 0) - // string is exactly in the middle => return it - return $half; - else if ($cmp < 0) - // The string is in the upper half - return $this->find_string($string, $start, $half); - else - // The string is in the lower half - return $this->find_string($string, $half, $end); - } - } - - /** - * Translates a string - * - * @access public - * @param string string to be translated - * @param integer $num found string number - * @return string translated string (or original, if not found) - */ - public function translate($string, &$num) - { - if ($this->short_circuit) - return $string; - $this->load_tables(); - - if ($this->enable_cache) { - // Caching enabled, get translated string from cache - if (array_key_exists($string, $this->cache_translations)) - return $this->cache_translations[$string]; - else - return $string; - } else { - // Caching not enabled, try to find string - $num = $this->find_string($string); - if ($num == -1) - return $string; - else - return $this->get_translation_string($num); - } - } - - /** - * Get possible plural forms from MO header - * - * @access private - * @return string plural form header - */ - private function get_plural_forms() - { - // lets assume message number 0 is header - // this is true, right? - $this->load_tables(); - - // cache header field for plural forms - if (! is_string($this->pluralheader)) { - if ($this->enable_cache) { - $header = $this->cache_translations[""]; - } else { - $header = $this->get_translation_string(0); - } - if (eregi("plural-forms: ([^\n]*)\n", $header, $regs)) - $expr = $regs[1]; - else - $expr = "nplurals=2; plural=n == 1 ? 0 : 1;"; - $this->pluralheader = $expr; - } - return $this->pluralheader; - } - - /** - * Detects which plural form to take - * - * @access private - * @param n count - * @return int array index of the right plural form - */ - private function select_string($n) - { - $string = $this->get_plural_forms(); - $string = str_replace('nplurals',"\$total",$string); - $string = str_replace("n",$n,$string); - $string = str_replace('plural',"\$plural",$string); - - $total = 0; - $plural = 0; - - eval("$string"); - if ($plural >= $total) $plural = $total - 1; - return $plural; - } - - /** - * Plural version of gettext - * - * @access public - * @param string single - * @param string plural - * @param string number - * @param integer $num found string number - * @return translated plural form - */ - public function ngettext($single, $plural, $number, &$num) - { - if ($this->short_circuit) { - if ($number != 1) - return $plural; - else - return $single; - } - - // find out the appropriate form - $select = $this->select_string($number); - - // this should contains all strings separated by NULLs - $key = $single.chr(0).$plural; - - - if ($this->enable_cache) { - if (! array_key_exists($key, $this->cache_translations)) { - return ($number != 1) ? $plural : $single; - } else { - $result = $this->cache_translations[$key]; - $list = explode(chr(0), $result); - return $list[$select]; - } - } else { - $num = $this->find_string($key); - if ($num == -1) { - return ($number != 1) ? $plural : $single; - } else { - $result = $this->get_translation_string($num); - $list = explode(chr(0), $result); - return $list[$select]; - } - } - } - - /** - * 关闭文件句柄 - * - * @access public - * @return void - */ - public function __destruct() - { - fclose($this->STREAM); - } -} diff --git a/php/typecho09/var/Typecho/I18n/GetTextMulti.php b/php/typecho09/var/Typecho/I18n/GetTextMulti.php deleted file mode 100644 index 717c4c454..000000000 --- a/php/typecho09/var/Typecho/I18n/GetTextMulti.php +++ /dev/null @@ -1,108 +0,0 @@ -addFile($fileName); - } - - /** - * 增加一个语言文件 - * - * @access public - * @param string $fileName 语言文件名 - * @return void - */ - public function addFile($fileName) - { - $this->_handles[] = new Typecho_I18n_GetText($fileName, true); - } - - /** - * Translates a string - * - * @access public - * @param string string to be translated - * @return string translated string (or original, if not found) - */ - public function translate($string) - { - foreach ($this->_handles as $handle) { - $string = $handle->translate($string, $count); - if (-1 != $count) { - break; - } - } - - return $string; - } - - /** - * Plural version of gettext - * - * @access public - * @param string single - * @param string plural - * @param string number - * @return translated plural form - */ - public function ngettext($single, $plural, $number) - { - foreach ($this->_handles as $handle) { - $string = $handle->ngettext($single, $plural, $number, $count); - if (-1 != $count) { - break; - } - } - - return $string; - } - - /** - * 关闭所有句柄 - * - * @access public - * @return void - */ - public function __destruct() - { - foreach ($this->_handles as $handle) { - /** 显示的释放内存 */ - unset($handle); - } - } -} diff --git a/php/typecho09/var/Typecho/Plugin.php b/php/typecho09/var/Typecho/Plugin.php deleted file mode 100644 index ace69ed77..000000000 --- a/php/typecho09/var/Typecho/Plugin.php +++ /dev/null @@ -1,466 +0,0 @@ -_handle = $handle; - } - - /** - * 插件handle比对 - * - * @access private - * @param array $pluginHandles - * @param array $otherPluginHandles - * @return void - */ - private static function pluginHandlesDiff(array $pluginHandles, array $otherPluginHandles) - { - foreach ($otherPluginHandles as $handle) { - while (false !== ($index = array_search($handle, $pluginHandles))) { - unset($pluginHandles[$index]); - } - } - - return $pluginHandles; - } - - /** - * 插件初始化 - * - * @access public - * @param array $plugins 插件列表 - * @param mixed $callback 获取插件系统变量的代理函数 - * @return void - */ - public static function init(array $plugins) - { - $plugins['activated'] = array_key_exists('activated', $plugins) ? $plugins['activated'] : array(); - $plugins['handles'] = array_key_exists('handles', $plugins) ? $plugins['handles'] : array(); - - /** 初始化变量 */ - self::$_plugins = $plugins; - } - - /** - * 获取实例化插件对象 - * - * @access public - * @return Typecho_Plugin - */ - public static function factory($handle) - { - return isset(self::$_instances[$handle]) ? self::$_instances[$handle] : - (self::$_instances[$handle] = new Typecho_Plugin($handle)); - } - - /** - * 启用插件 - * - * @access public - * @param string $pluginName 插件名称 - * @return void - */ - public static function activate($pluginName) - { - self::$_plugins['activated'][$pluginName] = self::$_tmp; - self::$_tmp = array(); - } - - /** - * 禁用插件 - * - * @access public - * @param string $pluginName 插件名称 - * @return void - */ - public static function deactivate($pluginName) - { - /** 去掉所有相关回调函数 */ - if (isset(self::$_plugins['activated'][$pluginName]['handles']) && is_array(self::$_plugins['activated'][$pluginName]['handles'])) { - foreach (self::$_plugins['activated'][$pluginName]['handles'] as $handle => $handles) { - self::$_plugins['handles'][$handle] = self::pluginHandlesDiff( - empty(self::$_plugins['handles'][$handle]) ? array() : self::$_plugins['handles'][$handle], - empty($handles) ? array() : $handles); - if (empty(self::$_plugins['handles'][$handle])) { - unset(self::$_plugins['handles'][$handle]); - } - } - } - - /** 禁用当前插件 */ - unset(self::$_plugins['activated'][$pluginName]); - } - - /** - * 导出当前插件设置 - * - * @access public - * @return array - */ - public static function export() - { - return self::$_plugins; - } - - /** - * 获取插件文件的头信息 - * - * @access public - * @param string $pluginFile 插件文件路径 - * @return void - */ - public static function parseInfo($pluginFile) - { - $tokens = token_get_all(file_get_contents($pluginFile)); - $isDoc = false; - $isFunction = false; - $isClass = false; - $isInClass = false; - $isInFunction = false; - $isDefined = false; - $current = NULL; - - /** 初始信息 */ - $info = array( - 'description' => '', - 'title' => '', - 'author' => '', - 'homepage' => '', - 'version' => '', - 'dependence' => '', - 'activate' => false, - 'deactivate' => false, - 'config' => false, - 'personalConfig' => false - ); - - $map = array( - 'package' => 'title', - 'author' => 'author', - 'link' => 'homepage', - 'dependence'=> 'dependence', - 'version' => 'version' - ); - - foreach ($tokens as $token) { - /** 获取doc comment */ - if (!$isDoc && is_array($token) && T_DOC_COMMENT == $token[0]) { - - /** 分行读取 */ - $described = false; - $lines = preg_split("(\r|\n)", $token[1]); - foreach ($lines as $line) { - $line = trim($line); - if (!empty($line) && '*' == $line[0]) { - $line = trim(substr($line, 1)); - if (!$described && !empty($line) && '@' == $line[0]) { - $described = true; - } - - if (!$described && !empty($line)) { - $info['description'] .= $line . "\n"; - } else if ($described && !empty($line) && '@' == $line[0]) { - $info['description'] = trim($info['description']); - $line = trim(substr($line, 1)); - $args = explode(' ', $line); - $key = array_shift($args); - - if (isset($map[$key])) { - $info[$map[$key]] = trim(implode(' ', $args)); - } - } - } - } - - $isDoc = true; - } - - if (is_array($token)) { - switch ($token[0]) { - case T_FUNCTION: - $isFunction = true; - break; - case T_IMPLEMENTS: - $isClass = true; - break; - case T_WHITESPACE: - case T_COMMENT: - case T_DOC_COMMENT: - break; - case T_STRING: - $string = strtolower($token[1]); - switch ($string) { - case 'typecho_plugin_interface': - $isInClass = $isClass; - break; - case 'activate': - case 'deactivate': - case 'config': - case 'personalconfig': - if ($isFunction) { - $current = ('personalconfig' == $string ? 'personalConfig' : $string); - } - break; - default: - if (!empty($current) && $isInFunction && $isInClass) { - $info[$current] = true; - } - break; - } - break; - default: - if (!empty($current) && $isInFunction && $isInClass) { - $info[$current] = true; - } - break; - } - } else { - $token = strtolower($token); - switch ($token) { - case '{': - if ($isDefined) { - $isInFunction = true; - } - break; - case '(': - if ($isFunction && !$isDefined) { - $isDefined = true; - } - break; - case '}': - case ';': - $isDefined = false; - $isFunction = false; - $isInFunction = false; - $current = NULL; - break; - default: - if (!empty($current) && $isInFunction && $isInClass) { - $info[$current] = true; - } - break; - } - } - } - - return $info; - } - - /** - * 获取插件路径和类名 - * 返回值为一个数组 - * 第一项为插件路径,第二项为类名 - * - * @access public - * @param string $pluginName 插件名 - * @param string $path 插件目录 - * @return array - */ - public static function portal($pluginName, $path) - { - switch (true) { - case file_exists($pluginFileName = $path . '/' . $pluginName . '/Plugin.php'): - $className = $pluginName . '_Plugin'; - break; - case file_exists($pluginFileName = $path . '/' . $pluginName . '.php'): - $className = $pluginName; - break; - default: - throw new Typecho_Plugin_Exception('Missing Plugin ' . $pluginName, 404); - } - - return array($pluginFileName, $className); - } - - /** - * 版本依赖性检测 - * - * @access public - * @param string $version 程序版本 - * @param string $versionRange 依赖的版本规则 - * @return boolean - */ - public static function checkDependence($version, $versionRange) - { - //如果没有检测规则,直接掠过 - if (empty($versionRange)) { - return true; - } - - $items = array_map('trim', explode('-', $versionRange)); - if (count($items) < 2) { - $items[1] = $items[0]; - } - - list ($minVersion, $maxVersion) = $items; - - //对*和?的支持,4个9是最大版本 - $minVersion = str_replace(array('*', '?'), array('9999', '9'), $minVersion); - $maxVersion = str_replace(array('*', '?'), array('9999', '9'), $maxVersion); - - if (version_compare($version, $minVersion, '>=') && version_compare($version, $maxVersion, '<=')) { - return true; - } - - return false; - } - - /** - * 插件调用后的触发器 - * - * @access public - * @param boolean $signal 触发器 - * @return Typecho_Plugin - */ - public function trigger(&$signal) - { - $signal = false; - $this->_signal = &$signal; - return $this; - } - - /** - * 判断插件是否存在 - * - * @access public - * @param string $pluginName 插件名称 - * @return void - */ - public function exists($pluginName) { - return array_search($pluginName, self::$_plugins['activated']); - } - - /** - * 设置回调函数 - * - * @access public - * @param string $component 当前组件 - * @param mixed $value 回调函数 - * @return void - */ - public function __set($component, $value) - { - $component = $this->_handle . ':' . $component; - self::$_plugins['handles'][$component][] = $value; - self::$_tmp['handles'][$component][] = $value; - } - - /** - * 通过魔术函数设置当前组件位置 - * - * @access public - * @param string $component 当前组件 - * @return Typecho_Plugin - */ - public function __get($component) - { - $this->_component = $component; - return $this; - } - - /** - * 回调处理函数 - * - * @access public - * @param string $component 当前组件 - * @param string $args 参数 - * @return mixed - */ - public function __call($component, $args) - { - $component = $this->_handle . ':' . $component; - $last = count($args); - $args[$last] = $last > 0 ? $args[0] : false; - - if (isset(self::$_plugins['handles'][$component])) { - $args[$last] = NULL; - $this->_signal = true; - foreach (self::$_plugins['handles'][$component] as $callback) { - $args[$last] = call_user_func_array($callback, $args); - } - } - - return $args[$last]; - } -} diff --git a/php/typecho09/var/Typecho/Plugin/Exception.php b/php/typecho09/var/Typecho/Plugin/Exception.php deleted file mode 100644 index 3a430ddce..000000000 --- a/php/typecho09/var/Typecho/Plugin/Exception.php +++ /dev/null @@ -1,19 +0,0 @@ - 'intval', - 'integer' => 'intval', - 'search' => array('Typecho_Common', 'filterSearchQuery'), - 'xss' => array('Typecho_Common', 'removeXSS'), - 'url' => array('Typecho_Common', 'safeUrl') - ); - - /** - * 获取单例句柄 - * - * @access public - * @return Typecho_Request - */ - public static function getInstance() - { - if (NULL === self::$_instance) { - self::$_instance = new Typecho_Request(); - } - - return self::$_instance; - } - - /** - * 应用过滤器 - * - * @access private - * @param mixed $value - * @return void - */ - private function _applyFilter($value) - { - if ($this->_filter) { - foreach ($this->_filter as $filter) { - $value = is_array($value) ? array_map($filter, $value) : - call_user_func($filter, $value); - } - } - - $this->_filter = array(); - return $value; - } - - /** - * 设置过滤器 - * - * @access public - * @param mixed $filter 过滤器名称 - * @return Typecho_Widget_Request - */ - public function filter() - { - $filters = func_get_args(); - - foreach ($filters as $filter) { - $this->_filter[] = is_string($filter) && isset(self::$_supportFilters[$filter]) - ? self::$_supportFilters[$filter] : $filter; - } - - return $this; - } - - /** - * 获取实际传递参数(magic) - * - * @access public - * @param string $key 指定参数 - * @return void - */ - public function __get($key) - { - return $this->get($key); - } - - /** - * 判断参数是否存在 - * - * @access public - * @param string $key 指定参数 - * @return void - */ - public function __isset($key) - { - return isset($_GET[$key]) - || isset($_POST[$key]) - || isset($_COOKIE[$key]) - || $this->isSetParam($key); - } - - /** - * 获取实际传递参数 - * - * @access public - * @param string $key 指定参数 - * @param mixed $default 默认参数 (default: NULL) - * @return void - */ - public function get($key, $default = NULL) - { - $value = $default; - - switch (true) { - case isset($this->_params[$key]): - $value = $this->_params[$key]; - break; - case isset($_GET[$key]): - $value = $_GET[$key]; - break; - case isset($_POST[$key]): - $value = $_POST[$key]; - break; - case isset($_COOKIE[$key]): - $value = $_COOKIE[$key]; - break; - default: - $value = $default; - break; - } - - $value = is_array($value) || strlen($value) > 0 ? $value : $default; - return $this->_filter ? $this->_applyFilter($value) : $value; - } - - /** - * 从参数列表指定的值中获取http传递参数 - * - * @access public - * @param mixed $parameter 指定的参数 - * @return array - */ - public function from($params) - { - $result = array(); - $args = is_array($params) ? $params : func_get_args(); - - foreach ($args as $arg) { - $result[$arg] = $this->get($arg); - } - - return $result; - } - - /** - * 获取指定的http传递参数 - * - * @access public - * @param string $key 指定的参数 - * @param mixed $default 默认的参数 - * @return mixed - */ - public function getParam($key, $default = NULL) - { - $value = isset($this->_params[$key]) ? $this->_params[$key] : $default; - $value = is_array($value) || strlen($value) > 0 ? $value : $default; - return $this->_filter ? $this->_applyFilter($value) : $value; - } - - /** - * 设置http传递参数 - * - * @access public - * @param string $name 指定的参数 - * @param mixed $value 参数值 - * @return void - */ - public function setParam($name, $value) - { - $this->_params[$name] = $value; - } - - /** - * 删除参数 - * - * @access public - * @param string $name 指定的参数 - * @return void - */ - public function unSetParam($name) - { - unset($this->_params[$name]); - } - - /** - * 参数是否存在 - * - * @access public - * @param string $key 指定的参数 - * @return boolean - */ - public function isSetParam($key) - { - return isset($this->_params[$key]); - } - - /** - * 设置多个参数 - * - * @access public - * @param mixed $params 参数列表 - * @return void - */ - public function setParams($params) - { - //处理字符串 - if (!is_array($params)) { - parse_str($params, $out); - $params = $out; - } - - $this->_params = array_merge($this->_params, $params); - } - - /** - * 获取当前请求url - * - * @access public - * @return string - */ - public function getRequestUrl() - { - $scheme = $this->isSecure() ? 'https' : 'http'; - return $scheme . '://' . $_SERVER['HTTP_HOST'] . $this->getRequestUri(); - } - - /** - * 获取请求地址 - * - * @access public - * @return string - */ - public function getRequestUri() - { - if (!empty($this->_requestUri)) { - return $this->_requestUri; - } - - //处理requestUri - $requestUri = '/'; - - if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch - $requestUri = $_SERVER['HTTP_X_REWRITE_URL']; - } elseif ( - // IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem) - isset($_SERVER['IIS_WasUrlRewritten']) - && $_SERVER['IIS_WasUrlRewritten'] == '1' - && isset($_SERVER['UNENCODED_URL']) - && $_SERVER['UNENCODED_URL'] != '' - ) { - $requestUri = $_SERVER['UNENCODED_URL']; - } elseif (isset($_SERVER['REQUEST_URI'])) { - $requestUri = $_SERVER['REQUEST_URI']; - if (isset($_SERVER['HTTP_HOST']) && strstr($requestUri, $_SERVER['HTTP_HOST'])) { - $parts = @parse_url($requestUri); - - if (false !== $parts) { - $requestUri = (empty($parts['path']) ? '' : $parts['path']) - . ((empty($parts['query'])) ? '' : '?' . $parts['query']); - } - } - } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI - $requestUri = $_SERVER['ORIG_PATH_INFO']; - if (!empty($_SERVER['QUERY_STRING'])) { - $requestUri .= '?' . $_SERVER['QUERY_STRING']; - } - } - - return $this->_requestUri = $requestUri; - } - - /** - * 根据当前uri构造指定参数的uri - * - * @access public - * @param mixed $parameter 指定的参数 - * @return string - */ - public function makeUriByRequest($parameter = NULL) - { - /** 初始化地址 */ - $requestUri = $this->getRequestUrl(); - $parts = parse_url($requestUri); - - /** 初始化参数 */ - if (is_string($parameter)) { - parse_str($parameter, $args); - } else if (is_array($parameter)) { - $args = $parameter; - } else { - return $requestUri; - } - - /** 构造query */ - if (isset($parts['query'])) { - parse_str($parts['query'], $currentArgs); - $args = array_merge($currentArgs, $args); - } - $parts['query'] = http_build_query($args); - - /** Typecho_Common */ - require_once 'Typecho/Common.php'; - - /** 返回地址 */ - return Typecho_Common::buildUrl($parts); - } - - /** - * 获取当前pathinfo - * - * @access public - * @param string $inputEncoding 输入编码 - * @param string $outputEncoding 输出编码 - * @return string - */ - public function getPathInfo($inputEncoding = NULL, $outputEncoding = NULL) - { - /** 缓存信息 */ - if (NULL !== $this->_pathInfo) { - return $this->_pathInfo; - } - - //参考Zend Framework对pahtinfo的处理, 更好的兼容性 - $pathInfo = NULL; - - //处理requestUri - $requestUri = $this->getRequestUri(); - - //处理baseUrl - $filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? basename($_SERVER['SCRIPT_FILENAME']) : ''; - - if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $filename) { - $baseUrl = $_SERVER['SCRIPT_NAME']; - } elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $filename) { - $baseUrl = $_SERVER['PHP_SELF']; - } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename) { - $baseUrl = $_SERVER['ORIG_SCRIPT_NAME']; // 1and1 shared hosting compatibility - } else { - // Backtrack up the script_filename to find the portion matching - // php_self - $path = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : ''; - $file = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : ''; - $segs = explode('/', trim($file, '/')); - $segs = array_reverse($segs); - $index = 0; - $last = count($segs); - $baseUrl = ''; - do { - $seg = $segs[$index]; - $baseUrl = '/' . $seg . $baseUrl; - ++$index; - } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos)); - } - - // Does the baseUrl have anything in common with the request_uri? - $finalBaseUrl = NULL; - - if (0 === strpos($requestUri, $baseUrl)) { - // full $baseUrl matches - $finalBaseUrl = $baseUrl; - } else if (0 === strpos($requestUri, dirname($baseUrl))) { - // directory portion of $baseUrl matches - $finalBaseUrl = rtrim(dirname($baseUrl), '/'); - } else if (!strpos($requestUri, basename($baseUrl))) { - // no match whatsoever; set it blank - $finalBaseUrl = ''; - } else if ((strlen($requestUri) >= strlen($baseUrl)) - && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) - { - // If using mod_rewrite or ISAPI_Rewrite strip the script filename - // out of baseUrl. $pos !== 0 makes sure it is not matching a value - // from PATH_INFO or QUERY_STRING - $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl)); - } - - $finalBaseUrl = (NULL === $finalBaseUrl) ? rtrim($baseUrl, '/') : $finalBaseUrl; - - // Remove the query string from REQUEST_URI - if ($pos = strpos($requestUri, '?')) { - $requestUri = substr($requestUri, 0, $pos); - } - - if ((NULL !== $finalBaseUrl) - && (false === ($pathInfo = substr($requestUri, strlen($finalBaseUrl))))) - { - // If substr() returns false then PATH_INFO is set to an empty string - $pathInfo = '/'; - } elseif (NULL === $finalBaseUrl) { - $pathInfo = $requestUri; - } - - if (!empty($pathInfo)) { - //针对iis的utf8编码做强制转换 - //参考http://docs.moodle.org/ja/%E5%A4%9A%E8%A8%80%E8%AA%9E%E5%AF%BE%E5%BF%9C%EF%BC%9A%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E8%A8%AD%E5%AE%9A - if (!empty($inputEncoding) && !empty($outputEncoding) && - (stripos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false - || stripos($_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer') !== false)) { - if (function_exists('mb_convert_encoding')) { - $pathInfo = mb_convert_encoding($pathInfo, $outputEncoding, $inputEncoding); - } else if (function_exists('iconv')) { - $pathInfo = iconv($pathInfoEncoding, $outputEncoding, $pathInfo); - } - } - } else { - $pathInfo = '/'; - } - - // fix issue 456 - return ($this->_pathInfo = '/' . ltrim(urldecode($pathInfo), '/')); - } - - /** - * 设置服务端参数 - * - * @access public - * @param string $name 参数名称 - * @param mixed $value 参数值 - * @return void - */ - public function setServer($name, $value = NULL) - { - if (NULL == $value) { - if (isset($_SERVER[$name])) { - $value = $_SERVER[$name]; - } else if (isset($_ENV[$name])) { - $value = $_ENV[$name]; - } - } - - $this->_server[$name] = $value; - } - - /** - * 获取环境变量 - * - * @access public - * @param string $name 获取环境变量名 - * @return string - */ - public function getServer($name) - { - if (!isset($this->_server[$name])) { - $this->setServer($name); - } - - return $this->_server[$name]; - } - - /** - * 设置ip地址 - * - * @access public - * @param unknown $ip - * @return unknown - */ - public function setIp($ip = NULL) - { - switch (true) { - case NULL !== $this->getServer('HTTP_X_FORWARDED_FOR'): - list($this->_ip) = array_map('trim', explode(',', $this->getServer('HTTP_X_FORWARDED_FOR'))); - return; - case NULL !== $this->getServer('HTTP_CLIENT_IP'): - $this->_ip = $this->getServer('HTTP_CLIENT_IP'); - return; - case NULL !== $this->getServer('REMOTE_ADDR'): - $this->_ip = $this->getServer('REMOTE_ADDR'); - return; - default: - break; - } - - $this->_ip = 'unknown'; - } - - /** - * 获取ip地址 - * - * @access public - * @return string - */ - public function getIp() - { - if (NULL === $this->_ip) { - $this->setIp(); - } - - return $this->_ip; - } - - /** - * 设置客户端 - * - * @access public - * @param string $agent 客户端字符串 - * @return void - */ - public function setAgent($agent = NULL) - { - $this->_agent = (NULL === $agent) ? $this->getServer('HTTP_USER_AGENT') : $agent; - } - - /** - * 获取客户端 - * - * @access public - * @return void - */ - public function getAgent() - { - if (NULL === $this->_agent) { - $this->setAgent(); - } - - return $this->_agent; - } - - /** - * 设置来源页 - * - * @access public - * @param string $referer 客户端字符串 - * @return void - */ - public function setReferer($referer = NULL) - { - $this->_referer = (NULL === $referer) ? $this->getServer('HTTP_REFERER') : $referer; - } - - /** - * 获取客户端 - * - * @access public - * @return void - */ - public function getReferer() - { - if (NULL === $this->_referer) { - $this->setReferer(); - } - - return $this->_referer; - } - - /** - * 判断是否为get方法 - * - * @access public - * @return boolean - */ - public function isGet() - { - return 'GET' == $this->getServer('REQUEST_METHOD'); - } - - /** - * 判断是否为post方法 - * - * @access public - * @return boolean - */ - public function isPost() - { - return 'POST' == $this->getServer('REQUEST_METHOD'); - } - - /** - * 判断是否为put方法 - * - * @access public - * @return boolean - */ - public function isPut() - { - return 'PUT' == $this->getServer('REQUEST_METHOD'); - } - - /** - * 判断是否为https - * - * @access public - * @return boolean - */ - public function isSecure() - { - return (!empty($_SERVER['HTTPS']) && 'off' != strtolower($_SERVER['HTTPS'])) - || (!empty($_SERVER['SERVER_PORT']) && 443 == $_SERVER['SERVER_PORT']); - } - - /** - * 判断是否为ajax - * - * @access public - * @return boolean - */ - public function isAjax() - { - return 'XMLHttpRequest' == $this->getServer('HTTP_X_REQUESTED_WITH'); - } - - /** - * 判断是否为flash - * - * @access public - * @return boolean - */ - public function isFlash() - { - return 'Shockwave Flash' == $this->getServer('USER_AGENT'); - } - - /** - * isMobile - * - * @static - * @access public - * @return boolean - */ - public function isMobile() - { - $userAgent = $this->getAgent(); - return preg_match('/android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$userAgent) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($userAgent,0,4)); - } - - /** - * 判断输入是否满足要求 - * - * @access public - * @param mixed $query 条件 - * @return boolean - */ - public function is($query) - { - $validated = false; - - /** 解析串 */ - if (is_string($query)) { - parse_str($query, $params); - } else if (is_array($query)) { - $params = $query; - } - - /** 验证串 */ - if ($params) { - $validated = true; - foreach ($params as $key => $val) { - $validated = empty($val) ? $this->__isset($key) : ($val == $this->get($key)); - - if (!$validated) { - break; - } - } - } - - return $validated; - } -} diff --git a/php/typecho09/var/Typecho/Response.php b/php/typecho09/var/Typecho/Response.php deleted file mode 100644 index a7166ea86..000000000 --- a/php/typecho09/var/Typecho/Response.php +++ /dev/null @@ -1,304 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 307 => 'Temporary Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported' - ); - - /** - * 字符编码 - * - * @var mixed - * @access private - */ - private $_charset; - - //默认的字符编码 - const CHARSET = 'UTF-8'; - - /** - * 单例句柄 - * - * @access private - * @var Typecho_Response - */ - private static $_instance = null; - - /** - * 获取单例句柄 - * - * @access public - * @return Typecho_Response - */ - public static function getInstance() - { - if (null === self::$_instance) { - self::$_instance = new Typecho_Response(); - } - - return self::$_instance; - } - - /** - * 解析ajax回执的内部函数 - * - * @access private - * @param mixed $message 格式化数据 - * @return string - */ - private function _parseXml($message) - { - /** 对于数组型则继续递归 */ - if (is_array($message)) { - $result = ''; - - foreach ($message as $key => $val) { - $tagName = is_int($key) ? 'item' : $key; - $result .= '<' . $tagName . '>' . $this->_parseXml($val) . ''; - } - - return $result; - } else { - return preg_match("/^[^<>]+$/is", $message) ? $message : ''; - } - } - - /** - * 设置默认回执编码 - * - * @access public - * @param string $charset 字符集 - * @return void - */ - public function setCharset($charset = null) - { - $this->_charset = empty($charset) ? self::CHARSET : $charset; - } - - /** - * 获取字符集 - * - * @access public - * @return void - */ - public function getCharset() - { - if (empty($this->_charset)) { - $this->setCharset(); - } - - return $this->_charset; - } - - /** - * 在http头部请求中声明类型和字符集 - * - * @access public - * @param string $contentType 文档类型 - * @return void - */ - public function setContentType($contentType = 'text/html') - { - header('Content-Type: ' . $contentType . '; charset=' . $this->getCharset(), true); - } - - /** - * 设置http头 - * - * @access public - * @param string $name 名称 - * @param string $value 对应值 - * @return void - */ - public function setHeader($name, $value) - { - header($name . ': ' . $value, true); - } - - /** - * 设置HTTP状态 - * - * @access public - * @param integer $code http代码 - * @return void - */ - public static function setStatus($code) - { - if (isset(self::$_httpCode[$code])) { - header((isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1') . ' ' . $code . ' ' . self::$_httpCode[$code], true, $code); - } - } - - /** - * 抛出ajax的回执信息 - * - * @access public - * @param string $message 消息体 - * @return void - */ - public function throwXml($message) - { - /** 设置http头信息 */ - $this->setContentType('text/xml'); - - /** 构建消息体 */ - echo 'getCharset() . '"?>', - '', - $this->_parseXml($message), - ''; - - /** 终止后续输出 */ - exit; - } - - /** - * 抛出json回执信息 - * - * @access public - * @param string $message 消息体 - * @return void - */ - public function throwJson($message) - { - /** 设置http头信息 */ - $this->setContentType('application/json'); - - echo json_encode($message); - - /** 终止后续输出 */ - exit; - } - - /** - * 重定向函数 - * - * @access public - * @param string $location 重定向路径 - * @param boolean $isPermanently 是否为永久重定向 - * @return void - */ - public function redirect($location, $isPermanently = false) - { - /** Typecho_Common */ - require_once 'Typecho/Common.php'; - $location = Typecho_Common::safeUrl($location); - - if ($isPermanently) { - header('Location: ' . $location, false, 301); - exit; - } else { - header('Location: ' . $location, false, 302); - exit; - } - } - - /** - * 返回来路 - * - * @access public - * @param string $anchor 附加地址 - * @param string $default 默认来路 - * @return void - */ - public function goBack($suffix = NULL, $default = NULL) - { - //获取来源 - $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; - - //判断来源 - if (!empty($referer)) { - // ~ fix Issue 38 - if (!empty($suffix)) { - $parts = parse_url($referer); - $myParts = parse_url($suffix); - - if (isset($myParts['fragment'])) { - $parts['fragment'] = $myParts['fragment']; - } - - if (isset($myParts['query'])) { - $args = array(); - if (isset($parts['query'])) { - parse_str($parts['query'], $args); - } - - parse_str($myParts['query'], $currentArgs); - $args = array_merge($args, $currentArgs); - $parts['query'] = http_build_query($args); - } - - $referer = Typecho_Common::buildUrl($parts); - } - - $this->redirect($referer, false); - } else if (!empty($default)) { - $this->redirect($default); - } - } -} diff --git a/php/typecho09/var/Typecho/Router.php b/php/typecho09/var/Typecho/Router.php deleted file mode 100644 index 012d2a165..000000000 --- a/php/typecho09/var/Typecho/Router.php +++ /dev/null @@ -1,222 +0,0 @@ - $route) { - if (preg_match($route['regx'], $pathInfo, $matches)) { - self::$current = $key; - - try { - /** 载入参数 */ - $params = NULL; - - if (!empty($route['params'])) { - unset($matches[0]); - $params = array_combine($route['params'], $matches); - } - - $widget = Typecho_Widget::widget($route['widget'], $parameter, $params); - - return $widget; - - } catch (Exception $e) { - if (404 == $e->getCode()) { - Typecho_Widget::destory($route['widget']); - continue; - } - - throw $e; - } - } - } - - return false; - } - - /** - * 设置全路径 - * - * @access public - * @param string $pathInfo - * @return void - */ - public static function setPathInfo($pathInfo = '/') - { - self::$_pathInfo = $pathInfo; - } - - /** - * 获取全路径 - * - * @access public - * @return string - */ - public static function getPathInfo() - { - if (NULL === self::$_pathInfo) { - self::setPathInfo(); - } - - return self::$_pathInfo; - } - - /** - * 路由分发函数 - * - * @param string $path 目的文件所在目录 - * @return void - * @throws Typecho_Route_Exception - */ - public static function dispatch() - { - /** 获取PATHINFO */ - $pathInfo = self::getPathInfo(); - - foreach (self::$_routingTable as $key => $route) { - if (preg_match($route['regx'], $pathInfo, $matches)) { - self::$current = $key; - - try { - /** 载入参数 */ - $params = NULL; - - if (!empty($route['params'])) { - unset($matches[0]); - $params = array_combine($route['params'], $matches); - } - - $widget = Typecho_Widget::widget($route['widget'], NULL, $params); - - if (isset($route['action'])) { - $widget->{$route['action']}(); - } - - return; - - } catch (Exception $e) { - if (404 == $e->getCode()) { - Typecho_Widget::destory($route['widget']); - continue; - } - - throw $e; - } - } - } - - /** 载入路由异常支持 */ - require_once 'Typecho/Router/Exception.php'; - throw new Typecho_Router_Exception("Path '{$pathInfo}' not found", 404); - } - - /** - * 路由反解析函数 - * - * @param string $name 路由配置表名称 - * @param string $value 路由填充值 - * @param string $prefix 最终合成路径的前缀 - * @return string - */ - public static function url($name, array $value = NULL, $prefix = NULL) - { - $route = self::$_routingTable[$name]; - - //交换数组键值 - $pattern = array(); - foreach ($route['params'] as $row) { - $pattern[$row] = isset($value[$row]) ? $value[$row] : '{' . $row . '}'; - } - - return Typecho_Common::url(vsprintf($route['format'], $pattern), $prefix); - } - - /** - * 设置路由器默认配置 - * - * @access public - * @param mixed $routes 配置信息 - * @return void - */ - public static function setRoutes($routes) - { - /** 载入路由解析支持 */ - require_once 'Typecho/Router/Parser.php'; - - if (isset($routes[0])) { - self::$_routingTable = $routes[0]; - } else { - /** 解析路由配置 */ - $parser = new Typecho_Router_Parser($routes); - self::$_routingTable = $parser->parse(); - } - } - - /** - * 获取路由信息 - * - * @param string $routeName 路由名称 - * @static - * @access public - * @return void - */ - public static function get($routeName) - { - return isset(self::$_routingTable[$routeName]) ? self::$_routingTable[$routeName] : NULL; - } -} diff --git a/php/typecho09/var/Typecho/Router/Exception.php b/php/typecho09/var/Typecho/Router/Exception.php deleted file mode 100644 index 8a7e05ffb..000000000 --- a/php/typecho09/var/Typecho/Router/Exception.php +++ /dev/null @@ -1,19 +0,0 @@ -_routingTable = $routingTable; - - $this->_defaultRegx = array( - 'string' => '(.%s)', - 'char' => '([^/]%s)', - 'digital'=> '([0-9]%s)', - 'alpha' => '([_0-9a-zA-Z-]%s)', - 'alphaslash' => '([_0-9a-zA-Z-/]%s)', - ); - } - - /** - * 局部匹配并替换正则字符串 - * - * @access public - * @param array $matches 匹配部分 - * @return string - */ - public function _match(array $matches) - { - $params = explode(' ', $matches[1]); - $paramsNum = count($params); - $this->_params[] = $params[0]; - - if (1 == $paramsNum) { - return sprintf($this->_defaultRegx['char'], '+'); - } else if (2 == $paramsNum) { - return sprintf($this->_defaultRegx[$params[1]], '+'); - } else if (3 == $paramsNum) { - return sprintf($this->_defaultRegx[$params[1]], $params[2] > 0 ? '{' . $params[2] . '}' : '*'); - } else if (4 == $paramsNum) { - return sprintf($this->_defaultRegx[$params[1]], '{' . $params[2] . ',' . $params[3] . '}'); - } - } - - /** - * 解析路由表 - * - * @access public - * @return array - */ - public function parse() - { - $result = array(); - - foreach ($this->_routingTable as $key => $route) { - $this->_params = array(); - $route['regx'] = preg_replace_callback("/%([^%]+)%/", array($this, '_match'), - preg_quote(str_replace(array('[', ']', ':'), array('%', '%', ' '), $route['url']))); - - /** 处理斜线 */ - $route['regx'] = rtrim($route['regx'], '/'); - $route['regx'] = '|^' . $route['regx'] . '[/]?$|'; - - $route['format'] = preg_replace("/\[([^\]]+)\]/", "%s", $route['url']); - $route['params'] = $this->_params; - - $result[$key] = $route; - } - - return $result; - } -} diff --git a/php/typecho09/var/Typecho/Validate.php b/php/typecho09/var/Typecho/Validate.php deleted file mode 100644 index f186c0d9b..000000000 --- a/php/typecho09/var/Typecho/Validate.php +++ /dev/null @@ -1,322 +0,0 @@ - - * $test = "hello"; - * $Validation = new TypechoValidation(); - * $Validation->form($test, array("alpha" => "不是字符"); - * var_dump($Validation->getErrorMsg()); - *
    - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id: Validation.php 106 2008-04-11 02:23:54Z magike.net $ - */ - -/** Typecho_Common */ -require_once 'Typecho/Common.php'; - -/** - * 验证类 - * - * @package Validate - */ -class Typecho_Validate -{ - /** - * 内部数据 - * - * @access private - * @var array - */ - private $_data; - - /** - * 当前验证指针 - * - * @access private - * @var string - */ - private $_key; - - /** - * 验证规则数组 - * - * @access private - * @var array - */ - private $_rules = array(); - - /** - * 中断模式,一旦出现验证错误即抛出而不再继续执行 - * - * @access private - * @var boolean - */ - private $_break = false; - - /** - * 增加验证规则 - * - * @access public - * @param string $key 数值键值 - * @param string $rule 规则名称 - * @param string $message 错误字符串 - * @return Typecho_Validation - */ - public function addRule($key, $rule, $message) - { - if (func_num_args() <= 3) { - $this->_rules[$key][] = array($rule, $message); - } else { - $params = func_get_args(); - $params = array_splice($params, 3); - $this->_rules[$key][] = array_merge(array($rule, $message), $params); - } - - return $this; - } - - /** - * 设置为中断模式 - * - * @access public - * @return void - */ - public function setBreak() - { - $this->_break = true; - } - - /** - * Run the Validator - * This function does all the work. - * - * @access public - * @param array $data 需要验证的数据 - * @param array $rules 验证数据遵循的规则 - * @return array - * @throws Typecho_Validate_Exception - */ - public function run(array $data, $rules = NULL) - { - $result = array(); - $this->_data = $data; - $rules = empty($rules) ? $this->_rules : $rules; - - // Cycle through the rules and test for errors - foreach ($rules as $key => $rules) { - $this->_key = $key; - $data[$key] = (0 == strlen($data[$key])) ? NULL : $data[$key]; - - foreach ($rules as $params) { - $method = $params[0]; - - if ('required' != $method && 'confirm' != $method && 0 == strlen($data[$key])) { - continue; - } - - $message = $params[1]; - $params[1] = $data[$key]; - $params = array_slice($params, 1); - - if (!call_user_func_array(is_array($method) ? $method : array($this, $method), $params)) { - $result[$key] = $message; - break; - } - } - - /** 开启中断 */ - if ($this->_break && $result) { - break; - } - } - - return $result; - } - - /** - * 最小长度 - * - * @access public - * @param string $str 待处理的字符串 - * @param integer $length 最小长度 - * @return boolean - */ - public function minLength($str, $length) - { - return (Typecho_Common::strLen($str) >= $length); - } - - /** - * 验证输入是否一致 - * - * @access public - * @param string $str 待处理的字符串 - * @param string $key 需要一致性检查的键值 - * @return boolean - */ - public function confirm($str, $key) - { - return !empty($this->_data[$key]) ? ($str == $this->_data[$key]) : empty($str); - } - - /** - * 是否为空 - * - * @access public - * @param string $str 待处理的字符串 - * @return boolean - */ - public function required($str) - { - return !empty($this->_data[$this->_key]); - } - - /** - * 枚举类型判断 - * - * @access public - * @param string $str 待处理的字符串 - * @param array $params 枚举值 - * @return unknown - */ - public function enum($str, array $params) - { - $keys = array_flip($params); - return isset($keys[$str]); - } - - /** - * Max Length - * - * @access public - * @param string - * @return boolean - */ - public function maxLength($str, $length) - { - return (Typecho_Common::strLen($str) < $length); - } - - /** - * Valid Email - * - * @access public - * @param string - * @return boolean - */ - public function email($str) - { - return preg_match("/^[^@\s<&>]+@([-a-z0-9]+\.)+[a-z]{2,}$/i", $str); - } - - /** - * 验证是否为网址 - * - * @access public - * @param string $str - * @return boolean - */ - public function url($str) - { - $parts = @parse_url($str); - if (!$parts) { - return false; - } - - return isset($parts['scheme']) && - in_array($parts['scheme'], array('http', 'https', 'ftp')) && - !preg_match('/(\(|\)|\\\|"|<|>|[\x00-\x08]|[\x0b-\x0c]|[\x0e-\x19])/', $str); - } - - /** - * Alpha - * - * @access public - * @param string - * @return boolean - */ - public function alpha($str) - { - return preg_match("/^([a-z])+$/i", $str) ? true : false; - } - - /** - * Alpha-numeric - * - * @access public - * @param string - * @return boolean - */ - public function alphaNumeric($str) - { - return preg_match("/^([a-z0-9])+$/i", $str); - } - - /** - * Alpha-numeric with underscores and dashes - * - * @access public - * @param string - * @return boolean - */ - public function alphaDash($str) - { - return preg_match("/^([_a-z0-9-])+$/i", $str) ? true : false; - } - - /** - * 对xss字符串的检测 - * - * @access public - * @param string $str - * @return boolean - */ - public function xssCheck($str) - { - $search = 'abcdefghijklmnopqrstuvwxyz'; - $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $search .= '1234567890!@#$%^&*()'; - $search .= '~`";:?+/={}[]-_|\'\\'; - - for ($i = 0; $i < strlen($search); $i++) { - // ;? matches the ;, which is optional - // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars - - // @ @ search for the hex values - $str = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $str); // with a ; - // @ @ 0{0,7} matches '0' zero to seven times - $str = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $str); // with a ; - } - - return !preg_match('/(\(|\)|\\\|"|<|>|[\x00-\x08]|[\x0b-\x0c]|[\x0e-\x19])/', $str); - } - - /** - * Numeric - * - * @access public - * @param integer - * @return boolean - */ - public function isFloat($str) - { - return ereg("^[0-9\.]+$", $str); - } - - /** - * Is Numeric - * - * @access public - * @param string - * @return boolean - */ - public function isInteger($str) - { - return is_numeric($str); - } -} diff --git a/php/typecho09/var/Typecho/Widget.php b/php/typecho09/var/Typecho/Widget.php deleted file mode 100644 index 3b4feb013..000000000 --- a/php/typecho09/var/Typecho/Widget.php +++ /dev/null @@ -1,417 +0,0 @@ -request = $request; - $this->response = $response; - $this->parameter = new Typecho_Config(); - - if (!empty($params)) { - $this->parameter->setDefault($params); - } - } - - /** - * execute function. - * - * @access public - * @return void - */ - public function execute(){} - - /** - * post事件触发 - * - * @param boolean $condition 触发条件 - * @return mixed - */ - public function on($condition) - { - if ($condition) { - return $this; - } else { - /** Typecho_Widget_Helper_Null */ - require_once 'Typecho/Widget/Helper/Empty.php'; - return new Typecho_Widget_Helper_Empty(); - } - } - - /** - * 获取对象插件句柄 - * - * @access public - * @param string $handle 句柄 - * @return Typecho_Plugin - */ - public function pluginHandle($handle = NULL) - { - return Typecho_Plugin::factory(empty($handle) ? get_class($this) : $handle); - } - - /** - * 工厂方法,将类静态化放置到列表中 - * - * @access public - * @param string $alias 组件别名 - * @param mixed $params 传递的参数 - * @param mixed $request 前端参数 - * @param boolean $enableResponse 是否允许http回执 - * @return object - * @throws Typecho_Exception - */ - public static function widget($alias, $params = NULL, $request = NULL, $enableResponse = true) - { - list($className) = explode('@', $alias); - - if (!isset(self::$_widgetPool[$alias])) { - $fileName = str_replace('_', '/', $className) . '.php'; - require_once $fileName; - - /** 如果类不存在 */ - if (!class_exists($className)) { - /** Typecho_Exception */ - require_once 'Typecho/Widget/Exception.php'; - throw new Typecho_Widget_Exception($className); - } - - /** 初始化request */ - if (!empty($request)) { - $requestObject = new Typecho_Request(); - $requestObject->setParams($request); - } else { - $requestObject = Typecho_Request::getInstance(); - } - - /** 初始化response */ - $responseObject = $enableResponse ? Typecho_Response::getInstance() - : Typecho_Widget_Helper_Empty::getInstance(); - - /** 初始化组件 */ - $widget = new $className($requestObject, $responseObject, $params); - - $widget->execute(); - self::$_widgetPool[$alias] = $widget; - } - - return self::$_widgetPool[$alias]; - } - - /** - * 释放组件 - * - * @access public - * @param string $alias 组件名称 - * @return void - */ - public static function destory($alias) - { - if (isset(self::$_widgetPool[$alias])) { - unset(self::$_widgetPool[$alias]); - } - } - - /** - * 将类本身赋值 - * - * @param string $variable 变量名 - * @return void - */ - public function to(&$variable) - { - return $variable = $this; - } - - /** - * 格式化解析堆栈内的所有数据 - * - * @param string $format 数据格式 - * @return void - */ - public function parse($format) - { - $rowsKey = array(); - - /** 过滤数据行 */ - foreach ($this->row as $key => $val) { - if (is_array($val) || is_object($val)) { - unset($this->row[$key]); - } - } - - //将数据格式化 - foreach ($this->row as $key => $val) { - $rowsKey[] = '{' . $key . '}'; - } - - foreach ($this->stack as $val) { - /** 过滤数据行 */ - foreach ($val as $inkey => $inval) { - if (is_array($inval) || is_object($inval)) { - unset($val[$inkey]); - } - } - echo str_replace($rowsKey, $val, $format) . "\n"; - } - - /** 重置指针 */ - reset($this->row); - reset($this->stack); - } - - /** - * 将每一行的值压入堆栈 - * - * @param array $value 每一行的值 - * @return array - */ - public function push(array $value) - { - //将行数据按顺序置位 - $this->row = $value; - $this->length ++; - - $this->stack[] = $value; - return $value; - } - - /** - * 根据余数输出 - * - * @access public - * @param string $param 需要输出的值 - * @return void - */ - public function alt() - { - $args = func_get_args(); - $num = func_num_args(); - $split = $this->sequence % $num; - echo $args[(0 == $split ? $num : $split) -1]; - } - - /** - * 输出顺序值 - * - * @access public - * @return void - */ - public function sequence() - { - echo $this->sequence; - } - - /** - * 输出数据长度 - * - * @access public - * @return void - */ - public function length() - { - echo $this->length; - } - - /** - * 返回堆栈是否为空 - * - * @return boolean - */ - public function have() - { - return !empty($this->stack); - } - - /** - * 返回堆栈每一行的值 - * - * @return array - */ - public function next() - { - if ($this->stack) { - $this->row = @$this->stack[key($this->stack)]; - next($this->stack); - $this->sequence ++; - } - - if (!$this->row) { - reset($this->stack); - if ($this->stack) { - $this->row = $this->stack[key($this->stack)]; - } - - $this->sequence = 0; - return false; - } - - return $this->row; - } - - /** - * 魔术函数,用于挂接其它函数 - * - * @access public - * @param string $name 函数名 - * @param array $args 函数参数 - * @return void - */ - public function __call($name, $args) - { - echo $this->{$name}; - } - - /** - * 魔术函数,用于获取内部变量 - * - * @access public - * @param string $name 变量名 - * @return mixed - */ - public function __get($name) - { - $method = '___' . $name; - - if (array_key_exists($name, $this->row)) { - return $this->row[$name]; - } else { - $method = '___' . $name; - - if (method_exists($this, $method)) { - return $this->$method(); - } else { - $return = $this->pluginHandle()->trigger($plugged)->{$method}($this); - if ($plugged) { - return $return; - } - } - } - - return NULL; - } - - /** - * 设定堆栈每一行的值 - * - * @param string $name 值对应的键值 - * @param mixed $value 相应的值 - * @return void - */ - public function __set($name, $value) - { - $this->row[$name] = $value; - } - - /** - * 验证堆栈值是否存在 - * - * @access public - * @param string $name - * @return boolean - */ - public function __isSet($name) - { - return isset($this->row[$name]); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Exception.php b/php/typecho09/var/Typecho/Widget/Exception.php deleted file mode 100644 index ccdeea149..000000000 --- a/php/typecho09/var/Typecho/Widget/Exception.php +++ /dev/null @@ -1,19 +0,0 @@ -setClose(false); - - /** 设置表单属性 */ - $this->setAction($action); - $this->setMethod($method); - $this->setEncodeType($enctype); - } - - /** - * 设置表单编码方案 - * - * @access public - * @param string $enctype 编码方法 - * @return Typecho_Widget_Helper_Form - */ - public function setEncodeType($enctype) - { - $this->setAttribute('enctype', $enctype); - return $this; - } - - /** - * 增加输入元素 - * - * @access public - * @param Typecho_Widget_Helper_Form_Abstract $input 输入元素 - * @return Typecho_Widget_Helper_Form - */ - public function addInput(Typecho_Widget_Helper_Form_Element $input) - { - $this->_inputs[$input->name] = $input; - $this->addItem($input); - return $this; - } - - /** - * 增加元素(重载) - * - * @access public - * @param Typecho_Widget_Helper_Layout $item 表单元素 - * @return Typecho_Widget_Helper_Layout - */ - public function addItem(Typecho_Widget_Helper_Layout $item) - { - if ($item instanceof Typecho_Widget_Helper_Form_Submit) { - $this->addItem($item); - } else { - parent::addItem($item); - } - - return $this; - } - - /** - * 获取输入项 - * - * @access public - * @param string $name 输入项名称 - * @return mixed - */ - public function getInput($name) - { - return $this->_inputs[$name]; - } - - /** - * 获取所有输入项的提交值 - * - * @access public - * @return array - */ - public function getAllRequest() - { - $result = array(); - $source = (self::POST_METHOD == $this->getAttribute('method')) ? $_POST : $_GET; - - foreach ($this->_inputs as $name => $input) { - $result[$name] = isset($source[$name]) ? $source[$name] : NULL; - } - return $result; - } - - /** - * 设置表单提交方法 - * - * @access public - * @param string $method 表单提交方法 - * @return Typecho_Widget_Helper_Form - */ - public function setMethod($method) - { - $this->setAttribute('method', $method); - return $this; - } - - /** - * 设置表单提交目的 - * - * @access public - * @param string $action 表单提交目的 - * @return Typecho_Widget_Helper_Form - */ - public function setAction($action) - { - $this->setAttribute('action', $action); - return $this; - } - - /** - * 获取此表单的所有输入项固有值 - * - * @access public - * @return array - */ - public function getValues() - { - $values = array(); - - foreach ($this->_inputs as $name => $input) { - $values[$name] = $input->value; - } - return $values; - } - - /** - * 获取此表单的所有输入项 - * - * @access public - * @return array - */ - public function getInputs() - { - return $this->_inputs; - } - - /** - * 获取提交数据源 - * - * @access public - * @param array $params 数据参数集 - * @return array - */ - public function getParams(array $params) - { - $result = array(); - $source = (self::POST_METHOD == $this->getAttribute('method')) ? $_POST : $_GET; - - foreach ($params as $param) { - $result[$param] = isset($source[$param]) ? $source[$param] : NULL; - } - - return $result; - } - - /** - * 验证表单 - * - * @access public - * @return void - */ - public function validate() - { - $validator = new Typecho_Validate(); - $rules = array(); - - foreach ($this->_inputs as $name => $input) { - $rules[$name] = $input->rules; - } - - $id = md5(implode('"', array_keys($this->_inputs))); - - /** 表单值 */ - $formData = $this->getParams(array_keys($rules)); - $error = $validator->run($formData, $rules); - - if ($error) { - /** 利用session记录错误 */ - $_SESSION['__typecho_form_message_' . $id] = $error; - - /** 利用session记录表单值 */ - $_SESSION['__typecho_form_record_' . $id] = $formData; - } - - return $error; - } - - /** - * 显示表单 - * - * @access public - * @return void - */ - public function render() - { - $id = md5(implode('"', array_keys($this->_inputs))); - - /** 恢复表单值 */ - if (isset($_SESSION['__typecho_form_record_' . $id])) { - $record = $_SESSION['__typecho_form_record_' . $id]; - $message = $_SESSION['__typecho_form_message_' . $id]; - foreach ($this->_inputs as $name => $input) { - $input->value(isset($record[$name]) ? $record[$name] : $input->value); - - /** 显示错误消息 */ - if (isset($message[$name])) { - $input->message($message[$name]); - } - } - - unset($_SESSION['__typecho_form_record_' . $id]); - } - - parent::render(); - unset($_SESSION['__typecho_form_message_' . $id]); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element.php deleted file mode 100644 index 97e5c00a5..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element.php +++ /dev/null @@ -1,324 +0,0 @@ - 'typecho-option', 'id' => 'typecho-option-item-' . $name . '-' . self::$uniqueId)); - $this->name = $name; - self::$uniqueId ++; - - /** 运行自定义初始函数 */ - $this->init(); - - /** 初始化表单标题 */ - if (NULL !== $label) { - $this->label($label); - } - - /** 初始化表单项 */ - $this->input = $this->input($name, $options); - - /** 初始化表单值 */ - if (NULL !== $value) { - $this->value($value); - } - - /** 初始化表单描述 */ - if (NULL !== $description) { - $this->description($description); - } - } - - /** - * filterValue - * - * @param mixed $value - * @access protected - * @return string - */ - protected function filterValue($value) - { - if (preg_match_all('/[_0-9a-z-]+/i', $value, $matches)) { - return implode('-', $matches[0]); - } - - return ''; - } - - /** - * 自定义初始函数 - * - * @access public - * @return void - */ - public function init(){} - - /** - * 创建表单标题 - * - * @access public - * @param string $value 标题字符串 - * @return Typecho_Widget_Helper_Form_Element - */ - public function label($value) - { - /** 创建标题元素 */ - if (empty($this->label)) { - $this->label = new Typecho_Widget_Helper_Layout('label', array('class' => 'typecho-label')); - $this->container($this->label); - } - - $this->label->html($value); - return $this; - } - - /** - * 在容器里增加元素 - * - * @access public - * @param Typecho_Widget_Helper_Layout $item 表单元素 - * @return $this - */ - public function container(Typecho_Widget_Helper_Layout $item) - { - /** 创建表单容器 */ - if (empty($this->container)) { - $this->container = new Typecho_Widget_Helper_Layout('li'); - $this->addItem($this->container); - } - - $this->container->addItem($item); - return $this; - } - - /** - * 设置提示信息 - * - * @access public - * @param string $message 提示信息 - * @return Typecho_Widget_Helper_Form_Element - */ - public function message($message) - { - if (empty($this->message)) { - $this->message = new Typecho_Widget_Helper_Layout('p', array('class' => 'message error')); - $this->container($this->message); - } - - $this->message->html($message); - return $this; - } - - /** - * 设置描述信息 - * - * @access public - * @param string $description 描述信息 - * @return Typecho_Widget_Helper_Form_Element - */ - public function description($description) - { - /** 创建描述元素 */ - if (empty($this->description)) { - $this->description = new Typecho_Widget_Helper_Layout('p', array('class' => 'description')); - $this->container($this->description); - } - - $this->description->html($description); - return $this; - } - - /** - * 设置表单元素值 - * - * @access public - * @param mixed $value 表单元素值 - * @return Typecho_Widget_Helper_Form_Element - */ - public function value($value) - { - $this->value = $value; - $this->_value($value); - return $this; - } - - /** - * 多行输出模式 - * - * @access public - * @return Typecho_Widget_Helper_Layout - */ - public function multiline() - { - $item = new Typecho_Widget_Helper_Layout('span'); - $this->multiline[] = $item; - return $item; - } - - /** - * 多行输出模式 - * - * @access public - * @return Typecho_Widget_Helper_Form_Element - */ - public function multiMode() - { - foreach ($this->multiline as $item) { - $item->setAttribute('class', 'multiline'); - } - return $this; - } - - /** - * 初始化当前输入项 - * - * @access public - * @param Typecho_Widget_Helper_Layout $container 容器对象 - * @param string $name 表单元素名称 - * @param array $options 选择项 - * @return Typecho_Widget_Helper_Form_Element - */ - abstract public function input($name = NULL, array $options = NULL); - - /** - * 设置表单元素值 - * - * @access protected - * @param mixed $value 表单元素值 - * @return void - */ - abstract protected function _value($value); - - /** - * 增加验证器 - * - * @access public - * @return Typecho_Widget_Helper_Form_Element - */ - public function addRule($name) - { - $this->rules[] = func_get_args(); - return $this; - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Checkbox.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Checkbox.php deleted file mode 100644 index e2b8af591..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Checkbox.php +++ /dev/null @@ -1,83 +0,0 @@ - $label) { - $this->_options[$value] = new Typecho_Widget_Helper_Layout('input'); - $item = $this->multiline(); - $id = $this->name . '-' . $this->filterValue($value); - $this->inputs[] = $this->_options[$value]; - - $item->addItem($this->_options[$value]->setAttribute('name', $this->name . '[]') - ->setAttribute('type', 'checkbox') - ->setAttribute('value', $value) - ->setAttribute('id', $id)); - - $labelItem = new Typecho_Widget_Helper_Layout('label'); - $item->addItem($labelItem->setAttribute('for', $id)->html($label)); - $this->container($item); - } - - return current($this->_options); - } - - /** - * 设置表单元素值 - * - * @access protected - * @param mixed $value 表单元素值 - * @return void - */ - protected function _value($value) - { - $values = is_array($value) ? $value : array($value); - - foreach ($this->_options as $option) { - $option->removeAttribute('checked'); - } - - foreach ($values as $value) { - if (isset($this->_options[$value])) { - $this->_options[$value]->setAttribute('checked', 'true'); - } - } - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Hidden.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Hidden.php deleted file mode 100644 index 889bc7e76..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Hidden.php +++ /dev/null @@ -1,64 +0,0 @@ -setAttribute('style', 'display:none'); - } - - /** - * 初始化当前输入项 - * - * @access public - * @param string $name 表单元素名称 - * @param array $options 选择项 - * @return Typecho_Widget_Helper_Layout - */ - public function input($name = NULL, array $options = NULL) - { - $input = new Typecho_Widget_Helper_Layout('input', array('name' => $name, 'type' => 'hidden')); - $this->container($input); - $this->inputs[] = $input; - return $input; - } - - /** - * 设置表单项默认值 - * - * @access protected - * @param string $value 表单项默认值 - * @return void - */ - protected function _value($value) - { - $this->input->setAttribute('value', $value); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Password.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Password.php deleted file mode 100644 index 811f28c8a..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Password.php +++ /dev/null @@ -1,54 +0,0 @@ - $name . '-0-' . self::$uniqueId, - 'name' => $name, 'type' => 'password', 'class' => 'password')); - $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); - $this->container($input); - $this->inputs[] = $input; - return $input; - } - - /** - * 设置表单项默认值 - * - * @access protected - * @param string $value 表单项默认值 - * @return void - */ - protected function _value($value) - { - $this->input->setAttribute('value', $value); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Radio.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Radio.php deleted file mode 100644 index 2b1a53964..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Radio.php +++ /dev/null @@ -1,81 +0,0 @@ - $label) { - $this->_options[$value] = new Typecho_Widget_Helper_Layout('input'); - $item = $this->multiline(); - $id = $this->name . '-' . $this->filterValue($value); - $this->inputs[] = $this->_options[$value]; - - $item->addItem($this->_options[$value]->setAttribute('name', $this->name) - ->setAttribute('type', 'radio') - ->setAttribute('value', $value) - ->setAttribute('id', $id)); - - $labelItem = new Typecho_Widget_Helper_Layout('label'); - $item->addItem($labelItem->setAttribute('for', $id)->html($label)); - $this->container($item); - } - - return current($this->_options); - } - - /** - * 设置表单元素值 - * - * @access protected - * @param mixed $value 表单元素值 - * @return void - */ - protected function _value($value) - { - foreach ($this->_options as $option) { - $option->removeAttribute('checked'); - } - - if (isset($this->_options[$value])) { - $this->value = $value; - $this->_options[$value]->setAttribute('checked', 'true'); - $this->input = $this->_options[$value]; - } - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Select.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Select.php deleted file mode 100644 index f09e2f66e..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Select.php +++ /dev/null @@ -1,74 +0,0 @@ -container($input->setAttribute('name', $name) - ->setAttribute('id', $name . '-0-' . self::$uniqueId)); - $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); - $this->inputs[] = $input; - - foreach ($options as $value => $label) { - $this->_options[$value] = new Typecho_Widget_Helper_Layout('option'); - $input->addItem($this->_options[$value]->setAttribute('value', $value)->html($label)); - } - - return $input; - } - - /** - * 设置表单元素值 - * - * @access protected - * @param mixed $value 表单元素值 - * @return void - */ - protected function _value($value) - { - foreach ($this->_options as $option) { - $option->removeAttribute('selected'); - } - - if (isset($this->_options[$value])) { - $this->_options[$value]->setAttribute('selected', 'true'); - } - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Submit.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Submit.php deleted file mode 100644 index 1d88f513e..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Submit.php +++ /dev/null @@ -1,54 +0,0 @@ -setAttribute('class', 'typecho-option typecho-option-submit'); - $input = new Typecho_Widget_Helper_Layout('button', array('type' => 'submit')); - $this->container($input); - $this->inputs[] = $input; - - return $input; - } - - /** - * 设置表单元素值 - * - * @access protected - * @param mixed $value 表单元素值 - * @return void - */ - protected function _value($value) - { - $this->input->html($value); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Text.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Text.php deleted file mode 100644 index df5b1e9c3..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Text.php +++ /dev/null @@ -1,55 +0,0 @@ - $name . '-0-' . self::$uniqueId, - 'name' => $name, 'type' => 'text', 'class' => 'text')); - $this->container($input); - $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); - $this->inputs[] = $input; - - return $input; - } - - /** - * 设置表单项默认值 - * - * @access protected - * @param mixed $value 表单项默认值 - * @return void - */ - protected function _value($value) - { - $this->input->setAttribute('value', $value); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Textarea.php b/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Textarea.php deleted file mode 100644 index 43d0e4976..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Form/Element/Textarea.php +++ /dev/null @@ -1,54 +0,0 @@ - $name . '-0-' . self::$uniqueId, 'name' => $name)); - $this->label->setAttribute('for', $name . '-0-' . self::$uniqueId); - $this->container($input->setClose(false)); - $this->inputs[] = $input; - - return $input; - } - - /** - * 设置表单项默认值 - * - * @access protected - * @param string $value 表单项默认值 - * @return void - */ - protected function _value($value) - { - $this->input->html($value); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/Layout.php b/php/typecho09/var/Typecho/Widget/Helper/Layout.php deleted file mode 100644 index b90c081ef..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/Layout.php +++ /dev/null @@ -1,352 +0,0 @@ -setTagName($tagName); - - if (!empty($attributes)) { - foreach ($attributes as $attributeName => $attributeValue) { - $this->setAttribute($attributeName, $attributeValue); - } - } - } - - /** - * 增加元素 - * - * @access public - * @param Typecho_Widget_Helper_Layout $item 元素 - * @return Typecho_Widget_Helper_Layout - */ - public function addItem(Typecho_Widget_Helper_Layout $item) - { - $item->setParent($this); - $this->_items[] = $item; - return $this; - } - - /** - * 删除元素 - * - * @access public - * @param Typecho_Widget_Helper_Layout $item 元素 - * @return Typecho_Widget_Helper_Layout - */ - public function removeItem(Typecho_Widget_Helper_Layout $item) - { - unset($this->_items[array_search($item, $this->_items)]); - return $this; - } - - /** - * getItems - * - * @access public - * @return array - */ - public function getItems() - { - return $this->_items; - } - - /** - * 设置内部数据 - * - * @access public - * @param mixed $html 内部数据 - * @return unknown - */ - public function html($html = false) - { - if (false === $html) { - if (empty($this->_html)) { - foreach ($this->_items as $item) { - $item->render(); - } - } else { - echo $this->_html; - } - } else { - $this->_html = $html; - return $this; - } - } - - /** - * 设置标签名 - * - * @access public - * @param string $tagName 标签名 - * @return void - */ - public function setTagName($tagName) - { - $this->_tagName = $tagName; - } - - /** - * getTagName - * - * @param mixed $tagName - * @access public - * @return void - */ - public function getTagName($tagName) - {} - - /** - * 设置表单属性 - * - * @access public - * @param string $attributeName 属性名称 - * @param string $attributeValue 属性值 - * @return Typecho_Widget_Helper_Layout - */ - public function setAttribute($attributeName, $attributeValue) - { - $this->_attributes[$attributeName] = $attributeValue; - return $this; - } - - /** - * 移除某个属性 - * - * @access public - * @param string $attributeName 属性名称 - * @return Typecho_Widget_Helper_Layout - */ - public function removeAttribute($attributeName) - { - if (isset($this->_attributes[$attributeName])) { - unset($this->_attributes[$attributeName]); - } - - return $this; - } - - /** - * 获取属性 - * - * @access public - * @param string $attributeName 属性名 - * @return string - */ - public function getAttribute($attributeName) - { - return isset($this->_attributes[$attributeName]) ? $this->_attributes[$attributeName] : NULL; - } - - /** - * 设置是否自闭合 - * - * @access public - * @param boolean $close 是否自闭合 - * @return Typecho_Widget_Helper_Layout - */ - public function setClose($close) - { - $this->_forceClose = $close; - return $this; - } - - /** - * 设置父节点 - * - * @access public - * @param Typecho_Widget_Helper_Layout $parent 父节点 - * @return Typecho_Widget_Helper_Layout - */ - public function setParent(Typecho_Widget_Helper_Layout $parent) - { - $this->_parent = $parent; - return $this; - } - - /** - * 获取父节点 - * - * @access public - * @return Typecho_Widget_Helper_Layout - */ - public function getParent() - { - return $this->_parent; - } - - /** - * 增加到某布局元素集合中 - * - * @access public - * @param Typecho_Widget_Helper_Layout $parent 布局对象 - * @return Typecho_Widget_Helper_Layout - */ - public function appendTo(Typecho_Widget_Helper_Layout $parent) - { - $parent->addItem($this); - return $this; - } - - /** - * 开始标签 - * - * @access public - * @return void - */ - public function start() - { - /** 输出标签 */ - echo $this->_tagName ? "<{$this->_tagName}" : NULL; - - /** 输出属性 */ - foreach ($this->_attributes as $attributeName => $attributeValue) { - echo " {$attributeName}=\"{$attributeValue}\""; - } - - /** 支持自闭合 */ - if (!$this->_close && $this->_tagName) { - echo ">\n"; - } - } - - /** - * 结束标签 - * - * @access public - * @return void - */ - public function end() - { - if ($this->_tagName) { - echo $this->_close ? " />\n" : "_tagName}>\n"; - } - } - - /** - * 设置属性 - * - * @access public - * @param string $attributeName 属性名称 - * @param string $attributeValue 属性值 - * @return void - */ - public function __set($name, $value) - { - $this->_attributes[$name] = $value; - } - - /** - * 获取属性 - * - * @access public - * @param string $attributeName 属性名称 - * @return void - */ - public function __get($name) - { - return isset($this->_attributes[$name]) ? $this->_attributes[$name] : NULL; - } - - /** - * 输出所有元素 - * - * @access public - * @return void - */ - public function render() - { - if (empty($this->_items) && empty($this->_html)) { - $this->_close = true; - } - - if (NULL !== $this->_forceClose) { - $this->_close = $this->_forceClose; - } - - $this->start(); - $this->html(); - $this->end(); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/PageNavigator.php b/php/typecho09/var/Typecho/Widget/Helper/PageNavigator.php deleted file mode 100644 index 600d241d0..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/PageNavigator.php +++ /dev/null @@ -1,133 +0,0 @@ -_total = $total; - $this->_totalPage = ceil($total / $pageSize); - $this->_currentPage = $currentPage; - $this->_pageSize = $pageSize; - $this->_pageTemplate = $pageTemplate; - - if (($currentPage > $this->_totalPage || $currentPage < 1) && $total > 0) { - throw new Typecho_Widget_Exception('Page Not Exists', 404); - } - } - - /** - * 设置页面占位符 - * - * @access protected - * @param string $holder 页面占位符 - * @return void - */ - public function setPageHolder($holder) - { - $this->_pageHolder = array('{' . $holder . '}', - str_replace(array('{', '}'), array('%7B', '%7D'), $holder)); - } - - /** - * 设置锚点 - * - * @access public - * @param string $anchor 锚点 - * @return void - */ - public function setAnchor($anchor) - { - $this->_anchor = '#' . $anchor; - } - - /** - * 输出方法 - * - * @access public - * @return void - */ - public function render() - { - /** 载入异常支持 */ - require_once 'Typecho/Widget/Exception.php'; - throw new Typecho_Widget_Exception(get_class($this) . ':' . __METHOD__, 500); - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/PageNavigator/Box.php b/php/typecho09/var/Typecho/Widget/Helper/PageNavigator/Box.php deleted file mode 100644 index c6d85bc48..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/PageNavigator/Box.php +++ /dev/null @@ -1,83 +0,0 @@ -_total < 1) { - return; - } - - $from = max(1, $this->_currentPage - $splitPage); - $to = min($this->_totalPage, $this->_currentPage + $splitPage); - - //输出上一页 - if ($this->_currentPage > 1) { - echo '
  • '; - } - - //输出第一页 - if ($from > 1) { - echo '
  • 1
  • '; - - if ($from > 2) { - //输出省略号 - echo '
  • ' . $splitWord . '
  • '; - } - } - - //输出中间页 - for ($i = $from; $i <= $to; $i ++) { - echo '_currentPage ? '' : ' class="' . $currentClass . '"') . '>' - . $i . ''; - } - - //输出最后页 - if ($to < $this->_totalPage) { - if ($to < $this->_totalPage - 1) { - echo '
  • ' . $splitWord . '
  • '; - } - - echo '
  • ' - . $this->_totalPage . '
  • '; - } - - //输出下一页 - if ($this->_currentPage < $this->_totalPage) { - echo '
  • '; - } - } -} diff --git a/php/typecho09/var/Typecho/Widget/Helper/PageNavigator/Classic.php b/php/typecho09/var/Typecho/Widget/Helper/PageNavigator/Classic.php deleted file mode 100644 index 0b0246b07..000000000 --- a/php/typecho09/var/Typecho/Widget/Helper/PageNavigator/Classic.php +++ /dev/null @@ -1,69 +0,0 @@ -prev($prevWord); - $this->next($nextWord); - } - - /** - * 输出上一页 - * - * @access public - * @param string $prevWord 上一页文字 - * @return void - */ - public function prev($prevWord = 'PREV') - { - //输出上一页 - if ($this->_total > 0 && $this->_currentPage > 1) { - echo ''; - } - } - - /** - * 输出下一页 - * - * @access public - * @param string $prevWord 下一页文字 - * @return void - */ - public function next($nextWord = 'NEXT') - { - //输出下一页 - if ($this->_total > 0 && $this->_currentPage < $this->_totalPage) { - echo ''; - } - } -} diff --git a/php/typecho09/var/Upgrade.php b/php/typecho09/var/Upgrade.php deleted file mode 100644 index eb3302494..000000000 --- a/php/typecho09/var/Upgrade.php +++ /dev/null @@ -1,1091 +0,0 @@ -query($db->select('coid', 'text')->from('table.comments') - ->order('coid', Typecho_Db::SORT_ASC)->page($i, 100)); - $j = 0; - - while ($row = $db->fetchRow($result)) { - $text = nl2br($row['text']); - - $db->query($db->update('table.comments') - ->rows(array('text' => $text)) - ->where('coid = ?', $row['coid'])); - - $j ++; - unset($text); - unset($row); - } - - if ($j < 100) { - break; - } - - $i ++; - unset($result); - } - - /** 转换内容 */ - $i = 1; - - while (true) { - $result = $db->query($db->select('cid', 'text')->from('table.contents') - ->order('cid', Typecho_Db::SORT_ASC)->page($i, 100)); - $j = 0; - - while ($row = $db->fetchRow($result)) { - $text = preg_replace( - array("/\s*

    /is", "/\s*<\/p>\s*/is", "/\s*\s*/is", - "/\s*<(div|blockquote|pre|table|ol|ul)>/is", "/<\/(div|blockquote|pre|table|ol|ul)>\s*/is"), - array('', "\n\n", "\n", "\n\n<\\1>", "\n\n"), - $row['text']); - - $db->query($db->update('table.contents') - ->rows(array('text' => $text)) - ->where('cid = ?', $row['cid'])); - - $j ++; - unset($text); - unset($row); - } - - if ($j < 100) { - break; - } - - $i ++; - unset($result); - } - } - - /** - * 升级至9.1.14 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_4r9_1_14($db, $options) - { - if (is_writeable(__TYPECHO_ROOT_DIR__ . '/config.inc.php')) { - $handle = fopen(__TYPECHO_ROOT_DIR__ . '/config.inc.php', 'ab'); - fwrite($handle, ' -/** 初始化时区 */ -Typecho_Date::setTimezoneOffset($options->timezone); -'); - fclose($handle); - } else { - throw new Typecho_Exception(_t('config.inc.php 文件无法写入, 请将它的权限设置为可写')); - } - } - - /** - * 升级至9.2.3 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_5r9_2_3($db, $options) - { - /** 转换评论 */ - $i = 1; - - while (true) { - $result = $db->query($db->select('coid', 'text')->from('table.comments') - ->order('coid', Typecho_Db::SORT_ASC)->page($i, 100)); - $j = 0; - - while ($row = $db->fetchRow($result)) { - $text = preg_replace("/\s*\s*/i", "\n", $row['text']); - - $db->query($db->update('table.comments') - ->rows(array('text' => $text)) - ->where('coid = ?', $row['coid'])); - - $j ++; - unset($text); - unset($row); - } - - if ($j < 100) { - break; - } - - $i ++; - unset($result); - } - } - - /** - * 升级至9.2.18 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_5r9_2_18($db, $options) - { - /** 升级编辑器接口 */ - $db->query($db->update('table.options') - ->rows(array('value' => 350)) - ->where('name = ?', 'editorSize')); - } - - /** - * 升级至9.2.25 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_5r9_2_25($db, $options) - { - /** 升级编辑器接口 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'useRichEditor', 'user' => 0, 'value' => 1))); - } - - /** - * 升级至9.4.3 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_6r9_4_3($db, $options) - { - /** 修改数据库字段 */ - $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); - - //删除老数据 - try { - switch (true) { - case false !== strpos($adapterName, 'Mysql'): - $db->query('ALTER TABLE `' . $prefix . 'users` DROP `meta`', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'Pgsql'): - $db->query('ALTER TABLE "' . $prefix . 'users" DROP COLUMN "meta"', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'SQLite'): - $uuid = uniqid(); - $db->query('CREATE TABLE ' . $prefix . 'users_' . $uuid . ' ( "uid" INTEGER NOT NULL PRIMARY KEY, - "name" varchar(32) default NULL , - "password" varchar(64) default NULL , - "mail" varchar(200) default NULL , - "url" varchar(200) default NULL , - "screenName" varchar(32) default NULL , - "created" int(10) default \'0\' , - "activated" int(10) default \'0\' , - "logged" int(10) default \'0\' , - "group" varchar(16) default \'visitor\' , - "authCode" varchar(64) default NULL)', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'users_' . $uuid . ' ("uid", "name", "password", "mail", "url" - , "screenName", "created", "activated", "logged", "group", "authCode") SELECT "uid", "name", "password", "mail", "url" - , "screenName", "created", "activated", "logged", "group", "authCode" FROM ' . $prefix . 'users', Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'users', Typecho_Db::WRITE); - $db->query('CREATE TABLE ' . $prefix . 'users ( "uid" INTEGER NOT NULL PRIMARY KEY, - "name" varchar(32) default NULL , - "password" varchar(64) default NULL , - "mail" varchar(200) default NULL , - "url" varchar(200) default NULL , - "screenName" varchar(32) default NULL , - "created" int(10) default \'0\' , - "activated" int(10) default \'0\' , - "logged" int(10) default \'0\' , - "group" varchar(16) default \'visitor\' , - "authCode" varchar(64) default NULL)', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'users SELECT * FROM ' . $prefix . 'users_' . $uuid, Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'users_' . $uuid, Typecho_Db::WRITE); - $db->query('CREATE UNIQUE INDEX ' . $prefix . 'users_name ON ' . $prefix . 'users ("name")', Typecho_Db::WRITE); - $db->query('CREATE UNIQUE INDEX ' . $prefix . 'users_mail ON ' . $prefix . 'users ("mail")', Typecho_Db::WRITE); - - break; - - default: - break; - } - } catch (Typecho_Db_Exception $e) { - //do nothing - } - - //将slug字段长度增加到200 - try { - switch (true) { - case false !== strpos($adapterName, 'Mysql'): - $db->query("ALTER TABLE `" . $prefix . "contents` MODIFY COLUMN `slug` varchar(200)", Typecho_Db::WRITE); - $db->query("ALTER TABLE `" . $prefix . "metas` MODIFY COLUMN `slug` varchar(200)", Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'Pgsql'): - $db->query('ALTER TABLE "' . $prefix . 'contents" ALTER COLUMN "slug" TYPE varchar(200)', Typecho_Db::WRITE); - $db->query('ALTER TABLE "' . $prefix . 'metas" ALTER COLUMN "slug" TYPE varchar(200)', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'SQLite'): - $uuid = uniqid(); - $db->query('CREATE TABLE ' . $prefix . 'contents' . $uuid . ' ( "cid" INTEGER NOT NULL PRIMARY KEY, - "title" varchar(200) default NULL , - "slug" varchar(200) default NULL , - "created" int(10) default \'0\' , - "modified" int(10) default \'0\' , - "text" text , - "order" int(10) default \'0\' , - "authorId" int(10) default \'0\' , - "template" varchar(32) default NULL , - "type" varchar(16) default \'post\' , - "status" varchar(16) default \'publish\' , - "password" varchar(32) default NULL , - "commentsNum" int(10) default \'0\' , - "allowComment" char(1) default \'0\' , - "allowPing" char(1) default \'0\' , - "allowFeed" char(1) default \'0\' )', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'contents' . $uuid . ' SELECT * FROM ' . $prefix . 'contents', Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'contents', Typecho_Db::WRITE); - $db->query('CREATE TABLE ' . $prefix . 'contents ( "cid" INTEGER NOT NULL PRIMARY KEY, - "title" varchar(200) default NULL , - "slug" varchar(200) default NULL , - "created" int(10) default \'0\' , - "modified" int(10) default \'0\' , - "text" text , - "order" int(10) default \'0\' , - "authorId" int(10) default \'0\' , - "template" varchar(32) default NULL , - "type" varchar(16) default \'post\' , - "status" varchar(16) default \'publish\' , - "password" varchar(32) default NULL , - "commentsNum" int(10) default \'0\' , - "allowComment" char(1) default \'0\' , - "allowPing" char(1) default \'0\' , - "allowFeed" char(1) default \'0\' )', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'contents SELECT * FROM ' . $prefix . 'contents' . $uuid, Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'contents' . $uuid, Typecho_Db::WRITE); - $db->query('CREATE UNIQUE INDEX ' . $prefix . 'contents_slug ON ' . $prefix . 'contents ("slug")', Typecho_Db::WRITE); - $db->query('CREATE INDEX ' . $prefix . 'contents_created ON ' . $prefix . 'contents ("created")', Typecho_Db::WRITE); - - $db->query('CREATE TABLE ' . $prefix . 'metas' . $uuid . ' ( "mid" INTEGER NOT NULL PRIMARY KEY, - "name" varchar(200) default NULL , - "slug" varchar(200) default NULL , - "type" varchar(32) NOT NULL , - "description" varchar(200) default NULL , - "count" int(10) default \'0\' , - "order" int(10) default \'0\' )', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'metas' . $uuid . ' SELECT * FROM ' . $prefix . 'metas', Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'metas', Typecho_Db::WRITE); - $db->query('CREATE TABLE ' . $prefix . 'metas ( "mid" INTEGER NOT NULL PRIMARY KEY, - "name" varchar(200) default NULL , - "slug" varchar(200) default NULL , - "type" varchar(32) NOT NULL , - "description" varchar(200) default NULL , - "count" int(10) default \'0\' , - "order" int(10) default \'0\' )', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'metas SELECT * FROM ' . $prefix . 'metas' . $uuid, Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'metas' . $uuid, Typecho_Db::WRITE); - $db->query('CREATE INDEX ' . $prefix . 'metas_slug ON ' . $prefix . 'metas ("slug")', Typecho_Db::WRITE); - - break; - - default: - break; - } - } catch (Typecho_Db_Exception $e) { - //do nothing - } - } - - /** - * 升级至9.4.21 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_6r9_4_21($db, $options) - { - //创建上传目录 - $uploadDir = Typecho_Common::url(Widget_Upload::UPLOAD_PATH, __TYPECHO_ROOT_DIR__); - if (is_dir($uploadDir)) { - if (!is_writeable($uploadDir)) { - if (!@chmod($uploadDir, 0644)) { - throw new Typecho_Widget_Exception(_t('上传目录无法写入, 请手动将安装目录下的 %s 目录的权限设置为可写然后继续升级', Widget_Upload::UPLOAD_PATH)); - } - } - } else { - if (!@mkdir($uploadDir, 0644)) { - throw new Typecho_Widget_Exception(_t('上传目录无法创建, 请手动创建安装目录下的 %s 目录, 并将它的权限设置为可写然后继续升级', Widget_Upload::UPLOAD_PATH)); - } - } - - /** 增加自定义主页 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'customHomePage', 'user' => 0, 'value' => 0))); - - /** 增加文件上传散列函数 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'uploadHandle', 'user' => 0, 'value' => 'a:2:{i:0;s:13:"Widget_Upload";i:1;s:12:"uploadHandle";}'))); - - /** 增加文件删除函数 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'deleteHandle', 'user' => 0, 'value' => 'a:2:{i:0;s:13:"Widget_Upload";i:1;s:12:"deleteHandle";}'))); - - /** 增加文件展现散列函数 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'attachmentHandle', 'user' => 0, 'value' => 'a:2:{i:0;s:13:"Widget_Upload";i:1;s:16:"attachmentHandle";}'))); - - /** 增加文件扩展名 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'attachmentTypes', 'user' => 0, 'value' => '*.jpg;*.gif;*.png;*.zip;*.tar.gz'))); - - /** 增加路由 */ - $routingTable = $options->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $pre = array_slice($routingTable, 0, 2); - $next = array_slice($routingTable, 2); - - $routingTable = array_merge($pre, array('attachment' => - array ( - 'url' => '/attachment/[cid:digital]/', - 'widget' => 'Widget_Archive', - 'action' => 'render', - )), $next); - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); - } - - /** - * 升级至9.6.1 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_6r9_6_1($db, $options) - { - /** 去掉所见即所得编辑器 */ - $db->query($db->delete('table.options') - ->where('name = ?', 'useRichEditor')); - - /** 修正自动保存值 */ - $db->query($db->update('table.options') - ->rows(array('value' => 0)) - ->where('name = ?', 'autoSave')); - - /** 增加堆楼楼层数目限制 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsMaxNestingLevels', 'user' => 0, 'value' => 5))); - } - - /** - * 升级至9.6.16 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_6_16($db, $options) - { - /** 增加附件handle */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'modifyHandle', 'value' => 'a:2:{i:0;s:13:"Widget_Upload";i:1;s:12:"modifyHandle";}'))); - - /** 增加附件handle */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'attachmentDataHandle', 'value' => 'a:2:{i:0;s:13:"Widget_Upload";i:1;s:20:"attachmentDataHandle";}'))); - - /** 转换附件 */ - $i = 1; - - while (true) { - $result = $db->query($db->select('cid', 'text')->from('table.contents') - ->where('type = ?', 'attachment') - ->order('cid', Typecho_Db::SORT_ASC)->page($i, 100)); - $j = 0; - - while ($row = $db->fetchRow($result)) { - $attachment = unserialize($row['text']); - $attachment['modifyHandle'] = array('Widget_Upload', 'modifyHandle'); - $attachment['attachmentDataHandle'] = array('Widget_Upload', 'attachmentDataHandle'); - - $db->query($db->update('table.contents') - ->rows(array('text' => serialize($attachment))) - ->where('cid = ?', $row['cid'])); - - $j ++; - unset($text); - unset($row); - } - - if ($j < 100) { - break; - } - - $i ++; - unset($result); - } - } - - /** - * 升级至9.6.16.1 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_6_16_1($db, $options) - { - //修改action路由 - $routingTable = $options->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $routingTable['do'] = array ( - 'url' => '/action/[action:alpha]', - 'widget' => 'Widget_Do', - 'action' => 'action' - ); - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); - - //干掉垃圾数据 - $db->query($db->update('table.options') - ->rows(array('value' => 'a:0:{}')) - ->where('name = ?', 'actionTable')); - } - - /** - * 升级至9.7.2 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_7_2($db, $options) - { - /** 增加默认内容格式 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'contentType', 'user' => 0, 'value' => 'text/html'))); - - /** 增加gzip开关 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'gzip', 'user' => 0, 'value' => 0))); - - - if(is_writeable(__TYPECHO_ROOT_DIR__ . '/config.inc.php')) { - - $contents = file_get_contents(__TYPECHO_ROOT_DIR__ . '/config.inc.php'); - $contents = preg_replace("/Typecho_Common::init([^;]+);/is", "Typecho_Common::init(array( - 'autoLoad' => true, - 'exception' => 'Widget_ExceptionHandle', - 'gpc' => true -));", $contents); - $contents = preg_replace("/\s*(\/[^\/]+\/)?\s*Typecho_Widget::widget([^;]+);/is", '', $contents); - $contents = preg_replace("/\s*(\/[^\/]+\/)?\s*Typecho_Router::setRoutes([^;]+);/is", '', $contents); - $contents = preg_replace("/\s*(\/[^\/]+\/)?\s*Typecho_Plugin::init([^;]+);/is", '', $contents); - $contents = preg_replace("/\s*(\/[^\/]+\/)?\s*Typecho_Date::setTimezoneOffset([^;]+);/is", '', $contents); - file_put_contents(__TYPECHO_ROOT_DIR__ . '/config.inc.php', $contents); - - } else { - /** 升级提示 */ - return _t('建议您在升级到 Typecho 0.7/9.7.2 以后的版本后, 立刻执行以下优化步骤'); - } - } - - /** - * 升级至9.9.2 - * 修改contents表的text字段类型为longtext(仅限mysql, pgsql和sqlite都是不限制长度的) - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_9_2($db, $options) - { - $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); - - if (false !== strpos($adapterName, 'Mysql')) { - $db->query("ALTER TABLE `{$prefix}contents` CHANGE `text` `text` LONGTEXT NULL DEFAULT NULL COMMENT '内容文字'", Typecho_Db::WRITE); - } - } - - /** - * 升级至9.9.15 - * 优化路由表结构 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_9_15($db, $options) - { - /** 增加路由 */ - $routingTable = $options->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $do = $routingTable['do']; - unset($routingTable['do']); - - $pre = array_slice($routingTable, 0, 1); - $next = array_slice($routingTable, 1); - - $routingTable = array_merge($pre, array('do' => $do), $next); - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); - } - - /** - * 升级至9.9.22 - * 此升级用于修复从0.6升级时损坏的路由表 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_9_22($db, $options) - { - /** 修改路由 */ - $routingTable = $options->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $routingTable['do'] = array ( - 'url' => '/action/[action:alpha]', - 'widget' => 'Widget_Do', - 'action' => 'action' - ); - - $do = $routingTable['do']; - unset($routingTable['do']); - - $pre = array_slice($routingTable, 0, 1); - $next = array_slice($routingTable, 1); - - $routingTable = array_merge($pre, array('do' => $do), $next); - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); - } - - /** - * 升级至9.9.27 - * 增加按作者归档 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_9_27($db, $options) - { - /** 修改路由 */ - $routingTable = $options->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $pre = array_slice($routingTable, 0, 6); - $next = array_slice($routingTable, 6); - $next_pre = array_slice($next, 0, 5); - $next_next = array_slice($next, 5); - - $author = array ( - 'url' => '/author/[uid:digital]/', - 'widget' => 'Widget_Archive', - 'action' => 'render', - ); - - $author_page = array ( - 'url' => '/author/[uid:digital]/[page:digital]/', - 'widget' => 'Widget_Archive', - 'action' => 'render', - ); - - $routingTable = array_merge($pre, array('author' => $author), $next_pre, - array('author_page' => $author_page), $next_next); - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); - } - - /** - * 升级至9.10.16 - * 增加评论分页 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_10_16($db, $options) - { - /** 修改路由 */ - $routingTable = $options->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $pre = array_slice($routingTable, 0, 20); - $next = array_slice($routingTable, 20); - - $commentPage = array ( - 'url' => '[permalink:string]/[commentType:alpha]-page-[commentPage:digital]', - 'widget' => 'Widget_Archive', - 'action' => 'render', - ); - - $routingTable = array_merge($pre, array('comment_page' => $commentPage), $next); - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); - } - - /** - * 升级至9.10.16 - * 增加评论分页 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_10_20($db, $options) - { - /** 修改数据库字段 */ - $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); - - switch (true) { - case false !== strpos($adapterName, 'Mysql'): - $db->query('ALTER TABLE `' . $prefix . 'contents` ADD `parent` INT(10) UNSIGNED NULL DEFAULT \'0\'', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'Pgsql'): - $db->query('ALTER TABLE "' . $prefix . 'contents" ADD COLUMN "parent" INT NULL DEFAULT \'0\'', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'SQLite'): - $uuid = uniqid(); - $db->query('CREATE TABLE ' . $prefix . 'contents_tmp ( "cid" INTEGER NOT NULL PRIMARY KEY, -"title" varchar(200) default NULL , -"slug" varchar(200) default NULL , -"created" int(10) default \'0\' , -"modified" int(10) default \'0\' , -"text" text , -"order" int(10) default \'0\' , -"authorId" int(10) default \'0\' , -"template" varchar(32) default NULL , -"type" varchar(16) default \'post\' , -"status" varchar(16) default \'publish\' , -"password" varchar(32) default NULL , -"commentsNum" int(10) default \'0\' , -"allowComment" char(1) default \'0\' , -"allowPing" char(1) default \'0\' , -"allowFeed" char(1) default \'0\' , -"parent" int(10) default \'0\' )', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'contents_tmp ("cid", "title", "slug", "created", "modified" - , "text", "order", "authorId", "template", "type", "status", "password", "commentsNum", "allowComment", - "allowPing", "allowFeed", "parent") SELECT "cid", "title", "slug", "created", "modified" - , "text", "order", "authorId", "template", "type", "status", "password", "commentsNum", "allowComment", - "allowPing", "allowFeed", "parent" FROM ' . $prefix . 'contents', Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'contents', Typecho_Db::WRITE); - $db->query('CREATE TABLE ' . $prefix . 'contents ( "cid" INTEGER NOT NULL PRIMARY KEY, -"title" varchar(200) default NULL , -"slug" varchar(200) default NULL , -"created" int(10) default \'0\' , -"modified" int(10) default \'0\' , -"text" text , -"order" int(10) default \'0\' , -"authorId" int(10) default \'0\' , -"template" varchar(32) default NULL , -"type" varchar(16) default \'post\' , -"status" varchar(16) default \'publish\' , -"password" varchar(32) default NULL , -"commentsNum" int(10) default \'0\' , -"allowComment" char(1) default \'0\' , -"allowPing" char(1) default \'0\' , -"allowFeed" char(1) default \'0\' , -"parent" int(10) default \'0\' )', Typecho_Db::WRITE); - $db->query('INSERT INTO ' . $prefix . 'contents SELECT * FROM ' . $prefix . 'contents_tmp', Typecho_Db::WRITE); - $db->query('DROP TABLE ' . $prefix . 'contents_tmp', Typecho_Db::WRITE); - - break; - - default: - break; - } - - $db->query($db->update('table.contents')->expression('parent', 'order') - ->where('type = ?', 'attachment')); - - $db->query($db->update('table.contents')->rows(array('order' => 0)) - ->where('type = ?', 'attachment')); - } - - /** - * 升级至9.10.31 - * 修正附件 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_7r9_10_31($db, $options) - { - $db->query($db->update('table.contents')->rows(array('status' => 'publish')) - ->where('type = ?', 'attachment')); - } - - /** - * 升级至9.11.25 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_8r9_11_25($db, $options) - { - /** 增加若干选项 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPageBreak', 'user' => 0, 'value' => 0))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsThreaded', 'user' => 0, 'value' => 1))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPageSize', 'user' => 0, 'value' => 20))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPageDisplay', 'user' => 0, 'value' => 'last'))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsOrder', 'user' => 0, 'value' => 'ASC'))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsCheckReferer', 'user' => 0, 'value' => 1))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsAutoClose', 'user' => 0, 'value' => 0))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPostIntervalEnable', 'user' => 0, 'value' => 1))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsPostInterval', 'user' => 0, 'value' => 60))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsShowCommentOnly', 'user' => 0, 'value' => 0))); - - /** 修改路由 */ - $routingTable = $options->routingTable; - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - if (isset($routingTable['comment_page'])) { - $routingTable['comment_page'] = array ( - 'url' => '[permalink:string]/comment-page-[commentPage:digital]', - 'widget' => 'Widget_Archive', - 'action' => 'render', - ); - } else { - $pre = array_slice($routingTable, 0, 20); - $next = array_slice($routingTable, 20); - - $commentPage = array ( - 'url' => '[permalink:string]/comment-page-[commentPage:digital]', - 'widget' => 'Widget_Archive', - 'action' => 'render', - ); - - $routingTable = array_merge($pre, array('comment_page' => $commentPage), $next); - } - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($routingTable))) - ->where('name = ?', 'routingTable')); - } - - /** - * 升级至9.12.11 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_8r9_12_11($db, $options) - { - /** 删除无用选项 */ - $db->query($db->delete('table.options') - ->where('name = ? OR name = ? OR name = ? OR name = ? OR name = ? OR name = ? OR name = ?', 'customHomePage', 'uploadHandle', - 'deleteHandle', 'modifyHandle', 'attachmentHandle', 'attachmentDataHandle', 'gzip')); - - // 增加自定义首页 - $db->query($db->insert('table.options') - ->rows(array('name' => 'frontPage', 'user' => 0, 'value' => 'recent'))); - } - - /** - * 升级至10.2.27 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_8r10_2_27($db, $options) - { - /** 增加若干选项 */ - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsAvatar', 'user' => 0, 'value' => 1))); - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsAvatarRating', 'user' => 0, 'value' => 'G'))); - - //更新扩展 - if (NULL != $options->attachmentTypes) { - $attachmentTypes = array_map('trim', explode(';', $options->attachmentTypes)); - $attachmentTypesResult = array(); - - foreach ($attachmentTypes as $type) { - $type = trim($type, '*.'); - if (!empty($type)) { - $attachmentTypesResult[] = $type; - } - } - - if (!empty($attachmentTypesResult)) { - $db->query($db->update('table.options') - ->rows(array('value' => implode(',', $attachmentTypesResult))) - ->where('name = ?', 'attachmentTypes')); - } - } - } - - /** - * 升级至10.3.8 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_8r10_3_8($db, $options) - { - /** 删除无用选项 */ - $db->query($db->delete('table.options') - ->where('name = ?', 'commentsAvatarSize')); - } - - /** - * 升级至10.5.17 - * - * @access public - * @param Typecho_Db $db 数据库对象 - * @param Typecho_Widget $options 全局信息组件 - * @return void - */ - public static function v0_8r10_5_17($db, $options) - { - Typecho_Widget::widget('Widget_Themes_Edit', NULL, 'change=' . $options->theme, false)->action(); - } - - - /** - * 升级至13.10.18 - * - * @param mixed $db - * @param mixed $options - * @static - * @access public - * @return void - */ - public static function v0_9r13_10_18($db, $options) - { - // 增加markdown - $db->query($db->insert('table.options') - ->rows(array('name' => 'markdown', 'user' => 0, 'value' => 0))); - - // 更新原来被搞乱的草稿 - $db->query($db->update('table.contents') - ->rows(array( - 'type' => 'post_draft', - 'status' => 'publish' - )) - ->where('type = ? AND status = ?', 'post', 'draft')); - - $db->query($db->update('table.contents') - ->rows(array( - 'type' => 'page_draft', - 'status' => 'publish' - )) - ->where('type = ? AND status = ?', 'page', 'draft')); - } - - /** - * v0_9r13_11_17 - * - * @param mixed $db - * @param mixed $options - * @static - * @access public - * @return void - */ - public static function v0_9r13_11_17($db, $options) - { - Helper::addRoute('archive', '/blog/', 'Widget_Archive', 'render', 'index'); - Helper::addRoute('archive_page', '/blog/[page:digital]/', 'Widget_Archive', 'render', 'index_page'); - $db->query($db->insert('table.options') - ->rows(array('name' => 'frontArchive', 'user' => 0, 'value' => 0))); - } - - /** - * v0_9r13_11_24 - * - * @param mixed $db - * @param mixed $options - * @static - * @access public - * @return void - */ - public static function v0_9r13_11_24($db, $options) - { - /* 增加数据表 */ - $adapterName = $db->getAdapterName(); - $prefix = $db->getPrefix(); - - switch (true) { - case false !== strpos($adapterName, 'Mysql'): - $config = $db->getConfig(); - $db->query("CREATE TABLE `{$prefix}fields` ( - `cid` int(10) unsigned NOT NULL, - `name` varchar(200) NOT NULL, - `type` varchar(8) default 'str', - `str_value` text, - `int_value` int(10) default '0', - `float_value` float default '0', - PRIMARY KEY (`cid`,`name`), - KEY `int_value` (`int_value`), - KEY `float_value` (`float_value`) -) ENGINE=MyISAM DEFAULT CHARSET=" . $config[0]->charset, Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'Pgsql'): - $db->query('CREATE TABLE "' . $prefix . 'fields" ("cid" INT NOT NULL, - "name" VARCHAR(200) NOT NULL, - "type" VARCHAR(8) NULL DEFAULT \'str\', - "str_value" TEXT NULL DEFAULT NULL, - "int_value" INT NULL DEFAULT \'0\', - "float_value" REAL NULL DEFAULT \'0\', - PRIMARY KEY ("cid","name") -)', Typecho_Db::WRITE); - $db->query('CREATE INDEX "' . $prefix . 'fields_int_value" ON "' . $prefix . 'fields" ("int_value")', Typecho_Db::WRITE); - $db->query('CREATE INDEX "' . $prefix . 'fields_float_value" ON "' . $prefix . 'fields" ("float_value")', Typecho_Db::WRITE); - break; - - case false !== strpos($adapterName, 'SQLite'): - $db->query('CREATE TABLE "' . $prefix . 'fields" ("cid" INTEGER NOT NULL, - "name" varchar(200) NOT NULL, - "type" varchar(8) default \'str\', - "str_value" text, - "int_value" int(10) default \'0\', - "float_value" real default \'0\' -)', Typecho_Db::WRITE); - $db->query('CREATE UNIQUE INDEX ' . $prefix . 'fields_cid_name ON ' . $prefix . 'fields ("cid", "name")', Typecho_Db::WRITE); - $db->query('CREATE INDEX ' . $prefix . 'fields_int_value ON ' . $prefix . 'fields ("int_value")', Typecho_Db::WRITE); - $db->query('CREATE INDEX ' . $prefix . 'fields_float_value ON ' . $prefix . 'fields ("float_value")', Typecho_Db::WRITE); - - break; - - default: - break; - } - - $db->query($db->insert('table.options') - ->rows(array('name' => 'commentsMarkdown', 'user' => 0, 'value' => 0))); - } - - /** - * v0_9r13_11_24 - * - * @param mixed $db - * @param mixed $options - * @access public - * @return void - */ - public function v0_9r13_12_6($db, $options) - { - $frontArchive = $db->fetchRow($db->select()->from('table.options')->where('name = ?', 'frontArchive')); - if (empty($frontArchive)) { - $db->query($db->insert('table.options') - ->rows(array('name' => 'frontArchive', 'user' => 0, 'value' => 0))); - } - } -} - diff --git a/php/typecho09/var/Widget/Abstract.php b/php/typecho09/var/Widget/Abstract.php deleted file mode 100644 index 91b9f1882..000000000 --- a/php/typecho09/var/Widget/Abstract.php +++ /dev/null @@ -1,111 +0,0 @@ -db = Typecho_Db::get(); - - /** 初始化常用组件 */ - $this->options = $this->widget('Widget_Options'); - $this->user = $this->widget('Widget_User'); - } - - /** - * 查询方法 - * - * @access public - * @return Typecho_Db_Query - */ - abstract public function select(); - - /** - * 获得所有记录数 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - abstract public function size(Typecho_Db_Query $condition); - - /** - * 增加记录方法 - * - * @access public - * @param array $rows 字段对应值 - * @return integer - */ - abstract public function insert(array $rows); - - /** - * 更新记录方法 - * - * @access public - * @param array $rows 字段对应值 - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - abstract public function update(array $rows, Typecho_Db_Query $condition); - - /** - * 删除记录方法 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - abstract public function delete(Typecho_Db_Query $condition); -} diff --git a/php/typecho09/var/Widget/Abstract/Comments.php b/php/typecho09/var/Widget/Abstract/Comments.php deleted file mode 100644 index 21bf8acd3..000000000 --- a/php/typecho09/var/Widget/Abstract/Comments.php +++ /dev/null @@ -1,439 +0,0 @@ -db->fetchRow($this->widget('Widget_Abstract_Contents')->select() - ->where('table.contents.cid = ?', $this->cid) - ->limit(1), array($this->widget('Widget_Abstract_Contents'), 'filter')); - } - - /** - * 获取当前评论标题 - * - * @access protected - * @return string - */ - protected function ___title() - { - return $this->parentContent['title']; - } - - /** - * 获取当前评论链接 - * - * @access protected - * @return string - */ - protected function ___permalink() - { - - if ($this->options->commentsPageBreak && 'approved' == $this->status) { - - $coid = $this->coid; - $parent = $this->parent; - - while ($parent > 0 && $this->options->commentsThreaded) { - $parentRows = $this->db->fetchRow($this->db->select('parent')->from('table.comments') - ->where('coid = ? AND status = ?', $parent, 'approved')->limit(1)); - - if (!empty($parentRows)) { - $coid = $parent; - $parent = $parentRows['parent']; - } else { - break; - } - } - - $select = $this->db->select('coid', 'parent') - ->from('table.comments')->where('cid = ? AND status = ?', $this->parentContent['cid'], 'approved') - ->where('coid ' . ('DESC' == $this->options->commentsOrder ? '>=' : '<=') . ' ?', $coid) - ->order('coid', Typecho_Db::SORT_ASC); - - if ($this->options->commentsShowCommentOnly) { - $select->where('type = ?', 'comment'); - } - - $comments = $this->db->fetchAll($select); - - $commentsMap = array(); - $total = 0; - - foreach ($comments as $comment) { - $commentsMap[$comment['coid']] = $comment['parent']; - - if (0 == $comment['parent'] || !isset($commentsMap[$comment['parent']])) { - $total ++; - } - } - - $currentPage = ceil($total / $this->options->commentsPageSize); - - $pageRow = array('permalink' => $this->parentContent['pathinfo'], 'commentPage' => $currentPage); - return Typecho_Router::url('comment_page', - $pageRow, $this->options->index) . '#' . $this->theId; - } - - return $this->parentContent['permalink'] . '#' . $this->theId; - } - - /** - * 获取当前评论内容 - * - * @access protected - * @return string - */ - protected function ___content() - { - $text = $this->parentContent['hidden'] ? _t('内容被隐藏') : $this->text; - - $text = $this->pluginHandle(__CLASS__)->trigger($plugged)->content($text, $this); - if (!$plugged) { - $text = $this->options->commentsMarkdown ? MarkdownExtraExtended::defaultTransform($text) - : Typecho_Common::cutParagraph($text); - } - - $text = $this->pluginHandle(__CLASS__)->contentEx($text, $this); - return Typecho_Common::stripTags($text, '


    ' . $this->options->commentsHTMLTagAllowed); - } - - /** - * 输出词义化日期 - * - * @access protected - * @return string - */ - protected function ___dateWord() - { - return $this->date->word(); - } - - /** - * 锚点id - * - * @access protected - * @return string - */ - protected function ___theId() - { - return $this->type . '-' . $this->coid; - } - - /** - * 获取查询对象 - * - * @access public - * @return Typecho_Db_Query - */ - public function select() - { - return $this->db->select('table.comments.coid', 'table.comments.cid', 'table.comments.author', 'table.comments.mail', 'table.comments.url', 'table.comments.ip', - 'table.comments.authorId', 'table.comments.ownerId', 'table.comments.agent', 'table.comments.text', 'table.comments.type', 'table.comments.status', 'table.comments.parent', 'table.comments.created') - ->from('table.comments'); - } - - /** - * 增加评论 - * - * @access public - * @param array $comment 评论结构数组 - * @return integer - */ - public function insert(array $comment) - { - /** 构建插入结构 */ - $insertStruct = array( - 'cid' => $comment['cid'], - 'created' => empty($comment['created']) ? $this->options->gmtTime : $comment['created'], - 'author' => empty($comment['author']) ? NULL : $comment['author'], - 'authorId' => empty($comment['authorId']) ? 0 : $comment['authorId'], - 'ownerId' => empty($comment['ownerId']) ? 0 : $comment['ownerId'], - 'mail' => empty($comment['mail']) ? NULL : $comment['mail'], - 'url' => empty($comment['url']) ? NULL : $comment['url'], - 'ip' => empty($comment['ip']) ? $this->request->getIp() : $comment['ip'], - 'agent' => empty($comment['agent']) ? $_SERVER["HTTP_USER_AGENT"] : $comment['agent'], - 'text' => empty($comment['text']) ? NULL : $comment['text'], - 'type' => empty($comment['type']) ? 'comment' : $comment['type'], - 'status' => empty($comment['status']) ? 'approved' : $comment['status'], - 'parent' => empty($comment['parent']) ? 0 : $comment['parent'], - ); - - if (!empty($comment['coid'])) { - $insertStruct['coid'] = $comment['coid']; - } - - /** 首先插入部分数据 */ - $insertId = $this->db->query($this->db->insert('table.comments')->rows($insertStruct)); - - /** 更新评论数 */ - $num = $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num'))->from('table.comments') - ->where('status = ? AND cid = ?', 'approved', $comment['cid']))->num; - - $this->db->query($this->db->update('table.contents')->rows(array('commentsNum' => $num)) - ->where('cid = ?', $comment['cid'])); - - return $insertId; - } - - /** - * 更新评论 - * - * @access public - * @param array $comment 评论结构数组 - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function update(array $comment, Typecho_Db_Query $condition) - { - /** 获取内容主键 */ - $updateCondition = clone $condition; - $updateComment = $this->db->fetchObject($condition->select('cid')->from('table.comments')->limit(1)); - - if ($updateComment) { - $cid = $updateComment->cid; - } else { - return false; - } - - /** 构建插入结构 */ - $preUpdateStruct = array( - 'author' => empty($comment['author']) ? NULL : $comment['author'], - 'mail' => empty($comment['mail']) ? NULL : $comment['mail'], - 'url' => empty($comment['url']) ? NULL : $comment['url'], - 'text' => empty($comment['text']) ? NULL : $comment['text'], - 'status' => empty($comment['status']) ? 'approved' : $comment['status'], - ); - - $updateStruct = array(); - foreach ($comment as $key => $val) { - if ((array_key_exists($key, $preUpdateStruct))) { - $updateStruct[$key] = $preUpdateStruct[$key]; - } - } - - /** 更新创建时间 */ - if (!empty($comment['created'])) { - $updateStruct['created'] = $comment['created']; - } - - /** 更新评论数据 */ - $updateRows = $this->db->query($updateCondition->update('table.comments')->rows($updateStruct)); - - /** 更新评论数 */ - $num = $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num'))->from('table.comments') - ->where('status = ? AND cid = ?', 'approved', $cid))->num; - - $this->db->query($this->db->update('table.contents')->rows(array('commentsNum' => $num)) - ->where('cid = ?', $cid)); - - return $updateRows; - } - - /** - * 删除数据 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function delete(Typecho_Db_Query $condition) - { - /** 获取内容主键 */ - $deleteCondition = clone $condition; - $deleteComment = $this->db->fetchObject($condition->select('cid')->from('table.comments')->limit(1)); - - if ($deleteComment) { - $cid = $deleteComment->cid; - } else { - return false; - } - - /** 删除评论数据 */ - $deleteRows = $this->db->query($deleteCondition->delete('table.comments')); - - /** 更新评论数 */ - $num = $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num'))->from('table.comments') - ->where('status = ? AND cid = ?', 'approved', $cid))->num; - - $this->db->query($this->db->update('table.contents')->rows(array('commentsNum' => $num)) - ->where('cid = ?', $cid)); - - return $deleteRows; - } - - /** - * 评论是否可以被修改 - * - * @access public - * @param Typecho_Db_Query $condition 条件 - * @return mixed - */ - public function commentIsWriteable(Typecho_Db_Query $condition = NULL) - { - if (empty($condition)) { - if ($this->have() && ($this->user->pass('editor', true) || $this->ownerId == $this->user->uid)) { - return true; - } - } else { - $post = $this->db->fetchRow($condition->select('ownerId')->from('table.comments')->limit(1)); - - if ($post && ($this->user->pass('editor', true) || $post['ownerId'] == $this->user->uid)) { - return true; - } - } - - return false; - } - - /** - * 按照条件计算评论数量 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function size(Typecho_Db_Query $condition) - { - return $this->db->fetchObject($condition->select(array('COUNT(coid)' => 'num'))->from('table.comments'))->num; - } - - /** - * 通用过滤器 - * - * @access public - * @param array $value 需要过滤的行数据 - * @return array - */ - public function filter(array $value) - { - $value['date'] = new Typecho_Date($value['created']); - $value = $this->pluginHandle(__CLASS__)->filter($value, $this); - return $value; - } - - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - return parent::push($value); - } - - /** - * 输出文章发布日期 - * - * @access public - * @param string $format 日期格式 - * @return void - */ - public function date($format = NULL) - { - echo $this->date->format(empty($format) ? $this->options->commentDateFormat : $format); - } - - /** - * 输出作者相关 - * - * @access public - * @param boolean $autoLink 是否自动加上链接 - * @param boolean $noFollow 是否加上nofollow标签 - * @return void - */ - public function author($autoLink = NULL, $noFollow = NULL) - { - $autoLink = (NULL === $autoLink) ? $this->options->commentsShowUrl : $autoLink; - $noFollow = (NULL === $noFollow) ? $this->options->commentsUrlNofollow : $noFollow; - - if ($this->url && $autoLink) { - echo '' , $this->author , ''; - } else { - echo $this->author; - } - } - - /** - * 调用gravatar输出用户头像 - * - * @access public - * @param integer $size 头像尺寸 - * @param string $default 默认输出头像 - * @return void - */ - public function gravatar($size = 32, $default = NULL) - { - if ($this->options->commentsAvatar && 'comment' == $this->type) { - $rating = $this->options->commentsAvatarRating; - - $this->pluginHandle(__CLASS__)->trigger($plugged)->gravatar($size, $rating, $default, $this); - if (!$plugged) { - - if (!empty($this->mail)) { - $mailHash = md5(strtolower($this->mail)); - } - - if ($this->request->isSecure()) { - $host = 'https://secure.gravatar.com'; - } else { - if (empty($this->mail)) { - $host = 'http://0.gravatar.com'; - } else { - $host = sprintf( "http://%d.gravatar.com", (hexdec($mailHash{0}) % 2)); - } - } - - $url = $host . '/avatar/'; - - if (!empty($this->mail)) { - $url .= $mailHash; - } - - $url .= '?s=' . $size; - $url .= '&r=' . $rating; - $url .= '&d=' . $default; - - echo '' .
-                $this->author . ''; - } - } - } - - /** - * 输出评论摘要 - * - * @access public - * @param integer $length 摘要截取长度 - * @param string $trim 摘要后缀 - * @return void - */ - public function excerpt($length = 100, $trim = '...') - { - echo Typecho_Common::subStr(strip_tags($this->content), 0, $length, $trim); - } -} diff --git a/php/typecho09/var/Widget/Abstract/Contents.php b/php/typecho09/var/Widget/Abstract/Contents.php deleted file mode 100644 index 6ce33bd3f..000000000 --- a/php/typecho09/var/Widget/Abstract/Contents.php +++ /dev/null @@ -1,899 +0,0 @@ -db->fetchAll($this->db - ->select()->from('table.metas') - ->join('table.relationships', 'table.relationships.mid = table.metas.mid') - ->where('table.relationships.cid = ?', $this->cid) - ->where('table.metas.type = ?', 'tag'), array($this->widget('Widget_Abstract_Metas'), 'filter')); - } - - /** - * 文章作者 - * - * @access protected - * @return Typecho_Config - */ - protected function ___author() - { - return $this->widget('Widget_Users_Author@' . $this->cid, array('uid' => $this->authorId)); - } - - /** - * 获取词义化日期 - * - * @access protected - * @return void - */ - protected function ___dateWord() - { - return $this->date->word(); - } - - /** - * 获取父id - * - * @access protected - * @return void - */ - protected function ___parentId() - { - return $this->row['parent']; - } - - /** - * 对文章的简短纯文本描述 - * - * @access protected - * @return string - */ - protected function ___description() - { - $plainTxt = str_replace("\n", '', trim(strip_tags($this->excerpt))); - $plainTxt = $plainTxt ? $plainTxt : $this->title; - return Typecho_Common::subStr($plainTxt, 0, 100, '...'); - } - - /** - * ___fields - * - * @access protected - * @return void - */ - protected function ___fields() - { - $fields = array(); - $rows = $this->db->fetchAll($this->db->select()->from('table.fields') - ->where('cid = ?', $this->cid)); - - foreach ($rows as $row) { - $fields[$row['name']] = $row[$row['type'] . '_value']; - } - - return new Typecho_Config($fields); - } - - /** - * 获取文章内容摘要 - * - * @access protected - * @return string - */ - protected function ___excerpt() - { - if ($this->hidden) { - return $this->text; - } - - $content = $this->pluginHandle(__CLASS__)->trigger($plugged)->excerpt($this->text, $this); - if (!$plugged) { - $content = $this->isMarkdown ? MarkdownExtraExtended::defaultTransform($content) - : Typecho_Common::cutParagraph($content); - } - - $contents = explode('', $content); - list($excerpt) = $contents; - - return Typecho_Common::fixHtml($this->pluginHandle(__CLASS__)->excerptEx($excerpt, $this)); - } - - /** - * 获取文章内容 - * - * @access protected - * @return string - */ - protected function ___content() - { - if ($this->hidden) { - return $this->text; - } - - $content = $this->pluginHandle(__CLASS__)->trigger($plugged)->content($this->text, $this); - - if (!$plugged) { - $content = $this->isMarkdown ? MarkdownExtraExtended::defaultTransform($content) - : Typecho_Common::cutParagraph($content); - } - - return $this->pluginHandle(__CLASS__)->contentEx($content, $this); - } - - /** - * 锚点id - * - * @access protected - * @return void - */ - protected function ___theId() - { - return $this->type . '-' . $this->cid; - } - - /** - * 回复框id - * - * @access protected - * @return void - */ - protected function ___respondId() - { - return 'respond-' . $this->theId; - } - - /** - * 评论地址 - * - * @access protected - * @return void - */ - protected function ___commentUrl() - { - /** 生成反馈地址 */ - /** 评论 */ - return Typecho_Router::url('feedback', - array('type' => 'comment', 'permalink' => $this->pathinfo), $this->options->index); - } - - /** - * trackback地址 - * - * @access protected - * @return void - */ - protected function ___trackbackUrl() - { - return Typecho_Router::url('feedback', - array('type' => 'trackback', 'permalink' => $this->pathinfo), $this->options->index); - } - - /** - * 回复地址 - * - * @access protected - * @return void - */ - protected function ___responseUrl() - { - return $this->permalink . '#' . $this->respondId; - } - - /** - * 获取页面偏移 - * - * @access protected - * @param string $column 字段名 - * @param integer $offset 偏移值 - * @param string $type 类型 - * @param string $status 状态值 - * @param integer $authorId 作者 - * @param integer $pageSize 分页值 - * @return integer - */ - protected function getPageOffset($column, $offset, $type, $status = NULL, $authorId = 0, $pageSize = 20) - { - $select = $this->db->select(array('COUNT(table.contents.cid)' => 'num'))->from('table.contents') - ->where("table.contents.{$column} > {$offset}") - ->where("table.contents.type = ?", $type); - - if (!empty($status)) { - $select->where("table.contents.status = ?", $status); - } - - if ($authorId > 0) { - $select->where('table.contents.authorId = ?', $authorId); - } - - $count = $this->db->fetchObject($select)->num + 1; - return ceil($count / $pageSize); - } - - /** - * 获取查询对象 - * - * @access public - * @return Typecho_Db_Query - */ - public function select() - { - return $this->db->select('table.contents.cid', 'table.contents.title', 'table.contents.slug', 'table.contents.created', 'table.contents.authorId', - 'table.contents.modified', 'table.contents.type', 'table.contents.status', 'table.contents.text', 'table.contents.commentsNum', 'table.contents.order', - 'table.contents.template', 'table.contents.password', 'table.contents.allowComment', 'table.contents.allowPing', 'table.contents.allowFeed', - 'table.contents.parent')->from('table.contents'); - } - - /** - * 插入内容 - * - * @access public - * @param array $content 内容数组 - * @return integer - */ - public function insert(array $content) - { - /** 构建插入结构 */ - $insertStruct = array( - 'title' => empty($content['title']) ? NULL : htmlspecialchars($content['title']), - 'created' => empty($content['created']) ? $this->options->gmtTime : $content['created'], - 'modified' => $this->options->gmtTime, - 'text' => empty($content['text']) ? NULL : $content['text'], - 'order' => empty($content['order']) ? 0 : intval($content['order']), - 'authorId' => isset($content['authorId']) ? $content['authorId'] : $this->user->uid, - 'template' => empty($content['template']) ? NULL : $content['template'], - 'type' => empty($content['type']) ? 'post' : $content['type'], - 'status' => empty($content['status']) ? 'publish' : $content['status'], - 'password' => empty($content['password']) ? NULL : $content['password'], - 'commentsNum' => empty($content['commentsNum']) ? 0 : $content['commentsNum'], - 'allowComment' => !empty($content['allowComment']) && 1 == $content['allowComment'] ? 1 : 0, - 'allowPing' => !empty($content['allowPing']) && 1 == $content['allowPing'] ? 1 : 0, - 'allowFeed' => !empty($content['allowFeed']) && 1 == $content['allowFeed'] ? 1 : 0, - 'parent' => empty($content['parent']) ? 0 : intval($content['parent']) - ); - - if (!empty($content['cid'])) { - $insertStruct['cid'] = $content['cid']; - } - - /** 首先插入部分数据 */ - $insertId = $this->db->query($this->db->insert('table.contents')->rows($insertStruct)); - - /** 更新缩略名 */ - if ($insertId > 0) { - $this->applySlug(empty($content['slug']) ? NULL : $content['slug'], $insertId); - } - - return $insertId; - } - - /** - * 更新内容 - * - * @access public - * @param array $content 内容数组 - * @param Typecho_Db_Query $condition 更新条件 - * @return integer - */ - public function update(array $content, Typecho_Db_Query $condition) - { - /** 首先验证写入权限 */ - if (!$this->isWriteable(clone $condition)) { - return false; - } - - /** 构建更新结构 */ - $preUpdateStruct = array( - 'title' => empty($content['title']) ? NULL : htmlspecialchars($content['title']), - 'order' => empty($content['order']) ? 0 : intval($content['order']), - 'text' => empty($content['text']) ? NULL : $content['text'], - 'template' => empty($content['template']) ? NULL : $content['template'], - 'type' => empty($content['type']) ? 'post' : $content['type'], - 'status' => empty($content['status']) ? 'publish' : $content['status'], - 'password' => empty($content['password']) ? NULL : $content['password'], - 'allowComment' => !empty($content['allowComment']) && 1 == $content['allowComment'] ? 1 : 0, - 'allowPing' => !empty($content['allowPing']) && 1 == $content['allowPing'] ? 1 : 0, - 'allowFeed' => !empty($content['allowFeed']) && 1 == $content['allowFeed'] ? 1 : 0, - 'parent' => empty($content['parent']) ? 0 : intval($content['parent']) - ); - - $updateStruct = array(); - foreach ($content as $key => $val) { - if (array_key_exists($key, $preUpdateStruct)) { - $updateStruct[$key] = $preUpdateStruct[$key]; - } - } - - /** 更新创建时间 */ - if (!empty($content['created'])) { - $updateStruct['created'] = $content['created']; - } - - $updateStruct['modified'] = $this->options->gmtTime; - - /** 首先插入部分数据 */ - $updateCondition = clone $condition; - $updateRows = $this->db->query($condition->update('table.contents')->rows($updateStruct)); - - /** 更新缩略名 */ - if ($updateRows > 0 && isset($content['slug'])) { - $this->applySlug(empty($content['slug']) ? NULL : $content['slug'], $condition); - } - - return $updateRows; - } - - /** - * 删除内容 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function delete(Typecho_Db_Query $condition) - { - return $this->db->query($condition->delete('table.contents')); - } - - /** - * 为内容应用缩略名 - * - * @access public - * @param string $slug 缩略名 - * @param mixed $cid 内容id - * @return string - */ - public function applySlug($slug, $cid) - { - if ($cid instanceof Typecho_Db_Query) { - $cid = $this->db->fetchObject($cid->select('cid') - ->from('table.contents')->limit(1))->cid; - } - - /** 生成一个非空的缩略名 */ - $slug = Typecho_Common::slugName($slug, $cid); - $result = $slug; - - /** 对草稿的slug做特殊处理 */ - $draft = $this->db->fetchObject($this->db->select('type', 'parent') - ->from('table.contents')->where('cid = ?', $cid)); - - if ('_draft' == substr($draft->type, -6) && $draft->parent) { - $result = '@' . $result; - } - - - /** 判断是否在数据库中已经存在 */ - $count = 1; - while ($this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents')->where('slug = ? AND cid <> ?', $result, $cid))->num > 0) { - $result = $slug . '-' . $count; - $count ++; - } - - $this->db->query($this->db->update('table.contents')->rows(array('slug' => $result)) - ->where('cid = ?', $cid)); - - return $result; - } - - /** - * 删除自定义字段 - * - * @param integer $cid - * @access public - * @return integer - */ - public function deleteFields($cid) - { - return $this->db->query($this->db->delete('table.contents') - ->where('cid = ?', $cid)); - } - - /** - * 检查字段名是否符合要求 - * - * @param string $name - * @access public - * @return boolean - */ - public function checkFieldName($name) - { - return preg_match("/^[_a-z][_a-z0-9]*$/i", $name); - } - - /** - * 保存自定义字段 - * - * @param array $fields - * @param mixed $cid - * @access public - * @return void - */ - public function applyFields(array $fields, $cid) - { - $exists = array_flip(Typecho_Common::arrayFlatten($this->db->fetchAll($this->db->select('name') - ->from('table.fields')->where('cid = ?', $cid)), 'name')); - - foreach ($fields as $name => $value) { - $type = 'str'; - - if (is_array($value) && 2 == count($value)) { - $type = $value[0]; - $value = $value[1]; - } else if (strpos($name, ':') > 0) { - list ($type, $name) = explode(':', $name, 2); - } - - if (!$this->checkFieldName($name)) { - continue; - } - - $isFieldReadOnly = $this->pluginHandle(__CLASS__)->trigger($plugged)->isFieldReadOnly($name); - if ($plugged && $isFieldReadOnly) { - continue; - } - - if (isset($exists[$name])) { - unset($exists[$name]); - } - - $this->setField($name, $type, $value, $cid); - } - - foreach ($exists as $name => $value) { - $this->db->query($this->db->delete('table.fields') - ->where('cid = ? AND name = ?', $cid, $name)); - } - } - - /** - * 设置单个字段 - * - * @param string $name - * @param string $type - * @param string $value - * @param integer $cid - * @access public - * @return integer - */ - public function setField($name, $type, $value, $cid) - { - if (empty($name) || !$this->checkFieldName($name) - || !in_array($type, array('str', 'int', 'float'))) { - return false; - } - - $exist = $this->db->fetchRow($this->db->select('cid')->from('table.fields') - ->where('cid = ? AND name = ?', $cid, $name)); - - if (empty($exist)) { - return $this->db->query($this->db->insert('table.fields') - ->rows(array( - 'cid' => $cid, - 'name' => $name, - 'type' => $type, - 'str_value' => 'str' == $type ? $value : NULL, - 'int_value' => 'int' == $type ? intval($value) : 0, - 'float_value' => 'float' == $type ? floatval($value) : 0 - ))); - } else { - return $this->db->query($this->db->update('table.fields') - ->rows(array( - 'type' => $type, - 'str_value' => 'str' == $type ? $value : NULL, - 'int_value' => 'int' == $type ? intval($value) : 0, - 'float_value' => 'float' == $type ? floatval($value) : 0 - )) - ->where('cid = ? AND name = ?', $cid, $name)); - } - } - - /** - * 自增一个整形字段 - * - * @param string $name - * @param integer $value - * @param integer $cid - * @access public - * @return integer - */ - public function incrIntField($name, $value, $cid) - { - if (!$this->checkFieldName($name)) { - return false; - } - - $exist = $this->db->fetchRow($this->db->select('type')->from('table.fields') - ->where('cid = ? AND name = ?', $cid, $name)); - $value = intval($value); - - if (empty($exist)) { - return $this->db->query($this->db->insert('table.fields') - ->rows(array( - 'cid' => $cid, - 'name' => $name, - 'type' => 'int', - 'str_value' => NULL, - 'int_value' => $value, - 'float_value' => 0 - ))); - } else { - $struct = array( - 'str_value' => NULL, - 'float_value' => NULL - ); - - if ('int' != $exist['type']) { - $struct['type'] = 'int'; - } - - return $this->db->query($this->db->update('table.fields') - ->rows($struct) - ->expression('int_value', 'int_value ' . ($value >= 0 ? '+' : '') . $value) - ->where('cid = ? AND name = ?', $cid, $name)); - } - } - - /** - * 内容是否可以被修改 - * - * @access public - * @param Typecho_Db_Query $condition 条件 - * @return mixed - */ - public function isWriteable(Typecho_Db_Query $condition) - { - $post = $this->db->fetchRow($condition->select('authorId')->from('table.contents')->limit(1)); - return $post && ($this->user->pass('editor', true) || $post['authorId'] == $this->user->uid); - } - - /** - * 按照条件计算内容数量 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function size(Typecho_Db_Query $condition) - { - return $this->db->fetchObject($condition->select(array('COUNT(table.contents.cid)' => 'num'))->from('table.contents'))->num; - } - - /** - * 获取当前所有自定义模板 - * - * @access public - * @return array - */ - public function getTemplates() - { - $files = glob(__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_THEME_DIR__ . '/' . $this->options->theme . '/*.php'); - $result = array(); - - foreach ($files as $file) { - $info = Typecho_Plugin::parseInfo($file); - $file = basename($file); - - if ('index.php' != $file && 'custom' == $info['title']) { - $result[$file] = $info['description']; - } - } - - return $result; - } - - /** - * 通用过滤器 - * - * @access public - * @param array $value 需要过滤的行数据 - * @return array - */ - public function filter(array $value) - { - /** 取出所有分类 */ - $value['categories'] = $this->db->fetchAll($this->db - ->select()->from('table.metas') - ->join('table.relationships', 'table.relationships.mid = table.metas.mid') - ->where('table.relationships.cid = ?', $value['cid']) - ->where('table.metas.type = ?', 'category') - ->order('table.metas.order', Typecho_Db::SORT_ASC), array($this->widget('Widget_Abstract_Metas'), 'filter')); - - /** 取出第一个分类作为slug条件 */ - $value['category'] = current(Typecho_Common::arrayFlatten($value['categories'], 'slug')); - - $value['date'] = new Typecho_Date($value['created']); - - /** 生成日期 */ - $value['year'] = $value['date']->year; - $value['month'] = $value['date']->month; - $value['day'] = $value['date']->day; - - /** 生成访问权限 */ - $value['hidden'] = false; - - /** 获取路由类型并判断此类型在路由表中是否存在 */ - $type = $value['type']; - $routeExists = (NULL != Typecho_Router::get($type)); - - $tmpSlug = $value['slug']; - $tmpCategory = $value['category']; - $value['slug'] = urlencode($value['slug']); - $value['category'] = urlencode($value['category']); - - /** 生成静态路径 */ - $value['pathinfo'] = $routeExists ? Typecho_Router::url($type, $value) : '#'; - - /** 生成静态链接 */ - $value['permalink'] = Typecho_Common::url($value['pathinfo'], $this->options->index); - - /** 处理附件 */ - if ('attachment' == $type) { - $content = @unserialize($value['text']); - - //增加数据信息 - $value['attachment'] = new Typecho_Config($content); - $value['attachment']->isImage = in_array($content['type'], array('jpg', 'jpeg', 'gif', 'png', 'tiff', 'bmp')); - $value['attachment']->url = Widget_Upload::attachmentHandle($value); - - if ($value['attachment']->isImage) { - $value['text'] = '' .
-                $value['title'] . ''; - } else { - $value['text'] = '' . $value['title'] . ''; - } - } - - /** 处理Markdown **/ - $value['isMarkdown'] = (0 === strpos($value['text'], '')); - if ($value['isMarkdown']) { - $value['text'] = substr($value['text'], 15); - } - - /** 生成聚合链接 */ - /** RSS 2.0 */ - $value['feedUrl'] = $routeExists ? Typecho_Router::url($type, $value, $this->options->feedUrl) : '#'; - - /** RSS 1.0 */ - $value['feedRssUrl'] = $routeExists ? Typecho_Router::url($type, $value, $this->options->feedRssUrl) : '#'; - - /** ATOM 1.0 */ - $value['feedAtomUrl'] = $routeExists ? Typecho_Router::url($type, $value, $this->options->feedAtomUrl) : '#'; - - $value['slug'] = $tmpSlug; - $value['category'] = $tmpCategory; - - /** 处理密码保护流程 */ - if (!empty($value['password']) && - $value['password'] != $this->request->protectPassword && - $value['authorId'] != $this->user->uid && - !$this->user->pass('editor', true)) { - $value['hidden'] = true; - - /** 抛出错误 */ - if ($this->request->isPost() && isset($this->request->protectPassword)) { - throw new Typecho_Widget_Exception(_t('对不起,您输入的密码错误'), 403); - } - } - - $value = $this->pluginHandle(__CLASS__)->filter($value, $this); - - /** 如果访问权限被禁止 */ - if ($value['hidden']) { - $value['text'] = '

    ' . - '

    ' . _t('请输入密码访问') . '

    ' . - '

    -

    ' . - '
    '; - - $value['title'] = _t('此内容被密码保护'); - $value['tags'] = array(); - $value['commentsNum'] = 0; - } - - return $value; - } - - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - return parent::push($value); - } - - /** - * 输出文章发布日期 - * - * @access public - * @param string $format 日期格式 - * @return void - */ - public function date($format = NULL) - { - echo $this->date->format(empty($format) ? $this->options->postDateFormat : $format); - } - - /** - * 输出文章内容 - * - * @access public - * @param string $more 文章截取后缀 - * @return void - */ - public function content($more = false) - { - echo false !== $more && false !== strpos($this->text, '') ? - $this->excerpt . "

    permalink}\" title=\"{$this->title}\">{$more}

    " : $this->content; - } - - /** - * 输出文章摘要 - * - * @access public - * @param integer $length 摘要截取长度 - * @param string $trim 摘要后缀 - * @return void - */ - public function excerpt($length = 100, $trim = '...') - { - echo Typecho_Common::subStr(strip_tags($this->excerpt), 0, $length, $trim); - } - - /** - * 输出标题 - * - * @access public - * @param integer $length 标题截取长度 - * @param string $trim 截取后缀 - * @return void - */ - public function title($length = 0, $trim = '...') - { - $title = $this->pluginHandle()->trigger($plugged)->title($this->title, $this); - if (!$plugged) { - echo $length > 0 ? Typecho_Common::subStr($this->title, 0, $length, $trim) : $this->title; - } - } - - /** - * 输出文章评论数 - * - * @access public - * @param string $string 评论数格式化数据 - * @return void - */ - public function commentsNum() - { - $args = func_get_args(); - if (!$args) { - $args[] = '%d'; - } - - $num = intval($this->commentsNum); - - echo sprintf(isset($args[$num]) ? $args[$num] : array_pop($args), $num); - } - - /** - * 获取文章权限 - * - * @access public - * @param string $permission 权限 - * @return unknown - */ - public function allow() - { - $permissions = func_get_args(); - $allow = true; - - foreach ($permissions as $permission) { - $permission = strtolower($permission); - - if ('edit' == $permission) { - $allow &= ($this->user->pass('editor', true) || $this->authorId == $this->user->uid); - } else { - /** 对自动关闭反馈功能的支持 */ - if (('ping' == $permission || 'comment' == $permission) && $this->options->commentsPostTimeout > 0 && - $this->options->commentsAutoClose) { - if ($this->options->gmtTime - $this->created > $this->options->commentsPostTimeout) { - return false; - } - } - - $allow &= ($this->row['allow' . ucfirst($permission)] == 1) and !$this->hidden; - } - } - - return $allow; - } - - /** - * 输出文章分类 - * - * @access public - * @param string $split 多个分类之间分隔符 - * @param boolean $link 是否输出链接 - * @param string $default 如果没有则输出 - * @return void - */ - public function category($split = ',', $link = true, $default = NULL) - { - $categories = $this->categories; - if ($categories) { - $result = array(); - - foreach ($categories as $category) { - $result[] = $link ? '' - . $category['name'] . '' : $category['name']; - } - - echo implode($split, $result); - } else { - echo $default; - } - } - - /** - * 输出文章标签 - * - * @access public - * @param string $split 多个标签之间分隔符 - * @param boolean $link 是否输出链接 - * @param string $default 如果没有则输出 - * @return void - */ - public function tags($split = ',', $link = true, $default = NULL) - { - /** 取出tags */ - if ($this->tags) { - $result = array(); - foreach ($this->tags as $tag) { - $result[] = $link ? '' - . $tag['name'] . '' : $tag['name']; - } - - echo implode($split, $result); - } else { - echo $default; - } - } - - /** - * 输出当前作者 - * - * @access public - * @param string $item 需要输出的项目 - * @return void - */ - public function author($item = 'screenName') - { - echo $this->author->{$item}; - } -} diff --git a/php/typecho09/var/Widget/Abstract/Metas.php b/php/typecho09/var/Widget/Abstract/Metas.php deleted file mode 100644 index 1d945b8d3..000000000 --- a/php/typecho09/var/Widget/Abstract/Metas.php +++ /dev/null @@ -1,258 +0,0 @@ -type . '-' . $this->mid; - } - - /** - * 获取原始查询对象 - * - * @access public - * @return Typecho_Db_Query - */ - public function select() - { - return $this->db->select()->from('table.metas'); - } - - /** - * 插入一条记录 - * - * @access public - * @param array $options 记录插入值 - * @return integer - */ - public function insert(array $options) - { - return $this->db->query($this->db->insert('table.metas')->rows($options)); - } - - /** - * 更新记录 - * - * @access public - * @param array $options 记录更新值 - * @param Typecho_Db_Query $condition 更新条件 - * @return integer - */ - public function update(array $options, Typecho_Db_Query $condition) - { - return $this->db->query($condition->update('table.metas')->rows($options)); - } - - /** - * 删除记录 - * - * @access public - * @param Typecho_Db_Query $condition 删除条件 - * @return integer - */ - public function delete(Typecho_Db_Query $condition) - { - return $this->db->query($condition->delete('table.metas')); - } - - /** - * 获取记录总数 - * - * @access public - * @param Typecho_Db_Query $condition 计算条件 - * @return integer - */ - public function size(Typecho_Db_Query $condition) - { - return $this->db->fetchObject($condition->select(array('COUNT(mid)' => 'num'))->from('table.metas'))->num; - } - - /** - * 通用过滤器 - * - * @access public - * @param array $value 需要过滤的行数据 - * @return array - */ - public function filter(array $value) - { - //生成静态链接 - $type = $value['type']; - $routeExists = (NULL != Typecho_Router::get($type)); - $tmpSlug = $value['slug']; - $value['slug'] = urlencode($value['slug']); - - $value['permalink'] = $routeExists ? Typecho_Router::url($type, $value, $this->options->index) : '#'; - - /** 生成聚合链接 */ - /** RSS 2.0 */ - $value['feedUrl'] = $routeExists ? Typecho_Router::url($type, $value, $this->options->feedUrl) : '#'; - - /** RSS 1.0 */ - $value['feedRssUrl'] = $routeExists ? Typecho_Router::url($type, $value, $this->options->feedRssUrl) : '#'; - - /** ATOM 1.0 */ - $value['feedAtomUrl'] = $routeExists ? Typecho_Router::url($type, $value, $this->options->feedAtomUrl) : '#'; - - $value['slug'] = $tmpSlug; - $value = $this->pluginHandle(__CLASS__)->filter($value, $this); - return $value; - } - - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - return parent::push($value); - } - - /** - * 对数据按照sort字段排序 - * - * @access public - * @param array $metas - * @param string $type - * @return void - */ - public function sort(array $metas, $type) - { - foreach ($metas as $sort => $mid) { - $this->update(array('order' => $sort + 1), - $this->db->sql()->where('mid = ?', $mid)->where('type = ?', $type)); - } - } - - /** - * 合并数据 - * - * @access public - * @param integer $mid 数据主键 - * @param string $type 数据类型 - * @param array $metas 需要合并的数据集 - * @return void - */ - public function merge($mid, $type, array $metas) - { - $contents = Typecho_Common::arrayFlatten($this->db->fetchAll($this->select('cid') - ->from('table.relationships') - ->where('mid = ?', $mid)), 'cid'); - - foreach ($metas as $meta) { - if ($mid != $meta) { - $existsContents = Typecho_Common::arrayFlatten($this->db->fetchAll($this->db - ->select('cid')->from('table.relationships') - ->where('mid = ?', $meta)), 'cid'); - - $where = $this->db->sql()->where('mid = ? AND type = ?', $meta, $type); - $this->delete($where); - $diffContents = array_diff($existsContents, $contents); - $this->db->query($this->db->delete('table.relationships')->where('mid = ?', $meta)); - - foreach ($diffContents as $content) { - $this->db->query($this->db->insert('table.relationships') - ->rows(array('mid' => $mid, 'cid' => $content))); - $contents[] = $content; - } - - unset($existsContents); - } - } - - $num = $this->db->fetchObject($this->db - ->select(array('COUNT(mid)' => 'num'))->from('table.relationships') - ->where('table.relationships.mid = ?', $mid))->num; - - $this->update(array('count' => $num), $this->db->sql()->where('mid = ?', $mid)); - } - - /** - * 根据tag获取ID - * - * @access public - * @param mixed $inputTags 标签名 - * @return array - */ - public function scanTags($inputTags) - { - $tags = is_array($inputTags) ? $inputTags : array($inputTags); - $result = array(); - - foreach ($tags as $tag) { - if (empty($tag)) { - continue; - } - - $row = $this->db->fetchRow($this->select() - ->where('type = ?', 'tag') - ->where('name = ?', $tag)->limit(1)); - - if ($row) { - $result[] = $row['mid']; - } else { - $slug = Typecho_Common::slugName($tag); - - if ($slug) { - $result[] = $this->insert(array( - 'name' => $tag, - 'slug' => $slug, - 'type' => 'tag', - 'count' => 0, - 'order' => 0, - )); - } - } - } - - return is_array($inputTags) ? $result : current($result); - } - - /** - * 根据内容的指定类别和状态更新相关meta的计数信息 - * - * @access public - * @param Tint $mid meta id - * @param string $type 类别 - * @param string $status 状态 - * @return void - */ - public function refreshCountByTypeAndStatus($mid, $type, $status = 'publish') - { - $num = $this->db->fetchObject($this->db->select(array('COUNT(table.contents.cid)' => 'num'))->from('table.contents') - ->join('table.relationships', 'table.contents.cid = table.relationships.cid') - ->where('table.relationships.mid = ?', $mid) - ->where('table.contents.type = ?', $type) - ->where('table.contents.status = ?', $status))->num; - - $this->db->query($this->db->update('table.metas')->rows(array('count' => $num)) - ->where('mid = ?', $mid)); - } -} diff --git a/php/typecho09/var/Widget/Abstract/Options.php b/php/typecho09/var/Widget/Abstract/Options.php deleted file mode 100644 index 91d023239..000000000 --- a/php/typecho09/var/Widget/Abstract/Options.php +++ /dev/null @@ -1,94 +0,0 @@ -db->select()->from('table.options'); - } - - /** - * 插入一条记录 - * - * @access public - * @param array $options 记录插入值 - * @return integer - */ - public function insert(array $options) - { - return $this->db->query($this->db->insert('table.options')->rows($options)); - } - - /** - * 更新记录 - * - * @access public - * @param array $options 记录更新值 - * @param Typecho_Db_Query $condition 更新条件 - * @return integer - */ - public function update(array $options, Typecho_Db_Query $condition) - { - return $this->db->query($condition->update('table.options')->rows($options)); - } - - /** - * 删除记录 - * - * @access public - * @param Typecho_Db_Query $condition 删除条件 - * @return integer - */ - public function delete(Typecho_Db_Query $condition) - { - return $this->db->query($condition->delete('table.options')); - } - - /** - * 获取记录总数 - * - * @access public - * @param Typecho_Db_Query $condition 计算条件 - * @return integer - */ - public function size(Typecho_Db_Query $condition) - { - return $this->db->fetchObject($condition->select(array('COUNT(name)' => 'num'))->from('table.options'))->num; - } -} diff --git a/php/typecho09/var/Widget/Abstract/Users.php b/php/typecho09/var/Widget/Abstract/Users.php deleted file mode 100644 index b45edf9f8..000000000 --- a/php/typecho09/var/Widget/Abstract/Users.php +++ /dev/null @@ -1,245 +0,0 @@ -db->fetchAll($this->db->select() - ->from('table.options')->where('user = ?', $this->uid)); - $options = array(); - foreach ($rows as $row) { - $options[$row['name']] = $row['value']; - } - - return new Typecho_Config($options); - } - - /** - * 判断用户名称是否存在 - * - * @access public - * @param string $name 用户名称 - * @return boolean - */ - public function nameExists($name) - { - $select = $this->db->select() - ->from('table.users') - ->where('name = ?', $name) - ->limit(1); - - if ($this->request->uid) { - $select->where('uid <> ?', $this->request->uid); - } - - $user = $this->db->fetchRow($select); - return $user ? false : true; - } - - /** - * 判断电子邮件是否存在 - * - * @access public - * @param string $mail 电子邮件 - * @return boolean - */ - public function mailExists($mail) - { - $select = $this->db->select() - ->from('table.users') - ->where('mail = ?', $mail) - ->limit(1); - - if ($this->request->uid) { - $select->where('uid <> ?', $this->request->uid); - } - - $user = $this->db->fetchRow($select); - return $user ? false : true; - } - - /** - * 判断用户昵称是否存在 - * - * @access public - * @param string $screenName 昵称 - * @return boolean - */ - public function screenNameExists($screenName) - { - $select = $this->db->select() - ->from('table.users') - ->where('screenName = ?', $screenName) - ->limit(1); - - if ($this->request->uid) { - $select->where('uid <> ?', $this->request->uid); - } - - $user = $this->db->fetchRow($select); - return $user ? false : true; - } - - /** - * 获取页面偏移 - * - * @access protected - * @param string $column 字段名 - * @param integer $offset 偏移值 - * @param string $group 用户组 - * @param integer $pageSize 分页值 - * @return integer - */ - protected function getPageOffset($column, $offset, $group = NULL, $pageSize = 20) - { - $select = $this->db->select(array('COUNT(uid)' => 'num'))->from('table.users') - ->where("table.users.{$column} > {$offset}"); - - if (!empty($group)) { - $select->where('table.users.group = ?', $group); - } - - $count = $this->db->fetchObject($select)->num + 1; - return ceil($count / $pageSize); - } - - /** - * 通用过滤器 - * - * @access public - * @param array $value 需要过滤的行数据 - * @return array - */ - public function filter(array $value) - { - //生成静态链接 - $routeExists = (NULL != Typecho_Router::get('author')); - - $value['permalink'] = $routeExists ? Typecho_Router::url('author', $value, $this->options->index) : '#'; - - /** 生成聚合链接 */ - /** RSS 2.0 */ - $value['feedUrl'] = $routeExists ? Typecho_Router::url('author', $value, $this->options->feedUrl) : '#'; - - /** RSS 1.0 */ - $value['feedRssUrl'] = $routeExists ? Typecho_Router::url('author', $value, $this->options->feedRssUrl) : '#'; - - /** ATOM 1.0 */ - $value['feedAtomUrl'] = $routeExists ? Typecho_Router::url('author', $value, $this->options->feedAtomUrl) : '#'; - - $value = $this->pluginHandle(__CLASS__)->filter($value, $this); - return $value; - } - - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - return parent::push($value); - } - - /** - * 查询方法 - * - * @access public - * @return Typecho_Db_Query - */ - public function select() - { - return $this->db->select()->from('table.users'); - } - - /** - * 获得所有记录数 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function size(Typecho_Db_Query $condition) - { - return $this->db->fetchObject($condition->select(array('COUNT(uid)' => 'num'))->from('table.users'))->num; - } - - /** - * 增加记录方法 - * - * @access public - * @param array $rows 字段对应值 - * @return integer - */ - public function insert(array $rows) - { - return $this->db->query($this->db->insert('table.users')->rows($rows)); - } - - /** - * 更新记录方法 - * - * @access public - * @param array $rows 字段对应值 - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function update(array $rows, Typecho_Db_Query $condition) - { - return $this->db->query($condition->update('table.users')->rows($rows)); - } - - /** - * 删除记录方法 - * - * @access public - * @param Typecho_Db_Query $condition 查询对象 - * @return integer - */ - public function delete(Typecho_Db_Query $condition) - { - return $this->db->query($condition->delete('table.users')); - } - - /** - * 调用gravatar输出用户头像 - * - * @access public - * @param integer $size 头像尺寸 - * @param string $rating 头像评级 - * @param string $default 默认输出头像 - * @return void - */ - public function gravatar($size = 40, $rating = 'X', $default = NULL, $class = NULL) - { - echo ''; - } -} diff --git a/php/typecho09/var/Widget/Ajax.php b/php/typecho09/var/Widget/Ajax.php deleted file mode 100644 index 4ebffdeab..000000000 --- a/php/typecho09/var/Widget/Ajax.php +++ /dev/null @@ -1,161 +0,0 @@ -options->generator == $this->request->getAgent()) { - echo 'OK'; - } - } - - /** - * 获取最新版本 - * - * @access public - * @return void - */ - public function checkVersion() - { - $this->user->pass('editor'); - $client = Typecho_Http_Client::get(); - if ($client) { - $client->setHeader('User-Agent', $this->options->generator) - ->send('https://github.com/typecho/typecho/releases.atom'); - - /** 匹配内容体 */ - $response = $client->getResponseBody(); - preg_match_all("/]+href=\"([^>]*)\"\s*\/>/is", $response, $matches); - $result = array('available' => 0); - - list($soft, $version) = explode(' ', $this->options->generator); - $current = explode('/', $version); - - if ($matches) { - foreach ($matches[0] as $key => $val) { - $title = trim($matches[1][$key]); - if (preg_match("/v([0-9\.]+)\-([0-9\.]+)\-release$/is", $title, $out)) { - if (version_compare($out[1], $current[0], '>=') - && version_compare($out[2], $current[1], '>')) { - $result = array( - 'available' => 1, - 'latest' => $out[1] . '-' . $out[2], - 'current' => $current[0] . '-' . $current[1], - 'link' => 'https://github.com' . $matches[1][$key] - ); - break; - } - } - } - } - - $this->response->throwJson($result); - return; - } - - throw new Typecho_Widget_Exception(_t('禁止访问'), 403); - } - - /** - * 远程请求代理 - * - * @access public - * @return void - */ - public function feed() - { - $this->user->pass('subscriber'); - $client = Typecho_Http_Client::get(); - if ($client) { - $client->setHeader('User-Agent', $this->options->generator) - ->send('http://typecho.org/feed/'); - - /** 匹配内容体 */ - $response = $client->getResponseBody(); - preg_match_all("/\s*([^>]*)<\/title>\s*<link>([^>]*)<\/link>\s*<guid>[^>]*<\/guid>\s*<pubDate>([^>]*)<\/pubDate>/is", $response, $matches); - - $data = array(); - - if ($matches) { - foreach ($matches[0] as $key => $val) { - $data[] = array( - 'title' => $matches[1][$key], - 'link' => $matches[2][$key], - 'date' => date('n.j', strtotime($matches[3][$key])) - ); - - if ($key > 3) { - break; - } - } - } - - $this->response->throwJson($data); - return; - } - - throw new Typecho_Widget_Exception(_t('禁止访问'), 403); - } - - /** - * 自定义编辑器大小 - * - * @access public - * @return void - */ - public function editorResize() - { - $this->user->pass('contributor'); - if ($this->db->fetchObject($this->db->select(array('COUNT(*)' => 'num')) - ->from('table.options')->where('name = ? AND user = ?', 'editorSize', $this->user->uid))->num > 0) { - $this->widget('Widget_Abstract_Options') - ->update(array('value' => $this->request->size), $this->db->sql()->where('name = ? AND user = ?', 'editorSize', $this->user->uid)); - } else { - $this->widget('Widget_Abstract_Options')->insert(array( - 'name' => 'editorSize', - 'value' => $this->request->size, - 'user' => $this->user->uid - )); - } - } - - /** - * 异步请求入口 - * - * @access public - * @return void - */ - public function action() - { - if (!$this->request->isAjax()) { - $this->response->goBack(); - } - - $this->on($this->request->is('do=remoteCallback'))->remoteCallback(); - $this->on($this->request->is('do=feed'))->feed(); - $this->on($this->request->is('do=checkVersion'))->checkVersion(); - $this->on($this->request->is('do=editorResize'))->editorResize(); - } -} diff --git a/php/typecho09/var/Widget/Archive.php b/php/typecho09/var/Widget/Archive.php deleted file mode 100644 index 508ecf898..000000000 --- a/php/typecho09/var/Widget/Archive.php +++ /dev/null @@ -1,1960 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id: Posts.php 200 2008-05-21 06:33:20Z magike.net $ - */ - -/** - * 内容的文章基类 - * 定义的css类 - * p.more:阅读全文链接所属段落 - * - * @package Widget - */ -class Widget_Archive extends Widget_Abstract_Contents -{ - /** - * 调用的风格文件 - * - * @access private - * @var string - */ - private $_themeFile; - - /** - * 风格目录 - * - * @access private - * @var string - */ - private $_themeDir; - - /** - * 分页计算对象 - * - * @access private - * @var Typecho_Db_Query - */ - private $_countSql; - - /** - * 所有文章个数 - * - * @access private - * @var integer - */ - private $_total = false; - - /** - * 标记是否为从外部调用 - * - * @access private - * @var boolean - */ - private $_invokeFromOutside = false; - - /** - * 是否由聚合调用 - * - * @access private - * @var boolean - */ - private $_invokeByFeed = false; - - /** - * 当前页 - * - * @access private - * @var integer - */ - private $_currentPage; - - /** - * 生成分页的内容 - * - * @access private - * @var array - */ - private $_pageRow = array(); - - /** - * 聚合器对象 - * - * @access private - * @var Typecho_Feed_Writer - */ - private $_feed; - - /** - * RSS 2.0聚合地址 - * - * @access private - * @var string - */ - private $_feedUrl; - - /** - * RSS 1.0聚合地址 - * - * @access private - * @var string - */ - private $_feedRssUrl; - - /** - * ATOM 聚合地址 - * - * @access private - * @var string - */ - private $_feedAtomUrl; - - /** - * 本页关键字 - * - * @access private - * @var string - */ - private $_keywords; - - /** - * 本页描述 - * - * @access private - * @var string - */ - private $_description; - - /** - * 聚合类型 - * - * @access private - * @var string - */ - private $_feedType; - - /** - * 聚合类型 - * - * @access private - * @var string - */ - private $_feedContentType; - - /** - * 当前feed地址 - * - * @access private - * @var string - */ - private $_currentFeedUrl; - - /** - * 归档标题 - * - * @access private - * @var string - */ - private $_archiveTitle = NULL; - - /** - * 归档类型 - * - * @access private - * @var string - */ - private $_archiveType = 'index'; - - /** - * 是否为单一归档 - * - * @access private - * @var string - */ - private $_archiveSingle = false; - - /** - * 是否为自定义首页, 主要为了标记自定义首页的情况 - * - * (default value: false) - * - * @var boolean - * @access private - */ - private $_makeSinglePageAsFrontPage = false; - - /** - * 归档缩略名 - * - * @access private - * @var string - */ - private $_archiveSlug; - - /** - * 设置分页对象 - * - * @access private - * @var Typecho_Widget_Helper_PageNavigator - */ - private $_pageNav; - - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - - $this->parameter->setDefault(array( - 'pageSize' => $this->options->pageSize, - 'type' => NULL, - 'checkPermalink' => true - )); - - /** 用于判断是路由调用还是外部调用 */ - if (NULL == $this->parameter->type) { - $this->parameter->type = Typecho_Router::$current; - } else { - $this->_invokeFromOutside = true; - } - - /** 用于判断是否为feed调用 */ - if ($this->parameter->isFeed) { - $this->_invokeByFeed = true; - } - - /** 初始化皮肤路径 */ - $this->_themeDir = __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_THEME_DIR__ . '/' . $this->options->theme . '/'; - - /** 处理feed模式 **/ - if ('feed' == $this->parameter->type) { - - $this->_currentFeedUrl = ''; - - /** 判断聚合类型 */ - switch (true) { - case 0 === strpos($this->request->feed, '/rss/') || '/rss' == $this->request->feed: - /** 如果是RSS1标准 */ - $this->request->feed = substr($this->request->feed, 4); - $this->_feedType = Typecho_Feed::RSS1; - $this->_currentFeedUrl = $this->options->feedRssUrl; - $this->_feedContentType = 'application/rdf+xml'; - break; - case 0 === strpos($this->request->feed, '/atom/') || '/atom' == $this->request->feed: - /** 如果是ATOM标准 */ - $this->request->feed = substr($this->request->feed, 5); - $this->_feedType = Typecho_Feed::ATOM1; - $this->_currentFeedUrl = $this->options->feedAtomUrl; - $this->_feedContentType = 'application/atom+xml'; - break; - default: - $this->_feedType = Typecho_Feed::RSS2; - $this->_currentFeedUrl = $this->options->feedUrl; - $this->_feedContentType = 'application/rss+xml'; - break; - } - - $feedQuery = $this->request->feed; - //$this->parameter->type = Typecho_Router::$current; - //$this->request->setParams($params); - - if ('/comments/' == $feedQuery || '/comments' == $feedQuery) { - /** 专为feed使用的hack */ - $this->parameter->type = 'comments'; - } else { - $matched = Typecho_Router::match($this->request->feed, 'pageSize=10&isFeed=1'); - if ($matched && $matched instanceof Widget_Archive) { - $this->import($matched); - } else { - throw new Typecho_Widget_Exception(_t('聚合页不存在'), 404); - } - } - - /** 初始化聚合器 */ - $this->setFeed(new Typecho_Feed(Typecho_Common::VERSION, $this->_feedType, $this->options->charset, _t('zh-CN'))); - - /** 默认输出10则文章 **/ - $this->parameter->pageSize = 10; - } - } - - /** - * 评论地址 - * - * @access protected - * @return void - */ - protected function ___commentUrl() - { - /** 生成反馈地址 */ - /** 评论 */ - $commentUrl = parent::___commentUrl(); - - //不依赖js的父级评论 - $reply = $this->request->filter('int')->replyTo; - if ($reply && $this->is('single')) { - $commentUrl .= '?parent=' . $reply; - } - - return $commentUrl; - } - - /** - * 设置分页对象 - * @param array $pageRow - * @return void - */ - public function setPageRow($pageRow) - { - $this->_pageRow = $pageRow; - } - - /** - * @param $_archiveSlug the $_archiveSlug to set - */ - public function setArchiveSlug($archiveSlug) - { - $this->_archiveSlug = $archiveSlug; - } - - /** - * @param $_archiveSingle the $_archiveSingle to set - */ - public function setArchiveSingle($archiveSingle) - { - $this->_archiveSingle = $archiveSingle; - } - - /** - * @param $_archiveType the $_archiveType to set - */ - public function setArchiveType($archiveType) - { - $this->_archiveType = $archiveType; - } - - /** - * @param $_archiveTitle the $_archiveTitle to set - */ - public function setArchiveTitle($archiveTitle) - { - $this->_archiveTitle = $archiveTitle; - } - - /** - * 增加标题 - * @param string $archiveTitle 标题 - * @return void - */ - public function addArchiveTitle($archiveTitle) - { - $current = $this->getArchiveTitle(); - $current[] = $archiveTitle; - $this->setArchiveTitle($current); - } - - /** - * @param $_feedType the $_feedType to set - */ - public function setFeedType($feedType) - { - $this->_feedType = $feedType; - } - - /** - * @param $_description the $_description to set - */ - public function setDescription($description) - { - $this->_description = $description; - } - - /** - * @param $_keywords the $_keywords to set - */ - public function setKeywords($keywords) - { - $this->_keywords = $keywords; - } - - /** - * @param $_feedAtomUrl the $_feedAtomUrl to set - */ - public function setFeedAtomUrl($feedAtomUrl) - { - $this->_feedAtomUrl = $feedAtomUrl; - } - - /** - * @param $_feedRssUrl the $_feedRssUrl to set - */ - public function setFeedRssUrl($feedRssUrl) - { - $this->_feedRssUrl = $feedRssUrl; - } - - /** - * @param $_feedUrl the $_feedUrl to set - */ - public function setFeedUrl($feedUrl) - { - $this->_feedUrl = $feedUrl; - } - - /** - * @param $_feed the $_feed to set - */ - public function setFeed($feed) - { - $this->_feed = $feed; - } - - /** - * @param $_countSql the $_countSql to set - */ - public function setCountSql($countSql) - { - $this->_countSql = $countSql; - } - - /** - * @param $_total the $_total to set - */ - public function setTotal($total) - { - $this->_total = $total; - } - - /** - * @param $_themeFile the $_themeFile to set - */ - public function setThemeFile($themeFile) - { - $this->_themeFile = $themeFile; - } - - /** - * @param $_themeDir the $_themeDir to set - */ - public function setThemeDir($themeDir) - { - $this->_themeDir = $themeDir; - } - - /** - * 获取分页对象 - * @return array - */ - public function getPageRow() - { - return $this->_pageRow; - } - - /** - * @return the $_archiveSlug - */ - public function getArchiveSlug() - { - return $this->_archiveSlug; - } - - /** - * @return the $_archiveSingle - */ - public function getArchiveSingle() - { - return $this->_archiveSingle; - } - - /** - * @return the $_archiveType - */ - public function getArchiveType() - { - return $this->_archiveType; - } - - /** - * @return the $_archiveTitle - */ - public function getArchiveTitle() - { - return $this->_archiveTitle; - } - - /** - * @return the $_feedType - */ - public function getFeedType() - { - return $this->_feedType; - } - - /** - * @return the $_description - */ - public function getDescription() - { - return $this->_description; - } - - /** - * @return the $_keywords - */ - public function getKeywords() - { - return $this->_keywords; - } - - /** - * @return the $_feedAtomUrl - */ - public function getFeedAtomUrl() - { - return $this->_feedAtomUrl; - } - - /** - * @return the $_feedRssUrl - */ - public function getFeedRssUrl() - { - return $this->_feedRssUrl; - } - - /** - * @return the $_feedUrl - */ - public function getFeedUrl() - { - return $this->_feedUrl; - } - - /** - * @return the $_feed - */ - public function getFeed() - { - return $this->_feed; - } - - /** - * @return the $_countSql - */ - public function getCountSql() - { - return $this->_countSql; - } - - /** - * @return the $_total - */ - public function getTotal() - { - return $this->_total; - } - - /** - * @return the $_currentPage - */ - public function getCurrentPage() - { - return $this->_currentPage; - } - - /** - * @return the $_themeFile - */ - public function getThemeFile() - { - return $this->_themeFile; - } - - /** - * @return the $_themeDir - */ - public function getThemeDir() - { - return $this->_themeDir; - } - - /** - * 检查链接是否正确 - * - * @access private - * @return void - */ - private function checkPermalink() - { - $type = $this->parameter->type; - - if (in_array($type, array('index', 'comment_page', 404)) - || $this->_makeSinglePageAsFrontPage // 自定义首页不处理 - || !$this->parameter->checkPermalink) { // 强制关闭 - return; - } - - if ($this->_archiveSingle) { - $permalink = $this->permalink; - } else { - $value = array_merge($this->_pageRow, array( - 'page' => $this->_currentPage - )); - - $path = Typecho_Router::url($type, $value); - $permalink = Typecho_Common::url($path, $this->options->index); - } - - $requestUrl = $this->request->getRequestUrl(); - - $src = parse_url($permalink); - $target = parse_url($requestUrl); - - if ($src['host'] != $target['host'] || $src['path'] != $target['path']) { - $this->response->redirect($permalink, true); - } - } - - /** - * 导入对象 - * - * @access private - * @param Widget_Archive $widget 需要导入的对象 - * @return void - */ - private function import(Widget_Archive $widget) - { - $currentProperties = get_object_vars($this); - - foreach ($currentProperties as $name => $value) { - if (false !== strpos('|request|response|parameter|_feed|_feedType|_currentFeedUrl|', '|' . $name . '|')) { - continue; - } - - if (isset($widget->{$name})) { - $this->{$name} = $widget->{$name}; - } else { - $method = ucfirst(trim($name, '_')); - $setMethod = 'set' . $method; - $getMethod = 'get' . $method; - - if (method_exists($this, $setMethod) - && method_exists($widget, $getMethod)) { - $this->{$setMethod}($widget->{$getMethod}()); - } - } - } - } - - /** - * 处理index - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function indexHandle(Typecho_Db_Query $select, &$hasPushed) - { - $select->where('table.contents.type = ?', 'post'); - - /** 插件接口 */ - $this->pluginHandle()->indexHandle($this, $select); - } - - /** - * 404页面处理 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function error404Handle(Typecho_Db_Query $select, &$hasPushed) - { - /** 设置header */ - $this->response->setStatus(404); - - /** 设置标题 */ - $this->_archiveTitle = _t('页面没找到'); - - /** 设置归档类型 */ - $this->_archiveType = 'archive'; - - /** 设置归档缩略名 */ - $this->_archiveSlug = 404; - - /** 设置归档模板 */ - $this->_themeFile = '404.php'; - - /** 设置单一归档类型 */ - $this->_archiveSingle = false; - - $hasPushed = true; - - /** 插件接口 */ - $this->pluginHandle()->error404Handle($this, $select); - } - - /** - * 独立页处理 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function singleHandle(Typecho_Db_Query $select, &$hasPushed) - { - if ('comment_page' == $this->parameter->type) { - $params = array(); - $matched = Typecho_Router::match($this->request->permalink); - - if ($matched && $matched instanceof Widget_Archive && $matched->is('single')) { - $this->import($matched); - $hasPushed = true; - return; - } - } - - /** 将这两个设置提前是为了保证在调用query的plugin时可以在插件中使用is判断初步归档类型 */ - /** 如果需要更细判断,则可以使用singleHandle来实现 */ - $this->_archiveSingle = true; - - /** 默认归档类型 */ - $this->_archiveType = 'single'; - - /** 匹配类型 */ - $select->where('table.contents.type = ?', $this->parameter->type); - - /** 如果是单篇文章或独立页面 */ - if (isset($this->request->cid)) { - $select->where('table.contents.cid = ?', $this->request->filter('int')->cid); - } - - /** 匹配缩略名 */ - if (isset($this->request->slug)) { - $select->where('table.contents.slug = ?', $this->request->slug); - } - - /** 匹配时间 */ - if (isset($this->request->year)) { - $year = $this->request->filter('int')->year; - - $fromMonth = 1; - $toMonth = 12; - - $fromDay = 1; - $toDay = 31; - - if (isset($this->request->month)) { - $fromMonth = $this->request->filter('int')->month; - $toMonth = $fromMonth; - - $fromDay = 1; - $toDay = date('t', mktime(0, 0, 0, $toMonth, 1, $year)); - - if (isset($this->request->day)) { - $fromDay = $this->request->filter('int')->day; - $toDay = $fromDay; - } - } - - /** 获取起始GMT时间的unix时间戳 */ - $from = mktime(0, 0, 0, $fromMonth, $fromDay, $year) - $this->options->timezone + $this->options->serverTimezone; - $to = mktime(23, 59, 59, $toMonth, $toDay, $year) - $this->options->timezone + $this->options->serverTimezone; - $select->where('table.contents.created > ? AND table.contents.created < ?', $from, $to); - } - - /** 保存密码至cookie */ - if ($this->request->isPost() && isset($this->request->protectPassword)) { - Typecho_Cookie::set('protectPassword', $this->request->protectPassword, 0, $this->options->siteUrl); - } - - /** 匹配类型 */ - $select->limit(1); - $this->query($select); - - if (!$this->have() || (isset($this->request->category) && $this->category != $this->request->category)) { - if (!$this->_invokeFromOutside) { - /** 对没有索引情况下的判断 */ - throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404); - } else { - $hasPushed = true; - return; - } - } - - /** 设置模板 */ - if ($this->template) { - /** 应用自定义模板 */ - $this->_themeFile = $this->template; - } - - /** 设置头部feed */ - /** RSS 2.0 */ - - //对自定义首页使用全局变量 - if (!$this->_makeSinglePageAsFrontPage) { - $this->_feedUrl = $this->feedUrl; - - /** RSS 1.0 */ - $this->_feedRssUrl = $this->feedRssUrl; - - /** ATOM 1.0 */ - $this->_feedAtomUrl = $this->feedAtomUrl; - - /** 设置标题 */ - $this->_archiveTitle = $this->title; - - /** 设置关键词 */ - $this->_keywords = implode(',', Typecho_Common::arrayFlatten($this->tags, 'name')); - - /** 设置描述 */ - $this->_description = $this->description; - } - - /** 设置归档类型 */ - $this->_archiveType = $this->type; - - /** 设置归档缩略名 */ - $this->_archiveSlug = ('post' == $this->type || 'attachment' == $this->type) ? $this->cid : $this->slug; - - /** 设置403头 */ - if ($this->hidden) { - $this->response->setStatus(403); - } - - $hasPushed = true; - - /** 插件接口 */ - $this->pluginHandle()->singleHandle($this, $select); - } - - /** - * 处理分类 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function categoryHandle(Typecho_Db_Query $select, &$hasPushed) - { - /** 如果是分类 */ - $categorySelect = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'category') - ->limit(1); - - if (isset($this->request->mid)) { - $categorySelect->where('mid = ?', $this->request->filter('int')->mid); - } - - if (isset($this->request->slug)) { - $categorySelect->where('slug = ?', $this->request->slug); - } - - $category = $this->db->fetchRow($categorySelect, - array($this->widget('Widget_Abstract_Metas'), 'filter')); - - if (!$category) { - throw new Typecho_Widget_Exception(_t('分类不存在'), 404); - } - - /** fix sql92 by 70 */ - $select->join('table.relationships', 'table.contents.cid = table.relationships.cid') - ->where('table.relationships.mid = ?', $category['mid']) - ->where('table.contents.type = ?', 'post'); - - /** 设置分页 */ - $this->_pageRow = array_merge($category, array( - 'slug' => urlencode($category['slug']) - )); - - /** 设置关键词 */ - $this->_keywords = $category['name']; - - /** 设置描述 */ - $this->_description = $category['description']; - - /** 设置头部feed */ - /** RSS 2.0 */ - $this->_feedUrl = $category['feedUrl']; - - /** RSS 1.0 */ - $this->_feedRssUrl = $category['feedRssUrl']; - - /** ATOM 1.0 */ - $this->_feedAtomUrl = $category['feedAtomUrl']; - - /** 设置标题 */ - $this->_archiveTitle = $category['name']; - - /** 设置归档类型 */ - $this->_archiveType = 'category'; - - /** 设置归档缩略名 */ - $this->_archiveSlug = $category['slug']; - - /** 插件接口 */ - $this->pluginHandle()->categoryHandle($this, $select); - } - - /** - * 处理标签 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function tagHandle(Typecho_Db_Query $select, &$hasPushed) - { - $tagSelect = $this->db->select()->from('table.metas') - ->where('type = ?', 'tag')->limit(1); - - if (isset($this->request->mid)) { - $tagSelect->where('mid = ?', $this->request->filter('int')->mid); - } - - if (isset($this->request->slug)) { - $tagSelect->where('slug = ?', $this->request->slug); - } - - /** 如果是标签 */ - $tag = $this->db->fetchRow($tagSelect, - array($this->widget('Widget_Abstract_Metas'), 'filter')); - - if (!$tag) { - throw new Typecho_Widget_Exception(_t('标签不存在'), 404); - } - - /** fix sql92 by 70 */ - $select->join('table.relationships', 'table.contents.cid = table.relationships.cid') - ->where('table.relationships.mid = ?', $tag['mid']) - ->where('table.contents.type = ?', 'post'); - - /** 设置分页 */ - $this->_pageRow = array_merge($tag, array( - 'slug' => urlencode($tag['slug']) - )); - - /** 设置关键词 */ - $this->_keywords = $tag['name']; - - /** 设置描述 */ - $this->_description = $tag['description']; - - /** 设置头部feed */ - /** RSS 2.0 */ - $this->_feedUrl = $tag['feedUrl']; - - /** RSS 1.0 */ - $this->_feedRssUrl = $tag['feedRssUrl']; - - /** ATOM 1.0 */ - $this->_feedAtomUrl = $tag['feedAtomUrl']; - - /** 设置标题 */ - $this->_archiveTitle = $tag['name']; - - /** 设置归档类型 */ - $this->_archiveType = 'tag'; - - /** 设置归档缩略名 */ - $this->_archiveSlug = $tag['slug']; - - /** 插件接口 */ - $this->pluginHandle()->tagHandle($this, $select); - } - - /** - * 处理作者 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function authorHandle(Typecho_Db_Query $select, &$hasPushed) - { - $uid = $this->request->filter('int')->uid; - - $author = $this->db->fetchRow($this->db->select()->from('table.users') - ->where('uid = ?', $uid), - array($this->widget('Widget_Abstract_Users'), 'filter')); - - if (!$author) { - throw new Typecho_Widget_Exception(_t('作者不存在'), 404); - } - - $select->where('table.contents.authorId = ?', $uid) - ->where('table.contents.type = ?', 'post'); - - /** 设置分页 */ - $this->_pageRow = $author; - - /** 设置关键词 */ - $this->_keywords = $author['screenName']; - - /** 设置描述 */ - $this->_description = $author['screenName']; - - /** 设置头部feed */ - /** RSS 2.0 */ - $this->_feedUrl = $author['feedUrl']; - - /** RSS 1.0 */ - $this->_feedRssUrl = $author['feedRssUrl']; - - /** ATOM 1.0 */ - $this->_feedAtomUrl = $author['feedAtomUrl']; - - /** 设置标题 */ - $this->_archiveTitle = $author['screenName']; - - /** 设置归档类型 */ - $this->_archiveType = 'author'; - - /** 设置归档缩略名 */ - $this->_archiveSlug = $author['uid']; - - /** 插件接口 */ - $this->pluginHandle()->authorHandle($this, $select); - } - - /** - * 处理日期 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function dateHandle(Typecho_Db_Query $select, &$hasPushed) - { - /** 如果是按日期归档 */ - $year = $this->request->filter('int')->year; - $month = $this->request->filter('int')->month; - $day = $this->request->filter('int')->day; - - if (!empty($year) && !empty($month) && !empty($day)) { - - /** 如果按日归档 */ - $from = mktime(0, 0, 0, $month, $day, $year); - $to = mktime(23, 59, 59, $month, $day, $year); - - /** 归档缩略名 */ - $this->_archiveSlug = 'day'; - - /** 设置标题 */ - $this->_archiveTitle = _t('%d年%d月%d日', $year, $month, $day); - } else if (!empty($year) && !empty($month)) { - - /** 如果按月归档 */ - $from = mktime(0, 0, 0, $month, 1, $year); - $to = mktime(23, 59, 59, $month, date('t', $from), $year); - - /** 归档缩略名 */ - $this->_archiveSlug = 'month'; - - /** 设置标题 */ - $this->_archiveTitle = _t('%d年%d月', $year, $month); - } else if (!empty($year)) { - - /** 如果按年归档 */ - $from = mktime(0, 0, 0, 1, 1, $year); - $to = mktime(23, 59, 59, 12, 31, $year); - - /** 归档缩略名 */ - $this->_archiveSlug = 'year'; - - /** 设置标题 */ - $this->_archiveTitle = _t('%d年', $year); - } - - $select->where('table.contents.created >= ?', $from - $this->options->timezone + $this->options->serverTimezone) - ->where('table.contents.created <= ?', $to - $this->options->timezone + $this->options->serverTimezone) - ->where('table.contents.type = ?', 'post'); - - /** 设置归档类型 */ - $this->_archiveType = 'date'; - - /** 设置头部feed */ - $value = array('year' => $year, 'month' => str_pad($month, 2, '0', STR_PAD_LEFT), 'day' => str_pad($day, 2, '0', STR_PAD_LEFT)); - - /** 设置分页 */ - $this->_pageRow = $value; - - /** 获取当前路由,过滤掉翻页情况 */ - $currentRoute = str_replace('_page', '', $this->parameter->type); - - /** RSS 2.0 */ - $this->_feedUrl = Typecho_Router::url($currentRoute, $value, $this->options->feedUrl); - - /** RSS 1.0 */ - $this->_feedRssUrl = Typecho_Router::url($currentRoute, $value, $this->options->feedRssUrl); - - /** ATOM 1.0 */ - $this->_feedAtomUrl = Typecho_Router::url($currentRoute, $value, $this->options->feedAtomUrl); - - /** 插件接口 */ - $this->pluginHandle()->dateHandle($this, $select); - } - - /** - * 处理搜索 - * - * @access private - * @param Typecho_Db_Query $select 查询对象 - * @param boolean $hasPushed 是否已经压入队列 - * @return void - */ - private function searchHandle(Typecho_Db_Query $select, &$hasPushed) - { - /** 增加自定义搜索引擎接口 */ - //~ fix issue 40 - $keywords = $this->request->filter('url', 'search')->keywords; - $this->pluginHandle()->trigger($hasPushed)->search($keywords, $this); - - if (!$hasPushed) { - $searchQuery = '%' . str_replace(' ', '%', $keywords) . '%'; - - /** 搜索无法进入隐私项保护归档 */ - $select->where('table.contents.password IS NULL') - ->where('table.contents.title LIKE ? OR table.contents.text LIKE ?', $searchQuery, $searchQuery) - ->where('table.contents.type = ?', 'post'); - } - - /** 设置关键词 */ - $this->_keywords = $keywords; - - /** 设置分页 */ - $this->_pageRow = array('keywords' => urlencode($keywords)); - - /** 设置头部feed */ - /** RSS 2.0 */ - $this->_feedUrl = Typecho_Router::url('search', array('keywords' => $keywords), $this->options->feedUrl); - - /** RSS 1.0 */ - $this->_feedRssUrl = Typecho_Router::url('search', array('keywords' => $keywords), $this->options->feedAtomUrl); - - /** ATOM 1.0 */ - $this->_feedAtomUrl = Typecho_Router::url('search', array('keywords' => $keywords), $this->options->feedAtomUrl); - - /** 设置标题 */ - $this->_archiveTitle = $keywords; - - /** 设置归档类型 */ - $this->_archiveType = 'search'; - - /** 插件接口 */ - $this->pluginHandle()->searchHandle($this, $select); - } - - /** - * 重载select - * - * @access public - * @return void - */ - public function select() - { - if ($this->_feed) { - // 对feed输出加入限制条件 - return parent::select()->where('table.contents.allowFeed = ?', 1) - ->where('table.contents.password IS NULL'); - } else { - return parent::select(); - } - } - - /** - * 提交查询 - * - * @access public - * @param mixed $select 查询对象 - * @return void - */ - public function query($select) - { - $this->pluginHandle()->trigger($queryPlugged)->query($this, $select); - if (!$queryPlugged) { - $this->db->fetchAll($select, array($this, 'push')); - } - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 避免重复取数据 */ - if ($this->have()) { - return; - } - - $handles = array( - 'index' => 'indexHandle', - 'index_page' => 'indexHandle', - 'archive' => 'error404Handle', - 'archive_page' => 'error404Handle', - 404 => 'error404Handle', - 'page' => 'singleHandle', - 'post' => 'singleHandle', - 'attachment' => 'singleHandle', - 'comment_page' => 'singleHandle', - 'category' => 'categoryHandle', - 'category_page' => 'categoryHandle', - 'tag' => 'tagHandle', - 'tag_page' => 'tagHandle', - 'author' => 'authorHandle', - 'author_page' => 'authorHandle', - 'archive_year' => 'dateHandle', - 'archive_year_page' => 'dateHandle', - 'archive_month' => 'dateHandle', - 'archive_month_page' => 'dateHandle', - 'archive_day' => 'dateHandle', - 'archive_day_page' => 'dateHandle', - 'search' => 'searchHandle', - 'search_page' => 'searchHandle' - ); - - /** 处理搜索结果跳转 */ - if (isset($this->request->s)) { - $filterKeywords = $this->request->filter('search')->s; - - /** 跳转到搜索页 */ - if (NULL != $filterKeywords) { - $this->response->redirect(Typecho_Router::url('search', - array('keywords' => urlencode($filterKeywords)), $this->options->index)); - } - } - - /** 自定义首页功能 */ - $frontPage = $this->options->frontPage; - if (!$this->_invokeByFeed && ('index' == $this->parameter->type || 'index_page' == $this->parameter->type)) { - //显示某个页面 - if (0 === strpos($frontPage, 'page:')) { - // 对某些变量做hack - $this->request->setParam('cid', intval(substr($frontPage, 5))); - $this->parameter->type = 'page'; - $this->_makeSinglePageAsFrontPage = true; - } else if (0 === strpos($frontPage, 'file:')) { - // 显示某个文件 - $this->setThemeFile(substr($frontPage, 5)); - return; - } - } - - if ('recent' != $frontPage && $this->options->frontArchive) { - $handles['archive'] = 'indexHandle'; - $handles['archive_page'] = 'indexHandle'; - $this->_archiveType = 'front'; - } - - /** 初始化分页变量 */ - $this->_currentPage = isset($this->request->page) ? $this->request->page : 1; - $hasPushed = false; - - /** select初始化 */ - $select = $this->pluginHandle()->trigger($selectPlugged)->select($this); - - /** 定时发布功能 */ - if (!$selectPlugged) { - if ('post' == $this->parameter->type || 'page' == $this->parameter->type) { - if ($this->user->hasLogin()) { - $select = $this->select()->where('table.contents.status = ? OR table.contents.status = ? OR - (table.contents.status = ? AND table.contents.authorId = ?)', - 'publish', 'hidden', 'private', $this->user->uid); - } else { - $select = $this->select()->where('table.contents.status = ? OR table.contents.status = ?', - 'publish', 'hidden'); - } - } else { - if ($this->user->hasLogin()) { - $select = $this->select()->where('table.contents.status = ? OR - (table.contents.status = ? AND table.contents.authorId = ?)', 'publish', 'private', $this->user->uid); - } else { - $select = $this->select()->where('table.contents.status = ?', 'publish'); - } - } - $select->where('table.contents.created < ?', $this->options->gmtTime); - } - - /** handle初始化 */ - $this->pluginHandle()->handleInit($this, $select); - - /** 初始化其它变量 */ - $this->_feedUrl = $this->options->feedUrl; - $this->_feedRssUrl = $this->options->feedRssUrl; - $this->_feedAtomUrl = $this->options->feedAtomUrl; - $this->_keywords = $this->options->keywords; - $this->_description = $this->options->description; - - if (isset($handles[$this->parameter->type])) { - $handle = $handles[$this->parameter->type]; - $this->{$handle}($select, $hasPushed); - } else { - $hasPushed = $this->pluginHandle()->handle($this->parameter->type, $this, $select); - } - - /** 初始化皮肤函数 */ - $functionsFile = $this->_themeDir . 'functions.php'; - if (!$this->_invokeFromOutside && file_exists($functionsFile)) { - require_once $functionsFile; - if (function_exists('themeInit')) { - themeInit($this); - } - } - - /** 如果已经提前压入则直接返回 */ - if ($hasPushed) { - return; - } - - /** 仅输出文章 */ - $this->_countSql = clone $select; - - $select->order('table.contents.created', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); - $this->query($select); - } - - /** - * 输出文章内容 - * - * @access public - * @param string $more 文章截取后缀 - * @return void - */ - public function content($more = NULL) - { - parent::content($this->is('single') ? false : $more); - } - - /** - * 输出分页 - * - * @access public - * @param string $prev 上一页文字 - * @param string $next 下一页文字 - * @param int $splitPage 分割范围 - * @param string $splitWord 分割字符 - * @return void - */ - public function pageNav($prev = '«', $next = '»', $splitPage = 3, $splitWord = '...', - $class = 'page-navigator', $currentClass = 'current') - { - if ($this->have()) { - $hasNav = false; - $this->_total = (false === $this->_total ? $this->size($this->_countSql) : $this->_total); - $this->pluginHandle()->trigger($hasNav)->pageNav($this->_currentPage, $this->_total, - $this->parameter->pageSize, $prev, $next, $splitPage, $splitWord); - - if (!$hasNav && $this->_total > $this->parameter->pageSize) { - $query = Typecho_Router::url($this->parameter->type . - (false === strpos($this->parameter->type, '_page') ? '_page' : NULL), - $this->_pageRow, $this->options->index); - - /** 使用盒状分页 */ - $nav = new Typecho_Widget_Helper_PageNavigator_Box($this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); - - echo '<ol class="' . $class . '">'; - $nav->render($prev, $next, $splitPage, $splitWord, $currentClass); - echo '</ol>'; - } - } - } - - /** - * 前一页 - * - * @access public - * @param string $word 链接标题 - * @param string $page 页面链接 - * @return void - */ - public function pageLink($word = '« Previous Entries', $page = 'prev') - { - if ($this->have()) { - if (empty($this->_pageNav)) { - $query = Typecho_Router::url($this->parameter->type . - (false === strpos($this->parameter->type, '_page') ? '_page' : NULL), - $this->_pageRow, $this->options->index); - - /** 使用盒状分页 */ - $this->_pageNav = new Typecho_Widget_Helper_PageNavigator_Classic(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); - } - - $this->_pageNav->{$page}($word); - } - } - - /** - * 获取评论归档对象 - * - * @access public - * @return Widget_Abstract_Comments - */ - public function comments() - { - $parameter = array( - 'parentId' => $this->hidden ? 0 : $this->cid, - 'parentContent' => $this->row, - 'respondId' => $this->respondId, - 'commentPage' => $this->request->filter('int')->commentPage, - 'allowComment' => $this->allow('comment') - ); - - return $this->widget('Widget_Comments_Archive', $parameter); - } - - /** - * 获取回响归档对象 - * - * @access public - * @return void - */ - public function pings() - { - return $this->widget('Widget_Comments_Ping', array( - 'parentId' => $this->hidden ? 0 : $this->cid, - 'parentContent' => $this->row, - 'allowPing' => $this->allow('ping') - )); - } - - /** - * 获取附件对象 - * - * @access public - * @param integer $limit 最大个数 - * @param integer $offset 重新 - * @return Widget_Contents_Attachment_Related - */ - public function attachments($limit = 0, $offset = 0) - { - return $this->widget('Widget_Contents_Attachment_Related', array('parentId' => $this->cid, 'limit' => $limit)); - } - - /** - * 显示下一个内容的标题链接 - * - * @access public - * @param string $format 格式 - * @param string $default 如果没有下一篇,显示的默认文字 - * @return void - */ - public function theNext($format = '%s', $default = NULL) - { - $content = $this->db->fetchRow($this->select()->where('table.contents.created > ? AND table.contents.created < ?', - $this->created, $this->options->gmtTime) - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.type = ?', $this->type) - ->where('table.contents.password IS NULL') - ->order('table.contents.created', Typecho_Db::SORT_ASC) - ->limit(1)); - - if ($content) { - $content = $this->filter($content); - $link = '<a href="' . $content['permalink'] . '" title="' . $content['title'] . '">' . $content['title'] . '</a>'; - printf($format, $link); - } else { - echo $default; - } - } - - /** - * 显示上一个内容的标题链接 - * - * @access public - * @param string $format 格式 - * @param string $default 如果没有上一篇,显示的默认文字 - * @return void - */ - public function thePrev($format = '%s', $default = NULL) - { - $content = $this->db->fetchRow($this->select()->where('table.contents.created < ?', $this->created) - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.type = ?', $this->type) - ->where('table.contents.password IS NULL') - ->order('table.contents.created', Typecho_Db::SORT_DESC) - ->limit(1)); - - if ($content) { - $content = $this->filter($content); - $link = '<a href="' . $content['permalink'] . '" title="' . $content['title'] . '">' . $content['title'] . '</a>'; - printf($format, $link); - } else { - echo $default; - } - } - - /** - * 获取关联内容组件 - * - * @access public - * @param integer $limit 输出数量 - * @param string $type 关联类型 - * @return Typecho_Widget - */ - public function related($limit = 5, $type = NULL) - { - $type = strtolower($type); - - switch ($type) { - case 'author': - /** 如果访问权限被设置为禁止,则tag会被置为空 */ - return $this->widget('Widget_Contents_Related_Author', - array('cid' => $this->cid, 'type' => $this->type, 'author' => $this->author->uid, 'limit' => $limit)); - default: - /** 如果访问权限被设置为禁止,则tag会被置为空 */ - return $this->widget('Widget_Contents_Related', - array('cid' => $this->cid, 'type' => $this->type, 'tags' => $this->tags, 'limit' => $limit)); - } - } - - /** - * 输出头部元数据 - * - * @access public - * @param string $rule 规则 - * @return void - */ - public function header($rule = NULL) - { - $rules = array(); - $allows = array( - 'description' => htmlspecialchars($this->_description), - 'keywords' => htmlspecialchars($this->_keywords), - 'generator' => $this->options->generator, - 'template' => $this->options->theme, - 'pingback' => $this->options->xmlRpcUrl, - 'xmlrpc' => $this->options->xmlRpcUrl . '?rsd', - 'wlw' => $this->options->xmlRpcUrl . '?wlw', - 'rss2' => $this->_feedUrl, - 'rss1' => $this->_feedRssUrl, - 'commentReply' => 1, - 'atom' => $this->_feedAtomUrl - ); - - /** 头部是否输出聚合 */ - $allowFeed = !$this->is('single') || $this->allow('feed') || $this->_makeSinglePageAsFrontPage; - - if (!empty($rule)) { - parse_str($rule, $rules); - $allows = array_merge($allows, $rules); - } - - $allows = $this->pluginHandle()->headerOptions($allows, $this); - - $header = ''; - if (!empty($allows['description'])) { - $header .= '<meta name="description" content="' . $allows['description'] . '" />' . "\n"; - } - - if (!empty($allows['keywords'])) { - $header .= '<meta name="keywords" content="' . $allows['keywords'] . '" />' . "\n"; - } - - if (!empty($allows['generator'])) { - $header .= '<meta name="generator" content="' . $allows['generator'] . '" />' . "\n"; - } - - if (!empty($allows['template'])) { - $header .= '<meta name="template" content="' . $allows['template'] . '" />' . "\n"; - } - - if (!empty($allows['pingback'])) { - $header .= '<link rel="pingback" href="' . $allows['pingback'] . '" />' . "\n"; - } - - if (!empty($allows['xmlrpc'])) { - $header .= '<link rel="EditURI" type="application/rsd+xml" title="RSD" href="' . $allows['xmlrpc'] . '" />' . "\n"; - } - - if (!empty($allows['wlw'])) { - $header .= '<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="' . $allows['wlw'] . '" />' . "\n"; - } - - if (!empty($allows['rss2']) && $allowFeed) { - $header .= '<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="' . $allows['rss2'] . '" />' . "\n"; - } - - if (!empty($allows['rss1']) && $allowFeed) { - $header .= '<link rel="alternate" type="application/rdf+xml" title="RSS 1.0" href="' . $allows['rss1'] . '" />' . "\n"; - } - - if (!empty($allows['atom']) && $allowFeed) { - $header .= '<link rel="alternate" type="application/atom+xml" title="ATOM 1.0" href="' . $allows['atom'] . '" />' . "\n"; - } - - if ($this->options->commentsThreaded && $this->is('single')) { - if ('' != $allows['commentReply']) { - if (1 == $allows['commentReply']) { - $header .= "<script type=\"text/javascript\"> -//<![CDATA[ -var TypechoComment = { - dom : function (id) { - return document.getElementById(id); - }, - - create : function (tag, attr) { - var el = document.createElement(tag); - - for (var key in attr) { - el.setAttribute(key, attr[key]); - } - - return el; - }, - - reply : function (cid, coid) { - var comment = this.dom(cid), parent = comment.parentNode, - response = this.dom('" . $this->respondId . "'), input = this.dom('comment-parent'), - form = 'form' == response.tagName ? response : response.getElementsByTagName('form')[0], - textarea = response.getElementsByTagName('textarea')[0]; - - if (null == input) { - input = this.create('input', { - 'type' : 'hidden', - 'name' : 'parent', - 'id' : 'comment-parent' - }); - - form.appendChild(input); - } - - input.setAttribute('value', coid); - - if (null == this.dom('comment-form-place-holder')) { - var holder = this.create('div', { - 'id' : 'comment-form-place-holder' - }); - - response.parentNode.insertBefore(holder, response); - } - - comment.appendChild(response); - this.dom('cancel-comment-reply-link').style.display = ''; - - if (null != textarea && 'text' == textarea.name) { - textarea.focus(); - } - - return false; - }, - - cancelReply : function () { - var response = this.dom('" . $this->respondId . "'), - holder = this.dom('comment-form-place-holder'), input = this.dom('comment-parent'); - - if (null != input) { - input.parentNode.removeChild(input); - } - - if (null == holder) { - return true; - } - - this.dom('cancel-comment-reply-link').style.display = 'none'; - holder.parentNode.insertBefore(response, holder); - return false; - } -} -//]]> -</script>"; - } else { - $header .= '<script src="' . $allows['commentReply'] . '" type="text/javascript"></script>'; - } - } - } - - /** 插件支持 */ - $this->pluginHandle()->header($header, $this); - - /** 输出header */ - echo $header; - } - - /** - * 支持页脚自定义 - * - * @access public - * @return void - */ - public function footer() - { - $this->pluginHandle()->footer($this); - } - - /** - * 输出cookie记忆别名 - * - * @access public - * @param string $cookieName 已经记忆的cookie名称 - * @param string $return 是否返回 - * @return string - */ - public function remember($cookieName, $return = false) - { - $cookieName = strtolower($cookieName); - if (!in_array($cookieName, array('author', 'mail', 'url'))) { - return; - } - - $value = Typecho_Cookie::get('__typecho_remember_' . $cookieName); - if ($return) { - return $value; - } else { - echo htmlspecialchars($value); - } - } - - /** - * 输出归档标题 - * - * @param mixed $defines - * @param string $before - * @param string $end - * @access public - * @return void - */ - public function archiveTitle($defines = NULL, $before = ' » ', $end = '') - { - if ($this->_archiveTitle) { - $define = '%s'; - if (is_array($defines) && !empty($defines[$this->_archiveType])) { - $define = $defines[$this->_archiveType]; - } - - echo $before . sprintf($define, $this->_archiveTitle) . $end; - } - } - - /** - * 输出关键字 - * - * @access public - * @return unknown - */ - public function keywords($split = ',', $default = '') - { - echo empty($this->_keywords) ? $default : str_replace(',', $split, htmlspecialchars($this->_keywords)); - } - - /** - * 判断归档类型和名称 - * - * @access public - * @param string $archiveType 归档类型 - * @param string $archiveSlug 归档名称 - * @return boolean - */ - public function is($archiveType, $archiveSlug = NULL) - { - return ($archiveType == $this->_archiveType || - (($this->_archiveSingle ? 'single' : 'archive') == $archiveType && 'index' != $this->_archiveType) || - ('index' == $archiveType && $this->_makeSinglePageAsFrontPage)) - && (empty($archiveSlug) ? true : $archiveSlug == $this->_archiveSlug); - } - - /** - * 获取主题文件 - * - * @access public - * @param string $fileName 主题文件 - * @return void - */ - public function need($fileName) - { - require __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_THEME_DIR__ . '/' . $this->options->theme . '/' . $fileName; - } - - /** - * 输出视图 - * - * @access public - * @return void - */ - public function render() - { - /** 处理静态链接跳转 */ - $this->checkPermalink(); - - /** 添加Pingback */ - $this->response->setHeader('X-Pingback', $this->options->xmlRpcUrl); - $validated = false; - - //~ 自定义模板 - if (!empty($this->_themeFile)) { - if (file_exists($this->_themeDir . $this->_themeFile)) { - $validated = true; - } - } - - if (!$validated && !empty($this->_archiveType)) { - - //~ 首先找具体路径, 比如 category/default.php - if (!$validated && !empty($this->_archiveSlug)) { - $themeFile = $this->_archiveType . '/' . $this->_archiveSlug . '.php'; - if (file_exists($this->_themeDir . $themeFile)) { - $this->_themeFile = $themeFile; - $validated = true; - } - } - - //~ 然后找归档类型路径, 比如 category.php - if (!$validated) { - $themeFile = $this->_archiveType . '.php'; - if (file_exists($this->_themeDir . $themeFile)) { - $this->_themeFile = $themeFile; - $validated = true; - } - } - - //针对attachment的hook - if (!$validated && 'attachment' == $this->_archiveType) { - if (file_exists($this->_themeDir . 'page.php')) { - $this->_themeFile = 'page.php'; - $validated = true; - } else if (file_exists($this->_themeDir . 'post.php')) { - $this->_themeFile = 'post.php'; - $validated = true; - } - } - - //~ 最后找归档路径, 比如 archive.php 或者 single.php - if (!$validated && 'index' != $this->_archiveType && 'front' != $this->_archiveType) { - $themeFile = $this->_archiveSingle ? 'single.php' : 'archive.php'; - if (file_exists($this->_themeDir . $themeFile)) { - $this->_themeFile = $themeFile; - $validated = true; - } - } - - if (!$validated) { - $themeFile = 'index.php'; - if (file_exists($this->_themeDir . $themeFile)) { - $this->_themeFile = $themeFile; - $validated = true; - } - } - } - - /** 文件不存在 */ - if (!$validated) { - Typecho_Common::error(500); - } - - /** 挂接插件 */ - $this->pluginHandle()->beforeRender($this); - - /** 输出模板 */ - require_once $this->_themeDir . $this->_themeFile; - - /** 挂接插件 */ - $this->pluginHandle()->afterRender($this); - } - - /** - * 输出feed - * - * @access public - * @return void - */ - public function feed() - { - $this->_feed->setSubTitle($this->_description); - $this->_feed->setFeedUrl($this->_currentFeedUrl); - - $this->_feed->setBaseUrl(('/' == $this->request->feed || 0 == strlen($this->request->feed) - || '/comments' == $this->request->feed || '/comments/' == $this->request->feed) ? - $this->options->siteUrl : Typecho_Common::url($this->request->feed, $this->options->index)); - $this->_feed->setFeedUrl($this->request->makeUriByRequest()); - - if ($this->is('single') || 'comments' == $this->parameter->type) { - $this->_feed->setTitle(_t('%s 的评论', - $this->options->title . ($this->_archiveTitle ? ' - ' . $this->_archiveTitle : NULL))); - - if ('comments' == $this->parameter->type) { - $comments = $this->widget('Widget_Comments_Recent', 'pageSize=10'); - } else { - $comments = $this->widget('Widget_Comments_Recent', 'pageSize=10&parentId=' . $this->cid); - } - - while ($comments->next()) { - $suffix = $this->pluginHandle()->trigger($plugged)->commentFeedItem($this->_feedType, $comments); - if (!$plugged) { - $suffix = NULL; - } - - $this->_feed->addItem(array( - 'title' => $comments->author, - 'content' => $comments->content, - 'date' => $comments->created, - 'link' => $comments->permalink, - 'author' => (object) array( - 'screenName' => $comments->author, - 'url' => $comments->url, - 'mail' => $comments->mail - ), - 'excerpt' => strip_tags($comments->content), - 'suffix' => $suffix - )); - } - } else { - $this->_feed->setTitle($this->options->title . ($this->_archiveTitle ? ' - ' . $this->_archiveTitle : NULL)); - - while ($this->next()) { - $suffix = $this->pluginHandle()->trigger($plugged)->feedItem($this->_feedType, $this); - if (!$plugged) { - $suffix = NULL; - } - - $feedUrl = ''; - if (Typecho_Feed::RSS2 == $this->_feedType) { - $feedUrl = $this->feedUrl; - } else if (Typecho_Feed::RSS1 == $this->_feedType) { - $feedUrl = $this->feedRssUrl; - } else if (Typecho_Feed::ATOM1 == $this->_feedType) { - $feedUrl = $this->feedAtomUrl; - } - - $this->_feed->addItem(array( - 'title' => $this->title, - 'content' => $this->options->feedFullText ? $this->content : (false !== strpos($this->text, '<!--more-->') ? - $this->excerpt . "<p class=\"more\"><a href=\"{$this->permalink}\" title=\"{$this->title}\">[...]</a></p>" : $this->content), - 'date' => $this->created, - 'link' => $this->permalink, - 'author' => $this->author, - 'excerpt' => $this->description, - 'comments' => $this->commentsNum, - 'commentsFeedUrl' => $feedUrl, - 'suffix' => $suffix - )); - } - } - - $this->response->setContentType($this->_feedContentType); - echo $this->_feed->__toString(); - } -} diff --git a/php/typecho09/var/Widget/Comments/Admin.php b/php/typecho09/var/Widget/Comments/Admin.php deleted file mode 100644 index b9145a4b5..000000000 --- a/php/typecho09/var/Widget/Comments/Admin.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 后台评论输出组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Comments_Admin extends Widget_Abstract_Comments -{ - /** - * 分页计算对象 - * - * @access private - * @var Typecho_Db_Query - */ - private $_countSql; - - /** - * 当前页 - * - * @access private - * @var integer - */ - private $_currentPage; - - /** - * 所有文章个数 - * - * @access private - * @var integer - */ - private $_total = false; - - /** - * 获取当前内容结构 - * - * @access protected - * @return array - */ - protected function ___parentContent() - { - $cid = isset($this->request->cid) ? $this->request->filter('int')->cid : $this->cid; - return $this->db->fetchRow($this->widget('Widget_Abstract_Contents')->select() - ->where('table.contents.cid = ?', $cid) - ->limit(1), array($this->widget('Widget_Abstract_Contents'), 'filter')); - } - - /** - * 获取菜单标题 - * - * @access public - * @return string - */ - public function getMenuTitle() - { - $content = $this->parentContent; - - if ($content) { - return _t('%s的评论', $content['title']); - } - - throw new Typecho_Widget_Exception(_t('内容不存在'), 404); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $select = $this->select(); - $this->parameter->setDefault('pageSize=20'); - $this->_currentPage = $this->request->get('page', 1); - - /** 过滤标题 */ - if (NULL != ($keywords = $this->request->filter('search')->keywords)) { - $select->where('table.comments.text LIKE ?', '%' . $keywords . '%'); - } - - /** 如果具有贡献者以上权限,可以查看所有评论,反之只能查看自己的评论 */ - if (!$this->user->pass('editor', true)) { - $select->where('table.comments.ownerId = ?', $this->user->uid); - } else if (!isset($this->request->cid)) { - if ('on' == $this->request->__typecho_all_comments) { - Typecho_Cookie::set('__typecho_all_comments', 'on'); - } else { - if ('off' == $this->request->__typecho_all_comments) { - Typecho_Cookie::set('__typecho_all_comments', 'off'); - } - - if ('on' != Typecho_Cookie::get('__typecho_all_comments')) { - $select->where('table.comments.ownerId = ?', $this->user->uid); - } - } - } - - if (in_array($this->request->status, array('approved', 'waiting', 'spam'))) { - $select->where('table.comments.status = ?', $this->request->status); - } else if ('hold' == $this->request->status) { - $select->where('table.comments.status <> ?', 'approved'); - } else { - $select->where('table.comments.status = ?', 'approved'); - } - - //增加按文章归档功能 - if (isset($this->request->cid)) { - $select->where('table.comments.cid = ?', $this->request->filter('int')->cid); - } - - $this->_countSql = clone $select; - - $select->order('table.comments.coid', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); - - $this->db->fetchAll($select, array($this, 'push')); - } - - /** - * 输出分页 - * - * @access public - * @return void - */ - public function pageNav() - { - $query = $this->request->makeUriByRequest('page={page}'); - - /** 使用盒状分页 */ - $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); - $nav->render(_t('«'), _t('»')); - } -} diff --git a/php/typecho09/var/Widget/Comments/Archive.php b/php/typecho09/var/Widget/Comments/Archive.php deleted file mode 100644 index 1c6d99925..000000000 --- a/php/typecho09/var/Widget/Comments/Archive.php +++ /dev/null @@ -1,491 +0,0 @@ -<?php -/** - * 评论归档 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 评论归档组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Comments_Archive extends Widget_Abstract_Comments -{ - /** - * 当前页 - * - * @access private - * @var integer - */ - private $_currentPage; - - /** - * 所有文章个数 - * - * @access private - * @var integer - */ - private $_total = false; - - /** - * 子父级评论关系 - * - * @access private - * @var array - */ - private $_threadedComments = array(); - - /** - * 多级评论回调函数 - * - * @access private - * @var mixed - */ - private $_customThreadedCommentsCallback = false; - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - $this->parameter->setDefault('parentId=0&commentPage=0&commentsNum=0&allowComment=1'); - - /** 初始化回调函数 */ - if (function_exists('threadedComments')) { - $this->_customThreadedCommentsCallback = true; - } - } - - /** - * 评论回调函数 - * - * @access private - * @param string $singleCommentOptions 单个评论自定义选项 - * @return void - */ - private function threadedCommentsCallback($singleCommentOptions) - { - if ($this->_customThreadedCommentsCallback) { - return threadedComments($this, $singleCommentOptions); - } - - $commentClass = ''; - if ($this->authorId) { - if ($this->authorId == $this->ownerId) { - $commentClass .= ' comment-by-author'; - } else { - $commentClass .= ' comment-by-user'; - } - } - - $commentLevelClass = $this->levels > 0 ? ' comment-child' : ' comment-parent'; -?> -<li id="<?php $this->theId(); ?>" class="comment-body<?php - if ($this->levels > 0) { - echo ' comment-child'; - $this->levelsAlt(' comment-level-odd', ' comment-level-even'); - } else { - echo ' comment-parent'; - } - $this->alt(' comment-odd', ' comment-even'); - echo $commentClass; -?>"> - <div class="comment-author"> - <?php $this->gravatar($singleCommentOptions->avatarSize, $singleCommentOptions->defaultAvatar); ?> - <cite class="fn"><?php $singleCommentOptions->beforeAuthor(); - $this->author(); - $singleCommentOptions->afterAuthor(); ?></cite> - </div> - <div class="comment-meta"> - <a href="<?php $this->permalink(); ?>"><?php $singleCommentOptions->beforeDate(); - $this->date($singleCommentOptions->dateFormat); - $singleCommentOptions->afterDate(); ?></a> - <?php if ('waiting' == $this->status) { ?> - <em class="comment-awaiting-moderation"><?php $singleCommentOptions->commentStatus(); ?></em> - <?php } ?> - </div> - <div class="comment-content"> - <?php $this->content(); ?> - </div> - <div class="comment-reply"> - <?php $this->reply($singleCommentOptions->replyWord); ?> - </div> - <?php if ($this->children) { ?> - <div class="comment-children"> - <?php $this->threadedComments($singleCommentOptions); ?> - </div> - <?php } ?> -</li> -<?php - } - - /** - * 获取当前评论链接 - * - * @access protected - * @return string - */ - protected function ___permalink() - { - - if ($this->options->commentsPageBreak) { - $pageRow = array('permalink' => $this->parentContent['pathinfo'], 'commentPage' => $this->_currentPage); - return Typecho_Router::url('comment_page', - $pageRow, $this->options->index) . '#' . $this->theId; - } - - return $this->parentContent['permalink'] . '#' . $this->theId; - } - - /** - * 子评论 - * - * @access protected - * @return array - */ - protected function ___children() - { - return $this->options->commentsThreaded && !$this->isTopLevel && isset($this->_threadedComments[$this->coid]) - ? $this->_threadedComments[$this->coid] : array(); - } - - /** - * 是否到达顶层 - * - * @access protected - * @return boolean - */ - protected function ___isTopLevel() - { - return $this->levels > $this->options->commentsMaxNestingLevels - 2; - } - - /** - * 重载内容获取 - * - * @access protected - * @return void - */ - protected function ___parentContent() - { - return $this->parameter->parentContent; - } - - /** - * 输出文章评论数 - * - * @access public - * @param string $string 评论数格式化数据 - * @return void - */ - public function num() - { - $args = func_get_args(); - if (!$args) { - $args[] = '%d'; - } - - $num = intval($this->_total); - - echo sprintf(isset($args[$num]) ? $args[$num] : array_pop($args), $num); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - if (!$this->parameter->parentId) { - return; - } - - $commentsAuthor = Typecho_Cookie::get('__typecho_remember_author'); - $commentsMail = Typecho_Cookie::get('__typecho_remember_mail'); - $select = $this->select()->where('table.comments.cid = ?', $this->parameter->parentId) - ->where('table.comments.status = ? OR (table.comments.author = ? AND table.comments.mail = ? AND table.comments.status = ?)', 'approved', $commentsAuthor, $commentsMail, 'waiting'); - $threadedSelect = NULL; - - if ($this->options->commentsShowCommentOnly) { - $select->where('table.comments.type = ?', 'comment'); - } - - $select->order('table.comments.coid', 'ASC'); - $this->db->fetchAll($select, array($this, 'push')); - - /** 需要输出的评论列表 */ - $outputComments = array(); - - /** 如果开启评论回复 */ - if ($this->options->commentsThreaded) { - - foreach ($this->stack as $coid => &$comment) { - - /** 取出父节点 */ - $parent = $comment['parent']; - - /** 如果存在父节点 */ - if (0 != $parent && isset($this->stack[$parent])) { - - /** 如果当前节点深度大于最大深度, 则将其挂接在父节点上 */ - if ($comment['levels'] >= $this->options->commentsMaxNestingLevels) { - $comment['levels'] = $this->stack[$parent]['levels']; - $parent = $this->stack[$parent]['parent']; // 上上层节点 - $comment['parent'] = $parent; - } - - /** 计算子节点顺序 */ - $comment['order'] = isset($this->_threadedComments[$parent]) - ? count($this->_threadedComments[$parent]) + 1 : 1; - - /** 如果是子节点 */ - $this->_threadedComments[$parent][$coid] = $comment; - } else { - $outputComments[$coid] = $comment; - } - - } - - $this->stack = $outputComments; - } - - /** 评论排序 */ - if ('DESC' == $this->options->commentsOrder) { - $this->stack = array_reverse($this->stack, true); - $this->_threadedComments = array_map('array_reverse', $this->_threadedComments); - } - - /** 评论总数 */ - $this->_total = count($this->stack); - - /** 对评论进行分页 */ - if ($this->options->commentsPageBreak) { - if ('last' == $this->options->commentsPageDisplay && !$this->parameter->commentPage) { - $this->_currentPage = ceil($this->_total / $this->options->commentsPageSize); - } else { - $this->_currentPage = $this->parameter->commentPage ? $this->parameter->commentPage : 1; - } - - /** 截取评论 */ - $this->stack = array_slice($this->stack, - ($this->_currentPage - 1) * $this->options->commentsPageSize, $this->options->commentsPageSize); - - /** 评论置位 */ - $this->row = current($this->stack); - $this->length = count($this->stack); - } - } - - /** - * 将每行的值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - $value = $this->filter($value); - - /** 计算深度 */ - if (0 != $value['parent'] && isset($this->stack[$value['parent']]['levels'])) { - $value['levels'] = $this->stack[$value['parent']]['levels'] + 1; - } else { - $value['levels'] = 0; - } - - /** 重载push函数,使用coid作为数组键值,便于索引 */ - $this->stack[$value['coid']] = $value; - - return $value; - } - - /** - * 输出分页 - * - * @access public - * @param string $prev 上一页文字 - * @param string $next 下一页文字 - * @param int $splitPage 分割范围 - * @param string $splitWord 分割字符 - * @return void - */ - public function pageNav($prev = '«', $next = '»', $splitPage = 3, $splitWord = '...') - { - if ($this->options->commentsPageBreak && $this->_total > $this->options->commentsPageSize) { - $pageRow = $this->parameter->parentContent; - $pageRow['permalink'] = $pageRow['pathinfo']; - - $query = Typecho_Router::url('comment_page', $pageRow, $this->options->index); - - /** 使用盒状分页 */ - $nav = new Typecho_Widget_Helper_PageNavigator_Box($this->_total, $this->_currentPage, $this->options->commentsPageSize, $query); - $nav->setPageHolder('commentPage'); - $nav->setAnchor('comments'); - - echo '<ol class="page-navigator">'; - $nav->render($prev, $next, $splitPage, $splitWord); - echo '</ol>'; - } - } - - /** - * 递归输出评论 - * - * @access protected - * @param string $before 在子评论之前输出 - * @param string $after 在子评论之后输出 - * @param Typecho_Config $singleCommentOptions 单个评论自定义选项 - * @return void - */ - public function threadedComments($singleCommentOptions = NULL) - { - $children = $this->children; - if ($children) { - //缓存变量便于还原 - $tmp = $this->row; - $this->sequence ++; - - //在子评论之前输出 - echo $singleCommentOptions->before; - - foreach ($children as $child) { - $this->row = $child; - $this->threadedCommentsCallback($singleCommentOptions); - $this->row = $tmp; - } - - //在子评论之后输出 - echo $singleCommentOptions->after; - - $this->sequence --; - } - } - - /** - * 列出评论 - * - * @access private - * @param mixed $singleCommentOptions 单个评论自定义选项 - * @return void - */ - public function listComments($singleCommentOptions = NULL) - { - if ($this->have()) { - //初始化一些变量 - $parsedSingleCommentOptions = Typecho_Config::factory($singleCommentOptions); - $parsedSingleCommentOptions->setDefault(array( - 'before' => '<ol class="comment-list">', - 'after' => '</ol>', - 'beforeAuthor' => '', - 'afterAuthor' => '', - 'beforeDate' => '', - 'afterDate' => '', - 'dateFormat' => $this->options->commentDateFormat, - 'replyWord' => _t('回复'), - 'commentStatus' => _t('您的评论正等待审核!'), - 'avatarSize' => 32, - 'defaultAvatar' => NULL - )); - - echo $parsedSingleCommentOptions->before; - - while ($this->next()) { - $this->threadedCommentsCallback($parsedSingleCommentOptions); - } - - echo $parsedSingleCommentOptions->after; - } - } - - /** - * 重载alt函数,以适应多级评论 - * - * @access public - * @return void - */ - public function alt() - { - $args = func_get_args(); - $num = func_num_args(); - - $sequence = $this->levels <= 0 ? $this->sequence : $this->order; - - $split = $sequence % $num; - echo $args[(0 == $split ? $num : $split) -1]; - } - - /** - * 根据深度余数输出 - * - * @access public - * @param string $param 需要输出的值 - * @return void - */ - public function levelsAlt() - { - $args = func_get_args(); - $num = func_num_args(); - $split = $this->levels % $num; - echo $args[(0 == $split ? $num : $split) -1]; - } - - /** - * 评论回复链接 - * - * @access public - * @param string $word 回复链接文字 - * @return void - */ - public function reply($word = '') - { - if ($this->options->commentsThreaded && !$this->isTopLevel && $this->parameter->allowComment) { - $word = empty($word) ? _t('回复') : $word; - $this->pluginHandle()->trigger($plugged)->reply($word, $this); - - if (!$plugged) { - echo '<a href="' . substr($this->permalink, 0, - strlen($this->theId) - 1) . '?replyTo=' . $this->coid . - '#' . $this->parameter->respondId . '" rel="nofollow" onclick="return TypechoComment.reply(\'' . - $this->theId . '\', ' . $this->coid . ');">' . $word . '</a>'; - } - } - } - - /** - * 取消评论回复链接 - * - * @access public - * @param string $word 取消回复链接文字 - * @return void - */ - public function cancelReply($word = '') - { - if ($this->options->commentsThreaded) { - $word = empty($word) ? _t('取消回复') : $word; - $this->pluginHandle()->trigger($plugged)->cancelReply($word, $this); - - if (!$plugged) { - $replyId = $this->request->filter('int')->replyTo; - echo '<a id="cancel-comment-reply-link" href="' . $this->parameter->parentContent['permalink'] . '#' . $this->parameter->respondId . - '" rel="nofollow"' . ($replyId ? '' : ' style="display:none"') . ' onclick="return TypechoComment.cancelReply();">' . $word . '</a>'; - } - } - } -} diff --git a/php/typecho09/var/Widget/Comments/Edit.php b/php/typecho09/var/Widget/Comments/Edit.php deleted file mode 100644 index dc6aa7358..000000000 --- a/php/typecho09/var/Widget/Comments/Edit.php +++ /dev/null @@ -1,378 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 评论编辑组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Comments_Edit extends Widget_Abstract_Comments implements Widget_Interface_Do -{ - /** - * 标记评论状态 - * - * @access private - * @param integer $coid 评论主键 - * @param string $status 状态 - * @return boolean - */ - private function mark($coid, $status) - { - $comment = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); - - if ($comment && $this->commentIsWriteable()) { - /** 增加评论编辑插件接口 */ - $this->pluginHandle()->mark($comment, $this, $status); - - /** 不必更新的情况 */ - if ($status == $comment['status']) { - return false; - } - - /** 更新评论 */ - $this->db->query($this->db->update('table.comments') - ->rows(array('status' => $status))->where('coid = ?', $coid)); - - /** 更新相关内容的评论数 */ - if ('approved' == $comment['status'] && 'approved' != $status) { - $this->db->query($this->db->update('table.contents') - ->expression('commentsNum', 'commentsNum - 1')->where('cid = ? AND commentsNum > 0', $comment['cid'])); - } else if ('approved' != $comment['status'] && 'approved' == $status) { - $this->db->query($this->db->update('table.contents') - ->expression('commentsNum', 'commentsNum + 1')->where('cid = ?', $comment['cid'])); - } - - return true; - } - - return false; - } - - /** - * 以数组形式获取coid - * - * @access private - * @return array - */ - private function getCoidAsArray() - { - $coid = $this->request->filter('int')->coid; - return $coid ? (is_array($coid) ? $coid : array($coid)) : array(); - } - - /** - * 标记为待审核 - * - * @access public - * @return void - */ - public function waitingComment() - { - $comments = $this->getCoidAsArray(); - $updateRows = 0; - - foreach ($comments as $comment) { - if ($this->mark($comment, 'waiting')) { - $updateRows ++; - } - } - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($updateRows > 0 ? _t('评论已经被标记为待审核') : _t('没有评论被标记为待审核'), - $updateRows > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 标记为垃圾 - * - * @access public - * @return void - */ - public function spamComment() - { - $comments = $this->getCoidAsArray(); - $updateRows = 0; - - foreach ($comments as $comment) { - if ($this->mark($comment, 'spam')) { - $updateRows ++; - } - } - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($updateRows > 0 ? _t('评论已经被标记为垃圾') : _t('没有评论被标记为垃圾'), - $updateRows > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 标记为展现 - * - * @access public - * @return void - */ - public function approvedComment() - { - $comments = $this->getCoidAsArray(); - $updateRows = 0; - - foreach ($comments as $comment) { - if ($this->mark($comment, 'approved')) { - $updateRows ++; - } - } - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($updateRows > 0 ? _t('评论已经被通过') : _t('没有评论被通过'), - $updateRows > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 删除评论 - * - * @access public - * @return void - */ - public function deleteComment() - { - $comments = $this->getCoidAsArray(); - $deleteRows = 0; - - foreach ($comments as $coid) { - $comment = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); - - if ($comment && $this->commentIsWriteable()) { - /** 删除评论 */ - $this->db->query($this->db->delete('table.comments')->where('coid = ?', $coid)); - - /** 更新相关内容的评论数 */ - if ('approved' == $comment['status']) { - $this->db->query($this->db->update('table.contents') - ->expression('commentsNum', 'commentsNum - 1')->where('cid = ?', $comment['cid'])); - } - - $deleteRows ++; - } - } - - if ($this->request->isAjax()) { - - if ($deleteRows > 0) { - $this->response->throwJson(array( - 'success' => 1, - 'message' => _t('删除评论成功') - )); - } else { - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('删除评论失败') - )); - } - - } else { - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteRows > 0 ? _t('评论已经被删除') : _t('没有评论被删除'), - $deleteRows > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - } - - /** - * 删除所有垃圾评论 - * - * @access public - * @return string - */ - public function deleteSpamComment() - { - $deleteQuery = $this->db->delete('table.comments')->where('status = ?', 'spam'); - if (!$this->request->__typecho_all_comments || !$this->user->pass('editor', true)) { - $deleteQuery->where('ownerId = ?', $this->user->uid); - } - - if (isset($this->request->cid)) { - $deleteQuery->where('cid = ?', $this->request->cid); - } - - $deleteRows = $this->db->query($deleteQuery); - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteRows > 0 ? - _t('所有垃圾评论已经被删除') : _t('没有垃圾评论被删除'), - $deleteRows > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 获取可编辑的评论 - * - * @access public - * @return void - */ - public function getComment() - { - $coid = $this->request->filter('int')->coid; - $comment = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); - - if ($comment && $this->commentIsWriteable()) { - - $this->response->throwJson(array( - 'success' => 1, - 'comment' => $comment - )); - - } else { - - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('获取评论失败') - )); - - } - } - - /** - * 编辑评论 - * - * @access public - * @return void - */ - public function editComment() - { - $coid = $this->request->filter('int')->coid; - $commentSelect = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); - - if ($commentSelect && $this->commentIsWriteable()) { - - $comment['text'] = $this->request->text; - $comment['author'] = $this->request->filter('strip_tags', 'trim', 'xss')->author; - $comment['mail'] = $this->request->filter('strip_tags', 'trim', 'xss')->mail; - $comment['url'] = $this->request->filter('url')->url; - - /** 评论插件接口 */ - $this->pluginHandle()->edit($comment, $this); - - /** 更新评论 */ - $this->update($comment, $this->db->sql()->where('coid = ?', $coid)); - - $updatedComment = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); - $updatedComment['content'] = $this->content; - - /** 评论插件接口 */ - $this->pluginHandle()->finishEdit($this); - - $this->response->throwJson(array( - 'success' => 1, - 'comment' => $updatedComment - )); - } - - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('修评论失败') - )); - } - - /** - * 回复评论 - * - * @access public - * @return void - */ - public function replyComment() - { - $coid = $this->request->filter('int')->coid; - $commentSelect = $this->db->fetchRow($this->select() - ->where('coid = ?', $coid)->limit(1), array($this, 'push')); - - if ($commentSelect && $this->commentIsWriteable()) { - - $comment = array( - 'cid' => $commentSelect['cid'], - 'created' => $this->options->gmtTime, - 'agent' => $this->request->getAgent(), - 'ip' => $this->request->getIp(), - 'ownerId' => $commentSelect['ownerId'], - 'authorId' => $this->user->uid, - 'type' => 'comment', - 'author' => $this->user->screenName, - 'mail' => $this->user->mail, - 'url' => $this->user->url, - 'parent' => $coid, - 'text' => $this->request->text, - 'status' => 'approved' - ); - - /** 评论插件接口 */ - $this->pluginHandle()->comment($comment, $this); - - /** 回复评论 */ - $commentId = $this->insert($comment); - - $insertComment = $this->db->fetchRow($this->select() - ->where('coid = ?', $commentId)->limit(1), array($this, 'push')); - $insertComment['content'] = $this->content; - - /** 评论完成接口 */ - $this->pluginHandle()->finishComment($this); - - $this->response->throwJson(array( - 'success' => 1, - 'comment' => $insertComment - )); - } - - $this->response->throwJson(array( - 'success' => 0, - 'message' => _t('回复评论失败') - )); - } - - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('contributor'); - $this->on($this->request->is('do=waiting'))->waitingComment(); - $this->on($this->request->is('do=spam'))->spamComment(); - $this->on($this->request->is('do=approved'))->approvedComment(); - $this->on($this->request->is('do=delete'))->deleteComment(); - $this->on($this->request->is('do=delete-spam'))->deleteSpamComment(); - $this->on($this->request->is('do=get&coid'))->getComment(); - $this->on($this->request->is('do=edit&coid'))->editComment(); - $this->on($this->request->is('do=reply&coid'))->replyComment(); - - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Comments/Ping.php b/php/typecho09/var/Widget/Comments/Ping.php deleted file mode 100644 index e8568ec90..000000000 --- a/php/typecho09/var/Widget/Comments/Ping.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php -/** - * 回响归档 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 回响归档组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Comments_Ping extends Widget_Abstract_Comments -{ - /** - * _customSinglePingCallback - * - * @var boolean - * @access private - */ - private $_customSinglePingCallback = false; - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - $this->parameter->setDefault('parentId=0'); - - /** 初始化回调函数 */ - if (function_exists('singlePing')) { - $this->_customSinglePingCallback = true; - } - } - - /** - * 重载内容获取 - * - * @access protected - * @return void - */ - protected function ___parentContent() - { - return $this->parameter->parentContent; - } - - /** - * 回响回调函数 - * - * @access private - * @param string $singlePingOptions 单个回响自定义选项 - * @return void - */ - private function singlePingCallback($singlePingOptions) - { - if ($this->_customSinglePingCallback) { - return singlePing($this, $singlePingOptions); - } - -?> -<li id="<?php $this->theId(); ?>" class="ping-body"> - <div class="ping-title"> - <cite class="fn"><?php - $singlePingOptions->beforeTitle(); - $this->author(true); - $singlePingOptions->afterTitle(); - ?></cite> - </div> - <div class="ping-meta"> - <a href="<?php $this->permalink(); ?>"><?php $singlePingOptions->beforeDate(); - $this->date($singlePingOptions->dateFormat); - $singlePingOptions->afterDate(); ?></a> - </div> - <?php $this->content(); ?> -</li> -<?php - } - - /** - * 输出文章回响数 - * - * @access public - * @param string $string 评论数格式化数据 - * @return void - */ - public function num() - { - $args = func_get_args(); - if (!$args) { - $args[] = '%d'; - } - - echo sprintf(isset($args[$this->length]) ? $args[$this->length] : array_pop($this->length), $this->length); - } - - /** - * execute - * - * @access public - * @return void - */ - public function execute() - { - if (!$this->parameter->parentId) { - return; - } - - $select = $this->select()->where('table.comments.status = ?', 'approved') - ->where('table.comments.cid = ?', $this->parameter->parentId) - ->where('table.comments.type <> ?', 'comment') - ->order('table.comments.coid', 'ASC'); - - $this->db->fetchAll($select, array($this, 'push')); - } - - /** - * 列出回响 - * - * @access private - * @param mixed $singlePingOptions 单个回响自定义选项 - * @return void - */ - public function listPings($singlePingOptions = NULL) - { - if ($this->have()) { - //初始化一些变量 - $parsedSinglePingOptions = Typecho_Config::factory($singlePingOptions); - $parsedSinglePingOptions->setDefault(array( - 'before' => '<ol class="ping-list">', - 'after' => '</ol>', - 'beforeTitle' => '', - 'afterTitle' => '', - 'beforeDate' => '', - 'afterDate' => '', - 'dateFormat' => $this->options->commentDateFormat - )); - - echo $parsedSinglePingOptions->before; - - while ($this->next()) { - $this->singlePingCallback($parsedSinglePingOptions); - } - - echo $parsedSinglePingOptions->after; - } - } -} diff --git a/php/typecho09/var/Widget/Comments/Recent.php b/php/typecho09/var/Widget/Comments/Recent.php deleted file mode 100644 index c3b3dc61e..000000000 --- a/php/typecho09/var/Widget/Comments/Recent.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 最近评论组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Comments_Recent extends Widget_Abstract_Comments -{ - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - $this->parameter->setDefault(array('pageSize' => $this->options->commentsListSize, 'parentId' => 0, 'ignoreAuthor' => false)); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $select = $this->select()->limit($this->parameter->pageSize) - ->where('table.comments.status = ?', 'approved') - ->order('table.comments.coid', Typecho_Db::SORT_DESC); - - if ($this->parameter->parentId) { - $select->where('cid = ?', $this->parameter->parentId); - } - - if ($this->options->commentsShowCommentOnly) { - $select->where('type = ?', 'comment'); - } - - /** 忽略作者评论 */ - if ($this->parameter->ignoreAuthor) { - $select->where('ownerId <> authorId'); - } - - $this->db->fetchAll($select, array($this, 'push')); - } -} diff --git a/php/typecho09/var/Widget/Contents/Attachment/Admin.php b/php/typecho09/var/Widget/Contents/Attachment/Admin.php deleted file mode 100644 index 77e31acc5..000000000 --- a/php/typecho09/var/Widget/Contents/Attachment/Admin.php +++ /dev/null @@ -1,124 +0,0 @@ -<?php -/** - * 文件管理列表 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 文件管理列表组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Attachment_Admin extends Widget_Abstract_Contents -{ - /** - * 用于计算数值的语句对象 - * - * @access private - * @var Typecho_Db_Query - */ - private $_countSql; - - /** - * 所有文章个数 - * - * @access private - * @var integer - */ - private $_total = false; - - /** - * 分页大小 - * - * @access private - * @var integer - */ - private $pageSize; - - /** - * 当前页 - * - * @access private - * @var integer - */ - private $_currentPage; - - /** - * 所属文章 - * - * @access protected - * @return Typecho_Config - */ - protected function ___parentPost() - { - return new Typecho_Config($this->db->fetchRow( - $this->select()->where('table.contents.cid = ?', $this->parentId) - ->limit(1))); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault('pageSize=20'); - $this->_currentPage = $this->request->get('page', 1); - - /** 构建基础查询 */ - $select = $this->select()->where('table.contents.type = ?', 'attachment'); - - /** 如果具有编辑以上权限,可以查看所有文件,反之只能查看自己的文件 */ - if (!$this->user->pass('editor', true)) { - $select->where('table.contents.authorId = ?', $this->user->uid); - } - - /** 过滤标题 */ - if (NULL != ($keywords = $this->request->filter('search')->keywords)) { - $args = array(); - $keywordsList = explode(' ', $keywords); - $args[] = implode(' OR ', array_fill(0, count($keywordsList), 'table.contents.title LIKE ?')); - - foreach ($keywordsList as $keyword) { - $args[] = '%' . $keyword . '%'; - } - - call_user_func_array(array($select, 'where'), $args); - } - - /** 给计算数目对象赋值,克隆对象 */ - $this->_countSql = clone $select; - - /** 提交查询 */ - $select->order('table.contents.created', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); - - $this->db->fetchAll($select, array($this, 'push')); - } - - /** - * 输出分页 - * - * @access public - * @return void - */ - public function pageNav() - { - $query = $this->request->makeUriByRequest('page={page}'); - - /** 使用盒状分页 */ - $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); - $nav->render('«', '»'); - } -} diff --git a/php/typecho09/var/Widget/Contents/Attachment/Edit.php b/php/typecho09/var/Widget/Contents/Attachment/Edit.php deleted file mode 100644 index 1d502b439..000000000 --- a/php/typecho09/var/Widget/Contents/Attachment/Edit.php +++ /dev/null @@ -1,273 +0,0 @@ -<?php -/** - * 编辑文章 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 编辑文章组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implements Widget_Interface_Do -{ - /** - * 获取页面偏移的URL Query - * - * @access protected - * @param integer $cid 文件id - * @param string $status 状态 - * @return string - */ - protected function getPageOffsetQuery($cid, $status = NULL) - { - return 'page=' . $this->getPageOffset('cid', $cid, 'attachment', $status, - $this->user->pass('editor', true) ? 0 : $this->user->uid); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 必须为贡献者以上权限 */ - $this->user->pass('contributor'); - - /** 获取文章内容 */ - if ((isset($this->request->cid) && 'delete' != $this->request->do - && 'insert' != $this->request->do) || 'update' == $this->request->do) { - $this->db->fetchRow($this->select() - ->where('table.contents.type = ?', 'attachment') - ->where('table.contents.cid = ?', $this->request->filter('int')->cid) - ->limit(1), array($this, 'push')); - - if (!$this->have()) { - throw new Typecho_Widget_Exception(_t('文件不存在'), 404); - } else if ($this->have() && !$this->allow('edit')) { - throw new Typecho_Widget_Exception(_t('没有编辑权限'), 403); - } - } - } - - /** - * 判断文件名转换到缩略名后是否合法 - * - * @access public - * @param string $name 文件名 - * @return boolean - */ - public function nameToSlug($name) - { - if (empty($this->request->slug)) { - $slug = Typecho_Common::slugName($name); - if (empty($slug) || !$this->slugExists($name)) { - return false; - } - } - - return true; - } - - /** - * 判断文件缩略名是否存在 - * - * @access public - * @param string $slug 缩略名 - * @return boolean - */ - public function slugExists($slug) - { - $select = $this->db->select() - ->from('table.contents') - ->where('type = ?', 'attachment') - ->where('slug = ?', Typecho_Common::slugName($slug)) - ->limit(1); - - if ($this->request->cid) { - $select->where('cid <> ?', $this->request->cid); - } - - $attachment = $this->db->fetchRow($select); - return $attachment ? false : true; - } - - /** - * 生成表单 - * - * @access public - * @param string $action 表单动作 - * @return Typecho_Widget_Helper_Form_Element - */ - public function form($action = NULL) - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/contents-attachment-edit', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 文件名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, $this->title, _t('标题 *')); - $form->addInput($name); - - /** 文件缩略名 */ - $slug = new Typecho_Widget_Helper_Form_Element_Text('slug', NULL, $this->slug, _t('缩略名'), - _t('文件缩略名用于创建友好的链接形式,建议使用字母,数字,下划线和横杠.')); - $form->addInput($slug); - - /** 文件描述 */ - $description = new Typecho_Widget_Helper_Form_Element_Textarea('description', NULL, $this->attachment->description, - _t('描述'), _t('此文字用于描述文件,在有的主题中它会被显示.')); - $form->addInput($description); - - /** 分类动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, 'update'); - $form->addInput($do); - - /** 分类主键 */ - $cid = new Typecho_Widget_Helper_Form_Element_Hidden('cid', NULL, $this->cid); - $form->addInput($cid); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('提交修改')); - $submit->input->setAttribute('class', 'primary'); - $delete = new Typecho_Widget_Helper_Layout('a', array('href' => - Typecho_Common::url('/action/contents-attachment-edit?do=delete&cid=' . $this->cid, $this->options->index), - 'class' => 'operate-delete', - 'lang' => _t('你确认删除文件 %s 吗?', $this->attachment->name))); - $submit->container($delete->html(_t('删除文件'))); - $form->addItem($submit); - - $name->addRule('required', _t('必须填写文件标题')); - $name->addRule(array($this, 'nameToSlug'), _t('文件标题无法被转换为缩略名')); - $slug->addRule(array($this, 'slugExists'), _t('缩略名已经存在')); - - return $form; - } - - /** - * 更新文件 - * - * @access public - * @return void - */ - public function updateAttachment() - { - if ($this->form('update')->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $input = $this->request->from('name', 'slug', 'description'); - $input['slug'] = Typecho_Common::slugName(empty($input['slug']) ? $input['name'] : $input['slug']); - - $attachment['title'] = $input['name']; - $attachment['slug'] = $input['slug']; - - $content = unserialize($this->attachment->__toString()); - $content['description'] = $input['description']; - - $attachment['text'] = serialize($content); - $cid = $this->request->filter('int')->cid; - - /** 更新数据 */ - $updateRows = $this->update($attachment, $this->db->sql()->where('cid = ?', $cid)); - - if ($updateRows > 0) { - - $this->db->fetchRow($this->select() - ->where('table.contents.type = ?', 'attachment') - ->where('table.contents.cid = ?', $cid) - ->limit(1), array($this, 'push')); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set('publish' == $this->status ? - _t('文件 <a href="%s">%s</a> 已经被更新', $this->permalink, $this->title) : - _t('未归档文件 %s 已经被更新', $this->title), 'success'); - - } - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-medias.php?' . - $this->getPageOffsetQuery($cid, $this->status), $this->options->adminUrl)); - } - - /** - * 删除文章 - * - * @access public - * @return void - */ - public function deleteAttachment() - { - $cid = $this->request->filter('int')->cid; - $deleteCount = 0; - $status = 'publish'; - - if ($cid) { - /** 格式化文章主键 */ - $posts = is_array($cid) ? $cid : array($cid); - foreach ($posts as $post) { - - $condition = $this->db->sql()->where('cid = ?', $post); - $row = $this->db->fetchRow($this->select() - ->where('table.contents.type = ?', 'attachment') - ->where('table.contents.cid = ?', $post) - ->limit(1), array($this, 'push')); - - if ($this->isWriteable($condition) && $this->delete($condition)) { - /** 删除文件 */ - Widget_Upload::deleteHandle($row); - - /** 删除评论 */ - $this->db->query($this->db->delete('table.comments') - ->where('cid = ?', $post)); - - $status = $this->status; - - $deleteCount ++; - } - - unset($condition); - } - } - - if ($this->request->isAjax()) { - $this->response->throwJson($deleteCount > 0 ? array('code' => 200, 'message' => _t('文件已经被删除')) - : array('code' => 500, 'message' => _t('没有文件被删除'))); - } else { - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('文件已经被删除') : _t('没有文件被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->redirect(Typecho_Common::url('manage-medias.php', $this->options->adminUrl)); - } - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->on($this->request->is('do=delete'))->deleteAttachment(); - $this->on($this->request->is('do=update'))->updateAttachment(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Contents/Attachment/Related.php b/php/typecho09/var/Widget/Contents/Attachment/Related.php deleted file mode 100644 index 1e28f636d..000000000 --- a/php/typecho09/var/Widget/Contents/Attachment/Related.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * 文章相关文件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 文章相关文件组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Attachment_Related extends Widget_Abstract_Contents -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault('parentId=0&limit=0'); - - //如果没有cid值 - if (!$this->parameter->parentId) { - return; - } - - /** 构建基础查询 */ - $select = $this->select()->where('table.contents.type = ?', 'attachment'); - - //order字段在文件里代表所属文章 - $select->where('table.contents.parent = ?', $this->parameter->parentId); - - /** 提交查询 */ - $select->order('table.contents.created', Typecho_Db::SORT_DESC); - - if ($this->parameter->limit > 0) { - $select->limit($this->parameter->limit); - } - - $this->db->fetchAll($select, array($this, 'push')); - } -} diff --git a/php/typecho09/var/Widget/Contents/Attachment/Unattached.php b/php/typecho09/var/Widget/Contents/Attachment/Unattached.php deleted file mode 100644 index e77170529..000000000 --- a/php/typecho09/var/Widget/Contents/Attachment/Unattached.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * 没有关联的文件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 没有关联的文件组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Attachment_Unattached extends Widget_Abstract_Contents -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 构建基础查询 */ - $select = $this->select()->where('table.contents.type = ? AND - (table.contents.parent = 0 OR table.contents.parent IS NULL)', 'attachment'); - - /** 加上对用户的判断 */ - $this->where('table.contents.authorId = ?', $this->user->uid); - - /** 提交查询 */ - $select->order('table.contents.created', Typecho_Db::SORT_DESC); - - $this->db->fetchAll($select, array($this, 'push')); - } -} diff --git a/php/typecho09/var/Widget/Contents/Page/Admin.php b/php/typecho09/var/Widget/Contents/Page/Admin.php deleted file mode 100644 index c478f162c..000000000 --- a/php/typecho09/var/Widget/Contents/Page/Admin.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * 独立页面管理列表 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 独立页面管理列表组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Page_Admin extends Widget_Contents_Post_Admin -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 过滤状态 */ - $select = $this->select()->where('table.contents.type = ? OR (table.contents.type = ? AND table.contents.parent = ?)', 'page', 'page_draft', 0); - - /** 过滤标题 */ - if (NULL != ($keywords = $this->request->keywords)) { - $args = array(); - $keywordsList = explode(' ', $keywords); - $args[] = implode(' OR ', array_fill(0, count($keywordsList), 'table.contents.title LIKE ?')); - - foreach ($keywordsList as $keyword) { - $args[] = '%' . Typecho_Common::filterSearchQuery($keyword) . '%'; - } - - call_user_func_array(array($select, 'where'), $args); - } - - /** 提交查询 */ - $select->order('table.contents.order', Typecho_Db::SORT_ASC); - - $this->db->fetchAll($select, array($this, 'push')); - } -} diff --git a/php/typecho09/var/Widget/Contents/Page/Edit.php b/php/typecho09/var/Widget/Contents/Page/Edit.php deleted file mode 100644 index 490b5552c..000000000 --- a/php/typecho09/var/Widget/Contents/Page/Edit.php +++ /dev/null @@ -1,257 +0,0 @@ -<?php -/** - * 编辑页面 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 编辑页面组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Page_Edit extends Widget_Contents_Post_Edit implements Widget_Interface_Do -{ - /** - * 自定义字段的hook名称 - * - * @var string - * @access protected - */ - protected $themeCustomFieldsHook = 'themePageFields'; - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 必须为编辑以上权限 */ - $this->user->pass('editor'); - - /** 获取文章内容 */ - if (!empty($this->request->cid) && 'delete' != $this->request->do - && 'sort' != $this->request->do) { - $this->db->fetchRow($this->select() - ->where('table.contents.type = ? OR table.contents.type = ?', 'page', 'page_draft') - ->where('table.contents.cid = ?', $this->request->filter('int')->cid) - ->limit(1), array($this, 'push')); - - if ('page_draft' == $this->status && $this->parent) { - $this->response->redirect(Typecho_Common::url('write-page.php?cid=' . $this->parent, $this->options->adminUrl)); - } - - if (!$this->have()) { - throw new Typecho_Widget_Exception(_t('页面不存在'), 404); - } else if ($this->have() && !$this->allow('edit')) { - throw new Typecho_Widget_Exception(_t('没有编辑权限'), 403); - } - } - } - - /** - * 发布文章 - * - * @access public - * @return void - */ - public function writePage() - { - $contents = $this->request->from('text', 'template', 'allowComment', - 'allowPing', 'allowFeed', 'slug', 'order', 'visibility'); - - $contents['title'] = $this->request->get('title', _t('未命名页面')); - $contents['created'] = $this->getCreated(); - $contents['visibility'] = ('hidden' == $contents['visibility'] ? 'hidden' : 'publish'); - - if ($this->request->markdown && $this->options->markdown) { - $contents['text'] = '<!--markdown-->' . $contents['text']; - } - - $contents = $this->pluginHandle()->write($contents, $this); - - if ($this->request->is('do=publish')) { - /** 重新发布已经存在的文章 */ - $contents['type'] = 'page'; - $this->publish($contents); - - /** 发送ping */ - $this->widget('Widget_Service')->sendPing($this->cid); - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set(_t('页面 "<a href="%s">%s</a>" 已经发布', $this->permalink, $this->title), 'success'); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 页面跳转 */ - $this->response->redirect(Typecho_Common::url('manage-pages.php?', $this->options->adminUrl)); - } else { - /** 保存文章 */ - $contents['type'] = 'page_draft'; - $this->save($contents); - - if ($this->request->isAjax()) { - $created = new Typecho_Date($this->options->gmtTime); - $this->response->throwJson(array( - 'success' => 1, - 'time' => $created->format('H:i:s A'), - 'cid' => $this->cid - )); - } else { - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set(_t('草稿 "%s" 已经被保存', $this->title), 'success'); - - /** 返回原页面 */ - $this->response->redirect(Typecho_Common::url('write-page.php?cid=' . $this->cid, $this->options->adminUrl)); - } - } - } - - /** - * 删除页面 - * - * @access public - * @return void - */ - public function deletePage() - { - $cid = $this->request->filter('int')->cid; - $deleteCount = 0; - - if ($cid) { - /** 格式化页面主键 */ - $pages = is_array($cid) ? $cid : array($cid); - foreach ($pages as $page) { - if ($this->delete($this->db->sql()->where('cid = ?', $page))) { - /** 删除评论 */ - $this->db->query($this->db->delete('table.comments') - ->where('cid = ?', $page)); - - /** 解除附件关联 */ - $this->unAttach($page); - - /** 解除首页关联 */ - if ($this->options->frontPage == 'page:' . $page) { - $this->db->query($this->db->update('table.options') - ->rows(array('value' => 'recent')) - ->where('name = ?', 'frontPage')); - } - - /** 删除草稿 */ - $draft = $this->db->fetchRow($this->db->select('cid') - ->from('table.contents') - ->where('table.contents.parent = ? AND table.contents.type = ?', - $page, 'page_draft') - ->limit(1)); - - /** 删除自定义字段 */ - $this->deleteFields($page); - - if ($draft) { - $this->deleteDraft($draft['cid']); - $this->deleteFields($draft['cid']); - } - - $deleteCount ++; - } - } - } - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('页面已经被删除') : _t('没有页面被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 删除页面所属草稿 - * - * @access public - * @return void - */ - public function deletePageDraft() - { - $cid = $this->request->filter('int')->cid; - $deleteCount = 0; - - if ($cid) { - /** 格式化文章主键 */ - $pages = is_array($cid) ? $cid : array($cid); - - foreach ($pages as $page) { - /** 删除草稿 */ - $draft = $this->db->fetchRow($this->db->select('cid') - ->from('table.contents') - ->where('table.contents.parent = ? AND table.contents.type = ?', - $page, 'page_draft') - ->limit(1)); - - if ($draft) { - $this->deleteDraft($draft['cid']); - $this->deleteFields($draft['cid']); - $deleteCount ++; - } - } - } - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('草稿已经被删除') : _t('没有草稿被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 页面排序 - * - * @access public - * @return void - */ - public function sortPage() - { - $pages = $this->request->filter('int')->cid; - - if ($pages && is_array($pages)) { - foreach ($pages as $sort => $cid) { - $this->db->query($this->db->update('table.contents')->rows(array('order' => $sort + 1)) - ->where('cid = ?', $cid)); - } - } - - if (!$this->request->isAjax()) { - /** 转向原页 */ - $this->response->goBack(); - } else { - $this->response->throwJson(array('success' => 1, 'message' => _t('页面排序已经完成'))); - } - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->on($this->request->is('do=publish') || $this->request->is('do=save'))->writePage(); - $this->on($this->request->is('do=delete'))->deletePage(); - $this->on($this->request->is('do=deleteDraft'))->deletePageDraft(); - $this->on($this->request->is('do=sort'))->sortPage(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Contents/Page/List.php b/php/typecho09/var/Widget/Contents/Page/List.php deleted file mode 100644 index 84d49da00..000000000 --- a/php/typecho09/var/Widget/Contents/Page/List.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * 独立页面列表 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 独立页面列表组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Page_List extends Widget_Abstract_Contents -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $select = $this->select()->where('table.contents.type = ?', 'page') - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.created < ?', $this->options->gmtTime) - ->order('table.contents.order', Typecho_Db::SORT_ASC); - - //去掉自定义首页 - $frontPage = explode(':', $this->options->frontPage); - if (2 == count($frontPage) && 'page' == $frontPage[0]) { - $select->where('table.contents.cid <> ?', $frontPage[1]); - } - - $this->db->fetchAll($select, array($this, 'push')); - } -} diff --git a/php/typecho09/var/Widget/Contents/Post/Admin.php b/php/typecho09/var/Widget/Contents/Post/Admin.php deleted file mode 100644 index 80621d330..000000000 --- a/php/typecho09/var/Widget/Contents/Post/Admin.php +++ /dev/null @@ -1,157 +0,0 @@ -<?php -/** - * 文章管理列表 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 文章管理列表组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Post_Admin extends Widget_Abstract_Contents -{ - /** - * 用于计算数值的语句对象 - * - * @access private - * @var Typecho_Db_Query - */ - private $_countSql; - - /** - * 所有文章个数 - * - * @access private - * @var integer - */ - private $_total = false; - - /** - * 分页大小 - * - * @access private - * @var integer - */ - private $pageSize; - - /** - * 当前页 - * - * @access private - * @var integer - */ - private $_currentPage; - - /** - * 当前文章的草稿 - * - * @access protected - * @return array - */ - protected function ___hasSaved() - { - $savedPost = $this->db->fetchRow($this->db->select('cid', 'modified') - ->from('table.contents') - ->where('table.contents.parent = ? AND (table.contents.type = ? OR table.contents.type = ?)', - $this->cid, 'post_draft', 'page_draft') - ->limit(1)); - - if ($savedPost) { - $this->modified = $savedPost['modified']; - return true; - } - - return false; - } - - /** - * 获取菜单标题 - * - * @access public - * @return string - */ - public function getMenuTitle() - { - if (isset($this->request->uid)) { - return _t('%s的文章', $this->db->fetchObject($this->db->select('screenName')->from('table.users') - ->where('uid = ?', $this->request->filter('int')->uid))->screenName); - } - - throw new Typecho_Widget_Exception(_t('用户不存在'), 404); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault('pageSize=20'); - $this->_currentPage = $this->request->get('page', 1); - - /** 构建基础查询 */ - $select = $this->select()->where('table.contents.type = ? OR (table.contents.type = ? AND table.contents.parent = ?)', 'post', 'post_draft', 0); - - /** 过滤分类 */ - if (NULL != ($category = $this->request->category)) { - $select->join('table.relationships', 'table.contents.cid = table.relationships.cid') - ->where('table.relationships.mid = ?', $category); - } - - /** 如果具有编辑以上权限,可以查看所有文章,反之只能查看自己的文章 */ - if (!$this->user->pass('editor', true)) { - $select->where('table.contents.authorId = ?', $this->user->uid); - } else if (isset($this->request->uid)) { - $select->where('table.contents.authorId = ?', $this->request->filter('int')->uid); - } - - /** 过滤标题 */ - if (NULL != ($keywords = $this->request->filter('search')->keywords)) { - $args = array(); - $keywordsList = explode(' ', $keywords); - $args[] = implode(' OR ', array_fill(0, count($keywordsList), 'table.contents.title LIKE ?')); - - foreach ($keywordsList as $keyword) { - $args[] = '%' . $keyword . '%'; - } - - call_user_func_array(array($select, 'where'), $args); - } - - /** 给计算数目对象赋值,克隆对象 */ - $this->_countSql = clone $select; - - /** 提交查询 */ - $select->order('table.contents.created', Typecho_Db::SORT_DESC) - ->page($this->_currentPage, $this->parameter->pageSize); - - $this->db->fetchAll($select, array($this, 'push')); - } - - /** - * 输出分页 - * - * @access public - * @return void - */ - public function pageNav() - { - $query = $this->request->makeUriByRequest('page={page}'); - - /** 使用盒状分页 */ - $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); - $nav->render('«', '»'); - } -} diff --git a/php/typecho09/var/Widget/Contents/Post/Date.php b/php/typecho09/var/Widget/Contents/Post/Date.php deleted file mode 100644 index 233c467d5..000000000 --- a/php/typecho09/var/Widget/Contents/Post/Date.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php -/** - * 按日期归档列表组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 按日期归档列表组件 - * - * @fixme 交给缓存 - * @author qining - * @category typecho - * @package Widget - */ -class Widget_Contents_Post_Date extends Typecho_Widget -{ - /** - * 全局选项 - * - * @access protected - * @var Widget_Options - */ - protected $options; - - /** - * 数据库对象 - * - * @access protected - * @var Typecho_Db - */ - protected $db; - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - - /** 初始化数据库 */ - $this->db = Typecho_Db::get(); - - /** 初始化常用组件 */ - $this->options = $this->widget('Widget_Options'); - } - - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 设置参数默认值 */ - $this->parameter->setDefault('format=Y-m&type=month&limit=0'); - - $resource = $this->db->query($this->db->select('created')->from('table.contents') - ->where('type = ?', 'post') - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.created < ?', $this->options->gmtTime) - ->order('table.contents.created', Typecho_Db::SORT_DESC)); - - $offset = $this->options->timezone - $this->options->serverTimezone; - $result = array(); - while ($post = $this->db->fetchRow($resource)) { - $timeStamp = $post['created'] + $offset; - $date = date($this->parameter->format, $timeStamp); - - if (isset($result[$date])) { - $result[$date]['count'] ++; - } else { - $result[$date]['year'] = date('Y', $timeStamp); - $result[$date]['month'] = date('m', $timeStamp); - $result[$date]['day'] = date('d', $timeStamp); - $result[$date]['date'] = $date; - $result[$date]['count'] = 1; - } - } - - if ($this->parameter->limit > 0) { - $result = array_slice($result, 0, $this->parameter->limit); - } - - foreach ($result as $row) { - $row['permalink'] = Typecho_Router::url('archive_' . $this->parameter->type, $row, $this->widget('Widget_Options')->index); - $this->push($row); - } - } -} diff --git a/php/typecho09/var/Widget/Contents/Post/Edit.php b/php/typecho09/var/Widget/Contents/Post/Edit.php deleted file mode 100644 index 04117c5c2..000000000 --- a/php/typecho09/var/Widget/Contents/Post/Edit.php +++ /dev/null @@ -1,880 +0,0 @@ -<?php -/** - * 编辑文章 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 编辑文章组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Post_Edit extends Widget_Abstract_Contents implements Widget_Interface_Do -{ - /** - * 自定义字段的hook名称 - * - * @var string - * @access protected - */ - protected $themeCustomFieldsHook = 'themePostFields'; - - /** - * 将tags取出 - * - * @access protected - * @return array - */ - protected function ___tags() - { - if ($this->have()) { - return $this->db->fetchAll($this->db - ->select()->from('table.metas') - ->join('table.relationships', 'table.relationships.mid = table.metas.mid') - ->where('table.relationships.cid = ?', $this->cid) - ->where('table.metas.type = ?', 'tag'), array($this->widget('Widget_Abstract_Metas'), 'filter')); - } - - return array(); - } - - /** - * 获取当前时间 - * - * @access protected - * @return Typecho_Date - */ - protected function ___date() - { - return new Typecho_Date($this->options->gmtTime); - } - - /** - * 当前文章的草稿 - * - * @access protected - * @return array - */ - protected function ___draft() - { - if ($this->have()) { - if ('post_draft' == $this->type) { - return $this->row; - } else { - return $this->db->fetchRow($this->widget('Widget_Abstract_Contents')->select() - ->where('table.contents.parent = ? AND (table.contents.type = ? OR table.contents.type = ?)', - $this->cid, 'post_draft', 'page_draft') - ->limit(1), array($this->widget('Widget_Abstract_Contents'), 'filter')); - } - } - - return NULL; - } - - /** - * getFields - * - * @access protected - * @return void - */ - protected function getFields() - { - $fields = array(); - - if (!empty($this->request->fieldNames)) { - $data = $this->request->from('fieldNames', 'fieldTypes', 'fieldValues'); - foreach ($data['fieldNames'] as $key => $val) { - if (empty($val)) { - continue; - } - - $fields[$val] = array($data['fieldTypes'][$key], $data['fieldValues'][$key]); - } - } - - if (!empty($this->request->fields)) { - $fields = array_merge($fields, $this->request->fields); - } - - return $fields; - } - - /** - * 根据提交值获取created字段值 - * - * @access protected - * @return integer - */ - protected function getCreated() - { - $created = $this->options->gmtTime; - if (!empty($this->request->created)) { - $created = $this->request->created; - } else if (!empty($this->request->date)) { - $created = strtotime($this->request->date) - $this->options->timezone + $this->options->serverTimezone; - } else if (!empty($this->request->year) && !empty($this->request->month) && !empty($this->request->day)) { - $second = intval($this->request->get('sec', date('s'))); - $min = intval($this->request->get('min', date('i'))); - $hour = intval($this->request->get('hour', date('H'))); - - $year = intval($this->request->year); - $month = intval($this->request->month); - $day = intval($this->request->day); - - $created = mktime($hour, $min, $second, $month, $day, $year) - $this->options->timezone + $this->options->serverTimezone; - } else if ($this->request->is('cid')) { - //如果是修改文章 - $created = $this->created; - } - - return $created; - } - - /** - * 同步附件 - * - * @access protected - * @param integer $cid 内容id - * @return void - */ - protected function attach($cid) - { - if ($this->request->attachment && is_array($this->request->attachment)) { - $attachments = $this->request->filter('int')->attachment; - - foreach ($attachments as $key => $attachment) { - $this->db->query($this->db->update('table.contents')->rows(array('parent' => $cid, 'status' => 'publish', - 'order' => $key + 1))->where('cid = ? AND type = ?', $attachment, 'attachment')); - } - } - } - - /** - * 取消附件关联 - * - * @access protected - * @param integer $cid 内容id - * @return void - */ - protected function unAttach($cid) - { - $this->db->query($this->db->update('table.contents')->rows(array('parent' => 0, 'status' => 'publish')) - ->where('parent = ? AND type = ?', $cid, 'attachment')); - } - - /** - * 获取页面偏移的URL Query - * - * @access protected - * @param integer $created 创建时间 - * @param string $status 状态 - * @return string - */ - protected function getPageOffsetQuery($created, $status = NULL) - { - return 'page=' . $this->getPageOffset('created', $created, 'post', $status, - 'on' == $this->request->__typecho_all_posts ? 0 : $this->user->uid); - } - - /** - * 删除草稿 - * - * @access protected - * @param integer $cid 草稿id - * @return void - */ - protected function deleteDraft($cid) - { - $this->delete($this->db->sql()->where('cid = ?', $cid)); - - /** 删除草稿分类 */ - $this->setCategories($cid, array(), false, false); - - /** 删除标签 */ - $this->setTags($cid, NULL, false, false); - } - - /** - * 发布内容 - * - * @access protected - * @param array $contents 内容结构 - * @return void - */ - protected function publish(array $contents) - { - /** 发布内容, 检查是否具有直接发布的权限 */ - if ($this->user->pass('editor', true)) { - if (empty($contents['visibility'])) { - $contents['status'] = 'publish'; - } else if ('password' == $contents['visibility'] || !in_array($contents['visibility'], array('private', 'waiting', 'publish', 'hidden'))) { - if (empty($contents['password']) || 'password' != $contents['visibility']) { - $contents['password'] = ''; - } - $contents['status'] = 'publish'; - } else { - $contents['status'] = $contents['visibility']; - $contents['password'] = ''; - } - } else { - $contents['status'] = 'waiting'; - $contents['password'] = ''; - } - - /** 真实的内容id */ - $realId = 0; - - /** 是否是从草稿状态发布 */ - $isDraftToPublish = ('post_draft' == $this->type); - - $isBeforePublish = ('publish' == $this->status); - $isAfterPublish = ('publish' == $contents['status']); - - /** 重新发布现有内容 */ - if ($this->have()) { - - /** 如果它本身不是草稿, 需要删除其草稿 */ - if (!$isDraftToPublish && $this->draft) { - $this->deleteDraft($this->draft['cid']); - $this->deleteFields($this->draft['cid']); - } - - /** 直接将草稿状态更改 */ - if ($this->update($contents, $this->db->sql()->where('cid = ?', $this->cid))) { - $realId = $this->cid; - } - - } else { - /** 发布一个新内容 */ - $realId = $this->insert($contents); - } - - if ($realId > 0) { - /** 插入分类 */ - if (array_key_exists('category', $contents)) { - $this->setCategories($realId, !empty($contents['category']) && is_array($contents['category']) ? - $contents['category'] : array($this->options->defaultCategory), !$isDraftToPublish && $isBeforePublish, $isAfterPublish); - } - - /** 插入标签 */ - if (array_key_exists('tags', $contents)) { - $this->setTags($realId, $contents['tags'], !$isDraftToPublish && $isBeforePublish, $isAfterPublish); - } - - /** 同步附件 */ - $this->attach($realId); - - /** 保存自定义字段 */ - $this->applyFields($this->getFields(), $realId); - - $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $realId)->limit(1), array($this, 'push')); - } - } - - /** - * 保存内容 - * - * @access protected - * @param array $contents 内容结构 - * @return void - */ - protected function save(array $contents) - { - /** 发布内容, 检查是否具有直接发布的权限 */ - if ($this->user->pass('editor', true)) { - if (empty($contents['visibility'])) { - $contents['status'] = 'publish'; - } else if ('password' == $contents['visibility'] || !in_array($contents['visibility'], array('private', 'waiting', 'publish', 'hidden'))) { - if (empty($contents['password']) || 'password' != $contents['visibility']) { - $contents['password'] = ''; - } - $contents['status'] = 'publish'; - } else { - $contents['status'] = $contents['visibility']; - $contents['password'] = ''; - } - } else { - $contents['status'] = 'waiting'; - $contents['password'] = ''; - } - - /** 真实的内容id */ - $realId = 0; - - /** 如果草稿已经存在 */ - if ($this->draft) { - - /** 直接将草稿状态更改 */ - if ($this->update($contents, $this->db->sql()->where('cid = ?', $this->draft['cid']))) { - $realId = $this->draft['cid']; - } - - } else { - if ($this->have()) { - $contents['parent'] = $this->cid; - } - - /** 发布一个新内容 */ - $realId = $this->insert($contents); - - if (!$this->have()) { - $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $realId)->limit(1), array($this, 'push')); - } - } - - if ($realId > 0) { - //$this->db->fetchRow($this->select()->where('table.contents.cid = ?', $realId)->limit(1), array($this, 'push')); - - /** 插入分类 */ - if (array_key_exists('category', $contents)) { - $this->setCategories($realId, !empty($contents['category']) && is_array($contents['category']) ? - $contents['category'] : array($this->options->defaultCategory), false, false); - } - - /** 插入标签 */ - if (array_key_exists('tags', $contents)) { - $this->setTags($realId, $contents['tags'], false, false); - } - - /** 同步附件 */ - $this->attach($this->cid); - - /** 保存自定义字段 */ - $this->applyFields($this->getFields(), $realId); - } - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 必须为贡献者以上权限 */ - $this->user->pass('contributor'); - - /** 获取文章内容 */ - if (!empty($this->request->cid) && 'delete' != $this->request->do) { - $this->db->fetchRow($this->select() - ->where('table.contents.type = ? OR table.contents.type = ?', 'post', 'post_draft') - ->where('table.contents.cid = ?', $this->request->filter('int')->cid) - ->limit(1), array($this, 'push')); - - if ('post_draft' == $this->type && $this->parent) { - $this->response->redirect(Typecho_Common::url('write-post.php?cid=' . $this->parent, $this->options->adminUrl)); - } - - if (!$this->have()) { - throw new Typecho_Widget_Exception(_t('文章不存在'), 404); - } else if ($this->have() && !$this->allow('edit')) { - throw new Typecho_Widget_Exception(_t('没有编辑权限'), 403); - } - } - } - - /** - * 过滤堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function filter(array $value) - { - if ('post' == $value['type'] || 'page' == $value['type']) { - $draft = $this->db->fetchRow($this->widget('Widget_Abstract_Contents')->select() - ->where('table.contents.parent = ? AND table.contents.type = ?', - $value['cid'], $value['type'] . '_draft') - ->limit(1)); - - if (!empty($draft)) { - $draft['slug'] = ltrim($draft['slug'], '@'); - $draft['type'] = $value['type']; - - $draft = parent::filter($draft); - - $draft['tags'] = $this->db->fetchAll($this->db - ->select()->from('table.metas') - ->join('table.relationships', 'table.relationships.mid = table.metas.mid') - ->where('table.relationships.cid = ?', $draft['cid']) - ->where('table.metas.type = ?', 'tag'), array($this->widget('Widget_Abstract_Metas'), 'filter')); - $draft['cid'] = $value['cid']; - - return $draft; - } - } - - return parent::filter($value); - } - - /** - * 输出文章发布日期 - * - * @access public - * @param string $format 日期格式 - * @return void - */ - public function date($format = NULL) - { - if (isset($this->created)) { - parent::date($format); - } else { - echo date($format, $this->options->gmtTime + $this->options->timezone - $this->options->serverTimezone); - } - } - - /** - * 获取文章权限 - * - * @access public - * @param string $permission 权限 - * @return unknown - */ - public function allow() - { - $permissions = func_get_args(); - $allow = true; - - foreach ($permissions as $permission) { - $permission = strtolower($permission); - - if ('edit' == $permission) { - $allow &= ($this->user->pass('editor', true) || $this->authorId == $this->user->uid); - } else { - $permission = 'allow' . ucfirst(strtolower($permission)); - $optionPermission = 'default' . ucfirst($permission); - $allow &= (isset($this->{$permission}) ? $this->{$permission} : $this->options->{$optionPermission}); - } - } - - return $allow; - } - - /** - * 获取网页标题 - * - * @access public - * @return string - */ - public function getMenuTitle() - { - return _t('编辑 %s', $this->title); - } - - /** - * getDefaultFieldItems - * - * @access public - * @return array - */ - public function getDefaultFieldItems() - { - $defaultFields = array(); - $configFile = __TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . $this->options->theme . '/functions.php'; - $layout = new Typecho_Widget_Helper_Layout(); - $fields = new Typecho_Config(); - - if ($this->have()) { - $fields = $this->fields; - } - - $this->pluginHandle()->getDefaultFieldItems($layout); - - if (file_exists($configFile)) { - require_once $configFile; - - if (function_exists('themeFields')) { - themeFields($layout); - } - - if (function_exists($this->themeCustomFieldsHook)) { - call_user_func($this->themeCustomFieldsHook, $layout); - } - } - - $items = $layout->getItems(); - foreach ($items as $item) { - if ($item instanceof Typecho_Widget_Helper_Form_Element) { - $name = $item->input->getAttribute('name'); - - $isFieldReadOnly = $this->pluginHandle('Widget_Abstract_Contents') - ->trigger($plugged)->isFieldReadOnly($name); - if ($plugged && $isFieldReadOnly) { - continue; - } - - if (preg_match("/^fields\[(.+)\]$/", $name, $matches)) { - $name = $matches[1]; - } else { - foreach ($item->inputs as $input) { - $input->setAttribute('name', 'fields[' . $name . ']'); - } - } - - $item->value($fields->{$name}); - - $elements = $item->container->getItems(); - array_shift($elements); - $div = new Typecho_Widget_Helper_Layout('div'); - - foreach ($elements as $el) { - $div->addItem($el); - } - - $defaultFields[$name] = array($item->label, $div); - } - } - - return $defaultFields; - } - - /** - * getFieldItems - * - * @access public - * @return void - */ - public function getFieldItems() - { - $fields = array(); - - if ($this->have()) { - $defaultFields = $this->getDefaultFieldItems(); - $rows = $this->db->fetchAll($this->db->select()->from('table.fields') - ->where('cid = ?', $this->cid)); - - foreach ($rows as $row) { - $isFieldReadOnly = $this->pluginHandle('Widget_Abstract_Contents') - ->trigger($plugged)->isFieldReadOnly($row['name']); - - if ($plugged && $isFieldReadOnly) { - continue; - } - - if (!isset($defaultFields[$row['name']])) { - $fields[] = $row; - } - } - } - - return $fields; - } - - /** - * 设置内容标签 - * - * @access public - * @param integer $cid - * @param string $tags - * @param boolean $count 是否参与计数 - * @return string - */ - public function setTags($cid, $tags, $beforeCount = true, $afterCount = true) - { - $tags = str_replace(',', ',', $tags); - $tags = array_unique(array_map('trim', explode(',', $tags))); - - /** 取出已有tag */ - $existTags = Typecho_Common::arrayFlatten($this->db->fetchAll( - $this->db->select('table.metas.mid') - ->from('table.metas') - ->join('table.relationships', 'table.relationships.mid = table.metas.mid') - ->where('table.relationships.cid = ?', $cid) - ->where('table.metas.type = ?', 'tag')), 'mid'); - - /** 删除已有tag */ - if ($existTags) { - foreach ($existTags as $tag) { - $this->db->query($this->db->delete('table.relationships') - ->where('cid = ?', $cid) - ->where('mid = ?', $tag)); - - if ($beforeCount) { - $this->db->query($this->db->update('table.metas') - ->expression('count', 'count - 1') - ->where('mid = ?', $tag)); - } - } - } - - /** 取出插入tag */ - $insertTags = $this->widget('Widget_Abstract_Metas')->scanTags($tags); - - /** 插入tag */ - if ($insertTags) { - foreach ($insertTags as $tag) { - $this->db->query($this->db->insert('table.relationships') - ->rows(array( - 'mid' => $tag, - 'cid' => $cid - ))); - - if ($afterCount) { - $this->db->query($this->db->update('table.metas') - ->expression('count', 'count + 1') - ->where('mid = ?', $tag)); - } - } - } - } - - /** - * 设置分类 - * - * @access public - * @param integer $cid 内容id - * @param array $categories 分类id的集合数组 - * @param boolean $count 是否参与计数 - * @return integer - */ - public function setCategories($cid, array $categories, $beforeCount = true, $afterCount = true) - { - $categories = array_unique(array_map('trim', $categories)); - - /** 取出已有category */ - $existCategories = Typecho_Common::arrayFlatten($this->db->fetchAll( - $this->db->select('table.metas.mid') - ->from('table.metas') - ->join('table.relationships', 'table.relationships.mid = table.metas.mid') - ->where('table.relationships.cid = ?', $cid) - ->where('table.metas.type = ?', 'category')), 'mid'); - - /** 删除已有category */ - if ($existCategories) { - foreach ($existCategories as $category) { - $this->db->query($this->db->delete('table.relationships') - ->where('cid = ?', $cid) - ->where('mid = ?', $category)); - - if ($beforeCount) { - $this->db->query($this->db->update('table.metas') - ->expression('count', 'count - 1') - ->where('mid = ?', $category)); - } - } - } - - /** 插入category */ - if ($categories) { - foreach ($categories as $category) { - /** 如果分类不存在 */ - if (!$this->db->fetchRow($this->db->select('mid') - ->from('table.metas') - ->where('mid = ?', $category) - ->limit(1))) { - continue; - } - - $this->db->query($this->db->insert('table.relationships') - ->rows(array( - 'mid' => $category, - 'cid' => $cid - ))); - - if ($afterCount) { - $this->db->query($this->db->update('table.metas') - ->expression('count', 'count + 1') - ->where('mid = ?', $category)); - } - } - } - } - - /** - * 发布文章 - * - * @access public - * @return void - */ - public function writePost() - { - $contents = $this->request->from('password', 'allowComment', - 'allowPing', 'allowFeed', 'slug', 'category', 'tags', 'text', 'visibility'); - - $contents['title'] = $this->request->get('title', _t('未命名文档')); - $contents['created'] = $this->getCreated(); - - if ($this->request->markdown && $this->options->markdown) { - $contents['text'] = '<!--markdown-->' . $contents['text']; - } - - $contents = $this->pluginHandle()->write($contents, $this); - - if ($this->request->is('do=publish')) { - /** 重新发布已经存在的文章 */ - $contents['type'] = 'post'; - $this->publish($contents); - - /** 发送ping */ - $trackback = array_unique(preg_split("/(\r|\n|\r\n)/", trim($this->request->trackback))); - $this->widget('Widget_Service')->sendPing($this->cid, $trackback); - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set('post' == $this->type ? - _t('文章 "<a href="%s">%s</a>" 已经发布', $this->permalink, $this->title) : - _t('文章 "%s" 等待审核', $this->title), 'success'); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 获取页面偏移 */ - $pageQuery = $this->getPageOffsetQuery($this->created); - - /** 页面跳转 */ - $this->response->redirect(Typecho_Common::url('manage-posts.php?' . $pageQuery, $this->options->adminUrl)); - } else { - /** 保存文章 */ - $contents['type'] = 'post_draft'; - $this->save($contents); - - if ($this->request->isAjax()) { - $created = new Typecho_Date($this->options->gmtTime); - $this->response->throwJson(array( - 'success' => 1, - 'time' => $created->format('H:i:s A'), - 'cid' => $this->cid - )); - } else { - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set(_t('草稿 "%s" 已经被保存', $this->title), 'success'); - - /** 返回原页面 */ - $this->response->redirect(Typecho_Common::url('write-post.php?cid=' . $this->cid, $this->options->adminUrl)); - } - } - } - - /** - * 删除文章 - * - * @access public - * @return void - */ - public function deletePost() - { - $cid = $this->request->filter('int')->cid; - $deleteCount = 0; - - if ($cid) { - /** 格式化文章主键 */ - $posts = is_array($cid) ? $cid : array($cid); - foreach ($posts as $post) { - - $condition = $this->db->sql()->where('cid = ?', $post); - $postObject = $this->db->fetchObject($this->db->select('status', 'type') - ->from('table.contents')->where('cid = ? AND type = ?', $post, 'post')); - - if ($this->isWriteable($condition) && - $postObject && - $this->delete($condition)) { - - /** 删除分类 */ - $this->setCategories($post, array(), 'publish' == $postObject->status - && 'post' == $postObject->type); - - /** 删除标签 */ - $this->setTags($post, NULL, 'publish' == $postObject->status - && 'post' == $postObject->type); - - /** 删除评论 */ - $this->db->query($this->db->delete('table.comments') - ->where('cid = ?', $post)); - - /** 解除附件关联 */ - $this->unAttach($post); - - /** 删除草稿 */ - $draft = $this->db->fetchRow($this->db->select('cid') - ->from('table.contents') - ->where('table.contents.parent = ? AND table.contents.type = ?', - $post, 'post_draft') - ->limit(1)); - - /** 删除自定义字段 */ - $this->deleteFields($post); - - if ($draft) { - $this->deleteDraft($draft['cid']); - $this->deleteFields($draft['cid']); - } - - $deleteCount ++; - } - - unset($condition); - } - } - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('文章已经被删除') : _t('没有文章被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 删除文章所属草稿 - * - * @access public - * @return void - */ - public function deletePostDraft() - { - $cid = $this->request->filter('int')->cid; - $deleteCount = 0; - - if ($cid) { - /** 格式化文章主键 */ - $posts = is_array($cid) ? $cid : array($cid); - - foreach ($posts as $post) { - /** 删除草稿 */ - $draft = $this->db->fetchRow($this->db->select('cid') - ->from('table.contents') - ->where('table.contents.parent = ? AND table.contents.type = ?', - $post, 'post_draft') - ->limit(1)); - - if ($draft) { - $this->deleteDraft($draft['cid']); - $this->deleteFields($draft['cid']); - $deleteCount ++; - } - } - } - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('草稿已经被删除') : _t('没有草稿被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 返回原网页 */ - $this->response->goBack(); - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->on($this->request->is('do=publish') || $this->request->is('do=save'))->writePost(); - $this->on($this->request->is('do=delete'))->deletePost(); - $this->on($this->request->is('do=deleteDraft'))->deletePostDraft(); - - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Contents/Post/Recent.php b/php/typecho09/var/Widget/Contents/Post/Recent.php deleted file mode 100644 index c5bd24a91..000000000 --- a/php/typecho09/var/Widget/Contents/Post/Recent.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * 最新文章 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 最新评论组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Post_Recent extends Widget_Abstract_Contents -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault(array('pageSize' => $this->options->postsListSize)); - - $this->db->fetchAll($this->select() - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.created < ?', $this->options->gmtTime) - ->where('table.contents.type = ?', 'post') - ->order('table.contents.created', Typecho_Db::SORT_DESC) - ->limit($this->parameter->pageSize), array($this, 'push')); - } -} diff --git a/php/typecho09/var/Widget/Contents/Related.php b/php/typecho09/var/Widget/Contents/Related.php deleted file mode 100644 index befc220af..000000000 --- a/php/typecho09/var/Widget/Contents/Related.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * 相关内容 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 相关内容组件(根据标签关联) - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Related extends Widget_Abstract_Contents -{ - /** - * 获取查询对象 - * - * @access public - * @return Typecho_Db_Query - */ - public function select() - { - return $this->db->select('DISTINCT table.contents.cid', 'table.contents.title', 'table.contents.slug', 'table.contents.created', 'table.contents.authorId', - 'table.contents.modified', 'table.contents.type', 'table.contents.status', 'table.contents.text', 'table.contents.commentsNum', 'table.contents.order', - 'table.contents.template', 'table.contents.password', 'table.contents.allowComment', 'table.contents.allowPing', 'table.contents.allowFeed') - ->from('table.contents'); - } - - /** - * 执行函数,初始化数据 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault('limit=5'); - - if ($this->parameter->tags) { - $tagsGroup = implode(',', Typecho_Common::arrayFlatten($this->parameter->tags, 'mid')); - $this->db->fetchAll($this->select() - ->join('table.relationships', 'table.contents.cid = table.relationships.cid') - ->where('table.relationships.mid IN (' . $tagsGroup . ')') - ->where('table.contents.cid <> ?', $this->parameter->cid) - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.password IS NULL') - ->where('table.contents.created < ?', $this->options->gmtTime) - ->where('table.contents.type = ?', $this->parameter->type) - ->order('table.contents.created', Typecho_Db::SORT_DESC) - ->limit($this->parameter->limit), array($this, 'push')); - } - } -} diff --git a/php/typecho09/var/Widget/Contents/Related/Author.php b/php/typecho09/var/Widget/Contents/Related/Author.php deleted file mode 100644 index f803188d3..000000000 --- a/php/typecho09/var/Widget/Contents/Related/Author.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * 相关内容 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 相关内容组件(根据作者关联) - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Contents_Related_Author extends Widget_Abstract_Contents -{ - /** - * 执行函数,初始化数据 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault('limit=5'); - - if ($this->parameter->author) { - $this->db->fetchAll($this->select() - ->where('table.contents.authorId = ?', $this->parameter->author) - ->where('table.contents.cid <> ?', $this->parameter->cid) - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.password IS NULL') - ->where('table.contents.created < ?', $this->options->gmtTime) - ->where('table.contents.type = ?', $this->parameter->type) - ->order('table.contents.created', Typecho_Db::SORT_DESC) - ->limit($this->parameter->limit), array($this, 'push')); - } - } -} diff --git a/php/typecho09/var/Widget/Do.php b/php/typecho09/var/Widget/Do.php deleted file mode 100644 index c197527b1..000000000 --- a/php/typecho09/var/Widget/Do.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 执行模块 - * - * @package Widget - */ -class Widget_Do extends Typecho_Widget -{ - /** - * 路由映射 - * - * @access private - * @var array - */ - private $_map = array( - 'ajax' => 'Widget_Ajax', - 'login' => 'Widget_Login', - 'logout' => 'Widget_Logout', - 'register' => 'Widget_Register', - 'upgrade' => 'Widget_Upgrade', - 'upload' => 'Widget_Upload', - 'service' => 'Widget_Service', - 'xmlrpc' => 'Widget_XmlRpc', - 'comments-edit' => 'Widget_Comments_Edit', - 'contents-page-edit' => 'Widget_Contents_Page_Edit', - 'contents-post-edit' => 'Widget_Contents_Post_Edit', - 'contents-attachment-edit' => 'Widget_Contents_Attachment_Edit', - 'metas-category-edit' => 'Widget_Metas_Category_Edit', - 'metas-tag-edit' => 'Widget_Metas_Tag_Edit', - 'metas-tag-edit' => 'Widget_Metas_Tag_Edit', - 'options-discussion' => 'Widget_Options_Discussion', - 'options-general' => 'Widget_Options_General', - 'options-permalink' => 'Widget_Options_Permalink', - 'options-reading' => 'Widget_Options_Reading', - 'plugins-edit' => 'Widget_Plugins_Edit', - 'themes-edit' => 'Widget_Themes_Edit', - 'users-edit' => 'Widget_Users_Edit', - 'users-profile' => 'Widget_Users_Profile' - ); - - /** - * 入口函数,初始化路由器 - * - * @access public - * @return void - */ - public function execute() - { - /** 验证路由地址 **/ - $action = $this->request->action; - - //兼容老版本 - if (empty($action)) { - $widget = trim($this->request->widget, '/'); - $objectName = 'Widget_' . str_replace('/', '_', $widget); - - if (Typecho_Common::isAvailableClass($objectName)) { - $widgetName = $objectName; - } - } else { - /** 判断是否为plugin */ - $actionTable = array_merge($this->_map, unserialize($this->widget('Widget_Options')->actionTable)); - - if (isset($actionTable[$action])) { - $widgetName = $actionTable[$action]; - } - } - - if (isset($widgetName) && class_exists($widgetName)) { - $reflectionWidget = new ReflectionClass($widgetName); - if ($reflectionWidget->implementsInterface('Widget_Interface_Do')) { - $this->widget($widgetName)->action(); - return; - } - } - - throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404); - } -} diff --git a/php/typecho09/var/Widget/ExceptionHandle.php b/php/typecho09/var/Widget/ExceptionHandle.php deleted file mode 100644 index 0a1c72f12..000000000 --- a/php/typecho09/var/Widget/ExceptionHandle.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 异常处理组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_ExceptionHandle extends Widget_Archive -{ - /** - * 重载构造函数 - * - * @access public - * @param Exception $excepiton 抛出的异常 - * @return void - */ - public function __construct() - { - $this->widget('Widget_Archive@404', 'type=404')->render(); - exit; - } -} diff --git a/php/typecho09/var/Widget/Feedback.php b/php/typecho09/var/Widget/Feedback.php deleted file mode 100644 index fb4cf7c89..000000000 --- a/php/typecho09/var/Widget/Feedback.php +++ /dev/null @@ -1,333 +0,0 @@ -<?php -/** - * 反馈提交 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 反馈提交组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interface_Do -{ - /** - * 内容对象 - * - * @access private - * @var Widget_Archive - */ - private $_content; - - /** - * 评论处理函数 - * - * @access private - * @return void - */ - private function comment() - { - $comment = array( - 'cid' => $this->_content->cid, - 'created' => $this->options->gmtTime, - 'agent' => $this->request->getAgent(), - 'ip' => $this->request->getIp(), - 'ownerId' => $this->_content->author->uid, - 'type' => 'comment', - 'status' => !$this->_content->allow('edit') && $this->options->commentsRequireModeration ? 'waiting' : 'approved' - ); - - /** 判断父节点 */ - if ($parentId = $this->request->filter('int')->get('parent')) { - if ($this->options->commentsThreaded && ($parent = $this->db->fetchRow($this->db->select('coid', 'cid')->from('table.comments') - ->where('coid = ?', $parentId))) && $this->_content->cid == $parent['cid']) { - $comment['parent'] = $parentId; - } else { - throw new Typecho_Widget_Exception(_t('父级评论不存在')); - } - } - - //检验格式 - $validator = new Typecho_Validate(); - $validator->addRule('author', 'required', _t('必须填写用户名')); - $validator->addRule('author', 'xssCheck', _t('请不要在用户名中使用特殊字符')); - $validator->addRule('author', array($this, 'requireUserLogin'), _t('您所使用的用户名已经被注册,请登录后再次提交')); - $validator->addRule('author', 'maxLength', _t('用户名最多包含200个字符'), 200); - - if ($this->options->commentsRequireMail && !$this->user->hasLogin()) { - $validator->addRule('mail', 'required', _t('必须填写电子邮箱地址')); - } - - $validator->addRule('mail', 'email', _t('邮箱地址不合法')); - $validator->addRule('mail', 'maxLength', _t('电子邮箱最多包含200个字符'), 200); - - if ($this->options->commentsRequireUrl && !$this->user->hasLogin()) { - $validator->addRule('url', 'required', _t('必须填写个人主页')); - } - $validator->addRule('url', 'url', _t('个人主页地址格式错误')); - $validator->addRule('url', 'maxLength', _t('个人主页地址最多包含200个字符'), 200); - - $validator->addRule('text', 'required', _t('必须填写评论内容')); - - $comment['text'] = $this->request->text; - - /** 对一般匿名访问者,将用户数据保存一个月 */ - if (!$this->user->hasLogin()) { - /** Anti-XSS */ - $comment['author'] = $this->request->filter('trim')->author; - $comment['mail'] = $this->request->filter('trim')->mail; - $comment['url'] = $this->request->filter('trim')->url; - - /** 修正用户提交的url */ - if (!empty($comment['url'])) { - $urlParams = parse_url($comment['url']); - if (!isset($urlParams['scheme'])) { - $comment['url'] = 'http://' . $comment['url']; - } - } - - $expire = $this->options->gmtTime + $this->options->timezone + 30*24*3600; - Typecho_Cookie::set('__typecho_remember_author', $comment['author'], $expire); - Typecho_Cookie::set('__typecho_remember_mail', $comment['mail'], $expire); - Typecho_Cookie::set('__typecho_remember_url', $comment['url'], $expire); - } else { - $comment['author'] = $this->user->screenName; - $comment['mail'] = $this->user->mail; - $comment['url'] = $this->user->url; - - /** 记录登录用户的id */ - $comment['authorId'] = $this->user->uid; - } - - /** 评论者之前须有评论通过了审核 */ - if (!$this->options->commentsRequireModeration && $this->options->commentsWhitelist) { - if ($commentApprovedNum = $this->size($this->select()->where('author = ? AND mail = ? AND status = ?', $comment['author'], $comment['mail'], 'approved'))) { - $comment['status'] = 'approved'; - } else { - $comment['status'] = 'waiting'; - } - } - - if ($error = $validator->run($comment)) { - /** 记录文字 */ - Typecho_Cookie::set('__typecho_remember_text', $comment['text']); - throw new Typecho_Widget_Exception(implode("\n", $error)); - } - - /** 生成过滤器 */ - try { - $comment = $this->pluginHandle()->comment($comment, $this->_content); - } catch (Typecho_Exception $e) { - Typecho_Cookie::set('__typecho_remember_text', $comment['text']); - throw $e; - } - - /** 添加评论 */ - $commentId = $this->insert($comment); - Typecho_Cookie::delete('__typecho_remember_text'); - $this->db->fetchRow($this->select()->where('coid = ?', $commentId) - ->limit(1), array($this, 'push')); - - /** 评论完成接口 */ - $this->pluginHandle()->finishComment($this); - - $this->response->goBack('#' . $this->theId); - } - - /** - * 引用处理函数 - * - * @access private - * @return void - */ - private function trackback() - { - /** 如果不是POST方法 */ - if (!$this->request->isPost() || $this->request->getReferer()) { - $this->response->redirect($this->_content->permalink); - } - - /** 如果库中已经存在当前ip为spam的trackback则直接拒绝 */ - if ($this->size($this->select() - ->where('status = ? AND ip = ?', 'spam', $this->request->getIp())) > 0) { - /** 使用404告诉机器人 */ - throw new Typecho_Widget_Exception(_t('找不到内容'), 404); - } - - $trackback = array( - 'cid' => $this->_content->cid, - 'created' => $this->options->gmtTime, - 'agent' => $this->request->getAgent(), - 'ip' => $this->request->getIp(), - 'ownerId' => $this->_content->author->uid, - 'type' => 'trackback', - 'status' => $this->options->commentsRequireModeration ? 'waiting' : 'approved' - ); - - $trackback['author'] = $this->request->filter('trim')->blog_name; - $trackback['url'] = $this->request->filter('trim')->url; - $trackback['text'] = $this->request->excerpt; - - //检验格式 - $validator = new Typecho_Validate(); - $validator->addRule('url', 'required', 'We require all Trackbacks to provide an url.') - ->addRule('url', 'url', 'Your url is not valid.') - ->addRule('url', 'maxLength', 'Your url is not valid.', 200) - ->addRule('text', 'required', 'We require all Trackbacks to provide an excerption.') - ->addRule('author', 'required', 'We require all Trackbacks to provide an blog name.') - ->addRule('author', 'xssCheck', 'Your blog name is not valid.') - ->addRule('author', 'maxLength', 'Your blog name is not valid.', 200); - - $validator->setBreak(); - if ($error = $validator->run($trackback)) { - $message = array('success' => 1, 'message' => current($error)); - $this->response->throwXml($message); - } - - /** 截取长度 */ - $trackback['text'] = Typecho_Common::subStr($trackback['text'], 0, 100, '[...]'); - - /** 如果库中已经存在重复url则直接拒绝 */ - if ($this->size($this->select() - ->where('cid = ? AND url = ? AND type <> ?', $this->_content->cid, $trackback['url'], 'comment')) > 0) { - /** 使用403告诉机器人 */ - throw new Typecho_Widget_Exception(_t('禁止重复提交'), 403); - } - - /** 生成过滤器 */ - $trackback = $this->pluginHandle()->trackback($trackback, $this->_content); - - /** 添加引用 */ - $trackbackId = $this->insert($trackback); - - /** 评论完成接口 */ - $this->pluginHandle()->finishTrackback($this); - - /** 返回正确 */ - $this->response->throwXml(array('success' => 0, 'message' => 'Trackback has registered.')); - } - - /** - * 过滤评论内容 - * - * @access public - * @param string $text 评论内容 - * @return string - */ - public function filterText($text) - { - $text = str_replace("\r", '', trim($text)); - $text = preg_replace("/\n{2,}/", "\n\n", $text); - - return Typecho_Common::removeXSS(Typecho_Common::stripTags( - $text, $this->options->commentsHTMLTagAllowed)); - } - - /** - * 对已注册用户的保护性检测 - * - * @access public - * @param string $userName 用户名 - * @return void - */ - public function requireUserLogin($userName) - { - if ($this->user->hasLogin() && $this->user->screenName != $userName) { - /** 当前用户名与提交者不匹配 */ - return false; - } else if (!$this->user->hasLogin() && $this->db->fetchRow($this->db->select('uid') - ->from('table.users')->where('screenName = ? OR name = ?', $userName, $userName)->limit(1))) { - /** 此用户名已经被注册 */ - return false; - } - - return true; - } - - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - /** 回调方法 */ - $callback = $this->request->type; - $this->_content = Typecho_Router::match($this->request->permalink); - - /** 判断内容是否存在 */ - if (false !== $this->_content && $this->_content instanceof Widget_Archive && - $this->_content->have() && $this->_content->is('single') && - in_array($callback, array('comment', 'trackback'))) { - - /** 如果文章不允许反馈 */ - if ('comment' == $callback) { - /** 评论关闭 */ - if (!$this->_content->allow('comment')) { - throw new Typecho_Widget_Exception(_t('对不起,此内容的反馈被禁止.'), 403); - } - - /** 检查来源 */ - if ($this->options->commentsCheckReferer) { - $referer = $this->request->getReferer(); - - if (empty($referer)) { - throw new Typecho_Widget_Exception(_t('评论来源页错误.'), 403); - } - - $refererPart = parse_url($referer); - $currentPart = parse_url($this->_content->permalink); - - if ($refererPart['host'] != $currentPart['host'] || - 0 !== strpos($refererPart['path'], $currentPart['path'])) { - - //自定义首页支持 - if ('page:' . $this->_content->cid == $this->options->frontPage) { - $currentPart = parse_url(rtrim($this->options->siteUrl, '/') . '/'); - - if ($refererPart['host'] != $currentPart['host'] || - 0 !== strpos($refererPart['path'], $currentPart['path'])) { - throw new Typecho_Widget_Exception(_t('评论来源页错误.'), 403); - } - } else { - throw new Typecho_Widget_Exception(_t('评论来源页错误.'), 403); - } - } - } - - /** 检查ip评论间隔 */ - if (!$this->user->pass('editor', true) && $this->_content->authorId != $this->user->uid && - $this->options->commentsPostIntervalEnable) { - $latestComment = $this->db->fetchRow($this->db->select('created')->from('table.comments') - ->where('cid = ?', $this->_content->cid) - ->order('created', Typecho_Db::SORT_DESC) - ->limit(1)); - - if ($latestComment && ($this->options->gmtTime - $latestComment['created'] > 0 && - $this->options->gmtTime - $latestComment['created'] < $this->options->commentsPostInterval)) { - throw new Typecho_Widget_Exception(_t('对不起, 您的发言过于频繁, 请稍侯再次发布.'), 403); - } - } - } - - /** 如果文章不允许引用 */ - if ('trackback' == $callback && !$this->_content->allow('ping')) { - throw new Typecho_Widget_Exception(_t('对不起,此内容的引用被禁止.'), 403); - } - - /** 调用函数 */ - $this->$callback(); - } else { - throw new Typecho_Widget_Exception(_t('找不到内容'), 404); - } - } -} diff --git a/php/typecho09/var/Widget/Init.php b/php/typecho09/var/Widget/Init.php deleted file mode 100644 index 8adb3ed98..000000000 --- a/php/typecho09/var/Widget/Init.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 初始化模块 - * - * @package Widget - */ -class Widget_Init extends Typecho_Widget -{ - /** - * 入口函数,初始化路由器 - * - * @access public - * @return void - */ - public function execute() - { - /** 对变量赋值 */ - $options = $this->widget('Widget_Options'); - - /** cookie初始化 */ - Typecho_Cookie::setPrefix($options->siteUrl); - - /** 初始化charset */ - Typecho_Common::$charset = $options->charset; - - /** 初始化exception */ - Typecho_Common::$exceptionHandle = 'Widget_ExceptionHandle'; - - /** 设置路径 */ - if (defined('__TYPECHO_PATHINFO_ENCODING__')) { - $pathInfo = $this->request->getPathInfo(__TYPECHO_PATHINFO_ENCODING__, $options->charset); - } else { - $pathInfo = $this->request->getPathInfo(); - } - - Typecho_Router::setPathInfo($pathInfo); - - /** 初始化路由器 */ - Typecho_Router::setRoutes($options->routingTable); - - /** 初始化插件 */ - Typecho_Plugin::init($options->plugins); - - /** 初始化回执 */ - $this->response->setCharset($options->charset); - $this->response->setContentType($options->contentType); - - /** 默认时区 */ - if (function_exists("ini_get") && !ini_get("date.timezone") && function_exists("date_default_timezone_set")) { - @date_default_timezone_set('UTC'); - } - - /** 初始化时区 */ - Typecho_Date::setTimezoneOffset($options->timezone); - - /** 开始会话, 减小负载只针对后台打开session支持 */ - if ($this->widget('Widget_User')->hasLogin()) { - @session_start(); - } - - /** 监听缓冲区 */ - ob_start(); - } -} diff --git a/php/typecho09/var/Widget/Interface/Do.php b/php/typecho09/var/Widget/Interface/Do.php deleted file mode 100644 index 355caf81c..000000000 --- a/php/typecho09/var/Widget/Interface/Do.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * 可以被Widget_Do调用的接口 - * - * @package Widget - * @version $id$ - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @author qining <magike.net@gmail.com> - * @license GNU General Public License 2.0 - */ -interface Widget_Interface_Do -{ - /** - * 接口需要实现的入口函数 - * - * @access public - * @return void - */ - public function action(); -} diff --git a/php/typecho09/var/Widget/Login.php b/php/typecho09/var/Widget/Login.php deleted file mode 100644 index 112072a79..000000000 --- a/php/typecho09/var/Widget/Login.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * 登录动作 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 登录组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Login extends Widget_Abstract_Users implements Widget_Interface_Do -{ - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - /** 如果已经登录 */ - if ($this->user->hasLogin()) { - /** 直接返回 */ - $this->response->redirect($this->options->index); - } - - /** 初始化验证类 */ - $validator = new Typecho_Validate(); - $validator->addRule('name', 'required', _t('请输入用户名')); - $validator->addRule('password', 'required', _t('请输入密码')); - - /** 截获验证异常 */ - if ($error = $validator->run($this->request->from('name', 'password'))) { - Typecho_Cookie::set('__typecho_remember_name', $this->request->name); - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($error); - $this->response->goBack(); - } - - /** 开始验证用户 **/ - $valid = $this->user->login($this->request->name, $this->request->password, - false, 1 == $this->request->remember ? $this->options->gmtTime + $this->options->timezone + 30*24*3600 : 0); - - /** 比对密码 */ - if (!$valid) { - /** 防止穷举,休眠3秒 */ - sleep(3); - - $this->pluginHandle()->loginFail($this->user, $this->request->name, - $this->request->password, 1 == $this->request->remember); - - Typecho_Cookie::set('__typecho_remember_name', $this->request->name); - $this->widget('Widget_Notice')->set(_t('用户名或密码无效'), 'error'); - $this->response->goBack('?referer=' . urlencode($this->request->referer)); - } - - $this->pluginHandle()->loginSucceed($this->user, $this->request->name, - $this->request->password, 1 == $this->request->remember); - - /** 跳转验证后地址 */ - if (NULL != $this->request->referer) { - $this->response->redirect($this->request->referer); - } else if (!$this->user->pass('contributor', true)) { - /** 不允许普通用户直接跳转后台 */ - $this->response->redirect($this->options->siteUrl); - } else { - $this->response->redirect($this->options->adminUrl); - } - } -} diff --git a/php/typecho09/var/Widget/Logout.php b/php/typecho09/var/Widget/Logout.php deleted file mode 100644 index c89847432..000000000 --- a/php/typecho09/var/Widget/Logout.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * 登出动作 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 登出组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Logout extends Widget_Abstract_Users implements Widget_Interface_Do -{ - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - $this->user->logout(); - $this->pluginHandle()->logout(); - $this->response->goBack(NULL, $this->options->index); - @session_destroy(); - } -} diff --git a/php/typecho09/var/Widget/Menu.php b/php/typecho09/var/Widget/Menu.php deleted file mode 100644 index d024d4971..000000000 --- a/php/typecho09/var/Widget/Menu.php +++ /dev/null @@ -1,331 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 后台菜单显示 - * - * @package Widget - */ -class Widget_Menu extends Typecho_Widget -{ - /** - * 父菜单列表 - * - * @access private - * @var array - */ - private $_menu = array(); - - /** - * 当前父菜单 - * - * @access private - * @var integer - */ - private $_currentParent = 1; - - /** - * 当前子菜单 - * - * @access private - * @var integer - */ - private $_currentChild = 0; - - /** - * 当前页面 - * - * @access private - * @var string - */ - private $_currentUrl; - - /** - * 全局选项 - * - * @access protected - * @var Widget_Options - */ - protected $options; - - /** - * 用户对象 - * - * @access protected - * @var Widget_User - */ - protected $user; - - /** - * 当前菜单标题 - * @var string - */ - public $title; - - /** - * 当前增加项目链接 - * @var string - */ - public $addLink; - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - - /** 初始化常用组件 */ - $this->options = $this->widget('Widget_Options'); - $this->user = $this->widget('Widget_User'); - } - - /** - * 执行函数,初始化菜单 - * - * @access public - * @return void - */ - public function execute() - { - $parentNodes = array(NULL, _t('控制台'), _t('撰写'), _t('管理'), _t('设置')); - - $childNodes = array( - array( - array(_t('登录'), _t('登录到%s', $this->options->title), 'login.php', 'visitor'), - array(_t('注册'), _t('注册到%s', $this->options->title), 'register.php', 'visitor') - ), - array( - array(_t('概要'), _t('网站概要'), 'index.php', 'subscriber'), - array(_t('个人设置'), _t('个人设置'), 'profile.php', 'subscriber'), - array(_t('插件'), _t('插件管理'), 'plugins.php', 'administrator'), - array(array('Widget_Plugins_Config', 'getMenuTitle'), array('Widget_Plugins_Config', 'getMenuTitle'), 'options-plugin.php?config=', 'administrator', true), - array(_t('外观'), _t('网站外观'), 'themes.php', 'administrator'), - array(array('Widget_Themes_Files', 'getMenuTitle'), array('Widget_Themes_Files', 'getMenuTitle'), 'theme-editor.php', 'administrator', true), - array(array('Widget_Themes_Config', 'getMenuTitle'), array('Widget_Themes_Config', 'getMenuTitle'), 'options-theme.php', 'administrator', true), - array(_t('升级'), _t('升级程序'), 'upgrade.php', 'administrator', true), - array(_t('欢迎'), _t('欢迎使用'), 'welcome.php', 'subscriber', true) - ), - array( - array(_t('撰写文章'), _t('撰写新文章'), 'write-post.php', 'contributor'), - array(array('Widget_Contents_Post_Edit', 'getMenuTitle'), array('Widget_Contents_Post_Edit', 'getMenuTitle'), 'write-post.php?cid=', 'contributor', true), - array(_t('创建页面'), _t('创建新页面'), 'write-page.php', 'editor'), - array(array('Widget_Contents_Page_Edit', 'getMenuTitle'), array('Widget_Contents_Page_Edit', 'getMenuTitle'), 'write-page.php?cid=', 'editor', true), - ), - array( - array(_t('文章'), _t('管理文章'), 'manage-posts.php', 'contributor', false, 'write-post.php'), - array(array('Widget_Contents_Post_Admin', 'getMenuTitle'), array('Widget_Contents_Post_Admin', 'getMenuTitle'), 'manage-posts.php?uid=', 'contributor', true), - array(_t('独立页面'), _t('管理独立页面'), 'manage-pages.php', 'editor', false, 'write-page.php'), - array(_t('评论'), _t('管理评论'), 'manage-comments.php', 'contributor'), - array(array('Widget_Comments_Admin', 'getMenuTitle'), array('Widget_Comments_Admin', 'getMenuTitle'), 'manage-comments.php?cid=', 'contributor', true), - array(_t('标签和分类'), _t('标签和分类'), 'manage-metas.php', 'editor'), - array(_t('文件'), _t('管理文件'), 'manage-medias.php', 'editor'), - array(array('Widget_Contents_Attachment_Edit', 'getMenuTitle'), array('Widget_Contents_Attachment_Edit', 'getMenuTitle'), 'media.php?cid=', 'contributor', true), - array(_t('用户'), _t('管理用户'), 'manage-users.php', 'administrator', false, 'user.php'), - array(_t('新增用户'), _t('新增用户'), 'user.php', 'administrator', true), - array(array('Widget_Users_Edit', 'getMenuTitle'), array('Widget_Users_Edit', 'getMenuTitle'), 'user.php?uid=', 'administrator', true), - ), - array( - array(_t('基本'), _t('基本设置'), 'options-general.php', 'administrator'), - array(_t('评论'), _t('评论设置'), 'options-discussion.php', 'administrator'), - array(_t('阅读'), _t('阅读设置'), 'options-reading.php', 'administrator'), - array(_t('永久链接'), _t('永久链接设置'), 'options-permalink.php', 'administrator'), - )); - - /** 获取扩展菜单 */ - $panelTable = unserialize($this->options->panelTable); - $extendingParentMenu = empty($panelTable['parent']) ? array() : $panelTable['parent']; - $extendingChildMenu = empty($panelTable['child']) ? array() : $panelTable['child']; - $currentUrl = $this->request->makeUriByRequest(); - $adminUrl = $this->options->adminUrl; - $menu = array(); - $defaultChildeNode = array(NULL, NULL, NULL, 'administrator', false, NULL); - - $currentUrlParts = parse_url($currentUrl); - $currentUrlParams = array(); - if (!empty($currentUrlParts['query'])) { - parse_str($currentUrlParts['query'], $currentUrlParams); - } - - if ('/' == $currentUrlParts['path'][strlen($currentUrlParts['path']) - 1]) { - $currentUrlParts['path'] .= 'index.php'; - } - - foreach ($extendingParentMenu as $key => $val) { - $parentNodes[10 + $key] = $val; - } - - foreach ($extendingChildMenu as $key => $val) { - $childNodes[$key] = array_merge(isset($childNodes[$key]) ? $childNodes[$key] : array(), $val); - } - - foreach ($parentNodes as $key => $parentNode) { - // this is a simple struct than before - $children = array(); - $showedChildrenCount = 0; - $firstUrl = NULL; - - foreach ($childNodes[$key] as $inKey => $childNode) { - // magic merge - $childNode += $defaultChildeNode; - list ($name, $title, $url, $access, $hidden, $addLink) = $childNode; - - // 保存最原始的hidden信息 - $orgHidden = $hidden; - - // parse url - $url = Typecho_Common::url($url, $adminUrl); - - // compare url - $urlParts = parse_url($url); - $urlParams = array(); - if (!empty($urlParts['query'])) { - parse_str($urlParts['query'], $urlParams); - } - - $validate = true; - if ($urlParts['path'] != $currentUrlParts['path']) { - $validate = false; - } else { - foreach ($urlParams as $paramName => $paramValue) { - if (!isset($currentUrlParams[$paramName])) { - $validate = false; - break; - } - } - } - - if ($validate - && basename($urlParts['path']) == 'extending.php' - && !empty($currentUrlParams['panel']) && !empty($urlParams['panel']) - && $urlParams['panel'] != $currentUrlParams['panel']){ - $validate = false; - } - - if ($hidden && $validate) { - $hidden = false; - } - - if (!$hidden && !$this->user->pass($access, true)) { - $hidden = true; - } - - if (!$hidden) { - $showedChildrenCount ++; - - if (empty($firstUrl)) { - $firstUrl = $url; - } - - if (is_array($name)) { - list($widget, $method) = $name; - $name = Typecho_Widget::widget($widget)->$method(); - } - - if (is_array($title)) { - list($widget, $method) = $title; - $title = Typecho_Widget::widget($widget)->$method(); - } - } - - if ($validate) { - if ('visitor' != $access) { - $this->user->pass($access); - } - - $this->_currentParent = $key; - $this->_currentChild = $inKey; - $this->title = $title; - $this->addLink = $addLink ? Typecho_Common::url($addLink, $adminUrl) : NULL; - } - - $children[$inKey] = array( - $name, - $title, - $url, - $access, - $hidden, - $addLink, - $orgHidden - ); - } - - $menu[$key] = array($parentNode, $showedChildrenCount > 0, $firstUrl,$children); - } - - $this->_menu = $menu; - $this->_currentUrl = $currentUrl; - } - - /** - * 获取当前菜单 - * - * @access public - * @return array - */ - public function getCurrentMenu() - { - return $this->_currentParent > 0 ? $this->_menu[$this->_currentParent][3][$this->_currentChild] : NULL; - } - - /** - * 输出父级菜单 - * - * @access public - * @return string - */ - public function output($class = 'focus', $childClass = 'focus') - { - foreach ($this->_menu as $key => $node) { - if (!$node[1] || !$key) { - continue; - } - - echo "<ul class=\"root" . ($key == $this->_currentParent ? ' ' . $class : NULL) - . "\"><li class=\"parent\"><a href=\"{$node[2]}\">{$node[0]}</a></dt>" - . "</li><ul class=\"child\">"; - - $last = 0; - foreach ($node[3] as $inKey => $inNode) { - if (!$inNode[4]) { - $last = $inKey; - } - } - - foreach ($node[3] as $inKey => $inNode) { - if ($inNode[4]) { - continue; - } - - $classes = array(); - if ($key == $this->_currentParent && $inKey == $this->_currentChild) { - $classes[] = $childClass; - } else if ($inNode[6]) { - continue; - } - - if ($inKey == $last) { - $classes[] = 'last'; - } - - echo "<li" . (!empty($classes) ? ' class="' . implode(' ', $classes) . '"' : NULL) . - "><a href=\"" . ($key == $this->_currentParent && $inKey == $this->_currentChild ? $this->_currentUrl : $inNode[2]) . "\">{$inNode[0]}</a></li>"; - } - - echo "</ul></ul>"; - } - } -} - diff --git a/php/typecho09/var/Widget/Metas/Category/Edit.php b/php/typecho09/var/Widget/Metas/Category/Edit.php deleted file mode 100644 index e33cfa001..000000000 --- a/php/typecho09/var/Widget/Metas/Category/Edit.php +++ /dev/null @@ -1,426 +0,0 @@ -<?php -/** - * 编辑分类 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 编辑分类组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget_Interface_Do -{ - /** - * 入口函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 编辑以上权限 */ - $this->user->pass('editor'); - } - - /** - * 判断分类是否存在 - * - * @access public - * @param integer $mid 分类主键 - * @return boolean - */ - public function categoryExists($mid) - { - $category = $this->db->fetchRow($this->db->select() - ->from('table.metas') - ->where('type = ?', 'category') - ->where('mid = ?', $mid)->limit(1)); - - return $category ? true : false; - } - - /** - * 判断分类名称是否存在 - * - * @access public - * @param string $name 分类名称 - * @return boolean - */ - public function nameExists($name) - { - $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'category') - ->where('name = ?', $name) - ->limit(1); - - if ($this->request->mid) { - $select->where('mid <> ?', $this->request->mid); - } - - $category = $this->db->fetchRow($select); - return $category ? false : true; - } - - /** - * 判断分类名转换到缩略名后是否合法 - * - * @access public - * @param string $name 分类名 - * @return boolean - */ - public function nameToSlug($name) - { - if (empty($this->request->slug)) { - $slug = Typecho_Common::slugName($name); - if (empty($slug) || !$this->slugExists($name)) { - return false; - } - } - - return true; - } - - /** - * 判断分类缩略名是否存在 - * - * @access public - * @param string $slug 缩略名 - * @return boolean - */ - public function slugExists($slug) - { - $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'category') - ->where('slug = ?', Typecho_Common::slugName($slug)) - ->limit(1); - - if ($this->request->mid) { - $select->where('mid <> ?', $this->request->mid); - } - - $category = $this->db->fetchRow($select); - return $category ? false : true; - } - - /** - * 生成表单 - * - * @access public - * @param string $action 表单动作 - * @return Typecho_Widget_Helper_Form_Element - */ - public function form($action = NULL) - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/metas-category-edit', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 分类名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('分类名称 *')); - $form->addInput($name); - - /** 分类缩略名 */ - $slug = new Typecho_Widget_Helper_Form_Element_Text('slug', NULL, NULL, _t('分类缩略名'), - _t('分类缩略名用于创建友好的链接形式,建议使用字母,数字,下划线和横杠.')); - $form->addInput($slug); - - /** 分类描述 */ - $description = new Typecho_Widget_Helper_Form_Element_Textarea('description', NULL, NULL, - _t('分类描述'), _t('此文字用于描述分类,在有的主题中它会被显示.')); - $form->addInput($description); - - /** 分类动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do'); - $form->addInput($do); - - /** 分类主键 */ - $mid = new Typecho_Widget_Helper_Form_Element_Hidden('mid'); - $form->addInput($mid); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit(); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - if (isset($this->request->mid) && 'insert' != $action) { - /** 更新模式 */ - $meta = $this->db->fetchRow($this->select() - ->where('mid = ?', $this->request->mid) - ->where('type = ?', 'category')->limit(1)); - - if (!$meta) { - $this->response->redirect(Typecho_Common::url('manage-metas.php', $this->options->adminUrl)); - } - - $name->value($meta['name']); - $slug->value($meta['slug']); - $description->value($meta['description']); - $do->value('update'); - $mid->value($meta['mid']); - $submit->value(_t('编辑分类')); - $_action = 'update'; - } else { - $do->value('insert'); - $submit->value(_t('增加分类')); - $_action = 'insert'; - } - - if (empty($action)) { - $action = $_action; - } - - /** 给表单增加规则 */ - if ('insert' == $action || 'update' == $action) { - $name->addRule('required', _t('必须填写分类名称')); - $name->addRule(array($this, 'nameExists'), _t('分类名称已经存在')); - $name->addRule(array($this, 'nameToSlug'), _t('分类名称无法被转换为缩略名')); - $slug->addRule(array($this, 'slugExists'), _t('缩略名已经存在')); - } - - if ('update' == $action) { - $mid->addRule('required', _t('分类主键不存在')); - $mid->addRule(array($this, 'categoryExists'), _t('分类不存在')); - } - - return $form; - } - - /** - * 增加分类 - * - * @access public - * @return void - */ - public function insertCategory() - { - if ($this->form('insert')->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $category = $this->request->from('name', 'slug', 'description'); - $category['slug'] = Typecho_Common::slugName(empty($category['slug']) ? $category['name'] : $category['slug']); - $category['type'] = 'category'; - $category['order'] = $this->db->fetchObject($this->db->select(array('MAX(order)' => 'maxOrder')) - ->from('table.metas') - ->where('type = ?', 'category'))->maxOrder + 1; - - /** 插入数据 */ - $category['mid'] = $this->insert($category); - $this->push($category); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('分类 <a href="%s">%s</a> 已经被增加', - $this->permalink, $this->name), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php', $this->options->adminUrl)); - } - - /** - * 更新分类 - * - * @access public - * @return void - */ - public function updateCategory() - { - if ($this->form('update')->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $category = $this->request->from('name', 'slug', 'description'); - $category['slug'] = Typecho_Common::slugName(empty($category['slug']) ? $category['name'] : $category['slug']); - $category['type'] = 'category'; - - /** 更新数据 */ - $this->update($category, $this->db->sql()->where('mid = ?', $this->request->filter('int')->mid)); - $category['mid'] = $this->request->mid; - $this->push($category); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('分类 <a href="%s">%s</a> 已经被更新', - $this->permalink, $this->name), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php', $this->options->adminUrl)); - } - - /** - * 删除分类 - * - * @access public - * @return void - */ - public function deleteCategory() - { - $categories = $this->request->filter('int')->mid; - $deleteCount = 0; - - if ($categories && is_array($categories)) { - foreach ($categories as $category) { - if ($this->delete($this->db->sql()->where('mid = ?', $category))) { - $this->db->query($this->db->sql()->delete('table.relationships')->where('mid = ?', $category)); - $deleteCount ++; - } - } - } - - /** 提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('分类已经删除') : _t('没有分类被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php', $this->options->adminUrl)); - } - - /** - * 合并分类 - * - * @access public - * @return void - */ - public function mergeCategory() - { - /** 验证数据 */ - $validator = new Typecho_Validate(); - $validator->addRule('merge', 'required', _t('分类主键不存在')); - $validator->addRule('merge', array($this, 'categoryExists'), _t('请选择需要合并的分类')); - - if ($validator->run($this->request->from('merge'))) { - $this->widget('Widget_Notice')->set($e->getMessages(), 'error'); - $this->response->goBack(); - } - - $merge = $this->request->merge; - $categories = $this->request->filter('int')->mid; - - if ($categories && is_array($categories)) { - $this->merge($merge, 'category', $categories); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('分类已经合并'), 'success'); - } else { - $this->widget('Widget_Notice')->set(_t('没有选择任何分类'), 'notice'); - } - - /** 转向原页 */ - $this->response->goBack(); - } - - /** - * 分类排序 - * - * @access public - * @return void - */ - public function sortCategory() - { - $categories = $this->request->filter('int')->mid; - if ($categories && is_array($categories)) { - $this->sort($categories, 'category'); - } - - if (!$this->request->isAjax()) { - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php', $this->options->adminUrl)); - } else { - $this->response->throwJson(array('success' => 1, 'message' => _t('分类排序已经完成'))); - } - } - - /** - * 刷新分类 - * - * @access public - * @return void - */ - public function refreshCategory() - { - $categories = $this->request->filter('int')->mid; - if ($categories && is_array($categories)) { - foreach ($categories as $category) { - $this->refreshCountByTypeAndStatus($category, 'post', 'publish'); - } - - $this->widget('Widget_Notice')->set(_t('分类刷新已经完成'), 'success'); - } else { - $this->widget('Widget_Notice')->set(_t('没有选择任何分类'), 'notice'); - } - - /** 转向原页 */ - $this->response->goBack(); - } - - /** - * 设置默认分类 - * - * @access public - * @return void - */ - public function defaultCategory() - { - /** 验证数据 */ - $validator = new Typecho_Validate(); - $validator->addRule('mid', 'required', _t('分类主键不存在')); - $validator->addRule('mid', array($this, 'categoryExists'), _t('分类不存在')); - - if ($error = $validator->run($this->request->from('mid'))) { - $this->widget('Widget_Notice')->set($error, 'error'); - } else { - - $this->db->query($this->db->update('table.options') - ->rows(array('value' => $this->request->mid)) - ->where('name = ?', 'defaultCategory')); - - $this->db->fetchRow($this->select()->where('mid = ?', $this->request->mid) - ->where('type = ?', 'category')->limit(1), array($this, 'push')); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('<a href="%s">%s</a> 已经被设为默认分类', - $this->permalink, $this->name), 'success'); - } - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php', $this->options->adminUrl)); - } - - /** - * 入口函数 - * - * @access public - * @return void - */ - public function action() - { - $this->on($this->request->is('do=insert'))->insertCategory(); - $this->on($this->request->is('do=update'))->updateCategory(); - $this->on($this->request->is('do=delete'))->deleteCategory(); - $this->on($this->request->is('do=merge'))->mergeCategory(); - $this->on($this->request->is('do=sort'))->sortCategory(); - $this->on($this->request->is('do=refresh'))->refreshCategory(); - $this->on($this->request->is('do=default'))->defaultCategory(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Metas/Category/List.php b/php/typecho09/var/Widget/Metas/Category/List.php deleted file mode 100644 index 5a97f6d8d..000000000 --- a/php/typecho09/var/Widget/Metas/Category/List.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * 分类输出 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 分类输出组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Metas_Category_List extends Widget_Abstract_Metas -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->db->fetchAll($this->select()->where('type = ?', 'category') - ->order('table.metas.order', Typecho_Db::SORT_ASC), array($this, 'push')); - } -} diff --git a/php/typecho09/var/Widget/Metas/Tag/Cloud.php b/php/typecho09/var/Widget/Metas/Tag/Cloud.php deleted file mode 100644 index 3d28f9b20..000000000 --- a/php/typecho09/var/Widget/Metas/Tag/Cloud.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php -/** - * 标签云 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 标签云组件 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Metas_Tag_Cloud extends Widget_Abstract_Metas -{ - /** - * 入口函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault(array('sort' => 'count', 'ignoreZeroCount' => false, 'desc' => true, 'limit' => 0)); - $select = $this->select()->where('type = ?', 'tag')->order($this->parameter->sort, - $this->parameter->desc ? Typecho_Db::SORT_DESC : Typecho_Db::SORT_ASC); - - /** 忽略零数量 */ - if ($this->parameter->ignoreZeroCount) { - $select->where('count > 0'); - } - - /** 总数限制 */ - if ($this->parameter->limit) { - $select->limit($this->parameter->limit); - } - - $this->db->fetchAll($select, array($this, 'push')); - } - - /** - * 按分割数输出字符串 - * - * @access public - * @param string $param 需要输出的值 - * @return void - */ - public function split() - { - $args = func_get_args(); - array_unshift($args, $this->count); - echo call_user_func_array(array('Typecho_Common', 'splitByCount'), $args); - } -} diff --git a/php/typecho09/var/Widget/Metas/Tag/Edit.php b/php/typecho09/var/Widget/Metas/Tag/Edit.php deleted file mode 100644 index d3755822d..000000000 --- a/php/typecho09/var/Widget/Metas/Tag/Edit.php +++ /dev/null @@ -1,359 +0,0 @@ -<?php -/** - * 标签编辑 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 标签编辑组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Interface_Do -{ - /** - * 入口函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 编辑以上权限 */ - $this->user->pass('editor'); - } - - /** - * 判断标签是否存在 - * - * @access public - * @param integer $mid 标签主键 - * @return boolean - */ - public function tagExists($mid) - { - $tag = $this->db->fetchRow($this->db->select() - ->from('table.metas') - ->where('type = ?', 'tag') - ->where('mid = ?', $mid)->limit(1)); - - return $tag ? true : false; - } - - /** - * 判断标签名称是否存在 - * - * @access public - * @param string $name 标签名称 - * @return boolean - */ - public function nameExists($name) - { - $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'tag') - ->where('name = ?', $name) - ->limit(1); - - if ($this->request->mid) { - $select->where('mid <> ?', $this->request->filter('int')->mid); - } - - $tag = $this->db->fetchRow($select); - return $tag ? false : true; - } - - /** - * 判断标签名转换到缩略名后是否合法 - * - * @access public - * @param string $name 标签名 - * @return boolean - */ - public function nameToSlug($name) - { - if (empty($this->request->slug)) { - $slug = Typecho_Common::slugName($name); - if (empty($slug) || !$this->slugExists($name)) { - return false; - } - } - - return true; - } - - /** - * 判断标签缩略名是否存在 - * - * @access public - * @param string $slug 缩略名 - * @return boolean - */ - public function slugExists($slug) - { - $select = $this->db->select() - ->from('table.metas') - ->where('type = ?', 'tag') - ->where('slug = ?', Typecho_Common::slugName($slug)) - ->limit(1); - - if ($this->request->mid) { - $select->where('mid <> ?', $this->request->mid); - } - - $tag = $this->db->fetchRow($select); - return $tag ? false : true; - } - - /** - * 生成表单 - * - * @access public - * @param string $action 表单动作 - * @return Typecho_Widget_Helper_Form - */ - public function form($action = NULL) - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/metas-tag-edit', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 标签名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, - _t('标签名称 *'), _t('这是标签在站点中显示的名称.可以使用中文,如 "地球".')); - $form->addInput($name); - - /** 标签缩略名 */ - $slug = new Typecho_Widget_Helper_Form_Element_Text('slug', NULL, NULL, - _t('标签缩略名'), _t('标签缩略名用于创建友好的链接形式, 如果留空则默认使用标签名称.')); - $form->addInput($slug); - - /** 标签动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do'); - $form->addInput($do); - - /** 标签主键 */ - $mid = new Typecho_Widget_Helper_Form_Element_Hidden('mid'); - $form->addInput($mid); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit(); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - if (isset($this->request->mid) && 'insert' != $action) { - /** 更新模式 */ - $meta = $this->db->fetchRow($this->select() - ->where('mid = ?', $this->request->mid) - ->where('type = ?', 'tag')->limit(1)); - - if (!$meta) { - $this->response->redirect(Typecho_Common::url('manage-metas.php?type=tag', $this->options->adminUrl)); - } - - $name->value($meta['name']); - $slug->value($meta['slug']); - $do->value('update'); - $mid->value($meta['mid']); - $submit->value(_t('编辑标签')); - $_action = 'update'; - } else { - $do->value('insert'); - $submit->value(_t('增加标签')); - $_action = 'insert'; - } - - if (empty($action)) { - $action = $_action; - } - - /** 给表单增加规则 */ - if ('insert' == $action || 'update' == $action) { - $name->addRule('required', _t('必须填写标签名称')); - $name->addRule(array($this, 'nameExists'), _t('标签名称已经存在')); - $name->addRule(array($this, 'nameToSlug'), _t('标签名称无法被转换为缩略名')); - $slug->addRule(array($this, 'slugExists'), _t('缩略名已经存在')); - } - - if ('update' == $action) { - $mid->addRule('required', _t('标签主键不存在')); - $mid->addRule(array($this, 'tagExists'), _t('标签不存在')); - } - - return $form; - } - - /** - * 插入标签 - * - * @access public - * @return void - */ - public function insertTag() - { - if ($this->form('insert')->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $tag = $this->request->from('name', 'slug'); - $tag['type'] = 'tag'; - $tag['slug'] = Typecho_Common::slugName(empty($tag['slug']) ? $tag['name'] : $tag['slug']); - - /** 插入数据 */ - $tag['mid'] = $this->insert($tag); - $this->push($tag); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('标签 <a href="%s">%s</a> 已经被增加', - $this->permalink, $this->name), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php?type=tag', $this->options->adminUrl)); - } - - /** - * 更新标签 - * - * @access public - * @return void - */ - public function updateTag() - { - if ($this->form('update')->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $tag = $this->request->from('name', 'slug', 'mid'); - $tag['type'] = 'tag'; - $tag['slug'] = Typecho_Common::slugName(empty($tag['slug']) ? $tag['name'] : $tag['slug']); - - /** 更新数据 */ - $this->update($tag, $this->db->sql()->where('mid = ?', $this->request->filter('int')->mid)); - $this->push($tag); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight($this->theId); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('标签 <a href="%s">%s</a> 已经被更新', - $this->permalink, $this->name), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php?type=tag', $this->options->adminUrl)); - } - - /** - * 删除标签 - * - * @access public - * @return void - */ - public function deleteTag() - { - $tags = $this->request->filter('int')->mid; - $deleteCount = 0; - - if ($tags && is_array($tags)) { - foreach ($tags as $tag) { - if ($this->delete($this->db->sql()->where('mid = ?', $tag))) { - $this->db->query($this->db->delete('table.relationships')->where('mid = ?', $tag)); - $deleteCount ++; - } - } - } - - /** 提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('标签已经删除') : _t('没有标签被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php?type=tag', $this->options->adminUrl)); - } - - /** - * 合并标签 - * - * @access public - * @return void - */ - public function mergeTag() - { - if (empty($this->request->merge)) { - $this->widget('Widget_Notice')->set(_t('请填写需要合并到的标签'), 'notice'); - $this->response->goBack(); - } - - $merge = $this->scanTags($this->request->merge); - if (empty($merge)) { - $this->widget('Widget_Notice')->set(_t('合并到的标签名不合法'), 'error'); - $this->response->goBack(); - } - - $tags = $this->request->filter('int')->mid; - - if ($tags && is_array($tags)) { - $this->merge($merge, 'tag', $tags); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('标签已经合并'), 'success'); - } else { - $this->widget('Widget_Notice')->set(_t('没有选择任何标签'), 'notice'); - } - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-metas.php?type=tag', $this->options->adminUrl)); - } - - /** - * 刷新标签 - * - * @access public - * @return void - */ - public function refreshTag() - { - $tags = $this->request->filter('int')->mid; - if ($tags && is_array($tags)) { - foreach ($tags as $tag) { - $this->refreshCountByTypeAndStatus($tag, 'post', 'publish'); - } - - $this->widget('Widget_Notice')->set(_t('标签刷新已经完成'), 'success'); - } else { - $this->widget('Widget_Notice')->set(_t('没有选择任何标签'), 'notice'); - } - - /** 转向原页 */ - $this->response->goBack(); - } - - /** - * 入口函数,绑定事件 - * - * @access public - * @return void - */ - public function action() - { - $this->on($this->request->is('do=insert'))->insertTag(); - $this->on($this->request->is('do=update'))->updateTag(); - $this->on($this->request->is('do=delete'))->deleteTag(); - $this->on($this->request->is('do=merge'))->mergeTag(); - $this->on($this->request->is('do=refresh'))->refreshTag(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Notice.php b/php/typecho09/var/Widget/Notice.php deleted file mode 100644 index a492af74c..000000000 --- a/php/typecho09/var/Widget/Notice.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id: Widget.php 48 2008-03-16 02:51:40Z magike.net $ - */ - -/** - * 提示框组件 - * - * @package Widget - */ -class Widget_Notice extends Typecho_Widget -{ - /** - * 提示高亮 - * - * @access public - * @var string - */ - public $highlight; - - /** - * 高亮相关元素 - * - * @access public - * @param string $theId 需要高亮元素的id - * @return void - */ - public function highlight($theId) - { - $this->highlight = $theId; - Typecho_Cookie::set('__typecho_notice_highlight', $theId, - $this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400, - $this->widget('Widget_Options')->siteUrl); - } - - /** - * 获取高亮的id - * - * @access public - * @return integer - */ - public function getHighlightId() - { - return preg_match("/[0-9]+/", $this->highlight, $matches) ? $matches[0] : 0; - } - - /** - * 设定堆栈每一行的值 - * - * @param string $value 值对应的键值 - * @param string $type 提示类型 - * @param string $typeFix 兼容老插件 - * @return array - */ - public function set($value, $type = 'notice', $typeFix = 'notice') - { - $notice = is_array($value) ? array_values($value) : array($value); - if (empty($type) && $typeFix) { - $type = $typeFix; - } - - Typecho_Cookie::set('__typecho_notice', json_encode($notice), - $this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400, - $this->widget('Widget_Options')->siteUrl); - Typecho_Cookie::set('__typecho_notice_type', $type, - $this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400, - $this->widget('Widget_Options')->siteUrl); - } -} diff --git a/php/typecho09/var/Widget/Options.php b/php/typecho09/var/Widget/Options.php deleted file mode 100644 index 93bacf65e..000000000 --- a/php/typecho09/var/Widget/Options.php +++ /dev/null @@ -1,500 +0,0 @@ -<?php -/** - * 全局选项 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 全局选项组件 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Options extends Typecho_Widget -{ - /** - * 缓存的插件配置 - * - * @access private - * @var array - */ - private $_pluginConfig = array(); - - /** - * 缓存的个人插件配置 - * - * @access private - * @var array - */ - private $_personalPluginConfig = array(); - - /** - * 数据库对象 - * - * @access protected - * @var Typecho_Db - */ - protected $db; - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - - /** 初始化数据库 */ - $this->db = Typecho_Db::get(); - } - - /** - * RSS2.0 - * - * @access protected - * @return string - */ - protected function ___feedUrl() - { - return Typecho_Router::url('feed', array('feed' => '/'), $this->index); - } - - /** - * RSS1.0 - * - * @access protected - * @return string - */ - protected function ___feedRssUrl() - { - return Typecho_Router::url('feed', array('feed' => '/rss/'), $this->index); - } - - /** - * ATOM1.O - * - * @access protected - * @return string - */ - protected function ___feedAtomUrl() - { - return Typecho_Router::url('feed', array('feed' => '/atom/'), $this->index); - } - - /** - * 评论RSS2.0聚合 - * - * @access protected - * @return string - */ - protected function ___commentsFeedUrl() - { - return Typecho_Router::url('feed', array('feed' => '/comments/'), $this->index); - } - - /** - * 评论RSS1.0聚合 - * - * @access protected - * @return string - */ - protected function ___commentsFeedRssUrl() - { - return Typecho_Router::url('feed', array('feed' => '/rss/comments/'), $this->index); - } - - /** - * 评论ATOM1.0聚合 - * - * @access protected - * @return string - */ - protected function ___commentsFeedAtomUrl() - { - return Typecho_Router::url('feed', array('feed' => '/atom/comments/'), $this->index); - } - - /** - * xmlrpc api地址 - * - * @access protected - * @return string - */ - protected function ___xmlRpcUrl() - { - return Typecho_Router::url('do', array('action' => 'xmlrpc'), $this->index); - } - - /** - * 获取解析路径前缀 - * - * @access protected - * @return string - */ - protected function ___index() - { - return $this->rewrite ? $this->siteUrl : Typecho_Common::url('index.php', $this->siteUrl); - } - - /** - * 获取模板路径 - * - * @access protected - * @return string - */ - protected function ___themeUrl() - { - return Typecho_Common::url(__TYPECHO_THEME_DIR__ . '/' . $this->theme, $this->siteUrl); - } - - /** - * 获取插件路径 - * - * @access protected - * @return string - */ - protected function ___pluginUrl() - { - return Typecho_Common::url(__TYPECHO_PLUGIN_DIR__, $this->siteUrl); - } - - /** - * 获取后台路径 - * - * @access protected - * @return string - */ - protected function ___adminUrl() - { - return Typecho_Common::url(defined('__TYPECHO_ADMIN_DIR__') ? - __TYPECHO_ADMIN_DIR__ : '/admin/', $this->siteUrl); - } - - /** - * 获取登录地址 - * - * @access protected - * @return string - */ - protected function ___loginUrl() - { - return Typecho_Common::url('login.php', $this->adminUrl); - } - - /** - * 获取登录提交地址 - * - * @access protected - * @return string - */ - protected function ___loginAction() - { - return Typecho_Router::url('do', array('action' => 'login', 'widget' => 'Login'), - Typecho_Common::url('index.php', $this->siteUrl)); - } - - /** - * 获取注册地址 - * - * @access protected - * @return string - */ - protected function ___registerUrl() - { - return Typecho_Common::url('register.php', $this->adminUrl); - } - - /** - * 获取登录提交地址 - * - * @access protected - * @return string - */ - protected function ___registerAction() - { - return Typecho_Router::url('do', array('action' => 'register', 'widget' => 'Register'), $this->index); - } - - /** - * 获取个人档案地址 - * - * @access protected - * @return string - */ - protected function ___profileUrl() - { - return Typecho_Common::url('profile.php', $this->adminUrl); - } - - /** - * 获取登出地址 - * - * @access protected - * @return string - */ - protected function ___logoutUrl() - { - return Typecho_Common::url('/action/logout', $this->index); - } - - /** - * 获取系统时区 - * - * @access protected - * @return integer - */ - protected function ___serverTimezone() - { - return Typecho_Date::$serverTimezoneOffset; - } - - /** - * 获取格林尼治标准时间 - * - * @access protected - * @return integer - */ - protected function ___gmtTime() - { - return Typecho_Date::gmtTime(); - } - - /** - * 获取格式 - * - * @access protected - * @return string - */ - protected function ___contentType() - { - return isset($this->contentType) ? $this->contentType : 'text/html'; - } - - /** - * 软件名称 - * - * @access protected - * @return string - */ - protected function ___software() - { - list($software, $version) = explode(' ', $this->generator); - return $software; - } - - /** - * 软件版本 - * - * @access protected - * @return string - */ - protected function ___version() - { - list($software, $version) = explode(' ', $this->generator); - return $version; - } - - /** - * 允许上传的文件类型 - * - * @access protected - * @return string - */ - protected function ___allowedAttachmentTypes() - { - $attachmentTypesResult = array(); - - if (NULL != $this->attachmentTypes) { - $attachmentTypes = str_replace( - array('@image@', '@media@', '@doc@'), - array('gif,jpg,png,tiff,bmp', 'mp3,wmv,wma,rmvb,rm,avi,flv', - 'txt,doc,docx,xls,xlsx,ppt,pptx,zip,rar,pdf'), $this->attachmentTypes); - - $attachmentTypesResult = array_unique(array_map('trim', explode(',', $attachmentTypes))); - } - - return $attachmentTypesResult; - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->db->fetchAll($this->db->select()->from('table.options') - ->where('user = 0'), array($this, 'push')); - - /** 支持皮肤变量重载 */ - if (!empty($this->row['theme:' . $this->row['theme']])) { - $themeOptions = NULL; - - /** 解析变量 */ - if ($themeOptions = unserialize($this->row['theme:' . $this->row['theme']])) { - /** 覆盖变量 */ - $this->row = array_merge($this->row, $themeOptions); - } - } - - $this->stack[] = &$this->row; - - /** 初始化站点信息 */ - $this->siteUrl = Typecho_Common::url(NULL, $this->siteUrl); - $this->plugins = unserialize($this->plugins); - - /** 增加对SSL连接的支持 */ - if ($this->request->isSecure() && 0 === strpos($this->siteUrl, 'http://')) { - $this->siteUrl = substr_replace($this->siteUrl, 'https', 0, 4); - } - - /** 自动初始化路由表 */ - $this->routingTable = unserialize($this->routingTable); - if (!isset($this->routingTable[0])) { - /** 解析路由并缓存 */ - $parser = new Typecho_Router_Parser($this->routingTable); - $parsedRoutingTable = $parser->parse(); - $this->routingTable = array_merge(array($parsedRoutingTable), $this->routingTable); - $this->db->query($this->db->update('table.options')->rows(array('value' => serialize($this->routingTable))) - ->where('name = ?', 'routingTable')); - } - } - - /** - * 重载父类push函数,将所有变量值压入堆栈 - * - * @access public - * @param array $value 每行的值 - * @return array - */ - public function push(array $value) - { - //将行数据按顺序置位 - $this->row[$value['name']] = $value['value']; - return $value; - } - - /** - * 输出网站路径 - * - * @access public - * @param string $path 子路径 - * @return void - */ - public function siteUrl($path = NULL) - { - echo Typecho_Common::url($path, $this->siteUrl); - } - - /** - * 输出解析地址 - * - * @access public - * @param string $path 子路径 - * @return void - */ - public function index($path = NULL) - { - echo Typecho_Common::url($path, $this->index); - } - - /** - * 输出模板路径 - * - * @access public - * @param string $path 子路径 - * @return void - */ - public function themeUrl($path = NULL) - { - echo Typecho_Common::url($path, $this->themeUrl); - } - - /** - * 输出插件路径 - * - * @access public - * @param string $path 子路径 - * @return void - */ - public function pluginUrl($path = NULL) - { - echo Typecho_Common::url($path, $this->pluginUrl); - } - - /** - * 输出后台路径 - * - * @access public - * @param string $path 子路径 - * @return void - */ - public function adminUrl($path = NULL) - { - echo Typecho_Common::url($path, $this->adminUrl); - } - - /** - * 编码输出允许出现在评论中的html标签 - * - * @access public - * @return void - */ - public function commentsHTMLTagAllowed() - { - echo htmlspecialchars($this->commentsHTMLTagAllowed); - } - - /** - * 获取插件系统参数 - * - * @param mixed $pluginName 插件名称 - * @return void - */ - public function plugin($pluginName) - { - if (!isset($this->_pluginConfig[$pluginName])) { - if (!empty($this->row['plugin:' . $pluginName]) - && false !== ($options = unserialize($this->row['plugin:' . $pluginName]))) { - $this->_pluginConfig[$pluginName] = new Typecho_Config($options); - } else { - throw new Typecho_Plugin_Exception(_t('插件%s的配置信息没有找到', $pluginName), 500); - } - } - - return $this->_pluginConfig[$pluginName]; - } - - /** - * 获取个人插件系统参数 - * - * @param mixed $pluginName 插件名称 - * @return void - */ - public function personalPlugin($pluginName) - { - if (!isset($this->_personalPluginConfig[$pluginName])) { - if (!empty($this->row['_plugin:' . $pluginName]) - && false !== ($options = unserialize($this->row['_plugin:' . $pluginName]))) { - $this->_personalPluginConfig[$pluginName] = new Typecho_Config($options); - } else { - throw new Typecho_Plugin_Exception(_t('插件%s的配置信息没有找到', $pluginName), 500); - } - } - - return $this->_personalPluginConfig[$pluginName]; - } -} diff --git a/php/typecho09/var/Widget/Options/Discussion.php b/php/typecho09/var/Widget/Options/Discussion.php deleted file mode 100644 index 25e48d9cf..000000000 --- a/php/typecho09/var/Widget/Options/Discussion.php +++ /dev/null @@ -1,238 +0,0 @@ -<?php -/** - * 评论设置 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 评论设置组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Options_Discussion extends Widget_Abstract_Options implements Widget_Interface_Do -{ - /** - * 输出表单结构 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function form() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/options-discussion', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 评论日期格式 */ - $commentDateFormat = new Typecho_Widget_Helper_Form_Element_Text('commentDateFormat', NULL, $this->options->commentDateFormat, - _t('评论日期格式'), _t('这是一个默认的格式,当你在模板中调用显示评论日期方法时, 如果没有指定日期格式, 将按照此格式输出.<br /> - 具体写法请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')); - $commentDateFormat->input->setAttribute('class', 'w-40 mono'); - $form->addInput($commentDateFormat); - - /** 评论列表数目 */ - $commentsListSize = new Typecho_Widget_Helper_Form_Element_Text('commentsListSize', NULL, $this->options->commentsListSize, - _t('评论列表数目'), _t('此数目用于指定显示在侧边栏中的评论列表数目.')); - $commentsListSize->input->setAttribute('class', 'w-20'); - $form->addInput($commentsListSize->addRule('isInteger', _t('请填入一个数字'))); - - $commentsShowOptions = array( - 'commentsShowCommentOnly' => _t('仅显示评论, 不显示 Pingback 和 Trackback'), - 'commentsMarkdown' => _t('在评论中使用Markdown语法'), - 'commentsShowUrl' => _t('评论者名称显示时自动加上其个人主页链接'), - 'commentsUrlNofollow' => _t('对评论者个人主页链接使用 <a href="http://en.wikipedia.org/wiki/Nofollow">nofollow 属性</a>'), - 'commentsAvatar' => _t('启用 <a href="http://gravatar.com">Gravatar</a> 头像服务, 最高显示评级为 %s 的头像', - '</label><select id="commentsShow-commentsAvatarRating" name="commentsAvatarRating"> - <option value="G"' . ('G' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>G - 普通</option> - <option value="PG"' . ('PG' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>PG - 13岁以上</option> - <option value="R"' . ('R' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>R - 17岁以上成人</option> - <option value="X"' . ('X' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>X - 限制级</option></select> - <label for="commentsShow-commentsAvatarRating">'), - 'commentsPageBreak' => _t('启用分页, 并且每页显示 %s 篇评论, 在列出时将 %s 作为默认显示', - '</label><input type="text" value="' . $this->options->commentsPageSize - . '" class="text num text-s" id="commentsShow-commentsPageSize" name="commentsPageSize" /><label for="commentsShow-commentsPageSize">', - '</label><select id="commentsShow-commentsPageDisplay" name="commentsPageDisplay"> - <option value="first"' . ('first' == $this->options->commentsPageDisplay ? ' selected="true"' : '') . '>' . _t('第一页') . '</option> - <option value="last"' . ('last' == $this->options->commentsPageDisplay ? ' selected="true"' : '') . '>' . _t('最后一页') . '</option></select>' - . '<label for="commentsShow-commentsPageDisplay">'), - 'commentsThreaded' => _t('启用评论回复, 以 %s 层作为每个评论最多的回复层数', - '</label><input name="commentsMaxNestingLevels" type="text" class="text num text-s" value="' . $this->options->commentsMaxNestingLevels . '" id="commentsShow-commentsMaxNestingLevels" /> - <label for="commentsShow-commentsMaxNestingLevels">') . '</label></span><span class="multiline">' - . _t('将 %s 的评论显示在前面', '<select id="commentsShow-commentsOrder" name="commentsOrder"> - <option value="DESC"' . ('DESC' == $this->options->commentsOrder ? ' selected="true"' : '') . '>' . _t('较新的') . '</option> - <option value="ASC"' . ('ASC' == $this->options->commentsOrder ? ' selected="true"' : '') . '>' . _t('较旧的') . '</option></select><label for="commentsShow-commentsOrder">') - ); - - $commentsShowOptionsValue = array(); - if ($this->options->commentsShowCommentOnly) { - $commentsShowOptionsValue[] = 'commentsShowCommentOnly'; - } - - if ($this->options->commentsMarkdown) { - $commentsShowOptionsValue[] = 'commentsMarkdown'; - } - - if ($this->options->commentsShowUrl) { - $commentsShowOptionsValue[] = 'commentsShowUrl'; - } - - if ($this->options->commentsUrlNofollow) { - $commentsShowOptionsValue[] = 'commentsUrlNofollow'; - } - - if ($this->options->commentsAvatar) { - $commentsShowOptionsValue[] = 'commentsAvatar'; - } - - if ($this->options->commentsPageBreak) { - $commentsShowOptionsValue[] = 'commentsPageBreak'; - } - - if ($this->options->commentsThreaded) { - $commentsShowOptionsValue[] = 'commentsThreaded'; - } - - $commentsShow = new Typecho_Widget_Helper_Form_Element_Checkbox('commentsShow', $commentsShowOptions, - $commentsShowOptionsValue, _t('评论显示')); - $form->addInput($commentsShow->multiMode()); - - /** 评论提交 */ - $commentsPostOptions = array( - 'commentsRequireModeration' => _t('所有评论必须经过审核'), - 'commentsWhitelist' => _t('评论者之前须有评论通过了审核'), - 'commentsRequireMail' => _t('必须填写邮箱'), - 'commentsRequireURL' => _t('必须填写网址'), - 'commentsCheckReferer' => _t('检查评论来源页 URL 是否与文章链接一致'), - 'commentsAutoClose' => _t('在文章发布 %s 天以后自动关闭评论', - '</label><input name="commentsPostTimeout" type="text" class="text num text-s" value="' . intval($this->options->commentsPostTimeout / (24 * 3600)) . '" id="commentsPost-commentsPostTimeout" /> - <label for="commentsPost-commentsPostTimeout">'), - 'commentsPostIntervalEnable' => _t('同一 IP 发布评论的时间间隔限制为 %s 分钟', - '</label><input name="commentsPostInterval" type="text" class="text num text-s" value="' . round($this->options->commentsPostInterval / (60), 1) . '" id="commentsPost-commentsPostInterval" /> - <label for="commentsPost-commentsPostInterval">') - ); - - $commentsPostOptionsValue = array(); - if ($this->options->commentsRequireModeration) { - $commentsPostOptionsValue[] = 'commentsRequireModeration'; - } - - if ($this->options->commentsWhitelist) { - $commentsPostOptionsValue[] = 'commentsWhitelist'; - } - - if ($this->options->commentsRequireMail) { - $commentsPostOptionsValue[] = 'commentsRequireMail'; - } - - if ($this->options->commentsRequireURL) { - $commentsPostOptionsValue[] = 'commentsRequireURL'; - } - - if ($this->options->commentsCheckReferer) { - $commentsPostOptionsValue[] = 'commentsCheckReferer'; - } - - if ($this->options->commentsAutoClose) { - $commentsPostOptionsValue[] = 'commentsAutoClose'; - } - - if ($this->options->commentsPostIntervalEnable) { - $commentsPostOptionsValue[] = 'commentsPostIntervalEnable'; - } - - $commentsPost = new Typecho_Widget_Helper_Form_Element_Checkbox('commentsPost', $commentsPostOptions, - $commentsPostOptionsValue, _t('评论提交')); - $form->addInput($commentsPost->multiMode()); - - /** 允许使用的HTML标签和属性 */ - $commentsHTMLTagAllowed = new Typecho_Widget_Helper_Form_Element_Textarea('commentsHTMLTagAllowed', NULL, - htmlspecialchars($this->options->commentsHTMLTagAllowed), - _t('允许使用的HTML标签和属性'), _t('默认的用户评论不允许填写任何的HTML标签, 你可以在这里填写允许使用的HTML标签.<br /> - 比如: <code><a href=""> <img src=""> <blockquote></code>')); - $commentsHTMLTagAllowed->input->setAttribute('class', 'mono'); - $form->addInput($commentsHTMLTagAllowed); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - return $form; - } - - /** - * 执行更新动作 - * - * @access public - * @return void - */ - public function updateDiscussionSettings() - { - /** 验证格式 */ - if ($this->form()->validate()) { - $this->response->goBack(); - } - - $settings = $this->request->from('commentDateFormat', 'commentsListSize', 'commentsShow', 'commentsPost', 'commentsPageSize', 'commentsPageDisplay', 'commentsAvatar', - 'commentsOrder', 'commentsMaxNestingLevels', 'commentsUrlNofollow', 'commentsPostTimeout', 'commentsUniqueIpInterval', 'commentsWhitelist', 'commentsRequireMail', 'commentsAvatarRating', - 'commentsPostTimeout', 'commentsPostInterval', 'commentsRequireModeration', 'commentsRequireURL', 'commentsHTMLTagAllowed', 'commentsStopWords', 'commentsIpBlackList'); - - $settings['commentsShowCommentOnly'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsShowCommentOnly'); - $settings['commentsMarkdown'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsMarkdown'); - $settings['commentsShowUrl'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsShowUrl'); - $settings['commentsUrlNofollow'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsUrlNofollow'); - $settings['commentsAvatar'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsAvatar'); - $settings['commentsPageBreak'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsPageBreak'); - $settings['commentsThreaded'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsThreaded'); - - $settings['commentsPageSize'] = intval($settings['commentsPageSize']); - $settings['commentsMaxNestingLevels'] = max(2, intval($settings['commentsMaxNestingLevels'])); - $settings['commentsPageDisplay'] = ('first' == $settings['commentsPageDisplay']) ? 'first' : 'last'; - $settings['commentsOrder'] = ('DESC' == $settings['commentsOrder']) ? 'DESC' : 'ASC'; - $settings['commentsAvatarRating'] = in_array($settings['commentsAvatarRating'], array('G', 'PG', 'R', 'X')) - ? $settings['commentsAvatarRating'] : 'G'; - - $settings['commentsRequireModeration'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsRequireModeration'); - $settings['commentsWhitelist'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsWhitelist'); - $settings['commentsRequireMail'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsRequireMail'); - $settings['commentsRequireURL'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsRequireURL'); - $settings['commentsCheckReferer'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsCheckReferer'); - $settings['commentsAutoClose'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsAutoClose'); - $settings['commentsPostIntervalEnable'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsPostIntervalEnable'); - - $settings['commentsPostTimeout'] = intval($settings['commentsPostTimeout']) * 24 * 3600; - $settings['commentsPostInterval'] = round($settings['commentsPostInterval'], 1) * 60; - - unset($settings['commentsShow']); - unset($settings['commentsPost']); - - foreach ($settings as $name => $value) { - $this->update(array('value' => $value), $this->db->sql()->where('name = ?', $name)); - } - - $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); - $this->response->goBack(); - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('administrator'); - $this->on($this->request->isPost())->updateDiscussionSettings(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Options/General.php b/php/typecho09/var/Widget/Options/General.php deleted file mode 100644 index 5a8f38a5f..000000000 --- a/php/typecho09/var/Widget/Options/General.php +++ /dev/null @@ -1,181 +0,0 @@ -<?php -/** - * 基本设置 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 基本设置组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Options_General extends Widget_Abstract_Options implements Widget_Interface_Do -{ - /** - * 输出表单结构 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function form() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/options-general', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 站点名称 */ - $title = new Typecho_Widget_Helper_Form_Element_Text('title', NULL, $this->options->title, _t('站点名称'), _t('站点的名称将显示在网页的标题处.')); - $form->addInput($title); - - /** 站点描述 */ - $description = new Typecho_Widget_Helper_Form_Element_Textarea('description', NULL, $this->options->description, _t('站点描述'), _t('站点描述将显示在网页代码的头部.')); - $form->addInput($description); - - /** 关键词 */ - $keywords = new Typecho_Widget_Helper_Form_Element_Text('keywords', NULL, $this->options->keywords, _t('关键词'), _t('请以半角逗号 "," 分割多个关键字.')); - $form->addInput($keywords); - - /** 注册 */ - $allowRegister = new Typecho_Widget_Helper_Form_Element_Radio('allowRegister', array('0' => _t('不允许'), '1' => _t('允许')), $this->options->allowRegister, _t('是否允许注册'), - _t('允许访问者注册到你的网站, 默认的注册用户不享有任何写入权限.')); - $form->addInput($allowRegister); - - /** 时区 */ - $timezoneList = array( - "0" => _t('格林威治(子午线)标准时间 (GMT)'), - "3600" => _t('中欧标准时间 阿姆斯特丹,荷兰,法国 (GMT +1)'), - "7200" => _t('东欧标准时间 布加勒斯特,塞浦路斯,希腊 (GMT +2)'), - "10800" => _t('莫斯科时间 伊拉克,埃塞俄比亚,马达加斯加 (GMT +3)'), - "14400" => _t('第比利斯时间 阿曼,毛里塔尼亚,留尼汪岛 (GMT +4)'), - "18000" => _t('新德里时间 巴基斯坦,马尔代夫 (GMT +5)'), - "21600" => _t('科伦坡时间 孟加拉 (GMT +6)'), - "25200" => _t('曼谷雅加达 柬埔寨,苏门答腊,老挝 (GMT +7)'), - "28800" => _t('北京时间 香港,新加坡,越南 (GMT +8)'), - "32400" => _t('东京平壤时间 西伊里安,摩鹿加群岛 (GMT +9)'), - "36000" => _t('悉尼关岛时间 塔斯马尼亚岛,新几内亚 (GMT +10)'), - "39600" => _t('所罗门群岛 库页岛 (GMT +11)'), - "43200" => _t('惠灵顿时间 新西兰,斐济群岛 (GMT +12)'), - "-3600" => _t('佛德尔群岛 亚速尔群岛,葡属几内亚 (GMT -1)'), - "-7200" => _t('大西洋中部时间 格陵兰 (GMT -2)'), - "-10800" => _t('布宜诺斯艾利斯 乌拉圭,法属圭亚那 (GMT -3)'), - "-14400" => _t('智利巴西 委内瑞拉,玻利维亚 (GMT -4)'), - "-18000" => _t('纽约渥太华 古巴,哥伦比亚,牙买加 (GMT -5)'), - "-21600" => _t('墨西哥城时间 洪都拉斯,危地马拉,哥斯达黎加 (GMT -6)'), - "-25200" => _t('美国丹佛时间 (GMT -7)'), - "-28800" => _t('美国旧金山时间 (GMT -8)'), - "-32400" => _t('阿拉斯加时间 (GMT -9)'), - "-36000" => _t('夏威夷群岛 (GMT -10)'), - "-39600" => _t('东萨摩亚群岛 (GMT -11)'), - "-43200" => _t('艾尼威托克岛 (GMT -12)') - ); - - $timezone = new Typecho_Widget_Helper_Form_Element_Select('timezone', $timezoneList, $this->options->timezone, _t('时区')); - $form->addInput($timezone); - - /** 扩展名 */ - $attachmentTypesOptionsResult = (NULL != trim($this->options->attachmentTypes)) ? - array_map('trim', explode(',', $this->options->attachmentTypes)) : array(); - $attachmentTypesOptionsValue = array(); - - if (in_array('@image@', $attachmentTypesOptionsResult)) { - $attachmentTypesOptionsValue[] = '@image@'; - } - - if (in_array('@media@', $attachmentTypesOptionsResult)) { - $attachmentTypesOptionsValue[] = '@media@'; - } - - if (in_array('@doc@', $attachmentTypesOptionsResult)) { - $attachmentTypesOptionsValue[] = '@doc@'; - } - - $attachmentTypesOther = array_diff($attachmentTypesOptionsResult, $attachmentTypesOptionsValue); - $attachmentTypesOtherValue = ''; - if (!empty($attachmentTypesOther)) { - $attachmentTypesOptionsValue[] = '@other@'; - $attachmentTypesOtherValue = implode(',', $attachmentTypesOther); - } - - $attachmentTypesOptions = array( - '@image@' => _t('图片文件') . ' <code>(gif jpg png tiff bmp)</code>', - '@media@' => _t('多媒体文件') . ' <code>(mp3 wmv wma rmvb rm avi flv)</code>', - '@doc@' => _t('常用档案文件') . ' <code>(txt doc docx xls xlsx ppt pptx zip rar pdf)</code>', - '@other@' => _t('其他格式 %s', ' <input type="text" class="w-50 text-s mono" name="attachmentTypesOther" value="' . htmlspecialchars($attachmentTypesOtherValue) . '" />'), - ); - - $attachmentTypes = new Typecho_Widget_Helper_Form_Element_Checkbox('attachmentTypes', $attachmentTypesOptions, - $attachmentTypesOptionsValue, _t('允许上传的文件类型'), _t('用逗号 "," 将后缀名隔开, 例如: <code>cpp, h, mak</code>')); - $form->addInput($attachmentTypes->multiMode()); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - return $form; - } - - /** - * 执行更新动作 - * - * @access public - * @return void - */ - public function updateGeneralSettings() - { - /** 验证格式 */ - if ($this->form()->validate()) { - $this->response->goBack(); - } - - $settings = $this->request->from('title', 'description', 'keywords', 'allowRegister', 'timezone', 'attachmentTypes'); - - $attachmentTypes = array(); - if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@image@')) { - $attachmentTypes[] = '@image@'; - } - - if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@media@')) { - $attachmentTypes[] = '@media@'; - } - - if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@doc@')) { - $attachmentTypes[] = '@doc@'; - } - - $attachmentTypesOther = $this->request->filter('trim')->attachmentTypesOther; - if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@other@') && !empty($attachmentTypesOther)) { - $attachmentTypes[] = implode(',', array_map('trim', explode(',', $attachmentTypesOther))); - } - - $settings['attachmentTypes'] = implode(',', $attachmentTypes); - foreach ($settings as $name => $value) { - $this->update(array('value' => $value), $this->db->sql()->where('name = ?', $name)); - } - - $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); - $this->response->goBack(); - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('administrator'); - $this->on($this->request->isPost())->updateGeneralSettings(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Options/Permalink.php b/php/typecho09/var/Widget/Options/Permalink.php deleted file mode 100644 index 0b777c3ef..000000000 --- a/php/typecho09/var/Widget/Options/Permalink.php +++ /dev/null @@ -1,344 +0,0 @@ -<?php -/** - * 基本设置 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 基本设置组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Options_Permalink extends Widget_Abstract_Options implements Widget_Interface_Do -{ - /** - * 编码自定义的路径 - * - * @access private - * @param string $rule 待编码的路径 - * @return string - */ - protected function encodeRule($rule) - { - return str_replace(array('{cid}', '{slug}', '{category}', '{year}', '{month}', '{day}', '{mid}'), - array('[cid:digital]', '[slug]', '[category]', '[year:digital:4]', '[month:digital:2]', '[day:digital:2]', '[mid:digital]'), $rule); - } - - /** - * 解析自定义的路径 - * - * @access private - * @param string $rule 待解码的路径 - * @return string - */ - protected function decodeRule($rule) - { - return preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $rule); - } - - /** - * 检验规则是否冲突 - * - * @access public - * @param string $value 路由规则 - * @return boolean - */ - public function checkRule($value) - { - if ('custom' != $value) { - return true; - } - - $routingTable = $this->options->routingTable; - $currentTable = array('custom' => array('url' => $this->encodeRule($this->request->customPattern))); - $parser = new Typecho_Router_Parser($currentTable); - $currentTable = $parser->parse(); - $regx = $currentTable['custom']['regx']; - - //echo $regx; die; - - foreach ($routingTable as $key => $val) { - if ('post' != $key && 'page' != $key) { - $pathInfo = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $val['url']); - $pathInfo = str_replace(array('{cid}', '{slug}', '{category}', '{year}', '{month}', '{day}', '{', '}'), - array('123', 'hello', 'default', '2008', '08', '08', '', ''), $pathInfo); - - if (preg_match($regx, $pathInfo)) { - return false; - } - } - } - - return true; - } - - /** - * 检查pagePattern里是否含有必要参数 - * - * @param mixed $value - * @access public - * @return void - */ - public function checkPagePattern($value) - { - return strpos($value, '{slug}') !== false || strpos($value, '{cid}') !== false; - } - - /** - * 检查categoryPattern里是否含有必要参数 - * - * @param mixed $value - * @access public - * @return void - */ - public function checkCategoryPattern($value) - { - return strpos($value, '{slug}') !== false || strpos($value, '{mid}') !== false; - } - - /** - * 检测是否可以rewrite - * - * @access public - * @param string $value 是否打开rewrite - * @return void - */ - public function checkRewrite($value) - { - if ($value) { - $this->user->pass('administrator'); - - /** 首先直接请求远程地址验证 */ - $client = Typecho_Http_Client::get(); - $hasWrote = false; - - if (!file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess')) { - if (is_writeable(__TYPECHO_ROOT_DIR__)) { - $parsed = parse_url($this->options->siteUrl); - $basePath = empty($parsed['path']) ? '/' : $parsed['path']; - $basePath = rtrim($basePath, '/') . '/'; - - $hasWrote = file_put_contents(__TYPECHO_ROOT_DIR__ . '/.htaccess', "<IfModule mod_rewrite.c> -RewriteEngine On -RewriteBase {$basePath} -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule ^(.*)$ {$basePath}index.php/$1 [L] -</IfModule>"); - } - } - - try { - if ($client) { - /** 发送一个rewrite地址请求 */ - $client->setData(array('do' => 'remoteCallback')) - ->setHeader('User-Agent', $this->options->generator) - ->send(Typecho_Common::url('/action/ajax', $this->options->siteUrl)); - - if (200 == $client->getResponseStatus() && 'OK' == $client->getResponseBody()) { - return true; - } - } - - if (false !== $hasWrote) { - @unlink(__TYPECHO_ROOT_DIR__ . '/.htaccess'); - - //增强兼容性,使用wordpress的redirect式rewrite规则,虽然效率有点地下,但是对fastcgi模式兼容性较好 - $hasWrote = file_put_contents(__TYPECHO_ROOT_DIR__ . '/.htaccess', "<IfModule mod_rewrite.c> -RewriteEngine On -RewriteBase {$basePath} -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule . {$basePath}index.php [L] -</IfModule>"); - - //再次进行验证 - $client = Typecho_Http_Client::get(); - - if ($client) { - /** 发送一个rewrite地址请求 */ - $client->setData(array('do' => 'remoteCallback')) - ->setHeader('User-Agent', $this->options->generator) - ->send(Typecho_Common::url('/action/ajax', $this->options->siteUrl)); - - if (200 == $client->getResponseStatus() && 'OK' == $client->getResponseBody()) { - return true; - } - } - - unlink(__TYPECHO_ROOT_DIR__ . '/.htaccess'); - } - } catch (Typecho_Http_Client_Exception $e) { - if (false !== $hasWrote) { - @unlink(__TYPECHO_ROOT_DIR__ . '/.htaccess'); - } - return false; - } - - return false; - } else if (file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess')) { - @unlink(__TYPECHO_ROOT_DIR__ . '/.htaccess'); - } - - return true; - } - - /** - * 输出表单结构 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function form() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('index.php/action/options-permalink', $this->options->siteUrl), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 是否使用地址重写功能 */ - $rewrite = new Typecho_Widget_Helper_Form_Element_Radio('rewrite', array('0' => _t('不启用'), '1' => _t('启用')), - $this->options->rewrite, _t('是否使用地址重写功能'), _t('地址重写即 rewrite 功能是某些服务器软件提供的优化内部连接的功能.<br /> - 打开此功能可以让你的链接看上去完全是静态地址.')); - - $errorStr = _t('重写功能检测失败, 请检查你的服务器设置'); - - /** 如果是apache服务器, 可能存在无法写入.htaccess文件的现象 */ - if (((isset($_SERVER['SERVER_SOFTWARE']) && false !== strpos(strtolower($_SERVER['SERVER_SOFTWARE']), 'apache')) - || function_exists('apache_get_version')) && !file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess') - && !is_writeable(__TYPECHO_ROOT_DIR__)) { - $errorStr .= '<br /><strong>' . _t('我们检测到你使用了apache服务器, 但是程序无法在根目录创建.htaccess文件, 这可能是产生这个错误的原因. - 请调整你的目录权限, 或者手动创建一个.htaccess文件.') . '</strong>'; - } - - $errorStr .= _t('<br />如果你仍然想启用此功能, <a href="%s">请点击这里</a>', Typecho_Common::url('index.php/action/options-permalink?do=enableRewriteAnyway', $this->options->siteUrl)); - - $form->addInput($rewrite->addRule(array($this, 'checkRewrite'), $errorStr)); - $patterns = array('/archives/[cid:digital]/' => _t('默认风格') . ' <code>/archives/{cid}/</code>', - '/archives/[slug].html' => _t('wordpress风格') . ' <code>/archives/{slug}.html</code>', - '/[year:digital:4]/[month:digital:2]/[day:digital:2]/[slug].html' => _t('按日期归档') . ' <code>/archives/{year}/{month}/{day}/{slug}.html</code>', - '/[category]/[slug].html' => _t('按分类归档') . ' <code>/{category}/{slug}.html</code>'); - - /** 自定义文章路径 */ - $postPatternValue = $this->options->routingTable['post']['url']; - - /** 增加个性化路径 */ - $customPatternValue = NULL; - if (isset($this->request->__typecho_form_item_postPattern)) { - $customPatternValue = $this->request->__typecho_form_item_postPattern; - Typecho_Cookie::delete('__typecho_form_item_postPattern'); - } else if (!isset($patterns[$postPatternValue])) { - $customPatternValue = $this->decodeRule($postPatternValue); - } - $patterns['custom'] = _t('个性化定义') . ' <input type="text" class="w-50 text-s mono" name="customPattern" value="' . $customPatternValue . '" />'; - - $postPattern = new Typecho_Widget_Helper_Form_Element_Radio('postPattern', $patterns, - $postPatternValue, _t('自定义文章路径'), _t('可用参数: <code>{cid}</code> 日志 ID, <code>{slug}</code> 日志缩略名, <code>{category}</code> 分类, <code>{year}</code> 年, <code>{month}</code> 月, <code>{day}</code> 日<br />选择一种合适的文章静态路径风格, 使得你的网站链接更加友好.<br /> - 一旦你选择了某种链接风格请不要轻易修改它.')); - if ($customPatternValue) { - $postPattern->value('custom'); - } - $form->addInput($postPattern->multiMode()); - - /** 独立页面后缀名 */ - $pagePattern = new Typecho_Widget_Helper_Form_Element_Text('pagePattern', NULL, $this->decodeRule($this->options->routingTable['page']['url']), _t('独立页面路径'), _t('可用参数: <code>{cid}</code> 页面 ID、<code>{slug}</code> 页面缩略名<br />请在路径中至少包含上述的一项参数.')); - $pagePattern->input->setAttribute('class', 'mono w-60'); - $form->addInput($pagePattern->addRule(array($this, 'checkPagePattern'), _t('独立页面路径中没有包含 {cid} 或者 {slug} '))); - - /** 分类页面 */ - $categoryPattern = new Typecho_Widget_Helper_Form_Element_Text('categoryPattern', NULL, $this->decodeRule($this->options->routingTable['category']['url']), _t('分类路径'), _t('可用参数: <code>{mid}</code> 分类 ID、<code>{slug}</code> 分类缩略名<br />请在路径中至少包含上述的一项参数.')); - $categoryPattern->input->setAttribute('class', 'mono w-60'); - $form->addInput($categoryPattern->addRule(array($this, 'checkCategoryPattern'), _t('分类路径中没有包含 {mid} 或者 {slug} '))); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - return $form; - } - - /** - * 执行更新动作 - * - * @access public - * @return void - */ - public function updatePermalinkSettings() - { - /** 验证格式 */ - if ($this->form()->validate()) { - Typecho_Cookie::set('__typecho_form_item_postPattern', $this->request->customPattern); - $this->response->goBack(); - } - - $patternValid = $this->checkRule($this->request->postPattern); - - /** 解析url pattern */ - if ('custom' == $this->request->postPattern) { - $this->request->postPattern = '/' . ltrim($this->encodeRule($this->request->customPattern), '/'); - } - - $settings = $this->request->from('rewrite'); - if (isset($this->request->postPattern) && isset($this->request->pagePattern)) { - $routingTable = $this->options->routingTable; - $routingTable['post']['url'] = $this->request->postPattern; - $routingTable['page']['url'] = '/' . ltrim($this->encodeRule($this->request->pagePattern), '/'); - $routingTable['category']['url'] = '/' . ltrim($this->encodeRule($this->request->categoryPattern), '/'); - $routingTable['category_page']['url'] = rtrim($routingTable['category']['url'], '/') . '/[page:digital]/'; - - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $settings['routingTable'] = serialize($routingTable); - } - - foreach ($settings as $name => $value) { - $this->update(array('value' => $value), $this->db->sql()->where('name = ?', $name)); - } - - if ($patternValid) { - $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); - } else { - $this->widget('Widget_Notice')->set(_t("自定义链接与现有规则存在冲突! 它可能影响解析效率, 建议你重新分配一个规则."), 'notice'); - } - $this->response->goBack(); - } - - /** - * 强行打开rewrite - * - * @access public - * @return void - */ - public function enableRewriteAnyway() - { - $this->update(array('value' => 1), $this->db->sql()->where('name = ?', 'rewrite')); - - $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); - $this->response->goBack(); - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('administrator'); - $this->on($this->request->isGet() && $this->request->is('do=enableRewriteAnyway'))->enableRewriteAnyway(); - $this->on($this->request->isPost())->updatePermalinkSettings(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Options/Reading.php b/php/typecho09/var/Widget/Options/Reading.php deleted file mode 100644 index 9c16a5f44..000000000 --- a/php/typecho09/var/Widget/Options/Reading.php +++ /dev/null @@ -1,215 +0,0 @@ -<?php -/** - * 文章阅读设置 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 文章阅读设置组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Options_Reading extends Widget_Options_Permalink -{ - /** - * 输出表单结构 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function form() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/options-reading', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 文章日期格式 */ - $postDateFormat = new Typecho_Widget_Helper_Form_Element_Text('postDateFormat', NULL, $this->options->postDateFormat, - _t('文章日期格式'), _t('此格式用于指定显示在文章归档中的日期默认显示格式.<br /> - 在某些主题中这个格式可能不会生效, 因为主题作者可以自定义日期格式.<br /> - 请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')); - $postDateFormat->input->setAttribute('class', 'w-40 mono'); - $form->addInput($postDateFormat); - - //首页显示 - $frontPageParts = explode(':', $this->options->frontPage); - $frontPageType = $frontPageParts[0]; - $frontPageValue = count($frontPageParts) > 1 ? $frontPageParts[1] : ''; - - $frontPageOptions = array( - 'recent' => _t('显示最新发布的文章') - ); - - $frontPattern = '</label></span><span class="multiline front-archive%class%">' - . '<input type="checkbox" id="frontArchive" name="frontArchive" value="1"' - . ($this->options->frontArchive && 'recent' != $frontPageType ? ' checked' : '') .' /> -<label for="frontArchive">' . _t('同时将文章列表页路径更改为 %s', - '<input type="text" name="archivePattern" class="w-20 mono" value="' - . htmlspecialchars($this->decodeRule($this->options->routingTable['archive']['url'])) . '" />') - . '</label>'; - - // 页面列表 - $pages = $this->db->fetchAll($this->db->select('cid', 'title') - ->from('table.contents')->where('type = ?', 'page') - ->where('status = ?', 'publish')->where('created < ?', $this->options->gmtTime)); - - if (!empty($pages)) { - $pagesSelect = '<select name="frontPagePage" id="frontPage-frontPagePage">'; - foreach ($pages as $page) { - $selected = ''; - if ('page' == $frontPageType && $page['cid'] == $frontPageValue) { - $selected = ' selected="true"'; - } - - $pagesSelect .= '<option value="' . $page['cid'] . '"' . $selected - . '>' . $page['title'] . '</option>'; - } - $pagesSelect .= '</select>'; - $frontPageOptions['page'] = _t('使用 %s 页面作为首页', '</label>' . $pagesSelect . '<label for="frontPage-frontPagePage">'); - $selectedFrontPageType = 'page'; - } - - // 自定义文件列表 - $files = glob(__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_THEME_DIR__ . '/' . $this->options->theme . '/*.php'); - $filesSelect = ''; - - foreach ($files as $file) { - $info = Typecho_Plugin::parseInfo($file); - $file = basename($file); - - if ('index.php' != $file && 'index' == $info['title']) { - $selected = ''; - if ('file' == $frontPageType && $file == $frontPageValue) { - $selected = ' selected="true"'; - } - - $filesSelect .= '<option value="' . $file . '"' . $selected - . '>' . $file . '</option>'; - } - } - - if (!empty($filesSelect)) { - $frontPageOptions['file'] = _t('直接调用 %s 模板文件', - '</label><select name="frontPageFile" id="frontPage-frontPageFile">' - . $filesSelect . '</select><label for="frontPage-frontPageFile">'); - $selectedFrontPageType = 'file'; - } - - if (isset($frontPageOptions[$frontPageType]) && 'recent' != $frontPageType && isset($selectedFrontPageType)) { - $selectedFrontPageType = $frontPageType; - $frontPattern = str_replace('%class%', '', $frontPattern); - } - - if (isset($selectedFrontPageType)) { - $frontPattern = str_replace('%class%', ' hidden', $frontPattern); - $frontPageOptions[$selectedFrontPageType] .= $frontPattern; - } - - $frontPage = new Typecho_Widget_Helper_Form_Element_Radio('frontPage', $frontPageOptions, - $frontPageType, _t('站点首页')); - $form->addInput($frontPage->multiMode()); - - /** 文章列表数目 */ - $postsListSize = new Typecho_Widget_Helper_Form_Element_Text('postsListSize', NULL, $this->options->postsListSize, - _t('文章列表数目'), _t('此数目用于指定显示在侧边栏中的文章列表数目.')); - $postsListSize->input->setAttribute('class', 'w-20'); - $form->addInput($postsListSize->addRule('isInteger', _t('请填入一个数字'))); - - /** 每页文章数目 */ - $pageSize = new Typecho_Widget_Helper_Form_Element_Text('pageSize', NULL, $this->options->pageSize, - _t('每页文章数目'), _t('此数目用于指定文章归档输出时每页显示的文章数目.')); - $pageSize->input->setAttribute('class', 'w-20'); - $form->addInput($pageSize->addRule('isInteger', _t('请填入一个数字'))); - - /** FEED全文输出 */ - $feedFullText = new Typecho_Widget_Helper_Form_Element_Radio('feedFullText', array('0' => _t('仅输出摘要'), '1' => _t('全文输出')), - $this->options->feedFullText, _t('聚合全文输出'), _t('如果你不希望在聚合中输出文章全文,请使用仅输出摘要选项.<br /> - 摘要的文字取决于你在文章中使用分隔符的位置.')); - $form->addInput($feedFullText); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - return $form; - } - - /** - * 执行更新动作 - * - * @access public - * @return void - */ - public function updateReadingSettings() - { - /** 验证格式 */ - if ($this->form()->validate()) { - $this->response->goBack(); - } - - $settings = $this->request->from('postDateFormat', 'frontPage', 'frontArchive', 'pageSize', 'postsListSize', 'feedFullText'); - - if ('page' == $settings['frontPage'] && isset($this->request->frontPagePage) && - $this->db->fetchRow($this->db->select('cid') - ->from('table.contents')->where('type = ?', 'page') - ->where('status = ?', 'publish')->where('created < ?', $this->options->gmtTime) - ->where('cid = ?', $pageId = intval($this->request->frontPagePage)))) { - - $settings['frontPage'] = 'page:' . $pageId; - - } else if ('file' == $settings['frontPage'] && isset($this->request->frontPageFile) && - file_exists(__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_THEME_DIR__ . '/' . $this->options->theme . '/' . - ($file = trim($this->request->frontPageFile, " ./\\")))) { - - $settings['frontPage'] = 'file:' . $file; - - } else { - $settings['frontPage'] = 'recent'; - } - - if ('recent' != $settings['frontPage']) { - $settings['frontArchive'] = empty($settings['frontArchive']) ? 0 : 1; - if ($settings['frontArchive']) { - $routingTable = $this->options->routingTable; - $routingTable['archive']['url'] = '/' . ltrim($this->encodeRule($this->request->archivePattern), '/'); - $routingTable['archive_page']['url'] = rtrim($routingTable['archive']['url'], '/') . '/page/[page:digital]/'; - - if (isset($routingTable[0])) { - unset($routingTable[0]); - } - - $settings['routingTable'] = serialize($routingTable); - } - } - - foreach ($settings as $name => $value) { - $this->update(array('value' => $value), $this->db->sql()->where('name = ?', $name)); - } - - $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); - $this->response->goBack(); - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('administrator'); - $this->on($this->request->isPost())->updateReadingSettings(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Plugins/Config.php b/php/typecho09/var/Widget/Plugins/Config.php deleted file mode 100644 index 23eb75b19..000000000 --- a/php/typecho09/var/Widget/Plugins/Config.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 插件配置组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Plugins_Config extends Widget_Abstract_Options -{ - /** - * 插件文件路径 - * - * @access private - * @var string - */ - private $_pluginFileName; - - /** - * 插件类 - * - * @access private - * @var string - */ - private $_className; - - /** - * 获取插件信息 - * - * @access public - * @var array - */ - public $info; - - /** - * 绑定动作 - * - * @access public - * @return unknown - */ - public function execute() - { - $this->user->pass('administrator'); - if (!isset($this->request->config)) { - throw new Typecho_Widget_Exception(_t('插件不存在'), 404); - } - - /** 获取插件入口 */ - list($this->_pluginFileName, $this->_className) = Typecho_Plugin::portal($this->request->config, - __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); - $this->info = Typecho_Plugin::parseInfo($this->_pluginFileName); - } - - /** - * 获取菜单标题 - * - * @access public - * @return string - */ - public function getMenuTitle() - { - return _t('设置插件 %s', $this->info['title']); - } - - /** - * 配置插件 - * - * @access public - * @return void - */ - public function config() - { - /** 获取插件名称 */ - $pluginName = $this->request->config; - - /** 获取已启用插件 */ - $plugins = Typecho_Plugin::export(); - $activatedPlugins = $plugins['activated']; - - /** 判断实例化是否成功 */ - if (!$this->info['config'] || !isset($activatedPlugins[$pluginName])) { - throw new Typecho_Widget_Exception(_t('无法配置插件'), 500); - } - - /** 载入插件 */ - require_once $this->_pluginFileName; - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/plugins-edit?config=' . $pluginName, - $this->options->index), Typecho_Widget_Helper_Form::POST_METHOD); - call_user_func(array($this->_className, 'config'), $form); - - $options = $this->options->plugin($pluginName); - - if (!empty($options)) { - foreach ($options as $key => $val) { - $form->getInput($key)->value($val); - } - } - - $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - return $form; - } -} diff --git a/php/typecho09/var/Widget/Plugins/Edit.php b/php/typecho09/var/Widget/Plugins/Edit.php deleted file mode 100644 index 3a3038ada..000000000 --- a/php/typecho09/var/Widget/Plugins/Edit.php +++ /dev/null @@ -1,295 +0,0 @@ -<?php -/** - * 插件管理 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 插件管理组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Plugins_Edit extends Widget_Abstract_Options implements Widget_Interface_Do -{ - /** - * 手动配置插件变量 - * - * @access public - * @static - * @param mixed $pluginName 插件名称 - * @param mixed array $settings 变量键值对 - * @param bool $isPersonal. (default: false) 是否为私人变量 - * @return void - */ - public static function configPlugin($pluginName, array $settings, $isPersonal = false) - { - $db = Typecho_Db::get(); - $pluginName = ($isPersonal ? '_' : '') . 'plugin:' . $pluginName; - - $select = $db->select()->from('table.options') - ->where('name = ?', $pluginName); - - $options = $db->fetchAll($select); - - if (empty($settings)) { - if (!empty($options)) { - $db->query($db->delete('table.options')->where('name = ?', $pluginName)); - } - } else { - if (empty($options)) { - $db->query($db->insert('table.options') - ->rows(array( - 'name' => $pluginName, - 'value' => serialize($settings), - 'user' => 0 - ))); - } else { - foreach ($options as $option) { - $value = unserialize($option['value']); - $value = array_merge($value, $settings); - - $db->query($db->update('table.options') - ->rows(array('value' => serialize($value))) - ->where('name = ?', $pluginName) - ->where('user = ?', $option['user'])); - } - } - } - } - - /** - * 启用插件 - * - * @access public - * @return void - */ - public function activate($pluginName) - { - /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($pluginName, __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); - $info = Typecho_Plugin::parseInfo($pluginFileName); - - /** 检测依赖信息 */ - list ($version, $build) = explode('/', Typecho_Common::VERSION); - if (Typecho_Plugin::checkDependence($build, $info['dependence'])) { - - /** 获取已启用插件 */ - $plugins = Typecho_Plugin::export(); - $activatedPlugins = $plugins['activated']; - - /** 载入插件 */ - require_once $pluginFileName; - - /** 判断实例化是否成功 */ - if (isset($activatedPlugins[$pluginName]) || !class_exists($className) - || !method_exists($className, 'activate')) { - throw new Typecho_Widget_Exception(_t('无法启用插件'), 500); - } - - try { - $result = call_user_func(array($className, 'activate')); - Typecho_Plugin::activate($pluginName); - $this->update(array('value' => serialize(Typecho_Plugin::export())), - $this->db->sql()->where('name = ?', 'plugins')); - } catch (Typecho_Plugin_Exception $e) { - /** 截获异常 */ - $this->widget('Widget_Notice')->set($e->getMessage(), 'error'); - $this->response->goBack(); - } - - $form = new Typecho_Widget_Helper_Form(); - call_user_func(array($className, 'config'), $form); - - $personalForm = new Typecho_Widget_Helper_Form(); - call_user_func(array($className, 'personalConfig'), $personalForm); - - $options = $form->getValues(); - $personalOptions = $personalForm->getValues(); - - if ($options && !$this->configHandle($pluginName, $options, true)) { - self::configPlugin($pluginName, $options); - } - - if ($personalOptions && !$this->personalConfigHandle($className, $personalOptions)) { - self::configPlugin($pluginName, $personalOptions, true); - } - - } else { - - $result = _t('<a href="%s">%s</a> 无法在此版本的typecho下正常工作', $info['link'], $info['title']); - - } - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('plugin-' . $pluginName); - - if (isset($result) && is_string($result)) { - $this->widget('Widget_Notice')->set($result, 'notice'); - } else { - $this->widget('Widget_Notice')->set(_t('插件已经被启用'), 'success'); - } - $this->response->goBack(); - } - - /** - * 禁用插件 - * - * @access public - * @return void - */ - public function deactivate($pluginName) - { - /** 获取已启用插件 */ - $plugins = Typecho_Plugin::export(); - $activatedPlugins = $plugins['activated']; - $pluginFileExist = true; - - try { - /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($pluginName, __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); - } catch (Typecho_Plugin_Exception $e) { - $pluginFileExist = false; - - if (!isset($activatedPlugins[$pluginName])) { - throw $e; - } - } - - /** 判断实例化是否成功 */ - if (!isset($activatedPlugins[$pluginName])) { - throw new Typecho_Widget_Exception(_t('无法禁用插件'), 500); - } - - if ($pluginFileExist) { - - /** 载入插件 */ - require_once $pluginFileName; - - /** 判断实例化是否成功 */ - if (!isset($activatedPlugins[$pluginName]) || !class_exists($className) - || !method_exists($className, 'deactivate')) { - throw new Typecho_Widget_Exception(_t('无法禁用插件'), 500); - } - - try { - $result = call_user_func(array($className, 'deactivate')); - } catch (Typecho_Plugin_Exception $e) { - /** 截获异常 */ - $this->widget('Widget_Notice')->set($e->getMessage(), 'error'); - $this->response->goBack(); - } - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('plugin-' . $pluginName); - } - - Typecho_Plugin::deactivate($pluginName); - $this->update(array('value' => serialize(Typecho_Plugin::export())), - $this->db->sql()->where('name = ?', 'plugins')); - - $this->delete($this->db->sql()->where('name = ?', 'plugin:' . $pluginName)); - $this->delete($this->db->sql()->where('name = ?', '_plugin:' . $pluginName)); - - if (isset($result) && is_string($result)) { - $this->widget('Widget_Notice')->set($result, 'notice'); - } else { - $this->widget('Widget_Notice')->set(_t('插件已经被禁用'), 'success'); - } - $this->response->goBack(); - } - - /** - * 配置插件 - * - * @access public - * @return void - */ - public function config($pluginName) - { - $form = $this->widget('Widget_Plugins_Config')->config(); - - /** 验证表单 */ - if ($form->validate()) { - $this->response->goBack(); - } - - $settings = $form->getAllRequest(); - - if (!$this->configHandle($pluginName, $settings, false)) { - self::configPlugin($pluginName, $settings); - } - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('plugin-' . $pluginName); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t("插件设置已经保存"), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('plugins.php', $this->options->adminUrl)); - } - - /** - * 用自有函数处理配置信息 - * - * @access public - * @param string $pluginName 插件名称 - * @param array $settings 配置值 - * @param boolean $isInit 是否为初始化 - * @return boolean - */ - public function configHandle($pluginName, array $settings, $isInit) - { - /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($pluginName, __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); - - if (method_exists($className, 'configHandle')) { - call_user_func(array($className, 'configHandle'), $settings, $isInit); - return true; - } - - return false; - } - - /** - * 用自有函数处理自定义配置信息 - * - * @access public - * @param string $className 类名 - * @param array $settings 配置值 - * @return boolean - */ - public function personalConfigHandle($className, array $settings) - { - if (method_exists($className, 'personalConfigHandle')) { - call_user_func(array($className, 'personalConfigHandle'), $settings, true); - return true; - } - - return false; - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('administrator'); - $this->on($this->request->is('activate'))->activate($this->request->activate); - $this->on($this->request->is('deactivate'))->deactivate($this->request->deactivate); - $this->on($this->request->is('config'))->config($this->request->config); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Plugins/List.php b/php/typecho09/var/Widget/Plugins/List.php deleted file mode 100644 index 130958531..000000000 --- a/php/typecho09/var/Widget/Plugins/List.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 插件列表组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Plugins_List extends Typecho_Widget -{ - /** - * 已启用插件 - * - * @access public - * @var array - */ - public $activatedPlugins = array(); - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 列出插件目录 */ - $pluginDirs = glob(__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__ . '/*'); - $this->parameter->setDefault(array('activated' => NULL)); - - /** 获取已启用插件 */ - $plugins = Typecho_Plugin::export(); - $this->activatedPlugins = $plugins['activated']; - - if (!empty($pluginDirs)) { - foreach ($pluginDirs as $pluginDir) { - if (is_dir($pluginDir)) { - /** 获取插件名称 */ - $pluginName = basename($pluginDir); - - /** 获取插件主文件 */ - $pluginFileName = $pluginDir . '/Plugin.php'; - } else if (file_exists($pluginDir) && 'index.php' != basename($pluginDir)) { - $pluginFileName = $pluginDir; - $part = explode('.', basename($pluginDir)); - if (2 == count($part) && 'php' == $part[1]) { - $pluginName = $part[0]; - } else { - continue; - } - } else { - continue; - } - - if (file_exists($pluginFileName)) { - $info = Typecho_Plugin::parseInfo($pluginFileName); - $info['name'] = $pluginName; - - list ($version, $build) = explode('/', Typecho_Common::VERSION); - $info['dependence'] = Typecho_Plugin::checkDependence($build, $info['dependence']); - - /** 默认即插即用 */ - $info['activated'] = true; - - if ($info['activate'] || $info['deactivate'] || $info['config'] || $info['personalConfig']) { - $info['activated'] = isset($this->activatedPlugins[$pluginName]); - - if (isset($this->activatedPlugins[$pluginName])) { - unset($this->activatedPlugins[$pluginName]); - } - } - - if (!is_bool($this->parameter->activated) || $info['activated'] == $this->parameter->activated) { - $this->push($info); - } - } - } - } - } -} diff --git a/php/typecho09/var/Widget/Plugins/List/Activated.php b/php/typecho09/var/Widget/Plugins/List/Activated.php deleted file mode 100644 index db7921b54..000000000 --- a/php/typecho09/var/Widget/Plugins/List/Activated.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 启用插件列表组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Plugins_List_Activated extends Widget_Plugins_List -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->activated = true; - parent::execute(); - } -} diff --git a/php/typecho09/var/Widget/Plugins/List/Deactivated.php b/php/typecho09/var/Widget/Plugins/List/Deactivated.php deleted file mode 100644 index 77f174b32..000000000 --- a/php/typecho09/var/Widget/Plugins/List/Deactivated.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 禁用插件列表组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Plugins_List_Deactivated extends Widget_Plugins_List -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->activated = false; - parent::execute(); - } -} diff --git a/php/typecho09/var/Widget/Register.php b/php/typecho09/var/Widget/Register.php deleted file mode 100644 index 0570f898a..000000000 --- a/php/typecho09/var/Widget/Register.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php -/** - * 注册组件 - * - * @author qining - * @category typecho - * @package Widget - */ -class Widget_Register extends Widget_Abstract_Users implements Widget_Interface_Do -{ - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - /** 如果已经登录 */ - if ($this->user->hasLogin() || !$this->options->allowRegister) { - /** 直接返回 */ - $this->response->redirect($this->options->index); - } - - /** 初始化验证类 */ - $validator = new Typecho_Validate(); - $validator->addRule('name', 'required', _t('必须填写用户名称')); - $validator->addRule('name', 'minLength', _t('用户名至少包含2个字符'), 2); - $validator->addRule('name', 'maxLength', _t('用户名最多包含32个字符'), 32); - $validator->addRule('name', 'xssCheck', _t('请不要在用户名中使用特殊字符')); - $validator->addRule('name', array($this, 'nameExists'), _t('用户名已经存在')); - $validator->addRule('mail', 'required', _t('必须填写电子邮箱')); - $validator->addRule('mail', array($this, 'mailExists'), _t('电子邮箱地址已经存在')); - $validator->addRule('mail', 'email', _t('电子邮箱格式错误')); - $validator->addRule('mail', 'maxLength', _t('电子邮箱最多包含200个字符'), 200); - - /** 如果请求中有password */ - if (array_key_exists('password', $_REQUEST)) { - $validator->addRule('password', 'required', _t('必须填写密码')); - $validator->addRule('password', 'minLength', _t('为了保证账户安全, 请输入至少六位的密码'), 6); - $validator->addRule('password', 'maxLength', _t('为了便于记忆, 密码长度请不要超过十八位'), 18); - $validator->addRule('confirm', 'confirm', _t('两次输入的密码不一致'), 'password'); - } - - /** 截获验证异常 */ - if ($error = $validator->run($this->request->from('name', 'password', 'mail', 'confirm'))) { - Typecho_Cookie::set('__typecho_remember_name', $this->request->name); - Typecho_Cookie::set('__typecho_remember_mail', $this->request->mail); - - /** 设置提示信息 */ - $this->widget('Widget_Notice')->set($error); - $this->response->goBack(); - } - - $generatedPassword = Typecho_Common::randString(7); - - $dataStruct = array( - 'name' => $this->request->name, - 'mail' => $this->request->mail, - 'screenName'=> $this->request->name, - 'password' => Typecho_Common::hash($generatedPassword), - 'created' => $this->options->gmtTime, - 'group' => 'subscriber' - ); - - $dataStruct = $this->pluginHandle()->register($dataStruct); - - $insertId = $this->insert($dataStruct); - $this->db->fetchRow($this->select()->where('uid = ?', $insertId) - ->limit(1), array($this, 'push')); - - $this->pluginHandle()->finishRegister($this); - - $this->user->login($this->request->name, $generatedPassword); - - Typecho_Cookie::delete('__typecho_first_run'); - Typecho_Cookie::delete('__typecho_remember_name'); - Typecho_Cookie::delete('__typecho_remember_mail'); - - $this->widget('Widget_Notice')->set(_t('用户 <strong>%s</strong> 已经成功注册, 密码为 <strong>%s</strong>', $this->screenName, $generatedPassword), 'success'); - $this->response->goBack(); - } -} diff --git a/php/typecho09/var/Widget/Service.php b/php/typecho09/var/Widget/Service.php deleted file mode 100644 index ab801aa37..000000000 --- a/php/typecho09/var/Widget/Service.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php -/** - * 通用异步服务 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 通用异步服务组件 - * - * @author qining - * @category typecho - * @package Widget - */ -class Widget_Service extends Widget_Abstract_Options implements Widget_Interface_Do -{ - /** - * 发送pingback实现 - * - * @access public - * @return void - */ - public function sendPingHandle() - { - /** 验证权限 */ - $this->user->pass('contributor'); - - /** 忽略超时 */ - ignore_user_abort(true); - - /** 获取post */ - $post = $this->widget('Widget_Archive', "type=post", "cid={$this->request->cid}"); - - if ($post->have() && preg_match_all("|<a[^>]*href=[\"'](.*?)[\"'][^>]*>(.*?)</a>|", $post->text, $matches)) { - $links = array_unique($matches[1]); - $permalinkPart = parse_url($post->permalink); - - /** 发送pingback */ - foreach ($links as $url) { - $urlPart = parse_url($url); - - if (isset($urlPart['scheme'])) { - if ('http' != $urlPart['scheme'] || 'https' != $urlPart['scheme']) { - continue; - } - } else { - $urlPart['scheme'] = 'http'; - $url = Typecho_Common::buildUrl($urlPart); - } - - if ($permalinkPart['host'] == $urlPart['host'] && $permalinkPart['path'] == $urlPart['path']) { - continue; - } - - $spider = Typecho_Http_Client::get(); - - if ($spider) { - $spider->setTimeout(10) - ->send($url); - - if (!($xmlrpcUrl = $spider->getResponseHeader('x-pingback'))) { - if (preg_match("/<link[^>]*rel=[\"']pingback[\"'][^>]*href=[\"']([^\"']+)[\"'][^>]*>/i", - $spider->getResponseBody(), $out)) { - $xmlrpcUrl = $out[1]; - } - } - - if (!empty($xmlrpcUrl)) { - try { - $xmlrpc = new IXR_Client($xmlrpcUrl); - $xmlrpc->pingback->ping($post->permalink, $url); - unset($xmlrpc); - } catch (Exception $e) { - continue; - } - } - } - - unset($spider); - } - } - - /** 发送trackback */ - if ($post->have() && !empty($this->request->trackback)) { - $links = $this->request->trackback; - foreach ($links as $url) { - - $client = Typecho_Http_Client::get(); - - if ($client) { - try { - $client->setTimeout(5) - ->setData(array( - 'blog_name' => $this->options->title . ' » ' . $post->title, - 'url' => $post->permalink, - 'excerpt' => $post->excerpt - )) - ->send($url); - - unset($client); - } catch (Typecho_Http_Client_Exception $e) { - continue; - } - } - - } - } - } - - /** - * 发送pingback - * <code> - * $this->sendPingbacks(365); - * </code> - * - * @access public - * @param integer $cid 内容id - * @param array $trackback trackback的url - * @return void - */ - public function sendPing($cid, array $trackback = NULL) - { - $this->user->pass('contributor'); - - if ($client = Typecho_Http_Client::get()) { - try { - - $input = array('do' => 'ping', 'cid' => $cid); - if (!empty($trackback)) { - $input['trackback'] = $trackback; - } - - $client->setCookie('__typecho_uid', Typecho_Cookie::get('__typecho_uid'), 0, $this->options->siteUrl) - ->setCookie('__typecho_authCode', Typecho_Cookie::get('__typecho_authCode'), 0, $this->options->siteUrl) - ->setHeader('User-Agent', $this->options->generator) - ->setTimeout(3) - ->setData($input) - ->setIp('127.0.0.1') - ->send(Typecho_Common::url('/action/service', $this->options->index)); - - } catch (Typecho_Http_Client_Exception $e) { - return; - } - } - } - - /** - * 异步请求入口 - * - * @access public - * @return void - */ - public function action() - { - $this->on($this->request->is('do=ping'))->sendPingHandle(); - } -} diff --git a/php/typecho09/var/Widget/Stat.php b/php/typecho09/var/Widget/Stat.php deleted file mode 100644 index b4af58bab..000000000 --- a/php/typecho09/var/Widget/Stat.php +++ /dev/null @@ -1,366 +0,0 @@ -<?php -/** - * 全局统计 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 全局统计组件 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Stat extends Typecho_Widget -{ - /** - * 用户对象 - * - * @access protected - * @var Widget_User - */ - protected $user; - - /** - * 数据库对象 - * - * @access protected - * @var Typecho_Db - */ - protected $db; - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - - /** 初始化数据库 */ - $this->db = Typecho_Db::get(); - - /** 初始化常用组件 */ - $this->user = $this->widget('Widget_User'); - } - - /** - * 获取已发布的文章数目 - * - * @access protected - * @return integer - */ - protected function ___publishedPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'publish'))->num; - } - - /** - * 获取待审核的文章数目 - * - * @access protected - * @return integer - */ - protected function ___waitingPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'waiting'))->num; - } - - /** - * 获取草稿文章数目 - * - * @access protected - * @return integer - */ - protected function ___draftPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'draft'))->num; - } - - /** - * 获取当前用户已发布的文章数目 - * - * @access protected - * @return integer - */ - protected function ___myPublishedPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.authorId = ?', $this->user->uid))->num; - } - - /** - * 获取当前用户待审核文章数目 - * - * @access protected - * @return integer - */ - protected function ___myWaitingPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'waiting') - ->where('table.contents.authorId = ?', $this->user->uid))->num; - } - - /** - * 获取当前用户草稿文章数目 - * - * @access protected - * @return integer - */ - protected function ___myDraftPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'draft') - ->where('table.contents.authorId = ?', $this->user->uid))->num; - } - - /** - * 获取当前用户已发布的文章数目 - * - * @access protected - * @return integer - */ - protected function ___currentPublishedPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.authorId = ?', $this->request->filter('int')->uid))->num; - } - - /** - * 获取当前用户待审核文章数目 - * - * @access protected - * @return integer - */ - protected function ___currentWaitingPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'waiting') - ->where('table.contents.authorId = ?', $this->request->filter('int')->uid))->num; - } - - /** - * 获取当前用户草稿文章数目 - * - * @access protected - * @return integer - */ - protected function ___currentDraftPostsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'draft') - ->where('table.contents.authorId = ?', $this->request->filter('int')->uid))->num; - } - - /** - * 获取已发布页面数目 - * - * @access protected - * @return integer - */ - protected function ___publishedPagesNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'page') - ->where('table.contents.status = ?', 'publish'))->num; - } - - /** - * 获取草稿页面数目 - * - * @access protected - * @return integer - */ - protected function ___draftPagesNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'page') - ->where('table.contents.status = ?', 'draft'))->num; - } - - /** - * 获取当前显示的评论数目 - * - * @access protected - * @return integer - */ - protected function ___publishedCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'approved'))->num; - } - - /** - * 获取当前待审核的评论数目 - * - * @access protected - * @return integer - */ - protected function ___waitingCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'waiting'))->num; - } - - /** - * 获取当前垃圾评论数目 - * - * @access protected - * @return integer - */ - protected function ___spamCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'spam'))->num; - } - - /** - * 获取当前用户显示的评论数目 - * - * @access protected - * @return integer - */ - protected function ___myPublishedCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'approved') - ->where('table.comments.ownerId = ?', $this->user->uid))->num; - } - - /** - * 获取当前用户显示的评论数目 - * - * @access protected - * @return integer - */ - protected function ___myWaitingCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'waiting') - ->where('table.comments.ownerId = ?', $this->user->uid))->num; - } - - /** - * 获取当前用户显示的评论数目 - * - * @access protected - * @return integer - */ - protected function ___mySpamCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'spam') - ->where('table.comments.ownerId = ?', $this->user->uid))->num; - } - - /** - * 获取当前文章的评论数目 - * - * @access protected - * @return integer - */ - protected function ___currentCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; - } - - /** - * 获取当前文章显示的评论数目 - * - * @access protected - * @return integer - */ - protected function ___currentPublishedCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'approved') - ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; - } - - /** - * 获取当前文章显示的评论数目 - * - * @access protected - * @return integer - */ - protected function ___currentWaitingCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'waiting') - ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; - } - - /** - * 获取当前文章显示的评论数目 - * - * @access protected - * @return integer - */ - protected function ___currentSpamCommentsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments') - ->where('table.comments.status = ?', 'spam') - ->where('table.comments.cid = ?', $this->request->filter('int')->cid))->num; - } - - /** - * 获取分类数目 - * - * @access protected - * @return integer - */ - protected function ___categoriesNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(mid)' => 'num')) - ->from('table.metas') - ->where('table.metas.type = ?', 'category'))->num; - } -} diff --git a/php/typecho09/var/Widget/Themes/Config.php b/php/typecho09/var/Widget/Themes/Config.php deleted file mode 100644 index a2ae9c75a..000000000 --- a/php/typecho09/var/Widget/Themes/Config.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 皮肤配置组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Themes_Config extends Widget_Abstract_Options -{ - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function execute() - { - $this->user->pass('administrator'); - - if (!self::isExists()) { - throw new Typecho_Widget_Exception(_t('外观配置功能不存在'), 404); - } - } - - /** - * 获取菜单标题 - * - * @access public - * @return string - */ - public function getMenuTitle() - { - return _t('设置外观 %s', $this->options->theme); - } - - /** - * 配置功能是否存在 - * - * @access public - * @return boolean - */ - public static function isExists() - { - $configFile = __TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . Typecho_Widget::widget('Widget_Options')->theme . '/functions.php'; - - if (file_exists($configFile)) { - require_once $configFile; - - if (function_exists('themeConfig')) { - return true; - } - } - - return false; - } - - /** - * 配置外观 - * - * @access public - * @return void - */ - public function config() - { - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/themes-edit?config', - $this->options->index), Typecho_Widget_Helper_Form::POST_METHOD); - themeConfig($form); - $inputs = $form->getInputs(); - - if (!empty($inputs)) { - foreach ($inputs as $key => $val) { - $form->getInput($key)->value($this->options->{$key}); - } - } - - $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - return $form; - } -} diff --git a/php/typecho09/var/Widget/Themes/Edit.php b/php/typecho09/var/Widget/Themes/Edit.php deleted file mode 100644 index e4495c154..000000000 --- a/php/typecho09/var/Widget/Themes/Edit.php +++ /dev/null @@ -1,174 +0,0 @@ -<?php -/** - * 编辑风格 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 编辑风格组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Themes_Edit extends Widget_Abstract_Options implements Widget_Interface_Do -{ - /** - * 更换外观 - * - * @access public - * @param string $theme 外观名称 - * @return void - */ - public function changeTheme($theme) - { - $theme = trim($theme, './'); - if (is_dir(__TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . $theme)) { - /** 删除原外观设置信息 */ - $this->delete($this->db->sql()->where('name = ?', 'theme:' . $this->options->theme)); - - $this->update(array('value' => $theme), $this->db->sql()->where('name = ?', 'theme')); - - /** 解除首页关联 */ - if (0 === strpos($this->options->frontPage, 'file:')) { - $this->update(array('value' => 'recent'), $this->db->sql()->where('name = ?', 'frontPage')); - } - - $configFile = __TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . $theme . '/functions.php'; - - if (file_exists($configFile)) { - require_once $configFile; - - if (function_exists('themeConfig')) { - $form = new Typecho_Widget_Helper_Form(); - themeConfig($form); - $options = $form->getValues(); - - if ($options && !$this->configHandle($options, true)) { - $this->insert(array( - 'name' => 'theme:' . $theme, - 'value' => serialize($options), - 'user' => 0 - )); - } - } - } - - $this->widget('Widget_Notice')->highlight('theme-' . $theme); - $this->widget('Widget_Notice')->set(_t("外观已经改变"), 'success'); - $this->response->goBack(); - } else { - throw new Typecho_Widget_Exception(_t('您选择的风格不存在')); - } - } - - /** - * 编辑外观文件 - * - * @access public - * @param string $theme 外观名称 - * @param string $file 文件名 - * @return void - */ - public function editThemeFile($theme, $file) - { - $path = __TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . trim($theme, './') . '/' . trim($file, './'); - - if (file_exists($path) && is_writeable($path)) { - $handle = fopen($path, 'wb'); - if ($handle && fwrite($handle, $this->request->content)) { - fclose($handle); - $this->widget('Widget_Notice')->set(_t("文件 %s 的更改已经保存", $file), 'success'); - } else { - $this->widget('Widget_Notice')->set(_t("文件 %s 无法被写入", $file), 'error'); - } - $this->response->goBack(); - } else { - throw new Typecho_Widget_Exception(_t('您编辑的文件不存在')); - } - } - - /** - * 配置外观 - * - * @access public - * @param string $theme 外观名 - * @return void - */ - public function config($theme) - { - // 已经载入了外观函数 - $form = $this->widget('Widget_Themes_Config')->config(); - - /** 验证表单 */ - if ($form->validate()) { - $this->response->goBack(); - } - - $settings = $form->getAllRequest(); - - if (!$this->configHandle($settings, false)) { - if ($this->options->__get('theme:' . $theme)) { - $this->update(array('value' => serialize($settings)), - $this->db->sql()->where('name = ?', 'theme:' . $theme)); - } else { - $this->insert(array( - 'name' => 'theme:' . $theme, - 'value' => serialize($settings), - 'user' => 0 - )); - } - } - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('theme-' . $theme); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t("外观设置已经保存"), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('options-theme.php', $this->options->adminUrl)); - } - - /** - * 用自有函数处理配置信息 - * - * @access public - * @param string $pluginName 插件名称 - * @param array $settings 配置值 - * @param boolean $isInit 是否为初始化 - * @return boolean - */ - public function configHandle(array $settings, $isInit) - { - if (function_exists('themeConfigHandle')) { - themeConfigHandle($settings, $isInit); - return true; - } - - return false; - } - - /** - * 绑定动作 - * - * @access public - * @return void - */ - public function action() - { - /** 需要管理员权限 */ - $this->user->pass('administrator'); - $this->on($this->request->is('change'))->changeTheme($this->request->change); - $this->on($this->request->is('edit&theme'))->editThemeFile($this->request->theme, $this->request->edit); - $this->on($this->request->is('config'))->config($this->options->theme); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Themes/Files.php b/php/typecho09/var/Widget/Themes/Files.php deleted file mode 100644 index 892a5bd3b..000000000 --- a/php/typecho09/var/Widget/Themes/Files.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php -/** - * 风格文件列表 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 风格文件列表组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Themes_Files extends Typecho_Widget -{ - /** - * 当前风格 - * - * @access private - * @var string - */ - private $_currentTheme; - - /** - * 当前文件 - * - * @access private - * @var string - */ - private $_currentFile; - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 管理员权限 */ - $this->widget('Widget_User')->pass('administrator'); - $this->_currentTheme = $this->request->get('theme', $this->widget('Widget_Options')->theme); - - if (preg_match("/^([_0-9a-z-\.\ ])+$/i", $this->_currentTheme) - && is_dir($dir = __TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . $this->_currentTheme)) { - $files = glob($dir . '/*.{php,PHP,js,JS,css,CSS,vbs,VBS}', GLOB_BRACE); - $this->_currentFile = $this->request->get('file', 'index.php'); - - if (preg_match("/^([_0-9a-z-\.\ ])+$/i", $this->_currentFile) - && file_exists($dir . '/' . $this->_currentFile)) { - foreach ($files as $file) { - if (file_exists($file)) { - $file = basename($file); - $this->push(array( - 'file' => $file, - 'theme' => $this->_currentTheme, - 'current' => ($file == $this->_currentFile) - )); - } - } - - return; - } - } - - throw new Typecho_Widget_Exception('风格文件不存在', 404); - } - - /** - * 获取菜单标题 - * - * @access public - * @return string - */ - public function getMenuTitle() - { - return _t('编辑文件 %s', $this->_currentFile); - } - - /** - * 获取文件内容 - * - * @access public - * @return string - */ - public function currentContent() - { - return htmlspecialchars(file_get_contents(__TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . - $this->_currentTheme . '/' . $this->_currentFile)); - } - - /** - * 获取文件是否可读 - * - * @access public - * @return string - */ - public function currentIsWriteable() - { - return is_writeable(__TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/' . - $this->_currentTheme . '/' . $this->_currentFile); - } - - /** - * 获取当前文件 - * - * @access public - * @return string - */ - public function currentFile() - { - return $this->_currentFile; - } - - /** - * 获取当前风格 - * - * @access public - * @return string - */ - public function currentTheme() - { - return $this->_currentTheme; - } -} diff --git a/php/typecho09/var/Widget/Themes/List.php b/php/typecho09/var/Widget/Themes/List.php deleted file mode 100644 index 9720c5940..000000000 --- a/php/typecho09/var/Widget/Themes/List.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * 风格列表 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 风格列表组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Themes_List extends Typecho_Widget -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $themes = glob(__TYPECHO_ROOT_DIR__ . __TYPECHO_THEME_DIR__ . '/*'); - - if ($themes) { - $options = $this->widget('Widget_Options'); - $siteUrl = $options->siteUrl; - $adminUrl = $options->adminUrl; - $activated = 0; - $result = array(); - - foreach ($themes as $key => $theme) { - $themeFile = $theme . '/index.php'; - if (file_exists($themeFile)) { - $info = Typecho_Plugin::parseInfo($themeFile); - $info['name'] = basename($theme); - - if ($info['activated'] = ($options->theme == $info['name'])) { - $activated = $key; - } - - $screen = glob($theme . '/screen*.{jpg,png,gif,bmp,jpeg,JPG,PNG,GIF,BMG,JPEG}', GLOB_BRACE); - if ($screen) { - $info['screen'] = Typecho_Common::url(trim(__TYPECHO_THEME_DIR__, '/') . - '/' . $info['name'] . '/' . basename(current($screen)), $siteUrl); - } else { - $info['screen'] = Typecho_Common::url('/img/noscreen.png', $adminUrl); - } - - $result[$key] = $info; - } - } - - $clone = $result[$activated]; - unset($result[$activated]); - array_unshift($result, $clone); - array_filter($result, array($this, 'push')); - } - } -} diff --git a/php/typecho09/var/Widget/Upgrade.php b/php/typecho09/var/Widget/Upgrade.php deleted file mode 100644 index 5feae4a06..000000000 --- a/php/typecho09/var/Widget/Upgrade.php +++ /dev/null @@ -1,126 +0,0 @@ -<?php -/** - * 升级动作 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 升级组件 - * - * @author qining - * @category typecho - * @package Widget - */ -class Widget_Upgrade extends Widget_Abstract_Options implements Widget_Interface_Do -{ - /** - * 当前内部版本号 - * - * @access private - * @var string - */ - private $_currentVersion; - - /** - * 对升级包按版本进行排序 - * - * @access public - * @param string $a a版本 - * @param string $b b版本 - * @return integer - */ - public function sortPackage($a, $b) - { - list ($ver, $rev) = explode('r', $a); - $a = str_replace('_', '.', $rev); - - list ($ver, $rev) = explode('r', $b); - $b = str_replace('_', '.', $rev); - - return version_compare($a, $b, '>') ? 1 : -1; - } - - /** - * 过滤低版本的升级包 - * - * @access public - * @param string $version 版本号 - * @return boolean - */ - public function filterPackage($version) - { - list ($ver, $rev) = explode('r', $version); - $rev = str_replace('_', '.', $rev); - return version_compare($rev, $this->_currentVersion, '>'); - } - - /** - * 执行升级程序 - * - * @access public - * @return void - */ - public function upgrade() - { - list($prefix, $this->_currentVersion) = explode('/', $this->options->generator); - $packages = get_class_methods('Upgrade'); - $packages = array_filter($packages, array($this, 'filterPackage')); - usort($packages, array($this, 'sortPackage')); - - $message = array(); - - foreach ($packages as $package) { - $options = $this->widget('Widget_Options@' . $package); - - /** 执行升级脚本 */ - try { - $result = call_user_func(array('Upgrade', $package), $this->db, $options); - if (!empty($result)) { - $message[] = $result; - } - } catch (Typecho_Exception $e) { - $this->widget('Widget_Notice')->set($e->getMessage(), 'error'); - $this->response->goBack(); - return; - } - - list ($ver, $rev) = explode('r', $package); - $ver = substr(str_replace('_', '.', $ver), 1); - $rev = str_replace('_', '.', $rev); - - /** 更新版本号 */ - $this->update(array('value' => 'Typecho ' . $ver . '/' . $rev), - $this->db->sql()->where('name = ?', 'generator')); - - $this->destory('Widget_Options@' . $package); - } - - /** 更新版本号 */ - $this->update(array('value' => 'Typecho ' . Typecho_Common::VERSION), - $this->db->sql()->where('name = ?', 'generator')); - - /** 删除更新cookie */ - Typecho_Cookie::delete('__typecho_check_version'); - - $this->widget('Widget_Notice')->set(empty($message) ? _t("升级已经完成") : $message, - empty($message) ? 'success' : 'notice'); - } - - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('administrator'); - $this->on($this->request->isPost())->upgrade(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Upload.php b/php/typecho09/var/Widget/Upload.php deleted file mode 100644 index 629dfa8ae..000000000 --- a/php/typecho09/var/Widget/Upload.php +++ /dev/null @@ -1,438 +0,0 @@ -<?php -/** - * 上传动作 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 上传组件 - * - * @author qining - * @category typecho - * @package Widget - */ -class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface_Do -{ - //上传文件目录 - const UPLOAD_PATH = '/usr/uploads'; - - /** - * 创建上传路径 - * - * @access private - * @param string $path 路径 - * @return boolean - */ - private static function makeUploadDir($path) - { - if (!@mkdir($path, 0777, true)) { - return false; - } - - $stat = @stat($path); - $perms = $stat['mode'] & 0007777; - @chmod($path, $perms); - - return true; - } - - /** - * 上传文件处理函数,如果需要实现自己的文件哈希或者特殊的文件系统,请在options表里把uploadHandle改成自己的函数 - * - * @access public - * @param array $file 上传的文件 - * @return mixed - */ - public static function uploadHandle($file) - { - if (empty($file['name'])) { - return false; - } - - $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasUploaded)->uploadHandle($file); - if ($hasUploaded) { - return $result; - } - - $fileName = preg_split("(\/|\\|:)", $file['name']); - $file['name'] = array_pop($fileName); - - //获取扩展名 - $ext = ''; - $part = explode('.', $file['name']); - if (($length = count($part)) > 1) { - $ext = strtolower($part[$length - 1]); - } - - if (!self::checkFileType($ext)) { - return false; - } - - $options = Typecho_Widget::widget('Widget_Options'); - $date = new Typecho_Date($options->gmtTime); - $path = Typecho_Common::url(self::UPLOAD_PATH, __TYPECHO_ROOT_DIR__) - . '/' . $date->year . '/' . $date->month; - - //创建上传目录 - if (!is_dir($path)) { - if (!self::makeUploadDir($path)) { - return false; - } - } - - //获取文件名 - $fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext; - $path = $path . '/' . $fileName; - - if (isset($file['tmp_name'])) { - - //移动上传文件 - if (!@move_uploaded_file($file['tmp_name'], $path)) { - return false; - } - } else if (isset($file['bytes'])) { - - //直接写入文件 - if (!file_put_contents($path, $file['bytes'])) { - return false; - } - } else { - return false; - } - - if (!isset($file['size'])) { - $file['size'] = filesize($path); - } - - //返回相对存储路径 - return array( - 'name' => $file['name'], - 'path' => self::UPLOAD_PATH . '/' . $date->year . '/' . $date->month . '/' . $fileName, - 'size' => $file['size'], - 'type' => $ext, - 'mime' => Typecho_Common::mimeContentType($path) - ); - } - - /** - * 修改文件处理函数,如果需要实现自己的文件哈希或者特殊的文件系统,请在options表里把modifyHandle改成自己的函数 - * - * @access public - * @param array $content 老文件 - * @param array $file 新上传的文件 - * @return mixed - */ - public static function modifyHandle($content, $file) - { - if (empty($file['name'])) { - return false; - } - - $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasModified)->modifyHandle($content, $file); - if ($hasModified) { - return $result; - } - - $fileName = preg_split("(\/|\\|:)", $file['name']); - $file['name'] = array_pop($fileName); - - //获取扩展名 - $ext = ''; - $part = explode('.', $file['name']); - if (($length = count($part)) > 1) { - $ext = strtolower($part[$length - 1]); - } - - if ($content['attachment']->type != $ext) { - return false; - } - - $path = Typecho_Common::url($content['attachment']->path, __TYPECHO_ROOT_DIR__); - $dir = dirname($path); - - //创建上传目录 - if (!is_dir($dir)) { - if (!self::makeUploadDir($dir)) { - return false; - } - } - - if (isset($file['tmp_name'])) { - - @unlink($path); - - //移动上传文件 - if (!@move_uploaded_file($file['tmp_name'], $path)) { - return false; - } - } else if (isset($file['bytes'])) { - - @unlink($path); - - //直接写入文件 - if (!file_put_contents($path, $file['bytes'])) { - return false; - } - } else { - return false; - } - - if (!isset($file['size'])) { - $file['size'] = filesize($path); - } - - //返回相对存储路径 - return array( - 'name' => $content['attachment']->name, - 'path' => $content['attachment']->path, - 'size' => $file['size'], - 'type' => $content['attachment']->type, - 'mime' => $content['attachment']->mime - ); - } - - /** - * 删除文件 - * - * @access public - * @param array $content 文件相关信息 - * @return string - */ - public static function deleteHandle(array $content) - { - $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasDeleted)->deleteHandle($content); - if ($hasDeleted) { - return $result; - } - - return @unlink(__TYPECHO_ROOT_DIR__ . '/' . $content['attachment']->path); - } - - /** - * 获取实际文件绝对访问路径 - * - * @access public - * @param array $content 文件相关信息 - * @return string - */ - public static function attachmentHandle(array $content) - { - $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasPlugged)->attachmentHandle($content); - if ($hasPlugged) { - return $result; - } - - $options = Typecho_Widget::widget('Widget_Options'); - return Typecho_Common::url($content['attachment']->path, $options->siteUrl); - } - - /** - * 获取实际文件数据 - * - * @access public - * @param array $content - * @return string - */ - public static function attachmentDataHandle(array $content) - { - $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasPlugged)->attachmentDataHandle($content); - if ($hasPlugged) { - return $result; - } - - return file_get_contents(Typecho_Common::url($content['attachment']->path, __TYPECHO_ROOT_DIR__)); - } - - /** - * 检查文件名 - * - * @access private - * @param string $ext 扩展名 - * @return boolean - */ - public static function checkFileType($ext) - { - $options = Typecho_Widget::widget('Widget_Options'); - return in_array($ext, $options->allowedAttachmentTypes); - } - - /** - * 执行升级程序 - * - * @access public - * @return void - */ - public function upload() - { - if (!empty($_FILES)) { - $file = array_pop($_FILES); - if (0 == $file['error'] && is_uploaded_file($file['tmp_name'])) { - $result = self::uploadHandle($file); - - if (false !== $result) { - $this->pluginHandle()->beforeUpload($result); - - $struct = array( - 'title' => $result['name'], - 'slug' => $result['name'], - 'type' => 'attachment', - 'status' => 'publish', - 'text' => serialize($result), - 'allowComment' => 1, - 'allowPing' => 0, - 'allowFeed' => 1 - ); - - if (isset($this->request->cid)) { - $cid = $this->request->filter('int')->cid; - - if ($this->isWriteable($this->db->sql()->where('cid = ?', $cid))) { - $struct['parent'] = $cid; - } - } - - $insertId = $this->insert($struct); - - $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $insertId) - ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); - - /** 增加插件接口 */ - $this->pluginHandle()->upload($this); - - if ($this->request->isAjax()) { - $this->response->throwJson(array($this->attachment->url, array( - 'cid' => $insertId, - 'title' => $this->attachment->name, - 'type' => $this->attachment->type, - 'size' => $this->attachment->size, - 'bytes' => number_format(ceil($this->attachment->size / 1024)) . ' Kb', - 'isImage' => $this->attachment->isImage, - 'url' => $this->attachment->url, - 'permalink' => $this->permalink - ))); - } else { - echo "<script>parent.fileUploadComplete('" . $this->request->_id - . "', '" . $this->attachment->url . "', " . json_encode(array( - 'cid' => $insertId, - 'title' => $this->attachment->name, - 'type' => $this->attachment->type, - 'size' => $this->attachment->size, - 'bytes' => number_format(ceil($this->attachment->size / 1024)) . ' Kb', - 'isImage' => $this->attachment->isImage, - 'url' => $this->attachment->url, - 'permalink' => $this->permalink - )) . ');</script>'; - - return; - } - } - } - } - - if ($this->request->isAjax()) { - $this->response->throwJson(false); - } else { - echo "<script>parent.fileUploadError('" . $this->request->_id . "');</script>"; - } - } - - /** - * 执行升级程序 - * - * @access public - * @return void - */ - public function modify() - { - if (!empty($_FILES)) { - $file = array_pop($_FILES); - if (0 == $file['error'] && is_uploaded_file($file['tmp_name'])) { - $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $this->request->filter('int')->cid) - ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); - - if (!$this->have()) { - $this->response->setStatus(404); - exit; - } - - if (!$this->allow('edit')) { - $this->response->setStatus(403); - exit; - } - - $result = self::modifyHandle($this->row, $file); - - if (false !== $result) { - $this->pluginHandle()->beforeModify($result); - - $this->update(array( - 'text' => serialize($result) - ), $this->db->sql()->where('cid = ?', $this->cid)); - - $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $this->cid) - ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); - - /** 增加插件接口 */ - $this->pluginHandle()->modify($this); - - if ($this->request->isAjax()) { - $this->response->throwJson(array($this->attachment->url, array( - 'cid' => $this->cid, - 'title' => $this->attachment->name, - 'type' => $this->attachment->type, - 'size' => $this->attachment->size, - 'bytes' => number_format(ceil($this->attachment->size / 1024)) . ' Kb', - 'isImage' => $this->attachment->isImage, - 'url' => $this->attachment->url, - 'permalink' => $this->permalink - ))); - } else { - echo "<script>parent.fileUploadComplete('" . $this->request->_id - . "', '" . $this->attachment->url . "', " . json_encode(array( - 'cid' => $this->cid, - 'title' => $this->attachment->name, - 'type' => $this->attachment->type, - 'size' => $this->attachment->size, - 'bytes' => number_format(ceil($this->attachment->size / 1024)) . ' Kb', - 'isImage' => $this->attachment->isImage, - 'url' => $this->attachment->url, - 'permalink' => $this->permalink - )) . ');</script>'; - - return; - } - } - } - } - - if ($this->request->isAjax()) { - $this->response->throwJson(false); - } else { - echo "<script>parent.fileUploadError('" . $this->request->_id . "');</script>"; - } - } - - /** - * 初始化函数 - * - * @access public - * @return void - */ - public function action() - { - if ($this->user->pass('contributor', true) && $this->request->isPost()) { - if ($this->request->is('do=modify&cid')) { - $this->modify(); - } else { - $this->upload(); - } - } else { - $this->response->setStatus(403); - } - } -} diff --git a/php/typecho09/var/Widget/User.php b/php/typecho09/var/Widget/User.php deleted file mode 100644 index 12ae5341c..000000000 --- a/php/typecho09/var/Widget/User.php +++ /dev/null @@ -1,268 +0,0 @@ -<?php - -/** - * 当前登录用户 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_User extends Typecho_Widget -{ - /** - * 用户 - * - * @access private - * @var array - */ - private $_user; - - /** - * 是否已经登录 - * - * @access private - * @var boolean - */ - private $_hasLogin = NULL; - - /** - * 全局选项 - * - * @access protected - * @var Widget_Options - */ - protected $options; - - /** - * 数据库对象 - * - * @access protected - * @var Typecho_Db - */ - protected $db; - - /** - * 用户组 - * - * @access public - * @var array - */ - public $groups = array( - 'administrator' => 0, - 'editor' => 1, - 'contributor' => 2, - 'subscriber' => 3, - 'visitor' => 4 - ); - - /** - * 构造函数,初始化组件 - * - * @access public - * @param mixed $request request对象 - * @param mixed $response response对象 - * @param mixed $params 参数列表 - * @return void - */ - public function __construct($request, $response, $params = NULL) - { - parent::__construct($request, $response, $params); - - /** 初始化数据库 */ - $this->db = Typecho_Db::get(); - $this->options = $this->widget('Widget_Options'); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - if ($this->hasLogin()) { - $rows = $this->db->fetchAll($this->db->select() - ->from('table.options')->where('user = ?', $this->_user['uid'])); - - $this->push($this->_user); - - foreach ($rows as $row) { - $this->options->__set($row['name'], $row['value']); - } - - //更新最后活动时间 - $this->db->query($this->db - ->update('table.users') - ->rows(array('activated' => $this->options->gmtTime)) - ->where('uid = ?', $this->_user['uid'])); - } - } - - /** - * 以用户名和密码登录 - * - * @access public - * @param string $name 用户名 - * @param string $password 密码 - * @param boolean $temporarily 是否为临时登录 - * @param integer $expire 过期时间 - * @return boolean - */ - public function login($name, $password, $temporarily = false, $expire = 0) - { - //插件接口 - $result = $this->pluginHandle()->trigger($loginPluggable)->login($name, $password, $temporarily, $expire); - if ($loginPluggable) { - return $result; - } - - /** 开始验证用户 **/ - $user = $this->db->fetchRow($this->db->select() - ->from('table.users') - ->where((strpos($name, '@') ? 'mail' : 'name') . ' = ?', $name) - ->limit(1)); - - $hashValidate = $this->pluginHandle()->trigger($hashPluggable)->hashValidate($password, $user['password']); - if (!$hashPluggable) { - $hashValidate = Typecho_Common::hashValidate($password, $user['password']); - } - - if ($user && $hashValidate) { - - if (!$temporarily) { - $authCode = sha1(Typecho_Common::randString(20)); - $user['authCode'] = $authCode; - - Typecho_Cookie::set('__typecho_uid', $user['uid'], $expire, $this->options->siteUrl); - Typecho_Cookie::set('__typecho_authCode', Typecho_Common::hash($authCode), - $expire, $this->options->siteUrl); - - //更新最后登录时间以及验证码 - $this->db->query($this->db - ->update('table.users') - ->expression('logged', 'activated') - ->rows(array('authCode' => $authCode)) - ->where('uid = ?', $user['uid'])); - } - - /** 压入数据 */ - $this->push($user); - $this->_hasLogin = true; - $this->pluginHandle()->loginSucceed($this, $name, $password, $temporarily, $expire); - - return true; - } - - $this->pluginHandle()->loginFail($this, $name, $password, $temporarily, $expire); - return false; - } - - /** - * 只需要提供uid即可登录的方法, 多用于插件等特殊场合 - * - * @access public - * @param integer $uid 用户id - * @return boolean - */ - public function simpleLogin($uid) - { - $user = $this->db->fetchRow($this->db->select() - ->from('table.users') - ->where('uid = ?', $uid) - ->limit(1)); - - if (empty($user)) { - return false; - } - - $this->push($user); - $this->_hasLogin = true; - - return true; - } - - /** - * 用户登出函数 - * - * @access public - * @return void - */ - public function logout() - { - $this->pluginHandle()->trigger($logoutPluggable)->logout(); - if ($logoutPluggable) { - return; - } - - Typecho_Cookie::delete('__typecho_uid', $this->options->siteUrl); - Typecho_Cookie::delete('__typecho_authCode', $this->options->siteUrl); - Typecho_Cookie::delete('__typecho_feed'); - Typecho_Cookie::delete('__typecho_check_version'); - } - - /** - * 判断用户是否已经登录 - * - * @access public - * @return void - */ - public function hasLogin() - { - if (NULL !== $this->_hasLogin) { - return $this->_hasLogin; - } else { - $cookieUid = Typecho_Cookie::get('__typecho_uid'); - if (NULL !== $cookieUid) { - /** 验证登陆 */ - $user = $this->db->fetchRow($this->db->select()->from('table.users') - ->where('uid = ?', intval($cookieUid)) - ->limit(1)); - - $cookieAuthCode = Typecho_Cookie::get('__typecho_authCode'); - if ($user && Typecho_Common::hashValidate($user['authCode'], $cookieAuthCode)) { - $this->_user = $user; - return ($this->_hasLogin = true); - } - - $this->logout(); - } - - return ($this->_hasLogin = false); - } - } - - /** - * 判断用户权限 - * - * @access public - * @param string $group 用户组 - * @param boolean $return 是否为返回模式 - * @return boolean - * @throws TypechoWidgetException - */ - public function pass($group, $return = false) - { - if ($this->hasLogin()) { - if (array_key_exists($group, $this->groups) && $this->groups[$this->group] <= $this->groups[$group]) { - return true; - } - } else { - if ($return) { - return false; - } else { - //防止循环重定向 - $this->response->redirect($this->options->loginUrl . - (0 === strpos($this->request->getReferer(), $this->options->loginUrl) ? '' : - '?referer=' . urlencode($this->request->makeUriByRequest())), false); - } - } - - if ($return) { - return false; - } else { - throw new Typecho_Widget_Exception(_t('禁止访问'), 403); - } - } -} diff --git a/php/typecho09/var/Widget/Users/Admin.php b/php/typecho09/var/Widget/Users/Admin.php deleted file mode 100644 index 905ff8db3..000000000 --- a/php/typecho09/var/Widget/Users/Admin.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 后台成员列表组件 - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Users_Admin extends Widget_Abstract_Users -{ - /** - * 分页计算对象 - * - * @access private - * @var Typecho_Db_Query - */ - private $_countSql; - - /** - * 所有文章个数 - * - * @access private - * @var integer - */ - private $_total = false; - - /** - * 分页大小 - * - * @access private - * @var integer - */ - private $_pageSize; - - /** - * 当前页 - * - * @access private - * @var integer - */ - private $_currentPage; - - /** - * 仅仅输出域名和路径 - * - * @access protected - * @return string - */ - protected function ___domainPath() - { - $parts = parse_url($this->url); - return $parts['host'] . (isset($parts['path']) ? $parts['path'] : NULL); - } - - /** - * 发布文章数 - * - * @access protected - * @return integer - */ - protected function ___postsNum() - { - return $this->db->fetchObject($this->db->select(array('COUNT(cid)' => 'num')) - ->from('table.contents') - ->where('table.contents.type = ?', 'post') - ->where('table.contents.status = ?', 'publish') - ->where('table.contents.authorId = ?', $this->uid))->num; - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - $this->parameter->setDefault('pageSize=20'); - $select = $this->select(); - $this->_currentPage = $this->request->get('page', 1); - - /** 过滤标题 */ - if (NULL != ($keywords = $this->request->keywords)) { - $select->where('name LIKE ? OR screenName LIKE ?', - '%' . Typecho_Common::filterSearchQuery($keywords) . '%', - '%' . Typecho_Common::filterSearchQuery($keywords) . '%'); - } - - $this->_countSql = clone $select; - - $select->order('table.users.uid', Typecho_Db::SORT_ASC) - ->page($this->_currentPage, $this->parameter->pageSize); - - $this->db->fetchAll($select, array($this, 'push')); - } - - /** - * 输出分页 - * - * @access public - * @return void - */ - public function pageNav() - { - $query = $this->request->makeUriByRequest('page={page}');; - - /** 使用盒状分页 */ - $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, - $this->_currentPage, $this->parameter->pageSize, $query); - $nav->render('«', '»'); - } -} diff --git a/php/typecho09/var/Widget/Users/Author.php b/php/typecho09/var/Widget/Users/Author.php deleted file mode 100644 index 79d73b1bb..000000000 --- a/php/typecho09/var/Widget/Users/Author.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * 相关内容 - * - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 相关内容组件(根据标签关联) - * - * @author qining - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Users_Author extends Widget_Abstract_Users -{ - /** - * 执行函数,初始化数据 - * - * @access public - * @return void - */ - public function execute() - { - if ($this->parameter->uid) { - $this->db->fetchRow($this->select() - ->where('uid = ?', $this->parameter->uid), array($this, 'push')); - } - } -} diff --git a/php/typecho09/var/Widget/Users/Edit.php b/php/typecho09/var/Widget/Users/Edit.php deleted file mode 100644 index dde92dd71..000000000 --- a/php/typecho09/var/Widget/Users/Edit.php +++ /dev/null @@ -1,306 +0,0 @@ -<?php -/** - * 编辑用户 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 编辑用户组件 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interface_Do -{ - /** - * 获取页面偏移的URL Query - * - * @access protected - * @param integer $uid 用户id - * @return string - */ - protected function getPageOffsetQuery($uid) - { - return 'page=' . $this->getPageOffset('uid', $uid); - } - - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 管理员以上权限 */ - $this->user->pass('administrator'); - - /** 更新模式 */ - if (($this->request->uid && 'delete' != $this->request->do) || 'update' == $this->request->do) { - $this->db->fetchRow($this->select() - ->where('uid = ?', $this->request->uid)->limit(1), array($this, 'push')); - - if (!$this->have()) { - throw new Typecho_Widget_Exception(_t('用户不存在'), 404); - } - } - } - - /** - * 获取菜单标题 - * - * @access public - * @return string - */ - public function getMenuTitle() - { - return _t('编辑用户 %s', $this->name); - } - - /** - * 判断用户是否存在 - * - * @access public - * @param integer $uid 用户主键 - * @return boolean - */ - public function userExists($uid) - { - $user = $this->db->fetchRow($this->db->select() - ->from('table.users') - ->where('uid = ?', $uid)->limit(1)); - - return $user ? true : false; - } - - /** - * 生成表单 - * - * @access public - * @param string $action 表单动作 - * @return Typecho_Widget_Helper_Form - */ - public function form($action = NULL) - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/users-edit', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 用户名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('用户名 *'), _t('此用户名将作为用户登录时所用的名称.<br /> - 请不要与系统中现有的用户名重复.')); - $form->addInput($name); - - /** 电子邮箱地址 */ - $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL, _t('电子邮箱地址 *'), _t('电子邮箱地址将作为此用户的主要联系方式.<br /> - 请不要与系统中现有的电子邮箱地址重复.')); - $form->addInput($mail); - - /** 用户昵称 */ - $screenName = new Typecho_Widget_Helper_Form_Element_Text('screenName', NULL, NULL, _t('用户昵称'), _t('用户昵称可以与用户名不同, 用于前台显示.<br /> - 如果你将此项留空, 将默认使用用户名.')); - $form->addInput($screenName); - - /** 用户密码 */ - $password = new Typecho_Widget_Helper_Form_Element_Password('password', NULL, NULL, _t('用户密码'), _t('为此用户分配一个密码.<br /> - 建议使用特殊字符与字母的混编样式,以增加系统安全性.')); - $password->input->setAttribute('class', 'w-60'); - $form->addInput($password); - - /** 用户密码确认 */ - $confirm = new Typecho_Widget_Helper_Form_Element_Password('confirm', NULL, NULL, _t('用户密码确认'), _t('请确认你的密码, 与上面输入的密码保持一致.')); - $confirm->input->setAttribute('class', 'w-60'); - $form->addInput($confirm); - - /** 个人主页地址 */ - $url = new Typecho_Widget_Helper_Form_Element_Text('url', NULL, NULL, _t('个人主页地址'), _t('此用户的个人主页地址, 请用 <code>http://</code> 开头.')); - $form->addInput($url); - - /** 用户组 */ - $group = new Typecho_Widget_Helper_Form_Element_Select('group', array('visitor' => _t('访问者'), - 'subscriber' => _t('关注者'), 'contributor' => _t('贡献者'), 'editor' => _t('编辑'), 'administrator' => _t('管理员')), - NULL, _t('用户组'), _t('不同的用户组拥有不同的权限.<br /> - 具体的权限分配表请<a href="http://docs.typecho.org/develop/acl">参考这里</a>.')); - $form->addInput($group); - - /** 用户动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do'); - $form->addInput($do); - - /** 用户主键 */ - $uid = new Typecho_Widget_Helper_Form_Element_Hidden('uid'); - $form->addInput($uid); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit(); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - if (NULL != $this->request->uid) { - $submit->value(_t('编辑用户')); - $name->value($this->name); - $screenName->value($this->screenName); - $url->value($this->url); - $mail->value($this->mail); - $group->value($this->group); - $do->value('update'); - $uid->value($this->uid); - $_action = 'update'; - } else { - $submit->value(_t('增加用户')); - $do->value('insert'); - $_action = 'insert'; - } - - if (empty($action)) { - $action = $_action; - } - - /** 给表单增加规则 */ - if ('insert' == $action || 'update' == $action) { - $screenName->addRule(array($this, 'screenNameExists'), _t('昵称已经存在')); - $url->addRule('url', _t('个人主页地址格式错误')); - $mail->addRule('required', _t('必须填写电子邮箱')); - $mail->addRule(array($this, 'mailExists'), _t('电子邮箱地址已经存在')); - $mail->addRule('email', _t('电子邮箱格式错误')); - $password->addRule('minLength', _t('为了保证账户安全, 请输入至少六位的密码'), 6); - $confirm->addRule('confirm', _t('两次输入的密码不一致'), 'password'); - } - - if ('insert' == $action) { - $name->addRule('required', _t('必须填写用户名称')); - $name->addRule('xssCheck', _t('请不要在用户名中使用特殊字符')); - $name->addRule(array($this, 'nameExists'), _t('用户名已经存在')); - $password->label(_t('用户密码 *')); - $confirm->label(_t('用户密码确认 *')); - $password->addRule('required', _t('必须填写密码')); - } - - if ('update' == $action) { - $name->input->setAttribute('disabled', 'disabled'); - $uid->addRule('required', _t('用户主键不存在')); - $uid->addRule(array($this, 'userExists'), _t('用户不存在')); - } - - return $form; - } - - /** - * 增加用户 - * - * @access public - * @return void - */ - public function insertUser() - { - if ($this->form('insert')->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $user = $this->request->from('name', 'mail', 'screenName', 'password', 'url', 'group'); - $user['screenName'] = empty($user['screenName']) ? $user['name'] : $user['screenName']; - $user['password'] = Typecho_Common::hash($user['password']); - $user['created'] = $this->options->gmtTime; - - /** 插入数据 */ - $user['uid'] = $this->insert($user); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('user-' . $user['uid']); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('用户 %s 已经被增加', $user['screenName']), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-users.php', $this->options->adminUrl)); - } - - /** - * 更新用户 - * - * @access public - * @return void - */ - public function updateUser() - { - if ($this->form('update')->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $user = $this->request->from('mail', 'screenName', 'password', 'url', 'group'); - $user['screenName'] = empty($user['screenName']) ? $user['name'] : $user['screenName']; - if (empty($user['password'])) { - unset($user['password']); - } else { - $user['password'] = Typecho_Common::hash($user['password']); - } - - /** 更新数据 */ - $this->update($user, $this->db->sql()->where('uid = ?', $this->request->uid)); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('user-' . $this->request->uid); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('用户 %s 已经被更新', $user['screenName']), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-users.php?' . - $this->getPageOffsetQuery($this->request->uid), $this->options->adminUrl)); - } - - /** - * 删除用户 - * - * @access public - * @return void - */ - public function deleteUser() - { - $users = $this->request->uid; - $deleteCount = 0; - - if ($users && is_array($users)) { - foreach ($users as $user) { - if (1 == $user) { - continue; - } - - if ($this->delete($this->db->sql()->where('uid = ?', $user))) { - $deleteCount ++; - } - } - } - - /** 提示信息 */ - $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('用户已经删除') : _t('没有用户被删除'), - $deleteCount > 0 ? 'success' : 'notice'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('manage-users.php', $this->options->adminUrl)); - } - - /** - * 入口函数 - * - * @access public - * @return void - */ - public function action() - { - $this->user->pass('administrator'); - $this->on($this->request->is('do=insert'))->insertUser(); - $this->on($this->request->is('do=update'))->updateUser(); - $this->on($this->request->is('do=delete'))->deleteUser(); - $this->response->redirect($this->options->adminUrl); - } -} diff --git a/php/typecho09/var/Widget/Users/Profile.php b/php/typecho09/var/Widget/Users/Profile.php deleted file mode 100644 index b94fd53d5..000000000 --- a/php/typecho09/var/Widget/Users/Profile.php +++ /dev/null @@ -1,424 +0,0 @@ -<?php -/** - * 编辑用户 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * 编辑用户组件 - * - * @link typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface_Do -{ - /** - * 执行函数 - * - * @access public - * @return void - */ - public function execute() - { - /** 注册用户以上权限 */ - $this->user->pass('subscriber'); - $this->request->setParam('uid', $this->user->uid); - } - - /** - * 生成表单 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function profileForm() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/users-profile', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 用户昵称 */ - $screenName = new Typecho_Widget_Helper_Form_Element_Text('screenName', NULL, NULL, _t('昵称'), _t('用户昵称可以与用户名不同, 用于前台显示.<br /> - 如果你将此项留空, 将默认使用用户名.')); - $form->addInput($screenName); - - /** 个人主页地址 */ - $url = new Typecho_Widget_Helper_Form_Element_Text('url', NULL, NULL, _t('个人主页地址'), _t('此用户的个人主页地址, 请用 <code>http://</code> 开头.')); - $form->addInput($url); - - /** 电子邮箱地址 */ - $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL, _t('电子邮箱地址 *'), _t('电子邮箱地址将作为此用户的主要联系方式.<br /> - 请不要与系统中现有的电子邮箱地址重复.')); - $form->addInput($mail); - - /** 用户动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, 'profile'); - $form->addInput($do); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('更新我的档案')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - $screenName->value($this->user->screenName); - $url->value($this->user->url); - $mail->value($this->user->mail); - - /** 给表单增加规则 */ - $screenName->addRule(array($this, 'screenNameExists'), _t('昵称已经存在')); - $url->addRule('url', _t('个人主页地址格式错误')); - $mail->addRule('required', _t('必须填写电子邮箱')); - $mail->addRule(array($this, 'mailExists'), _t('电子邮箱地址已经存在')); - $mail->addRule('email', _t('电子邮箱格式错误')); - - return $form; - } - - /** - * 输出表单结构 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function optionsForm() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/users-profile', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 自动保存 */ - $markdown = new Typecho_Widget_Helper_Form_Element_Radio('markdown', - array('0' => _t('关闭'), '1' => _t('打开')), - $this->options->markdown, _t('使用 Markdown 语法编辑和解析内容'), - _t('使用 <a href="http://daringfireball.net/projects/markdown/">Markdown</a> 语法能够使您的撰写过程更加简便直观.<br /> -此功能开启不会影响以前没有使用 Markdown 语法编辑的内容.')); - $form->addInput($markdown); - - /** 自动保存 */ - $autoSave = new Typecho_Widget_Helper_Form_Element_Radio('autoSave', - array('0' => _t('关闭'), '1' => _t('打开')), - $this->options->autoSave, _t('自动保存'), _t('自动保存功能可以更好地保护你的文章不会丢失.')); - $form->addInput($autoSave); - - /** 默认允许 */ - $allow = array(); - if ($this->options->defaultAllowComment) { - $allow[] = 'comment'; - } - - if ($this->options->defaultAllowPing) { - $allow[] = 'ping'; - } - - if ($this->options->defaultAllowFeed) { - $allow[] = 'feed'; - } - - $defaultAllow = new Typecho_Widget_Helper_Form_Element_Checkbox('defaultAllow', - array('comment' => _t('可以被评论'), 'ping' => _t('可以被引用'), 'feed' => _t('出现在聚合中')), - $allow, _t('默认允许'), _t('设置你经常使用的默认允许权限')); - $form->addInput($defaultAllow); - - /** 用户动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, 'options'); - $form->addInput($do); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('保存设置')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - return $form; - } - - /** - * 输出自定义设置选项 - * - * @access public - * @param string $pluginName 插件名称 - * @param string $className 类名称 - * @param string $pluginFileName 插件文件名 - * @param string $group 用户组 - * @return Typecho_Widget_Helper_Form - */ - public function personalForm($pluginName, $className, $pluginFileName, &$group) - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/users-profile', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - $form->setAttribute('name', $pluginName); - $form->setAttribute('id', $pluginName); - - require_once $pluginFileName; - $group = call_user_func(array($className, 'personalConfig'), $form); - $group = $group ? $group : 'subscriber'; - - $options = $this->options->personalPlugin($pluginName); - - if (!empty($options)) { - foreach ($options as $key => $val) { - $form->getInput($key)->value($val); - } - } - - $form->addItem(new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, 'personal')); - $form->addItem(new Typecho_Widget_Helper_Form_Element_Hidden('plugin', NULL, $pluginName)); - $form->addItem(new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置'))); - return $form; - } - - /** - * 自定义设置列表 - * - * @access public - * @return void - */ - public function personalFormList() - { - $this->widget('Widget_Plugins_List_Activated')->to($plugins); - while ($plugins->next()) { - if ($plugins->personalConfig) { - echo '<h3>' . $plugins->title . '</h3>'; - list($pluginFileName, $className) = Typecho_Plugin::portal($plugins->name, - __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); - - $form = $this->personalForm($plugins->name, $className, $pluginFileName, $group); - if ($this->user->pass($group, true)) { - $form->render(); - } - } - } - } - - /** - * 生成表单 - * - * @access public - * @return Typecho_Widget_Helper_Form - */ - public function passwordForm() - { - /** 构建表格 */ - $form = new Typecho_Widget_Helper_Form(Typecho_Common::url('/action/users-profile', $this->options->index), - Typecho_Widget_Helper_Form::POST_METHOD); - - /** 用户密码 */ - $password = new Typecho_Widget_Helper_Form_Element_Password('password', NULL, NULL, _t('用户密码'), _t('为此用户分配一个密码.<br /> - 建议使用特殊字符与字母的混编样式,以增加系统安全性.')); - $password->input->setAttribute('class', 'w-60'); - $form->addInput($password); - - /** 用户密码确认 */ - $confirm = new Typecho_Widget_Helper_Form_Element_Password('confirm', NULL, NULL, _t('用户密码确认'), _t('请确认你的密码, 与上面输入的密码保持一致.')); - $confirm->input->setAttribute('class', 'w-60'); - $form->addInput($confirm); - - /** 用户动作 */ - $do = new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, 'password'); - $form->addInput($do); - - /** 提交按钮 */ - $submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', NULL, _t('更新密码')); - $submit->input->setAttribute('class', 'primary'); - $form->addItem($submit); - - $password->addRule('required', _t('必须填写密码')); - $password->addRule('minLength', _t('为了保证账户安全, 请输入至少六位的密码'), 6); - $confirm->addRule('confirm', _t('两次输入的密码不一致'), 'password'); - - return $form; - } - - /** - * 更新用户 - * - * @access public - * @return void - */ - public function updateProfile() - { - if ($this->profileForm()->validate()) { - $this->response->goBack(); - } - - /** 取出数据 */ - $user = $this->request->from('mail', 'screenName', 'url'); - $user['screenName'] = empty($user['screenName']) ? $user['name'] : $user['screenName']; - - /** 更新数据 */ - $this->update($user, $this->db->sql()->where('uid = ?', $this->user->uid)); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('user-' . $this->user->uid); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('您的档案已经更新'), 'success'); - - /** 转向原页 */ - $this->response->goBack(); - } - - /** - * 执行更新动作 - * - * @access public - * @return void - */ - public function updateOptions() - { - $settings['autoSave'] = $this->request->autoSave ? 1 : 0; - $settings['markdown'] = $this->request->markdown ? 1 : 0; - - $settings['defaultAllowComment'] = is_array($this->request->defaultAllow) - && in_array('comment', $this->request->defaultAllow) ? 1 : 0; - - $settings['defaultAllowPing'] = is_array($this->request->defaultAllow) - && in_array('ping', $this->request->defaultAllow) ? 1 : 0; - - $settings['defaultAllowFeed'] = is_array($this->request->defaultAllow) - && in_array('feed', $this->request->defaultAllow) ? 1 : 0; - - foreach ($settings as $name => $value) { - if ($this->db->fetchObject($this->db->select(array('COUNT(*)' => 'num')) - ->from('table.options')->where('name = ? AND user = ?', $name, $this->user->uid))->num > 0) { - $this->widget('Widget_Abstract_Options') - ->update(array('value' => $value), $this->db->sql()->where('name = ? AND user = ?', $name, $this->user->uid)); - } else { - $this->widget('Widget_Abstract_Options')->insert(array( - 'name' => $name, - 'value' => $value, - 'user' => $this->user->uid - )); - } - } - - $this->widget('Widget_Notice')->set(_t("设置已经保存"), 'success'); - $this->response->goBack(); - } - - /** - * 更新密码 - * - * @access public - * @return void - */ - public function updatePassword() - { - /** 验证格式 */ - if ($this->passwordForm()->validate()) { - $this->response->goBack(); - } - - $password = Typecho_Common::hash($this->request->password); - - /** 更新数据 */ - $this->update(array('password' => $password), - $this->db->sql()->where('uid = ?', $this->user->uid)); - - /** 设置高亮 */ - $this->widget('Widget_Notice')->highlight('user-' . $this->user->uid); - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t('密码已经成功修改'), 'success'); - - /** 转向原页 */ - $this->response->goBack(); - } - - /** - * 更新个人设置 - * - * @access public - * @return void - */ - public function updatePersonal() - { - /** 获取插件名称 */ - $pluginName = $this->request->plugin; - - /** 获取已启用插件 */ - $plugins = Typecho_Plugin::export(); - $activatedPlugins = $plugins['activated']; - - /** 获取插件入口 */ - list($pluginFileName, $className) = Typecho_Plugin::portal($this->request->plugin, - __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__); - $info = Typecho_Plugin::parseInfo($pluginFileName); - - if (!$info['personalConfig'] || !isset($activatedPlugins[$pluginName])) { - throw new Typecho_Widget_Exception(_t('无法配置插件'), 500); - } - - $form = $this->personalForm($pluginName, $className, $pluginFileName, $group); - $this->user->pass($group); - - /** 验证表单 */ - if ($form->validate()) { - $this->response->goBack(); - } - - $settings = $form->getAllRequest(); - unset($settings['do'], $settings['plugin']); - $name = '_plugin:' . $pluginName; - - if (!$this->personalConfigHandle($className, $settings)) { - if ($this->db->fetchObject($this->db->select(array('COUNT(*)' => 'num')) - ->from('table.options')->where('name = ? AND user = ?', $name, $this->user->uid))->num > 0) { - $this->widget('Widget_Abstract_Options') - ->update(array('value' => serialize($settings)), $this->db->sql()->where('name = ? AND user = ?', $name, $this->user->uid)); - } else { - $this->widget('Widget_Abstract_Options')->insert(array( - 'name' => $name, - 'value' => serialize($settings), - 'user' => $this->user->uid - )); - } - } - - /** 提示信息 */ - $this->widget('Widget_Notice')->set(_t("%s 设置已经保存", $info['title']), 'success'); - - /** 转向原页 */ - $this->response->redirect(Typecho_Common::url('profile.php', $this->options->adminUrl)); - } - - /** - * 用自有函数处理自定义配置信息 - * - * @access public - * @param string $className 类名 - * @param array $settings 配置值 - * @return boolean - */ - public function personalConfigHandle($className, array $settings) - { - if (method_exists($className, 'personalConfigHandle')) { - call_user_func(array($className, 'personalConfigHandle'), $settings, false); - return true; - } - - return false; - } - - /** - * 入口函数 - * - * @access public - * @return void - */ - public function action() - { - $this->on($this->request->is('do=profile'))->updateProfile(); - $this->on($this->request->is('do=options'))->updateOptions(); - $this->on($this->request->is('do=password'))->updatePassword(); - $this->on($this->request->is('do=personal&plugin'))->updatePersonal(); - $this->response->redirect($this->options->siteUrl); - } -} diff --git a/php/typecho09/var/Widget/XmlRpc.php b/php/typecho09/var/Widget/XmlRpc.php deleted file mode 100644 index 6afd17e53..000000000 --- a/php/typecho09/var/Widget/XmlRpc.php +++ /dev/null @@ -1,2093 +0,0 @@ -<?php -/** - * Typecho Blog Platform - * - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - * @version $Id$ - */ - -/** - * XmlRpc接口 - * - * @author blankyao - * @category typecho - * @package Widget - * @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org) - * @license GNU General Public License 2.0 - */ -class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface_Do -{ - /** - * 当前错误 - * - * @access private - * @var IXR_Error - */ - private $error; - - /** - * wordpress风格的系统选项 - * - * @access private - * @var array - */ - private $_wpOptions; - - /** - * 已经使用过的组件列表 - * - * @access private - * @var array - */ - private $_usedWidgetNameList = array(); - - /** - * 获取扩展字段 - * - * @access private - * @param Widget_Abstract_Contents $content - * @return array - */ - private function getPostExtended(Widget_Abstract_Contents $content) - { - //根据客户端显示来判断是否显示html代码 - $agent = $this->request->getAgent(); - $text = ''; - - switch (true) { - case false !== strpos($agent, 'wp-iphone'): // wordpress iphone客户端 - case false !== strpos($agent, 'wp-blackberry'): // 黑莓 - case false !== strpos($agent, 'wp-andriod'): // andriod - case false !== strpos($agent, 'plain-text'): // 这是预留给第三方开发者的接口, 用于强行调用非所见即所得数据 - $text = $content->text; - break; - default: - $text = $content->content; - break; - } - - $post = explode('<!--more-->', $text, 2); - return array(Typecho_Common::fixHtml($post[0]), isset($post[1]) ? Typecho_Common::fixHtml($post[1]) : NULL); - } - - /** - * 将typecho的状态类型转换为wordperss的风格 - * - * @access private - * @param string $status typecho的状态 - * @param string $type 内容类型 - * @return string - */ - private function typechoToWordpressStatus($status, $type = 'post') - { - if ('post' == $type) { - /** 文章状态 */ - switch ($status) { - case 'waiting': - return 'pending'; - case 'publish': - case 'draft': - case 'private': - return $status; - default: - return 'publish'; - } - } else if ('page' == $type) { - switch ($status) { - case 'publish': - case 'draft': - case 'private': - return $status; - default: - return 'publish'; - } - } else if ('comment' == $type) { - switch ($status) { - case 'publish': - case 'approved': - return 'approve'; - case 'waiting': - return 'hold'; - case 'spam': - return $status; - default: - return 'approve'; - } - } - - return ''; - } - - /** - * 将wordpress的状态类型转换为typecho的风格 - * - * @access private - * @param string $status wordpress的状态 - * @param string $type 内容类型 - * @return string - */ - private function wordpressToTypechoStatus($status, $type = 'post') - { - if ('post' == $type) { - /** 文章状态 */ - switch ($status) { - case 'pending': - return 'waiting'; - case 'publish': - case 'draft': - case 'private': - case 'waiting': - return $status; - default: - return 'publish'; - } - } else if ('page' == $type) { - switch ($status) { - case 'publish': - case 'draft': - case 'private': - return $status; - default: - return 'publish'; - } - } else if ('comment' == $type) { - switch ($status) { - case 'approve': - case 'publish': - case 'approved': - return 'approved'; - case 'hold': - case 'waiting': - return 'waiting'; - case 'spam': - return $status; - default: - return 'approved'; - } - } - - return ''; - } - - /** - * 代理工厂方法,将类静态化放置到列表中 - * - * @access public - * @param string $alias 组件别名 - * @param mixed $params 传递的参数 - * @param mixed $request 前端参数 - * @param boolean $enableResponse 是否允许http回执 - * @return object - * @throws Typecho_Exception - */ - private function singletonWidget($alias, $params = NULL, $request = NULL, $enableResponse = true) - { - $this->_usedWidgetNameList[] = $alias; - return Typecho_Widget::widget($alias, $params, $request, $enableResponse); - } - - /** - * 如果这里没有重载, 每次都会被默认执行 - * - * @access public - * @param boolen $run 是否执行 - * @return void - */ - public function execute($run = false) - { - if ($run) { - parent::execute(); - } - - $this->_wpOptions = array( - // Read only options - 'software_name' => array( - 'desc' => _t( '软件名称' ), - 'readonly' => true, - 'value' => $this->options->software - ), - 'software_version' => array( - 'desc' => _t( '软件版本' ), - 'readonly' => true, - 'value' => $this->options->version - ), - 'blog_url' => array( - 'desc' => _t( '博客地址' ), - 'readonly' => true, - 'option' => 'siteUrl' - ), - - // Updatable options - 'time_zone' => array( - 'desc' => _t( '时区' ), - 'readonly' => false, - 'option' => 'timezone' - ), - 'blog_title' => array( - 'desc' => _t( '博客标题' ), - 'readonly' => false, - 'option' => 'title' - ), - 'blog_tagline' => array( - 'desc' => _t( '博客关键字' ), - 'readonly' => false, - 'option' => 'description' - ), - 'date_format' => array( - 'desc' => _t( '日期格式' ), - 'readonly' => false, - 'option' => 'postDateFormat' - ), - 'time_format' => array( - 'desc' => _t( '时间格式' ), - 'readonly' => false, - 'option' => 'postDateFormat' - ), - 'users_can_register' => array( - 'desc' => _t( '是否允许注册' ), - 'readonly' => false, - 'option' => 'allowRegister' - ) - ); - } - - /** - * 检查权限 - * - * @access public - * @return void - */ - public function checkAccess($name, $password, $level = 'contributor') - { - if ($this->user->login($name, $password, true)) { - /** 验证权限 */ - if ($this->user->pass($level, true)) { - return true; - } else { - $this->error = new IXR_Error(403, _t('权限不足')); - return false; - } - } else { - $this->error = new IXR_Error(403, _t('无法登陆, 密码错误')); - return false; - } - } - - /** about wp xmlrpc api, you can see http://codex.wordpress.org/XML-RPC*/ - - /** - * 获取pageId指定的page - * - * @param int $blogId - * @param int $pageId - * @param string $userName - * @param string $password - * @access public - * @return struct $pageStruct - */ - public function wpGetPage($blogId, $pageId, $userName, $password) - { - /** 检查权限 */ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - /** 获取页面 */ - try { - /** 由于Widget_Contents_Page_Edit是从request中获取参数, 因此我们需要强行设置flush一下request */ - /** widget方法的第三个参数可以指定强行转换传入此widget的request参数 */ - /** 此组件会进行复杂的权限检测 */ - $page = $this->singletonWidget('Widget_Contents_Page_Edit', NULL, "cid={$pageId}"); - } catch (Typecho_Widget_Exception $e) { - /** 截获可能会抛出的异常(参见 Widget_Contents_Page_Edit 的 execute 方法) */ - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - /** 对文章内容做截取处理,以获得description和text_more*/ - list($excerpt, $more) = $this->getPostExtended($page); - - $pageStruct = array( - 'dateCreated' => new IXR_Date($this->options->timezone + $page->created), - 'userid' => $page->authorId, - 'page_id' => $page->cid, - 'page_status' => $this->typechoToWordpressStatus($page->status, 'page'), - 'description' => $excerpt, - 'title' => $page->title, - 'link' => $page->permalink, - 'permalink' => $page->permalink, - 'categories' => $page->categories, - 'excerpt' => $page->description, - 'text_more' => $more, - 'mt_allow_comments' => intval($page->allowComment), - 'mt_allow_pings' => intval($page->allowPing), - 'wp_slug' => $page->slug, - 'wp_password' => $page->password, - 'wp_author' => $page->author->name, - 'wp_page_parent_id' => '0', - 'wp_page_parent_title' => '', - 'wp_page_order' => $page->order, //meta是描述字段, 在page时表示顺序 - 'wp_author_id' => $page->authorId, - 'wp_author_display_name' => $page->author->screenName, - 'date_created_gmt' => new IXR_Date($page->created), - 'custom_fields' => array(), - 'wp_page_template' => $page->template - ); - - return $pageStruct; - } - - /** - * 获取所有的page - * - * @param int $blogId - * @param string $userName - * @param string $password - * @access public - * @return array(contains $pageStruct) - */ - public function wpGetPages($blogId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - /** 过滤type为page的contents */ - /** 同样需要flush一下, 需要取出所有status的页面 */ - $pages = $this->singletonWidget('Widget_Contents_Page_Admin', NULL, 'status=all'); - - /** 初始化要返回的数据结构 */ - $pageStructs = array(); - - while ($pages->next()) { - /** 对文章内容做截取处理,以获得description和text_more*/ - list($excerpt, $more) = $this->getPostExtended($pages); - $pageStructs[] = array( - 'dateCreated' => new IXR_Date($this->options->timezone + $pages->created), - 'userid' => $pages->authorId, - 'page_id' => $pages->cid, - /** todo:此处有疑问 */ - 'page_status' => $this->typechoToWordpressStatus($pages->status, 'page'), - 'description' => $excerpt, - 'title' => $pages->title, - 'link' => $pages->permalink, - 'permalink' => $pages->permalink, - 'categories' => $pages->categories, - 'excerpt' => $pages->description, - 'text_more' => $more, - 'mt_allow_comments' => intval($pages->allowComment), - 'mt_allow_pings' => intval($pages->allowPing), - 'wp_slug' => $pages->slug, - 'wp_password' => $pages->password, - 'wp_author' => $pages->author->name, - 'wp_page_parent_id' => '0', - 'wp_page_parent_title' => '', - 'wp_page_order' => $pages->order, //meta是描述字段, 在page时表示顺序 - 'wp_author_id' => $pages->authorId, - 'wp_author_display_name' => $pages->author->screenName, - 'date_created_gmt' => new IXR_Date($pages->created), - 'custom_fields' => array(), - 'wp_page_template' => $pages->template - ); - } - - return $pageStructs; - } - - /** - * 撰写一个新page - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param struct $content - * @param bool $publish - * @access public - * @return void - */ - public function wpNewPage($blogId, $userName, $password, $content, $publish) - { - if (!$this->checkAccess($userName, $password, 'editor')) { - return $this->error; - } - $content['post_type'] = 'page'; - $this->mwNewPost($blogId, $userName, $password, $content, $publish); - } - - /** - * 删除pageId指定的page - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param int $pageId - * @access public - * @return bool - */ - public function wpDeletePage($blogId, $userName, $password, $pageId) - { - if (!$this->checkAccess($userName, $password, 'editor')) { - return $this->error; - } - - /** 删除页面 */ - try { - /** 此组件会进行复杂的权限检测 */ - $this->singletonWidget('Widget_Contents_Page_Edit', NULL, "cid={$pageId}", false)->deletePage(); - } catch (Typecho_Widget_Exception $e) { - /** 截获可能会抛出的异常(参见 Widget_Contents_Page_Edit 的 execute 方法) */ - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - return true; - } - - /** - * 编辑pageId指定的page - * - * @param int $blogId - * @param int $pageId - * @param string $userName - * @param string $password - * @param struct $content - * @param bool $publish - * @access public - * @return bool - */ - public function wpEditPage($blogId, $pageId, $userName, $password, $content, $publish) - { - $content['type'] = 'page'; - $this->mwEditPost($blogId, $pageId, $userName, $password, $content, $publish); - } - - /** - * 获取page列表,没有wpGetPages获得的详细 - * - * @param int $blogId - * @param string $userName - * @param string $password - * @access public - * @return array - */ - public function wpGetPageList($blogId, $userName, $password) - { - if (!$this->checkAccess($userName, $password, 'editor')) { - return ($this->error); - } - $pages = $this->singletonWidget('Widget_Contents_Page_Admin', NULL, 'status=all'); - /**初始化*/ - $pageStructs = array(); - - while ($pages->next()) { - $pageStructs[] = array( - 'dateCreated' => new IXR_Date($this->options->timezone + $pages->created), - 'date_created_gmt' => new IXR_Date($this->options->timezone + $pages->created), - 'page_id' => $pages->cid, - 'page_title' => $pages->title, - 'page_parent_id' => '0', - ); - } - - return $pageStructs; - } - - /** - * 获得一个由blog所有作者的信息组成的数组 - * - * @param int $blogId - * @param string $userName - * @param string $password - * @access public - * @return struct - */ - public function wpGetAuthors($blogId, $userName, $password) - { - if (!$this->checkAccess($userName, $password, 'editor')) { - return ($this->error); - } - - /** 构建查询*/ - $select = $this->db->select('table.users.uid', 'table.users.name', 'table.users.screenName')->from('table.users'); - $authors = $this->db->fetchAll($select); - - $authorStructs = array(); - foreach ($authors as $author) { - $authorStructs[] = array( - 'user_id' => $author['uid'], - 'user_login' => $author['name'], - 'display_name' => $author['screenName'] - ); - } - - return $authorStructs; - } - - /** - * 添加一个新的分类 - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param struct $category - * @access public - * @return void - */ - public function wpNewCategory($blogId, $userName, $password, $category) - { - if (!$this->checkAccess($userName, $password)) { - return ($this->error); - } - - /** 开始接受数据 */ - $input['name'] = $category['name']; - $input['slug'] = Typecho_Common::slugName(empty($category['slug']) ? $category['name'] : $category['slug']); - $input['type'] = 'category'; - $input['description'] = isset($category['description']) ? $category['description'] : $category['name']; - $input['do'] = 'insert'; - - /** 调用已有组件 */ - try { - /** 插入 */ - $this->singletonWidget('Widget_Metas_Category_Edit', NULL, $input, false)->action(); - return $this->singletonWidget('Widget_Notice')->getHighlightId() ? true : false; - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - return true; - } - - /** - * 获取由给定的string开头的链接组成的数组 - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param string $category - * @param int $max_results - * @access public - * @return array - */ - public function wpSuggestCategories($blogId, $userName, $password, $category, $max_results) - { - if (!$this->checkAccess($userName, $password)) { - return ($this->error); - } - - $meta = $this->singletonWidget('Widget_Abstract_Metas'); - - /** 构造出查询语句并且查询*/ - $key = Typecho_Common::filterSearchQuery($category); - $key = '%' . $key . '%'; - $select = $meta->select()->where('table.metas.type = ? AND (table.metas.name LIKE ? OR slug LIKE ?)', 'category', $key, $key); - - /** 不要category push到contents的容器中 */ - $categories = $this->db->fetchAll($select); - - /** 初始化categorise数组*/ - $categoryStructs = array(); - foreach ($categories as $category) { - $categoryStructs[] = array( - 'category_id' => $category['mid'], - 'category_name' => $category['name'], - ); - } - - return $categoryStructs; - } - - /** - * 获取用户 - * - * @access public - * @param string $userName 用户名 - * @param string $password 密码 - * @return array - */ - public function wpGetUsersBlogs($userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $struct = array(); - $struct[] = array( - 'isAdmin' => $this->user->pass('administrator', true), - 'url' => $this->options->siteUrl, - 'blogid' => '1', - 'blogName' => $this->options->title, - 'xmlrpc' => $this->options->xmlRpcUrl - ); - - return $struct; - } - - /** - * 获取标签列表 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @return array - */ - public function wpGetTags($blogId, $userName, $password) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $struct = array(); - $tags = $this->singletonWidget('Widget_Metas_Tag_Cloud'); - - while ($tags->next()) { - $struct[] = array( - 'tag_id' => $tags->mid, - 'name' => $tags->name, - 'count' => $tags->count, - 'slug' => $tags->slug, - 'html_url' => $tags->permalink, - 'rss_url' => $tags->feedUrl - ); - } - - return $struct; - } - - /** - * 删除分类 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param integer $categoryId - * @return array - */ - public function wpDeleteCategory($blogId, $userName, $password, $categoryId) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password, 'editor')) { - return $this->error; - } - - try { - $this->singletonWidget('Widget_Metas_Category_Edit', NULL, 'do=delete&mid=' . intval($categoryId), false); - return true; - } catch (Typecho_Exception $e) { - return false; - } - } - - /** - * 获取评论数目 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param integer $postId - * @return array - */ - public function wpGetCommentCount($blogId, $userName, $password, $postId) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $stat = $this->singletonWidget('Widget_Stat', NULL, 'cid=' . intval($postId), false); - - return array( - 'approved' => $stat->currentPublishedCommentsNum, - 'awaiting_moderation' => $stat->currentWaitingCommentsNum, - 'spam' => $stat->currentSpamCommentsNum, - 'total_comments' => $stat->currentCommentsNum - ); - } - - /** - * 获取文章状态列表 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @return array - */ - public function wpGetPostStatusList($blogId, $userName, $password) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - return array( - 'draft' => _t('草稿'), - 'pending' => _t('待审核'), - 'publish' => _t('已发布') - ); - } - - /** - * 获取页面状态列表 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @return array - */ - public function wpGetPageStatusList($blogId, $userName, $password) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password, 'editor')) { - return $this->error; - } - - return array( - 'draft' => _t('草稿'), - 'publish' => _t('已发布') - ); - } - - /** - * 获取评论状态列表 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @return array - */ - public function wpGetCommentStatusList($blogId, $userName, $password) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - return array( - 'hold' => _t('待审核'), - 'approve' => _t('显示'), - 'spam' => _t('垃圾') - ); - } - - /** - * 获取页面模板 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @return array - */ - public function wpGetPageTemplates($blogId, $userName, $password) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password, 'editor')) { - return $this->error; - } - - $templates = array_flip($this->getTemplates()); - $templates['Default'] = ''; - - return $templates; - } - - /** - * 获取系统选项 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param array $options - * @return array - */ - public function wpGetOptions($blogId, $userName, $password, $options = array()) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password, 'administrator')) { - return $this->error; - } - - $struct = array(); - if (empty($options)) { - $options = array_keys($this->_wpOptions); - } - - foreach ($options as $option) { - if (isset($this->_wpOptions[$option])) { - $struct[$option] = $this->_wpOptions[$option]; - if (isset($struct[$option]['option'])) { - $struct[$option]['value'] = $this->options->{$struct[$option]['option']}; - unset($struct[$option]['option']); - } - } - } - - return $struct; - } - - /** - * 设置系统选项 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param array $options - * @return array - */ - public function wpSetOptions($blogId, $userName, $password, $options = array()) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password, 'administrator')) { - return $this->error; - } - - $struct = array(); - foreach ($options as $option => $value) { - if (isset($this->_wpOptions[$option])) { - $struct[$option] = $this->_wpOptions[$option]; - if (isset($struct[$option]['option'])) { - $struct[$option]['value'] = $this->options->{$struct[$option]['option']}; - unset($struct[$option]['option']); - } - - if (!$this->_wpOptions[$option]['readonly'] && isset($this->_wpOptions[$option]['option'])) { - if ($db->query($db->update('table.options') - ->rows(array('value' => $value)) - ->where('name = ?', $this->_wpOptions[$option]['option'])) > 0) { - $struct[$option]['value'] = $value; - } - } - } - } - - return $struct; - } - - /** - * 获取评论 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param integer $commentId - * @return array - */ - public function wpGetComment($blogId, $userName, $password, $commentId) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $comment = $this->singletonWidget('Widget_Comments_Edit', NULL, 'do=get&coid=' . intval($commentId), false); - - if (!$comment->have()) { - return new IXR_Error(404, _t('评论不存在')); - } - - if (!$comment->commentIsWriteable()) { - return new IXR_Error(403, _t('没有获取评论的权限')); - } - - return array( - 'date_created_gmt' => new IXR_Date($this->options->timezone + $comment->created), - 'user_id' => $comment->authorId, - 'comment_id' => $comment->coid, - 'parent' => $comment->parent, - 'status' => $this->typechoToWordpressStatus($comment->status, 'comment'), - 'content' => $comment->text, - 'link' => $comment->permalink, - 'post_id' => $comment->cid, - 'post_title' => $comment->title, - 'author' => $comment->author, - 'author_url' => $comment->url, - 'author_email' => $comment->mail, - 'author_ip' => $comment->ip, - 'type' => $comment->type - ); - } - - /** - * 获取评论列表 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param array $struct - * @return array - */ - public function wpGetComments($blogId, $userName, $password, $struct) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $input = array(); - if (!empty($struct['status'])) { - $input['status'] = 'hold' == $input['status'] ? $input['status'] : - $this->wordpressToTypechoStatus($struct['status']); - } else { - $input['__typecho_all_comments'] = 'on'; - } - - if (!empty($struct['post_id'])) { - $input['cid'] = $struct['post_id']; - } - - $pageSize = 10; - if (!empty($struct['number'])) { - $pageSize = abs(intval($struct['number'])); - } - - if (!empty($struct['offset'])) { - $offset = abs(intval($struct['offset'])); - $input['page'] = ceil($offset / $pageSize); - } - - $comments = $this->singletonWidget('Widget_Comments_Admin', 'pageSize=' . $pageSize, $input, false); - $commentsStruct = array(); - - while ($comments->next()) { - $commentsStruct[] = array( - 'date_created_gmt' => new IXR_Date($this->options->timezone + $comments->created), - 'user_id' => $comments->authorId, - 'comment_id' => $comments->coid, - 'parent' => $comments->parent, - 'status' => $this->typechoToWordpressStatus($comments->status, 'comment'), - 'content' => $comments->text, - 'link' => $comments->permalink, - 'post_id' => $comments->cid, - 'post_title' => $comments->title, - 'author' => $comments->author, - 'author_url' => $comments->url, - 'author_email' => $comments->mail, - 'author_ip' => $comments->ip, - 'type' => $comments->type - ); - } - - return $commentsStruct; - } - - /** - * 获取评论 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param integer $commentId - * @return boolean - */ - public function wpDeleteComment($blogId, $userName, $password, $commentId) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $commentId = abs(intval($commentId)); - return intval($this->singletonWidget('Widget_Abstract_Comments')->delete( - $this->db->sql()->where('coid = ?', $commentId))) > 0; - } - - /** - * 编辑评论 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param integer $commentId - * @param array $struct - * @return boolean - */ - public function wpEditComment($blogId, $userName, $password, $commentId, $struct) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $commentId = abs(intval($commentId)); - $commentWidget = $this->singletonWidget('Widget_Abstract_Comments'); - $where = $this->db->sql()->where('coid = ?', $commentId); - - if (!$commentWidget->commentIsWriteable($where)) { - return new IXR_Error(403, _t('无法编辑此评论')); - } - - $input = array(); - - if (isset($struct['date_created_gmt'])) { - $input['created'] = $struct['date_created_gmt']->getTimestamp() - $this->options->timezone + $this->options->serverTimezone; - } - - if (isset($struct['status'])) { - $input['status'] = $this->wordpressToTypechoStatus($struct['status'], 'comment'); - } - - if (isset($struct['content'])) { - $input['text'] = $struct['content']; - } - - if (isset($struct['author'])) { - $input['author'] = $struct['author']; - } - - if (isset($struct['author_url'])) { - $input['url'] = $struct['author_url']; - } - - if (isset($struct['author_email'])) { - $input['mail'] = $struct['author_email']; - } - - $result = $commentWidget->update((array) $input, $where); - - if (!$result) { - return new IXR_Error(404, _t('评论不存在')); - } - - return true; - } - - /** - * 更新评论 - * - * @access public - * @param integer $blogId - * @param string $userName - * @param string $password - * @param mixed $post - * @param array $struct - * @return boolean - */ - public function wpNewComment($blogId, $userName, $password, $path, $struct) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - if (is_numeric($path)) { - $post = $this->singletonWidget('Widget_Archive', 'type=single', 'cid=' . $path, false); - } else { - /** 检查目标地址是否正确*/ - $pathInfo = Typecho_Common::url(substr($path, strlen($this->options->index)), '/'); - $post = Typecho_Router::match($pathInfo); - } - - /** 这样可以得到cid或者slug*/ - if (!isset($post) || !($post instanceof Widget_Archive) || !$post->have() || !$post->is('single')) { - return new IXR_Error(404, _t('这个目标地址不存在')); - } - - $input = array(); - $input['permalink'] = $post->pathinfo; - $input['type'] = 'comment'; - - if (isset($struct['comment_author'])) { - $input['author'] = $struct['author']; - } - - if (isset($struct['comment_author_email'])) { - $input['mail'] = $struct['author_email']; - } - - if (isset($struct['comment_author_url'])) { - $input['url'] = $struct['author_url']; - } - - if (isset($struct['comment_parent'])) { - $input['parent'] = $struct['comment_parent']; - } - - if (isset($struct['content'])) { - $input['text'] = $struct['content']; - } - - try { - $this->singletonWidget('Widget_Feedback', NULL, $input, false); - } catch (Typecho_Exception $e) { - return new IXR_Error(500, $e->getMessage()); - } - - return true; - } - - /**about MetaWeblog API, you can see http://www.xmlrpc.com/metaWeblogApi*/ - /** - * MetaWeblog API - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param struct $content - * @param bool $publish - * @access public - * @return int - */ - public function mwNewPost($blogId, $userName, $password, $content, $publish) - { - /** 检查权限*/ - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - /** 取得content内容 */ - $input = array(); - $type = isset($content['post_type']) && 'page' == $content['post_type'] ? 'page' : 'post'; - - $input['title'] = trim($content['title']) == NULL ? _t('未命名文档') : $content['title']; - - if (isset($content['slug'])) { - $input['slug'] = $content['slug']; - } else if (isset($content['wp_slug'])) { - //fix issue 338, wlw只发送这个 - $input['slug'] = $content['wp_slug']; - } - - $input['text'] = !empty($content['mt_text_more']) ? $content['description'] - . "\n<!--more-->\n" . $content['mt_text_more'] : $content['description']; - $input['text'] = $this->pluginHandle()->textFilter($input['text'], $this); - - $input['password'] = isset($content["wp_password"]) ? $content["wp_password"] : NULL; - $input['order'] = isset($content["wp_page_order"]) ? $content["wp_page_order"] : NULL; - - $input['tags'] = isset($content['mt_keywords']) ? $content['mt_keywords'] : NULL; - $input['category'] = array(); - - if (isset($content['postId'])) { - $input['cid'] = $content['postId']; - } - - if ('page' == $type && isset($content['wp_page_template'])) { - $input['template'] = $content['wp_page_template']; - } - - if (isset($content['dateCreated'])) { - /** 解决客户端与服务器端时间偏移 */ - $input['created'] = $content['dateCreated']->getTimestamp() - $this->options->timezone + $this->options->serverTimezone; - } - - if (!empty($content['categories']) && is_array($content['categories'])) { - foreach ($content['categories'] as $category) { - if (!$this->db->fetchRow($this->db->select('mid') - ->from('table.metas')->where('type = ? AND name = ?', 'category', $category))) { - $result = $this->wpNewCategory($blogId, $userName, $password, array('name' => $category)); - if (true !== $result) { - return $result; - } - } - - $input['category'][] = $this->db->fetchObject($this->db->select('mid') - ->from('table.metas')->where('type = ? AND name = ?', 'category', $category) - ->limit(1))->mid; - } - } - - $input['allowComment'] = (isset($content['mt_allow_comments']) && (1 == $content['mt_allow_comments'] - || 'open' == $content['mt_allow_comments'])) ? 1 : ((isset($content['mt_allow_comments']) && (0 == $content['mt_allow_comments'] - || 'closed' == $content['mt_allow_comments'])) ? 0 : $this->options->defaultAllowComment); - - $input['allowPing'] = (isset($content['mt_allow_pings']) && (1 == $content['mt_allow_pings'] - || 'open' == $content['mt_allow_pings'])) ? 1 : ((isset($content['mt_allow_pings']) && (0 == $content['mt_allow_pings'] - || 'closed' == $content['mt_allow_pings'])) ? 0 : $this->options->defaultAllowPing); - - $input['allowFeed'] = $this->options->defaultAllowFeed; - $input['do'] = $publish ? 'publish' : 'save'; - - /** 调整状态 */ - if (isset($content["{$type}_status"])) { - $status = $this->wordpressToTypechoStatus($content["{$type}_status"], $type); - - if ('publish' == $status || 'waiting' == $status || 'private' == $status) { - $input['do'] = 'publish'; - - if ('private' == $status) { - $input['private'] = 1; - } - } else { - $input['do'] = 'save'; - } - } - - /** 对未归档附件进行归档 */ - $unattached = $this->db->fetchAll($this->select()->where('table.contents.type = ? AND - (table.contents.parent = 0 OR table.contents.parent IS NULL)', 'attachment'), array($this, 'filter')); - - if (!empty($unattached)) { - foreach ($unattached as $attach) { - if (false !== strpos($input['text'], $attach['attachment']->url)) { - if (!isset($input['attachment'])) { - $input['attachment'] = array(); - } - - $input['attachment'][] = $attach['cid']; - } - } - } - - /** 调用已有组件 */ - try { - /** 插入 */ - if ('page' == $type) { - $this->singletonWidget('Widget_Contents_Page_Edit', NULL, $input, false)->action(); - } else { - $this->singletonWidget('Widget_Contents_Post_Edit', NULL, $input, false)->action(); - } - - return $this->singletonWidget('Widget_Notice')->getHighlightId(); - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - } - - /** - * 编辑post - * - * @param int $postId - * @param string $userName - * @param string $password - * @param struct $content - * @param bool $publish - * @access public - * @return int - */ - public function mwEditPost($postId, $userName, $password, $content, $publish = true) - { - $content['postId'] = $postId; - return $this->mwNewPost(1, $userName, $password, $content, $publish); - } - - /** - * 获取指定id的post - * - * @param int $postId - * @param string $userName - * @param string $password - * @access public - * @return void - */ - public function mwGetPost($postId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - /** 对文章内容做截取处理,以获得description和text_more*/ - list($excerpt, $more) = $this->getPostExtended($post); - /** 只需要分类的name*/ - $categories = Typecho_Common::arrayFlatten($post->categories, 'name'); - $tags = Typecho_Common::arrayFlatten($post->tags, 'name'); - - $postStruct = array( - 'dateCreated' => new IXR_Date($this->options->timezone + $post->created), - 'userid' => $post->authorId, - 'postid' => $post->cid, - 'description' => $excerpt, - 'title' => $post->title, - 'link' => $post->permalink, - 'permalink' => $post->permalink, - 'categories' => $categories, - 'mt_excerpt' => $post->description, - 'mt_text_more' => $more, - 'mt_allow_comments' => intval($post->allowComment), - 'mt_allow_pings' => intval($post->allowPing), - 'mt_keywords' => implode(', ', $tags), - 'wp_slug' => $post->slug, - 'wp_password' => $post->password, - 'wp_author' => $post->author->name, - 'wp_author_id' => $post->authorId, - 'wp_author_display_name' => $post->author->screenName, - 'date_created_gmt' => new IXR_Date($post->created), - 'post_status' => $this->typechoToWordpressStatus($post->status, 'post'), - 'custom_fields' => array(), - 'sticky' => 0 - ); - - return $postStruct; - } - - /** - * 获取前$postsNum个post - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param int $postsNum - * @access public - * @return postStructs - */ - public function mwGetRecentPosts($blogId, $userName, $password, $postsNum) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $posts = $this->singletonWidget('Widget_Contents_Post_Admin', "pageSize={$postsNum}", 'status=all'); - - $postStructs = array(); - /** 如果这个post存在则输出,否则输出错误 */ - while ($posts->next()) { - /** 对文章内容做截取处理,以获得description和text_more*/ - list($excerpt, $more) = $this->getPostExtended($posts); - - /** 只需要分类的name*/ - /** 可以用flatten函数处理 */ - $categories = Typecho_Common::arrayFlatten($posts->categories, 'name'); - $tags = Typecho_Common::arrayFlatten($posts->tags, 'name'); - - $postStructs[] = array( - 'dateCreated' => new IXR_Date($this->options->timezone + $posts->created), - 'userid' => $posts->authorId, - 'postid' => $posts->cid, - 'description' => $excerpt, - 'title' => $posts->title, - 'link' => $posts->permalink, - 'permalink' => $posts->permalink, - 'categories' => $categories, - 'mt_excerpt' => $posts->description, - 'mt_text_more' => $more, - 'mt_allow_comments' => intval($posts->allowComment), - 'mt_allow_pings' => intval($posts->allowPing), - 'mt_keywords' => implode(', ', $tags), - 'wp_slug' => $posts->slug, - 'wp_password' => $posts->password, - 'wp_author' => $posts->author->name, - 'wp_author_id' => $posts->authorId, - 'wp_author_display_name' => $posts->author->screenName, - 'date_created_gmt' => new IXR_Date($posts->created), - 'post_status' => $this->typechoToWordpressStatus($posts->status, 'post'), - 'custom_fields' => array(), - 'sticky' => 0 - ); - } - - return $postStructs; - } - - /** - * 获取所有的分类 - * - * @param int $blogId - * @param string $userName - * @param string $password - * @access public - * @return categoryStructs - */ - public function mwGetCategories($blogId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return ($this->error); - } - - $categories = $this->singletonWidget('Widget_Metas_Category_List'); - - /** 初始化category数组*/ - $categoryStructs = array(); - while ($categories->next()) { - $categoryStructs[] = array( - 'categoryId' => $categories->mid, - 'parentId' => '0', - 'categoryName' => $categories->name, - 'categoryDescription' => $categories->description, - 'description' => $categories->name, - 'htmlUrl' => $categories->permalink, - 'rssUrl' => $categories->feedUrl, - ); - } - - return $categoryStructs; - } - - /** - * mwNewMediaObject - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param mixed $data - * @access public - * @return void - */ - public function mwNewMediaObject($blogId, $userName, $password, $data) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $result = Widget_Upload::uploadHandle($data); - - if (false === $result) { - return IXR_Error(500, _t('上传失败')); - } else { - - $insertId = $this->insert(array( - 'title' => $result['name'], - 'slug' => $result['name'], - 'type' => 'attachment', - 'status' => 'publish', - 'text' => serialize($result), - 'allowComment' => 1, - 'allowPing' => 0, - 'allowFeed' => 1 - )); - - $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $insertId) - ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); - - /** 增加插件接口 */ - $this->pluginHandle()->upload($this); - - return array( - 'file' => $this->attachment->name, - 'url' => $this->attachment->url - ); - } - } - - /** - * 获取 $postNum个post title - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param int $postNum - * @access public - * @return postTitleStructs - */ - public function mtGetRecentPostTitles($blogId, $userName, $password, $postsNum) - { - if (!$this->checkAccess($userName, $password)) { - return ($this->error); - } - - /** 读取数据*/ - $posts = $this->singletonWidget('Widget_Contents_Post_Admin', "pageSize=$postsNum", 'status=all'); - - /**初始化*/ - $postTitleStructs = array(); - while ($posts->next()) { - $postTitleStructs[] = array( - 'dateCreated' => new IXR_Date($this->options->timezone + $posts->created), - 'userid' => $posts->authorId, - 'postid' => $posts->cid, - 'title' => $posts->title, - 'date_created_gmt' => new IXR_Date($this->options->timezone + $posts->created) - ); - } - - return $postTitleStructs; - } - - /** - * 获取分类列表 - * - * @param int $blogId - * @param string $userName - * @param string $password - * @access public - * @return categories - */ - public function mtGetCategoryList($blogId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return ($this->error); - } - - $categories = $this->singletonWidget('Widget_Metas_Category_List'); - - /** 初始化categorise数组*/ - $categoryStructs = array(); - while ($categories->next()) { - $categoryStructs[] = array( - 'categoryId' => $categories->mid, - 'categoryName' => $categories->name, - ); - } - return $categoryStructs; - } - - /** - * 获取指定post的分类 - * - * @param int $postId - * @param string $userName - * @param string $password - * @access public - * @return void - */ - public function mtGetPostCategories($postId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - /** 格式化categories*/ - $categories = array(); - foreach ($post->categories as $category) { - $categories[] = array( - 'categoryName' => $category['name'], - 'categoryId' => $category['mid'], - 'isPrimary' => true - ); - } - return $categories; - } - - /** - * 修改post的分类 - * - * @param int $postId - * @param string $userName - * @param string $password - * @param string $categories - * @access public - * @return bool - */ - public function mtSetPostCategories($postId, $userName, $password, $categories) - { - if (!$this->checkAccess($userName, $password, 'editor')) { - return $this->error; - } - - try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - $post->setCategories($postId, Typecho_Common::arrayFlatten($categories, 'categoryId'), - 'publish' == $post->status); - return true; - } - - /** - * 发布(重建)数据 - * - * @param int $postId - * @param string $userName - * @param string $password - * @access public - * @return bool - */ - public function mtPublishPost($postId, $userName, $password) - { - if (!$this->checkAccess($userName, $password, 'editor')) { - return $this->error; - } - - /** 过滤id为$postId的post */ - $select = $this->select()->where('table.contents.cid = ? AND table.contents.type = ?', $postId, 'post')->limit(1); - - /** 提交查询 */ - $post = $this->$db->fetchRow($select, array($this, 'push')); - if ($this->authorId != $this->user->uid && !$this->checkAccess($userName, $password, 'administrator')) { - return new IXR_Error(403, '权限不足.'); - } - - /** 暂时只做成发布*/ - $content = array(); - $this->update($content, $this->db->sql()->where('table.contents.cid = ?', $postId)); - - - } - - /** - * 取得当前用户的所有blog - * - * @param int $blogId - * @param string $userName - * @param string $password - * @access public - * @return void - */ - public function bloggerGetUsersBlogs($blogId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $struct = array(); - $struct[] = array( - 'isAdmin' => $this->user->pass('administrator', true), - 'url' => $this->options->siteUrl, - 'blogid' => '1', - 'blogName' => $this->options->title, - 'xmlrpc' => $this->options->xmlRpcUrl - ); - - return $struct; - } - - /** - * 返回当前用户的信息 - * - * @param int $blogId - * @param string $userName - * @param string $password - * @access public - * @return void - */ - public function bloggerGetUserInfo($blogId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - $struct = array( - 'nickname' => $this->user->screenName, - 'userid' => $this->user->uid, - 'url' => $this->user->url, - 'email' => $this->user->mail, - 'lastname' => '', - 'firstname' => '' - ); - - return $struct; - } - - /** - * 获取当前作者的一个指定id的post的详细信息 - * - * @param int $blogId - * @param int $postId - * @param string $userName - * @param string $password - * @access public - * @return void - */ - public function bloggerGetPost($blogId, $postId, $userName, $password) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - - try { - $post = $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}"); - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - - $categories = Typecho_Common::arrayFlatten($post->categories, 'name'); - - $content = '<title>' . $post->title . ''; - $content .= '' . implode(',', $categories) . ''; - $content .= stripslashes($post->text); - - $struct = array( - 'userid' => $post->authorId, - 'dateCreated' => new IXR_Date($this->options->timezone + $post->created), - 'content' => $content, - 'postid' => $post->cid - ); - return $struct; - } - - /** - * bloggerDeletePost - * 删除文章 - * @param mixed $blogId - * @param mixed $userName - * @param mixed $password - * @param mixed $publish - * @access public - * @return bool - */ - public function bloggerDeletePost($blogId, $postId, $userName, $password, $publish) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - try { - $this->singletonWidget('Widget_Contents_Post_Edit', NULL, "cid={$postId}", false)->deletePost(); - } catch (Typecho_Widget_Exception $e) { - return new IXR_Error($e->getCode(), $e->getMessage()); - } - } - - /** - * 获取当前作者前postsNum个post - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param int $postsNum - * @access public - * @return void - */ - public function bloggerGetRecentPosts($blogId, $userName, $password, $postsNum) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - //todo:限制数量 - $posts = $this->singletonWidget('Widget_Contents_Post_Admin', "pageSize=$postsNum", 'status=all'); - - $postStructs = array(); - while ($posts->next()) { - $categories = Typecho_Common::arrayFlatten($posts->categories, 'name'); - - $content = '' . $posts->title . ''; - $content .= '' . implode(',', $categories) . ''; - $content .= stripslashes($posts->text); - - $struct = array( - 'userid' => $posts->authorId, - 'dateCreated' => new IXR_Date($this->options->timezone + $posts->created), - 'content' => $content, - 'postid' => $posts->cid, - ); - $postStructs[] = $struct; - } - if (NULL == $postStructs) { - return new IXR_Error('404', '没有任何文章'); - } - return $postStructs; - } - - /** - * bloggerGetTemplate - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param mixed $template - * @access public - * @return void - */ - public function bloggerGetTemplate($blogId, $userName, $password, $template) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - /** todo:暂时先返回true*/ - return true; - } - - /** - * bloggerSetTemplate - * - * @param int $blogId - * @param string $userName - * @param string $password - * @param mixed $content - * @param mixed $template - * @access public - * @return void - */ - public function bloggerSetTemplate($blogId, $userName, $password, $content, $template) - { - if (!$this->checkAccess($userName, $password)) { - return $this->error; - } - /** todo:暂时先返回true*/ - return true; - } - - /** - * pingbackPing - * - * @param string $source - * @param string $target - * @access public - * @return void - */ - public function pingbackPing($source, $target) - { - /** 检查源地址是否存在*/ - if (!($http = Typecho_Http_Client::get())) { - return new IXR_Error(16, _t('源地址服务器错误')); - } - - try { - - $http->setTimeout(5)->send($source); - $response = $http->getResponseBody(); - - if (200 == $http->getResponseStatus()) { - - if (!$http->getResponseHeader('x-pingback')) { - preg_match_all("/]*rel=[\"']([^\"']*)[\"'][^>]*href=[\"']([^\"']*)[\"'][^>]*>/i", $response, $out); - if (!isset($out[1]['pingback'])) { - return new IXR_Error(50, _t('源地址不支持PingBack')); - } - } - - } else { - return new IXR_Error(16, _t('源地址服务器错误')); - } - - } catch (Exception $e) { - return new IXR_Error(16, _t('源地址服务器错误')); - } - - /** 检查目标地址是否正确*/ - $pathInfo = Typecho_Common::url(substr($target, strlen($this->options->index)), '/'); - $post = Typecho_Router::match($pathInfo); - - /** 这样可以得到cid或者slug*/ - if (!($post instanceof Widget_Archive) || !$post->have() || !$post->is('single')) { - return new IXR_Error(33, _t('这个目标地址不存在')); - } - - if ($post) { - /** 检查是否可以ping*/ - if ($post->allowPing) { - - /** 现在可以ping了,但是还得检查下这个pingback是否已经存在了*/ - $pingNum = $this->db->fetchObject($this->db->select(array('COUNT(coid)' => 'num')) - ->from('table.comments')->where('table.comments.cid = ? AND table.comments.url = ? AND table.comments.type <> ?', - $post->cid, $source, 'comment'))->num; - - if ($pingNum <= 0) { - - /** 现在开始插入以及邮件提示了 $response就是第一行请求时返回的数组*/ - preg_match("/\([^<]*?)\<\/title\\>/is", $response, $matchTitle); - $finalTitle = Typecho_Common::removeXSS(trim(strip_tags($matchTitle[1]))); - - /** 干掉html tag,只留下*/ - $text = Typecho_Common::stripTags($response, ''); - - /** 此处将$target quote,留着后面用*/ - $pregLink = preg_quote($target); - - /** 找出含有target链接的最长的一行作为$finalText*/ - $finalText = ''; - $lines = explode("\n", $text); - - foreach ($lines as $line) { - $line = trim($line); - if (NULL != $line) { - if (preg_match("|]*href=[\"']{$pregLink}[\"'][^>]*>(.*?)|",$line)) { - if (strlen($line) > strlen($finalText)) { - /** 也要干掉,*/ - $finalText = Typecho_Common::stripTags($line); - } - } - } - } - - /** 截取一段字*/ - if (NULL == trim($finalText)) { - return new IXR_Error('17', _t('源地址中不包括目标地址')); - } - - $finalText = '[...]' . Typecho_Common::subStr($finalText, 0, 200, '') . '[...]'; - - $pingback = array( - 'cid' => $post->cid, - 'created' => $this->options->gmtTime, - 'agent' => $this->request->getAgent(), - 'ip' => $this->request->getIp(), - 'author' => $finalTitle, - 'url' => Typecho_Common::safeUrl($source), - 'text' => $finalText, - 'ownerId' => $post->author->uid, - 'type' => 'pingback', - 'status' => $this->options->commentsRequireModeration ? 'waiting' : 'approved' - ); - - /** 加入plugin */ - $pingback = $this->pluginHandle()->pingback($pingback, $post); - - /** 执行插入*/ - $insertId = $this->singletonWidget('Widget_Abstract_Comments')->insert($pingback); - - /** 评论完成接口 */ - $this->pluginHandle()->finishPingback($this); - - return $insertId; - - /** todo:发送邮件提示*/ - } else { - return new IXR_Error(48, _t('PingBack已经存在')); - } - } else { - return IXR_Error(49, _t('目标地址禁止Ping')); - } - } else { - return new IXR_Error(33, _t('这个目标地址不存在')); - } - } - - /** - * 回收变量 - * - * @access public - * @param string $methodName 方法 - * @return void - */ - public function hookAfterCall($methodName) - { - if (!empty($this->_usedWidgetNameList)) { - foreach ($this->_usedWidgetNameList as $key => $widgetName) { - $this->destory($widgetName); - unset($this->_usedWidgetNameList[$key]); - } - } - } - - - /** - * 入口执行方法 - * - * @access public - * @return void - */ - public function action() - { - if (isset($this->request->rsd)) { - echo -<< - - - Typecho - http://www.typecho.org/ - {$this->options->siteUrl} - - - - - - - - -EOF; - } else if (isset($this->request->wlw)) { - echo -<< - - - Yes - Yes - Yes - Yes - Yes - - Yes - Yes - No - Yes - Yes - Yes - - Yes - Yes - Yes - Yes - Yes - Yes - - Yes - - Yes - No - Yes - True - No - - - -EOF; - } else { - /** 直接把初始化放到这里 */ - new IXR_Server(array( - /** WordPress API */ - 'wp.getPage' => array($this, 'wpGetPage'), - 'wp.getPages' => array($this, 'wpGetPages'), - 'wp.newPage' => array($this, 'wpNewPage'), - 'wp.deletePage' => array($this, 'wpDeletePage'), - 'wp.editPage' => array($this, 'wpEditPage'), - 'wp.getPageList' => array($this, 'wpGetPageList'), - 'wp.getAuthors' => array($this, 'wpGetAuthors'), - 'wp.getCategories' => array($this, 'mwGetCategories'), - 'wp.newCategory' => array($this, 'wpNewCategory'), - 'wp.suggestCategories' => array($this, 'wpSuggestCategories'), - 'wp.uploadFile' => array($this, 'mwNewMediaObject'), - - /** New Wordpress API since 2.9.2 */ - 'wp.getUsersBlogs' => array($this, 'wpGetUsersBlogs'), - 'wp.getTags' => array($this, 'wpGetTags'), - 'wp.deleteCategory' => array($this, 'wpDeleteCategory'), - 'wp.getCommentCount' => array($this, 'wpGetCommentCount'), - 'wp.getPostStatusList' => array($this, 'wpGetPostStatusList'), - 'wp.getPageStatusList' => array($this, 'wpGetPageStatusList'), - 'wp.getPageTemplates' => array($this, 'wpGetPageTemplates'), - 'wp.getOptions' => array($this, 'wpGetOptions'), - 'wp.setOptions' => array($this, 'wpSetOptions'), - 'wp.getComment' => array($this, 'wpGetComment'), - 'wp.getComments' => array($this, 'wpGetComments'), - 'wp.deleteComment' => array($this, 'wpDeleteComment'), - 'wp.editComment' => array($this, 'wpEditComment'), - 'wp.newComment' => array($this, 'wpNewComment'), - 'wp.getCommentStatusList' => array($this, 'wpGetCommentStatusList'), - - - /** Blogger API */ - 'blogger.getUsersBlogs' => array($this, 'bloggerGetUsersBlogs'), - 'blogger.getUserInfo' => array($this, 'bloggerGetUserInfo'), - 'blogger.getPost' => array($this, 'bloggerGetPost'), - 'blogger.getRecentPosts' => array($this, 'bloggerGetRecentPosts'), - 'blogger.getTemplate' => array($this, 'bloggerGetTemplate'), - 'blogger.setTemplate' => array($this, 'bloggerSetTemplate'), - 'blogger.deletePost' => array($this, 'bloggerDeletePost'), - - /** MetaWeblog API (with MT extensions to structs) */ - 'metaWeblog.newPost' => array($this, 'mwNewPost'), - 'metaWeblog.editPost' => array($this, 'mwEditPost'), - 'metaWeblog.getPost' => array($this, 'mwGetPost'), - 'metaWeblog.getRecentPosts' => array($this, 'mwGetRecentPosts'), - 'metaWeblog.getCategories' => array($this, 'mwGetCategories'), - 'metaWeblog.newMediaObject' => array($this, 'mwNewMediaObject'), - - /** MetaWeblog API aliases for Blogger API */ - 'metaWeblog.deletePost' => array($this, 'bloggerDeletePost'), - 'metaWeblog.getTemplate' => array($this, 'bloggerGetTemplate'), - 'metaWeblog.setTemplate' => array($this, 'bloggerSetTemplate'), - 'metaWeblog.getUsersBlogs' => array($this, 'bloggerGetUsersBlogs'), - - /** MovableType API */ - 'mt.getCategoryList' => array($this, 'mtGetCategoryList'), - 'mt.getRecentPostTitles' => array($this, 'mtGetRecentPostTitles'), - 'mt.getPostCategories' => array($this, 'mtGetPostCategories'), - 'mt.setPostCategories' => array($this, 'mtSetPostCategories'), - 'mt.publishPost' => array($this, 'mtPublishPost'), - - /** PingBack */ - 'pingback.ping' => array($this,'pingbackPing'), - 'pingback.extensions.getPingbacks' => array($this,'pingbackExtensionsGetPingbacks'), - - /** hook after */ - 'hook.afterCall' => array($this, 'hookAfterCall'), - )); - } - } -} diff --git a/php/typecho11/favicon.ico b/php/typecho11/favicon.ico new file mode 100644 index 000000000..576ee0af7 Binary files /dev/null and b/php/typecho11/favicon.ico differ diff --git a/php/typecho12/.gitignore b/php/typecho12/.gitignore index 2b9ce0a56..2a5a73910 100644 --- a/php/typecho12/.gitignore +++ b/php/typecho12/.gitignore @@ -1 +1,20 @@ -config.inc.php \ No newline at end of file +.vscode/ +.idea/ +.temp/ +vendor/ +node_modules/ +composer.lock +package.lock + +# Typehcho v1.2 + +/admin +/install +/usr/plugins/HelloWorld +/usr/themes/default +/usr/uploads +/var +/index.php +/install.php +LICENSE.txt +config.inc.php diff --git a/php/typecho12/favicon.ico b/php/typecho12/favicon.ico new file mode 100644 index 000000000..576ee0af7 Binary files /dev/null and b/php/typecho12/favicon.ico differ